#include "skeleton.h"
#include <exec/libraries.h>
#include <proto/intuition.h>
#include <proto/req.h>

FILE * ptr = NULL;

char f[DSIZE+FCHARS] = "",*file = &f[0];

struct ReqFileRequester	MyFileReqStruct;
char filename[FCHARS] = "";
char directoryname[DSIZE] = "";

BOOL filerequest(void)
{
	BOOL result;
	
	file[0] = 0;
	MyFileReqStruct.PathName = file;
	MyFileReqStruct.Dir = directoryname;
	MyFileReqStruct.File = filename;
	MyFileReqStruct.Flags = FRQCACHINGM;
	MyFileReqStruct.dirnamescolor = 2;
	MyFileReqStruct.devicenamescolor = 2;
	result = FileRequester(&MyFileReqStruct);
	PurgeFiles(&MyFileReqStruct);

	if(filename[0]==0)
		return(FALSE);
		
	return(result);
}

void new(void)
{
    obj_ptr frame,next,hold;

    frame = framehead;

    while(frame!=NULL)
    {
        next = frame->next;
        while(frame!=NULL)
        {
            hold = frame->framedown;
            if(frame->image!=NULL) deleteline(frame->image);
            if(frame->skeleton!=NULL) deleteline(frame->skeleton);
            if(frame->outline!=NULL) deleteline(frame->outline);
            free(frame,sizeof(struct object));
            frame = hold;
        }
        frame = next;
    }

/* adjust global variables */
    framehead = makeobject();
}


void writeline(line_ptr line)
{
	/* not too sure what will happen to structures with 0 pts */
	while(line!=NULL)
	{
		fwrite((char *)line,sizeof(struct line),1,ptr);
		if((line->pts!=NULL) && (line->number!=0))
			fwrite((char *)line->pts,sizeof(struct pts),line->number,ptr);
		line=line->next;
	}
}

line_ptr readline(void)
{
	line_ptr first,seg,prev;
	/* not too sure what will happen to structures with 0 pts */

	prev = NULL;
        seg=(line_ptr)malloc(sizeof(struct line));
	first = seg;
	do
	{
		if(fread((char *)seg,sizeof(struct line),1,ptr)==0)
		{
			free(seg,sizeof(struct line));
			if(prev!=NULL) prev->next = NULL;
			if(first==seg)
				return(NULL);
			else
				return(first);
			
		}
		if((seg->pts!=NULL) && (seg->number!=0))
		{
			seg->pts=(struct pts *)malloc(sizeof(struct pts)*POINTS*((seg->number-1)/POINTS+1));
			if(fread((char *)seg->pts,sizeof(struct pts),seg->number,ptr)!=seg->number)
			{
				free(seg->pts,sizeof(struct pts)*POINTS*((seg->number-1)/POINTS+1));
				seg->pts = NULL;
				seg->number = 0;
				seg->next = NULL;
				return(first);
			}
			if(seg->number==1)
			{
				seg->pts->p[1][0] = seg->pts->p[0][0];
				seg->pts->p[1][1] = seg->pts->p[0][1];
			}
		}
		else
		{
			seg->pts = NULL;
			seg->number = 0;
		}
		if(seg->next!=NULL)
			seg->next=(line_ptr)malloc(sizeof(struct line));
		prev = seg;
		seg = seg->next;
	}
	while(seg!=NULL);
	
	return(first);
}

void writeobject(obj_ptr object)
{
	if(object==NULL) return;

	fwrite((char *)object,sizeof(struct object),1,ptr);

	if(((object->entry&IMAGE)!=0) && (object->image!=NULL))
	{
		writeline(object->image);
	}
	if(((object->entry&SKELETON)!=0) && (object->skeleton!=NULL))
	{
		writeline(object->skeleton);
	}
	if(((object->entry&XOUTLINE)!=0) && (object->outline!=NULL))
	{
		writeline(object->outline);
	}
}

obj_ptr readobject(void)
{
	obj_ptr object;

	object = makeobject(); /* clear things up */
	if(fread((char *)object,sizeof(struct object),1,ptr)==0)
	{
		free(object,sizeof(struct object));
		return(NULL);
	}
	if(((object->entry&IMAGE)!=0) && (object->image!=NULL))
		object->image = readline();
	else
		object->image = NULL;	
	if(((object->entry&SKELETON)!=0) && (object->skeleton!=NULL))
		object->skeleton = readline();
	else
		object->skeleton = NULL;
	if(((object->entry&XOUTLINE)!=0) && (object->outline!=NULL))
		object->outline = readline();
	else
		object->outline = NULL;

	return(object);
}

void writechain(obj_ptr chain)
{
	/* writes first and any subsequents with entry flags*/
	obj_ptr next,hold;
	int count;
	
	while(chain!=NULL)
	{
		next = chain->next;
		hold = chain->next;
		
		count = 1;
		while((next!=NULL) && (next->entry==0))
		{
			next = next->next;
			count++;
		}
		if(next==NULL) count = 0;
		chain->next = (obj_ptr)count;	/* store number of frames to next */
		writeobject(chain);
		chain->next = hold;
		chain = next;
	}
}

obj_ptr readchain(void)
{
	/* writes first and any subsequents with entry flags*/
	obj_ptr first, object,next;
	int count;

	object = readobject();
	first = object;
	
	while(object!=NULL)
	{
		count = (int)object->next;
		object->frameup=object->framedown=NULL;
		if(count!=0)
		{
			next = readobject();
			object->next = NULL;
			addobject(object,next,count);
		}
		else
			next = NULL;
		object = next;
	}
	
	return(first);
}

void save(void)
{
    obj_ptr chain,frame;

    int count;

    ptr = fopen(file,"w");
    if(ptr==NULL) return;
    
    frame = framehead;
    count = 0;
    
    while(frame!=NULL)
    {
	chain = frame->framedown;
	while(chain!=NULL)
	{
		if(chain->prev==NULL)
		{
			chain->prev = (obj_ptr)count;
			writechain(chain);
		}
		chain = chain->framedown;
	}
	frame = frame->next;
	count++;
    }
    fclose(ptr);
}

void load(void)
{
    obj_ptr chain,frame;

    int count,pos;

    ptr = fopen(file,"r");
    if(ptr==NULL) return;
    
    new();
    count = 0;	/* 1 frame has header */
   
    chain = readchain();   
    while(chain!=NULL)
    {
    	pos = (int)chain->prev;
    	chain->prev = NULL;
    
    	if(pos>count)
    	{
		addobject(framehead,makeobject(),pos);
		count = pos;
    	}

    	frame = framehead;
    	for(;pos>0;pos--)
    		frame = frame->next;
    	addchain(frame,chain);
	
	chain = readchain();
    }
    fclose(ptr);
}
	
