#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define FALSE 0
#define TRUE 1

int readTrailer(FILE* f);
int readXRef(FILE* f);

static int startxref = 0;
static char buffer[1024];

int main(int argc, char** argv)
{
	FILE* f;
	if (argc<2) {
		printf("usage: pdf_tester <filename>\n");
		return -1;
	}

	f = fopen(argv[1], "rb");
	if (!f) {
		printf("unable to open file\n");
		return -1;
	}
	readTrailer(f);
	readXRef(f);
	fclose(f);

	
	return 0;
}

int fetchObject(FILE* f, char* entry)
{
	int savePos = ftell(f);
	int offset;
	int gen_num;
	char used;
	char* line = NULL;
	size_t line_length;
	
	offset = strtol(entry, NULL,10);
	gen_num = strtol(entry+11, NULL,10);
	used = *(entry+17);
	if(used == 'f')
		return;
	printf("\tfetching Object [offset=%i,gen=%i,used=%c]\n",offset,gen_num,used);

	fseek(f,offset,SEEK_SET);
	line = NULL;
	getline(&line, &line_length, f);
	printf("\t----> %s\n", line);
	free(line);

	fseek(f,savePos,SEEK_SET);
}

int readXRef(FILE* f)
{
	char* line = NULL;
	size_t line_length;
	int start, count;
	fseek(f,startxref,SEEK_SET);
	int i;

	printf("---XREF---\n");
	fread(buffer, sizeof(char), 4, f);
	if(!(buffer[0] == 'x' && buffer[1] == 'r' && buffer[2] == 'e' && buffer[3] == 'f')) {
		buffer[4] = '\0';
		printf("xref not found at startxref, found %s\n", buffer);
		return FALSE;
	}
	printf("xref found at startxref\n");
	
	//read the reste of the line
	line = NULL;
	getline(&line,&line_length,f);
	free(line);

	while(!feof(f)) {
		line = NULL;
		getline(&line,&line_length,f);
		if(sscanf(line, "%i %i",&start,&count) != 2)
			break;
		printf("start: %i, count: %i\n",start,count);
		free(line);
		line = NULL;
		for(i=0; i<count; i++) {
			char entry[20];
			fread(entry, sizeof(char),20,f);
			printf("%s",entry);
			fetchObject(f, entry);
		}

	}
	printf("---END XREF---\n");
}

int readTrailer(FILE* f)
{
	int i;
	int eof_pos; //eof offset from the end
	
	printf("---TRAILER---\n");
	fseek(f,-1024,SEEK_END);
	fread(buffer, sizeof(char), 1024, f);

	for(i=1024;i>4;i--) { //%%EOF is in last 1024 octets
		if(buffer[i] == 'F'&&
		   buffer[i-1] == 'O' && 
		   buffer[i-2] == 'E' && 
		   buffer[i-3] == '%' && 
		   buffer[i-4] == '%')
				break;	
		
	}
	if(i==1019) {
		printf("%%EOF not found\n");
		return FALSE;
	}
	eof_pos = 1024-i;
	printf("%%%%EOF found\n");

	fseek(f,-(eof_pos+1024),SEEK_END);
	fread(buffer, sizeof(char), 1024, f);

	for(i=1023; i>=0;i--) {
		if(buffer[i] >= 48 && buffer[i] <= 57) {//we have a number
			int j = i;
			while(buffer[j] >= 48 && buffer[j] <= 57) {//read the whole number
				startxref += (buffer[j]-48)*pow(10,(i-j));
				j--;
			}
			break;
		}
	}
	if (startxref == 0) {
		printf("startxref == 0\n");
		return FALSE;
	}
	printf("startxref: %i\n", startxref);
	
	printf("---END TRAILER---\n");
}

