#include "skeleton.h"

/* object, object chain, and frame manipulation primitives */

obj_ptr locateframe(obj_ptr object)
    {
    if(object==NULL) return(NULL);
    while(object->frameup!=NULL)
        object = object->frameup;
    return(object);
    }

obj_ptr locatestart(obj_ptr object)
    {
    if(object==NULL) return(NULL);
    while(object->prev!=NULL)
        object = object->prev;
    return(object);
    }

void moveobject(obj_ptr object,int dx,int dy)
    {
    if(object!=NULL)
        {
        object->offset[0] = object->offset[0] + dx;
        object->offset[1] = object->offset[1] + dy;
        }
    }

void moveobjectchain(obj_ptr object,int dx,int dy)
    {
    while(object!=NULL)
        {
        object->offset[0] = object->offset[0] + dx;
        object->offset[1] = object->offset[1] + dy;
        object = object->next;
        }
    }

void addimage(obj_ptr object,line_ptr line,int type)
{
    if(line!=NULL)
    {
        if(type==IMAGE)
            object->image = line;
        else if(type==SKELETON)
            object->skeleton = line;
        else if(type==XOUTLINE)
            object->outline = line;
        object->entry = object->entry & type;
    }
}

obj_ptr makeobject(void)
    {
    obj_ptr object;

    object = (obj_ptr)malloc(sizeof(struct object));

    object->offset[0] = 0;
    object->offset[1] = 0;
    object->next = NULL;
    object->prev = NULL;
    object->frameup = NULL;
    object->framedown = NULL;
    object->image = NULL;
    object->skeleton = NULL;
    object->outline = NULL;
    object->entry = 0;
    object->ilaw = 0;

    return(object);
    }

void mergeobject(obj_ptr object,obj_ptr append)
    {
    int fixx,fixy,i;
    line_ptr line;

    fixx = 0;
    fixy = 0;

    if(object==NULL || append==NULL) return;

    fixx = object->offset[0] - append->offset[0];
    fixy = object->offset[1] - append->offset[1];

    if(append->image!=NULL)
        {
        if(fixx!=0 || fixy!=0)
            {
            line = append->image;
            while(line!=NULL)
                {
                for(i=0;i<line->number;i++)
                    {
                    line->pts->p[i][0] = line->pts->p[i][0] + fixx;
                    line->pts->p[i][1] = line->pts->p[i][1] + fixy;

                    }
                line = line->next;
                }
             }
        if(object->image!=NULL)
            appendline(object->image,append->image);
        else
            object->image = append->image;
        }
    if(object->skeleton==NULL)
        {
        if(fixx!=0 || fixy!=0)
            {
            line = append->skeleton;
            while(line!=NULL)
                {
                for(i=0;i<line->number;i++)
                    {
                    line->pts->p[i][0] = line->pts->p[i][0] + fixx;
                    line->pts->p[i][1] = line->pts->p[i][1] + fixy;
                    }
                line = line->next;
                }
             }
        object->skeleton = append->skeleton;
        }
    if(object->outline==NULL)
        {
        if(fixx!=0 || fixy!=0)
            {
            line = append->outline;
            while(line!=NULL)
                {
                for(i=0;i<line->number;i++)
                    {
                    line->pts->p[i][0] = line->pts->p[i][0] + fixx;
                    line->pts->p[i][1] = line->pts->p[i][1] + fixy;
                    }
                line = line->next;
                }
             }
        object->outline = append->outline;
        }
    }

void addobject(obj_ptr chain,obj_ptr object,int frames)
/* frames is the number of frames after chain that object is added */
{
    if(chain == NULL) return;
    for(;frames>1;frames--)
    {
        if(chain->next==NULL)
	{
            chain->next = makeobject();
	    chain->next->prev = chain;
	}
	chain=chain->next;
    }
    if(chain->next==NULL)
    {
        chain->next = object;
	object->prev = chain;
    }
    else
        mergeobject(chain->next,object);
}

void addchain(obj_ptr frame,obj_ptr chain)
{
    obj_ptr find;

    if(frame == NULL) return;

    while(chain!=NULL)
    {
        find = frame;
        while(find->framedown!=NULL)
            find = find->framedown;

        chain->frameup = find;
        find->framedown = chain;
        chain = chain->next;
        if(chain!=NULL)
        {
            if(frame->next==NULL)
	    {
                frame->next = makeobject();
		frame->next->prev = frame;
	    }
            frame = frame->next;
        }
    }
}

void removechain(obj_ptr chain)
{
    while(chain!=NULL)
    {
        chain->frameup->framedown = chain->framedown;
        chain->framedown->frameup = chain->frameup;
        chain->frameup = NULL;
        chain->framedown = NULL;
	chain = chain->next;
    }
}

void deletechain(obj_ptr chain)
{
    obj_ptr next;

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

/*
copyobject(object)

copychain(chain)

insertframe(frame)

deleteframe(frame)
 */
