

#include	"ZBoxColl.h"



int		typebox;


int MBOXinit(mmachine m)
{
    boxnet s;
    int nbox,nlink;
    int l,p;

    nlink=MMpull(m)>>1;
    nbox=MMpull(m)>>1;

    if ((nlink<=0)||(nbox<=0)) return MMpush(m,NIL);
        
    l=(sizeof(struct BoxNet)+3)>>2;
    p=MMmalloc(m,l,TYPEBUF); if (p==NIL) return MERRMEM;
    s=(boxnet)MMstart(m,p);

    if (BOXinit(s,nbox,nlink)) return MMpush(m,NIL);
    return MMpush(m,p+p+1);
}

int MBOXreset(mmachine m)
{
    int p;
    boxnet s;
    
    p=MMget(m,0);
    if (p==NIL) return 0;
    s=(boxnet)MMstart(m,p>>1);
    BOXreset(s);
    MMset(m,0,0);
    return 0;
}

int MBOXend(mmachine m)
{
    int p;
    boxnet s;
    
    p=MMget(m,0);
    if (p==NIL) return 0;
    s=(boxnet)MMstart(m,p>>1);
    BOXend(s);
    MMset(m,0,0);
    return 0;
}

int nummbox=0;
int MBOXcreate(mmachine m)
{
    boxnet s;
    int nbox,nlink;
    int l,p;

    nlink=MMpull(m)>>1;
    nbox=MMpull(m)>>1;

    if ((nlink<=0)||(nbox<=0))
	{
		MMset(m,0,NIL);
		return 0;
	}
        
    l=(sizeof(struct BoxNet)+3)>>2;
    p=MMmalloc(m,l,TYPEBUF); if (p==NIL) return MERRMEM;
    s=(boxnet)MMstart(m,p);

    if (BOXinit(s,nbox,nlink))
	{
		MMset(m,0,NIL);
		return 0;
	}
    if (MMpush(m,p+p+1))return MERRMEM;

	return OBJcreate(m,typebox,nummbox++,-1,0);
}

int MBOXdestroy(mmachine m)
{
	int p;

    p=MMget(m,0);
    if (p==NIL) return 0;
	OBJdelTM(m,typebox,p);
	MMset(m,0,0);
	return 0;
}

int MBOXdestroy2(mmachine m,int q,int p)
{
	boxnet s;

    s=(boxnet)MMstart(m,p>>1);
    BOXend(s);
	return 0;
}

int MBOXload(mmachine m)
{
    int p,q;
    boxnet s;
    
    q=MMpull(m);
    p=MMpull(m);
    
    if ((q==NIL)||(p==NIL)) return MMpush(m,NIL);

    s=(boxnet)MMstart(m,p>>1);

    p=BOXload(s,MMstartstr(m,q>>1));
    return MMpush(m,p*2);
}

int MBOXprojection(mmachine m)
{
    int p,q,x,r,k;
    boxnet s;
	ZVector3 v,u;

	r=MMpull(m)>>1;
    q=MMpull(m)>>1;
    p=MMpull(m);
    if (p==NIL) return MMpush(m,NIL);
    s=(boxnet)MMstart(m,p>>1);

    x=MMfetch(m,q,0)>>1; u.x=x;
    x=MMfetch(m,q,1)>>1; u.y=x;
    x=MMfetch(m,q,2)>>1; u.z=x;

    p=BOXprojection(s,&v,&u,r);
    if (p==-1) return MMpush(m,NIL);
	if (MMpush(m,p*2)) return MERRMEM;
    x=v.x; if (MMpush(m,x<<1)) return MERRMEM;
    x=v.y; if (MMpush(m,x<<1)) return MERRMEM;
    x=v.z; if (MMpush(m,x<<1)) return MERRMEM;
    if (MMpush(m,3*2)) return MERRMEM;
    if (k=MBdeftab(m)) return k;
    if (MMpush(m,2*2)) return MERRMEM;
    return MBdeftab(m);
}

int MBOXmove(mmachine m)
{
    int p,q,x,r,k,b;
    boxnet s;
	ZVector3 u;

	r=MMpull(m)>>1;
    q=MMpull(m)>>1;
	b=MMpull(m)>>1;
    p=MMpull(m);
    if (p==NIL) return MMpush(m,NIL);
    s=(boxnet)MMstart(m,p>>1);

    x=MMfetch(m,q,0)>>1; u.x=x;
    x=MMfetch(m,q,1)>>1; u.y=x;
    x=MMfetch(m,q,2)>>1; u.z=x;

    p=BOXmove(s,b,&u,r);
    if (p==-1) return MMpush(m,NIL);
	if (MMpush(m,p*2)) return MERRMEM;
    x=u.x; if (MMpush(m,x<<1)) return MERRMEM;
    x=u.y; if (MMpush(m,x<<1)) return MERRMEM;
    x=u.z; if (MMpush(m,x<<1)) return MERRMEM;
    if (MMpush(m,3*2)) return MERRMEM;
    if (k=MBdeftab(m)) return k;
    if (MMpush(m,2*2)) return MERRMEM;
    return MBdeftab(m);
}

int MBOXcenter(mmachine m)
{
    int p,o,x;
    boxnet s;
	ZVector3 v;

    o=MMpull(m);
    p=MMpull(m);
    if (p==NIL) return MMpush(m,NIL);
    s=(boxnet)MMstart(m,p>>1);
    p=BOXcenter(s,o>>1,&v);
    if (p==-1) return MMpush(m,NIL);
    x=v.x; if (MMpush(m,x<<1)) return MERRMEM;
    x=v.y; if (MMpush(m,x<<1)) return MERRMEM;
    x=v.z; if (MMpush(m,x<<1)) return MERRMEM;
    if (MMpush(m,3*2)) return MERRMEM;
    return MBdeftab(m);
}

int MBOXbyNum(mmachine m)
{
    int p,o;
    boxnet s;

    o=MMpull(m);
    p=MMget(m,0);
    if (p==NIL) return 0;
    s=(boxnet)MMstart(m,p>>1);
    p=BOXbyNum(s,o>>1);
    if (p!=-1) p*=2;
    MMset(m,0,p);
    return 0;
}
int MBOXactivate(mmachine m)
{
    int p,o;
    boxnet s;

    o=MMpull(m);
    p=MMget(m,0);
    if (p==NIL) return 0;
    s=(boxnet)MMstart(m,p>>1);
    p=BOXactivate(s,o>>1);
    if (p!=-1) p*=2;
    MMset(m,0,p);
    return 0;
}
int MBOXdesactivate(mmachine m)
{
    int p,o;
    boxnet s;

    o=MMpull(m);
    p=MMget(m,0);
    if (p==NIL) return 0;
    s=(boxnet)MMstart(m,p>>1);
    p=BOXdesactivate(s,o>>1);
    if (p!=-1) p*=2;
    MMset(m,0,p);
    return 0;
}
int MBOXsize(mmachine m)
{
    int p,o;
    boxnet s;

    o=MMpull(m);
    p=MMget(m,0);
    if (p==NIL) return 0;
    s=(boxnet)MMstart(m,p>>1);
    p=BOXsize(s,o>>1);
    if (p!=-1) p*=2;
    MMset(m,0,p);
    return 0;
}
int MBOXnumber(mmachine m)
{
    int p,o;
    boxnet s;

    o=MMpull(m);
    p=MMget(m,0);
    if (p==NIL) return 0;
    s=(boxnet)MMstart(m,p>>1);
    p=BOXnumber(s,o>>1);
    if (p!=-1) p*=2;
    MMset(m,0,p);
    return 0;
}







///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////																											   ////
///										DECLARATION DES FONCTIONS POUR SCOL											///
////																											   ////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



#define NBOXPKG 16


//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition des noms de fonction SCOL
//////////////////////////////////////////////////////////////////////////////////////////////
char* mboxname[NBOXPKG]=
{
	"SBox",
	"Box",
	"MBOXinit",
	"MBOXreset",
	"MBOXend",
	"MBOXload",
	"MBOXprojection",
	"MBOXmove",
	"MBOXcenter",
	"MBOXbyNum",
	"MBOXactivate",
	"MBOXdesactivate",
	"MBOXsize",
	"MBOXnumber",
	"MBOXcreate",
	"MBOXdestroy"
};



//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition des pointeurs sur fonctions
//////////////////////////////////////////////////////////////////////////////////////////////
int (*mboxfun[NBOXPKG])(mmachine m)=
{
	NULL,
	NULL,
	MBOXinit,
	MBOXreset,
	MBOXend,
	MBOXload,
	MBOXprojection,
	MBOXmove,
	MBOXcenter,
	MBOXbyNum,
	MBOXactivate,
	MBOXdesactivate,
	MBOXsize,
	MBOXnumber,
	MBOXcreate,
	MBOXdestroy
};



//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition du nombre de paramètres
//////////////////////////////////////////////////////////////////////////////////////////////
int mboxnarg[NBOXPKG]=
{
	TYPTYPE,
	TYPTYPE,
	2,
	1,
	1,
	2,
	3,
	4,
	2,
	2,
	2,
	2,
	2,
	2,
	3,
	1
};



//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition des grammaires fontionnelles
//////////////////////////////////////////////////////////////////////////////////////////////
char* mboxtype[NBOXPKG]=
{
	NULL,
	NULL,
	"fun [I I] SBox",
	"fun [SBox] I",
	"fun [SBox] I",
	"fun [SBox S] I",
	"fun [SBox [I I I] I] [Box [I I I]]",
	"fun [SBox Box [I I I] I] [Box [I I I]]",
	"fun [SBox Box] [I I I]",
	"fun [SBox I] Box",
	"fun [SBox Box] I",
	"fun [SBox Box] I",
	"fun [SBox Box] I",
	"fun [SBox Box] I",
	"fun [Chn I I] SBox",
	"fun [SBox] I"

};



int SCOLloadBOX(mmachine m)
{
    int k;

	k = PKhardpak(m, "ZooBox", NBOXPKG, mboxname, mboxfun, mboxnarg, mboxtype);

	typebox = OBJregister(0,0,MBOXdestroy2,"OBJTYPEBOXSW");

	return k;
}
