/*****************************************************************************/
/* htmlfunctions.cpp - 27/10/99 - By Christophe LOREK - CRYO-NETWORKS        */
/*                                                                           */
/* SCOL functions of the libHTML                                             */
/*                                                                           */
/* last modified on 27/10/99 By Christophe LOREK                             */
/*****************************************************************************/



//
// Modifications History
//
//$ LB (13/06/2002)  : changed ObjBitmap management, according to the new ObjBitmap structure
//




#ifdef HTML_INCLUDE

#include <stdio.h>

#include "htmlfunctions.h"

#include "html.h"
#include "structs.h"
#include "parser.h"
#include "htmldraw.h"
#include "htmltree.h"

//extern cbmachine ww;

// HTML definitions
int OBJTYPHTML;
int HtmlHandler = 2;

/*
 * _CRhtml
 * "fun [Chn S] ObjHtml"
 */
int _CRhtml(mmachine m)
{
  int					buf;
	int					lenstr;
	char				*startstr;
	char				*inbuf;
	TagStruct		*roottag;
	HTML				*currentHTML;

	buf=MMpull(m)>>1;

	if ((buf==NIL))
	{
		MMechostr(MSKTRACE,"_CRHtml : S given is NIL...\n");
		MMset(m,0,NIL);					
		return 0;
	}
	startstr = MMstartstr(m,buf);

	lenstr = MMsizestr(m,buf);
	inbuf = (char*) malloc((lenstr+1)*sizeof(char));
	if (inbuf == NULL)
	{
		MMechostr(MSKDEBUG,"_CRHtml : could not allocate memory for inbuf...\n");
		MMset(m,0,NIL);
		return MERROK;
	}
  if (memcpy(inbuf,startstr,lenstr) == NULL) 
	{
		MMechostr(MSKDEBUG,"_CRHtml : could not copy data in inbuf...\n");
		free(inbuf);
		MMset(m,0,NIL);
		return MERROK;
	}
  inbuf[lenstr]='\0';

	roottag = parse(inbuf);
	currentHTML = new HTML(m,roottag);
	free(inbuf);
	FreeList(roottag);

// the ObjHtml is pushed on the stack by the HTML class constructor
	return OBJcreate(m,OBJTYPHTML,(int)HtmlHandler++,-1,0);
}

/*
 * _DShtml
 * "fun [Objhtml] I"
 */
int _DShtml(mmachine m)
{
	OBJdelTM(m,OBJTYPHTML,MMget(m,0));
	MMset(m,0,0);
	return 0;
}

/*
 * _GETrequiredFilesHtml
 * "fun [ObjHtml] [[S I] r1]"
 */
int _GETrequiredFilesHtml(mmachine m)
{
	int		objhtml;
	int		node;
	HTML	*currentHTML;

	
	objhtml=MMpull(m)>>1;
	if ((objhtml==NIL))
	{
		MMechostr(MSKTRACE,"GetRequiredFilesHtml : ObjHtml given is NIL...\n");
		return MMpush(m,NIL);
	}
	node = MMfetch(m,objhtml,OBJHTML_NODE)>>1;
	currentHTML = (HTML*) MMfetch(m,MMfetch(m,node,NODE_STRUCT)>>1,NODESTRUCT_STRUCT);
	if (currentHTML == NULL)
		return MMpush(m,NIL);

	currentHTML->URLListToScolStack(m);

	return 0;
}

int SetBitmapByUrl (mmachine m,int node,char *givenurl,int objvoidbuf)
{
	int						nodesontab,nodebrothertab;
	int						nodetype;
	HTMLBITMAP		*currentHTMLBITMAP;

	nodesontab = MMfetch(m,node,NODE_SON)>>1;
	if (nodesontab != NIL)
	{
		nodetype		= MMfetch(m,nodesontab,NODE_TYPE)>>1;
		switch (nodetype)
		{
			case NODE_TYPBITMAP:
				currentHTMLBITMAP = (HTMLBITMAP*) MMfetch(m,MMfetch(m,nodesontab,NODE_STRUCT)>>1,NODESTRUCT_STRUCT);
				if (!strcmp(currentHTMLBITMAP->Url(),givenurl))
				{
					MMstore(m,nodesontab,NODE_OBJBITMAP,(objvoidbuf << 1)+1);
					currentHTMLBITMAP->SetStatus(HTMLBITMAP_STATUS_OK);
				}

			default:
				SetBitmapByUrl (m,nodesontab,givenurl,objvoidbuf);
				break;
		}
	}

	nodebrothertab = MMfetch(m,node,NODE_BROTHER)>>1;
	if (nodebrothertab != NIL)
	{
		nodetype		= MMfetch(m,nodebrothertab,NODE_TYPE)>>1;
		switch (nodetype)
		{
			case NODE_TYPBITMAP:
				currentHTMLBITMAP = (HTMLBITMAP*) MMfetch(m,MMfetch(m,nodebrothertab,NODE_STRUCT)>>1,NODESTRUCT_STRUCT);
				if (!strcmp(currentHTMLBITMAP->Url(),givenurl))
				{
					MMstore(m,nodebrothertab,NODE_OBJBITMAP,(objvoidbuf << 1)+1);
					currentHTMLBITMAP->SetStatus(HTMLBITMAP_STATUS_OK);
				}

			default:
				SetBitmapByUrl (m,nodebrothertab,givenurl,objvoidbuf);
				break;
		}
	}
	return 0;
}

/*
 * _GIVEbitmapHtml
 * "fun [ObjHtml S ObjBitmap] I"
 *        HTML  URL   BMP    STATUS
 */
int _GIVEbitmapHtml(mmachine m)
{
	int						objvoidbuf;
	int						urlbuf;
	int						objhtmltab;
	int						nodehtmltab;
	char					*url;

	objvoidbuf	= MMpull(m)>>1;
	urlbuf			= MMpull(m)>>1;
	objhtmltab	= MMpull(m)>>1;

	if (objhtmltab == NIL)
	{
	MMechostr(MSKDEBUG,"_GIVEbitmapHtml : ObjHtml == NIL\n");
		return MMpush(m,1 << 1);
	}

	if (urlbuf == NIL)
	{
	MMechostr(MSKDEBUG,"_GIVEbitmapHtml : url == NIL\n");
		return MMpush(m,1 << 1);
	}

	if (objvoidbuf == NIL)
	{
	MMechostr(MSKDEBUG,"_GIVEbitmapHtml : ObjBitmap == NIL\n");
		return MMpush(m,1 << 1);
	}

	nodehtmltab = MMfetch(m,objhtmltab,OBJHTML_NODE)>>1;

	url = MMstartstr(m,urlbuf);
	SetBitmapByUrl (m,nodehtmltab,url,objvoidbuf);

	return MMpush(m,0 << 1);
}

/*
 * _DRAWhtml
 * "fun [ObjHtml ObjBitmap I I I I] ObjHtml"
 *        HTML     BMP     x y w h   HTML
 */
int _DRAWhtml(mmachine m)
{
	int						objvoidbuf;
	int						objhtmltab;
	int						nodehtmltab;
	PtrObjVoid		ptrOB;
	PtrObjBitmap	ptrBMP;
	HtmlBounds		bounds;
	int						cx,cy;

	bounds.h = MMpull(m)>>1;
	bounds.w = MMpull(m)>>1;
	bounds.y = MMpull(m)>>1;
	bounds.x = MMpull(m)>>1;
	objvoidbuf = MMpull(m)>>1;

	if (bounds.x == NIL) bounds.x = 0;
	if (bounds.y == NIL) bounds.y = 0;
	cx = 0;
	cy = 0;

	if ((objvoidbuf==NIL))
		return 0;
	ptrOB = (PtrObjVoid) MMstart(m,objvoidbuf);
	if (ptrOB->Type != OBJ_TYPE_BITMAP << 1)
		return -1;
	ptrBMP = (PtrObjBitmap) MMstart(m,ptrOB->Buffer >> 1);

	if (bounds.w == NIL) bounds.w = ptrBMP->TailleW;
	if (bounds.h == NIL) bounds.h = ptrBMP->TailleH;

	objhtmltab = MMget(m,0)>>1;
	if ((objhtmltab==NIL))
		return 0;
	nodehtmltab = MMfetch(m,objhtmltab,OBJHTML_NODE)>>1;
	if (ptrBMP->bits != NULL)
	{
		HtmlContent (m,nodehtmltab,ptrBMP,&bounds,&cx,&cy,HTMLCONTENT_FORMAT);
		HtmlContent (m,nodehtmltab,ptrBMP,&bounds,&cx,&cy,HTMLCONTENT_DRAW);
	}

	return 0;
}

/*
 * _GETlinkHtml
 * "fun [ObjHtml I I] S"
 *        HTML   X Y  URL
 */
int _GETlinkHtml(mmachine m)
{
	int						objhtmltab;
	int						nodehtmltab;
	int						x;
	int						y;
	char					*returnedurl;

	y = MMpull(m)>>1;
	x = MMpull(m)>>1;
	objhtmltab	= MMpull(m)>>1;

	if (x == NIL || y == NIL || objhtmltab == NIL)
		return MMpush(m,NIL);

	nodehtmltab = MMfetch(m,objhtmltab,OBJHTML_NODE)>>1;
	returnedurl = ClickHtml(m,nodehtmltab,x,y);

	if (returnedurl == NULL)
		return MMpush(m,NIL);

	return Mpushstrbloc(m,returnedurl);
}

/*
 * FreeNodeStruct
 */
int FreeNodeStruct(mmachine m,int node)
{
	HTML				*currentHTML;
	HTMLTEXT		*currentHTMLTEXT;
	HTMLBITMAP	*currentHTMLBITMAP;
	HTMLTABLE		*currentHTMLTABLE;
	HTMLROW			*currentHTMLROW;
	HTMLCELL		*currentHTMLCELL;
	int					nodetype;
	int					sonnode;
	int					brothernode;

	if (node == NIL) return 0;

	nodetype = MMfetch(m,node,NODE_TYPE)>>1;
	sonnode	= MMfetch(m,node,NODE_SON)>>1;
	brothernode	= MMfetch(m,node,NODE_BROTHER)>>1;

	switch (nodetype)
	{
		case NODE_TYPTEXT:
			currentHTMLTEXT = (HTMLTEXT*) MMfetch(m,MMfetch(m,node,NODE_STRUCT)>>1,NODESTRUCT_STRUCT);
			if (sonnode != NIL)
				FreeNodeStruct(m,sonnode);
			if (brothernode != NIL)
				FreeNodeStruct(m,brothernode);
			if (currentHTMLTEXT == NULL)
				return 0;	
			delete currentHTMLTEXT;
			MMstore(m,node,NODE_STRUCT,NULL);			
			break;

		case NODE_TYPBITMAP:
			currentHTMLBITMAP = (HTMLBITMAP*) MMfetch(m,MMfetch(m,node,NODE_STRUCT)>>1,NODESTRUCT_STRUCT);
			if (sonnode != NIL)
				FreeNodeStruct(m,sonnode);
			if (brothernode != NIL)
				FreeNodeStruct(m,brothernode);
			if (currentHTMLBITMAP == NULL)
				return 0;	
			delete currentHTMLBITMAP;
			MMstore(m,node,NODE_STRUCT,NULL);			
			break;

		case NODE_TYPTABLE:
			currentHTMLTABLE = (HTMLTABLE*) MMfetch(m,MMfetch(m,node,NODE_STRUCT)>>1,NODESTRUCT_STRUCT);
			if (sonnode != NIL)
				FreeNodeStruct(m,sonnode);
			if (brothernode != NIL)
				FreeNodeStruct(m,brothernode);
			if (currentHTMLTABLE == NULL)
				return 0;	
			delete currentHTMLTABLE;
			MMstore(m,node,NODE_STRUCT,NULL);			
			break;

		case NODE_TYPROW:
			currentHTMLROW = (HTMLROW*) MMfetch(m,MMfetch(m,node,NODE_STRUCT)>>1,NODESTRUCT_STRUCT);
			if (sonnode != NIL)
				FreeNodeStruct(m,sonnode);
			if (brothernode != NIL)
				FreeNodeStruct(m,brothernode);
			if (currentHTMLROW == NULL)
				return 0;	
			delete currentHTMLROW;
			MMstore(m,node,NODE_STRUCT,NULL);			
			break;

		case NODE_TYPCELL:
			currentHTMLCELL = (HTMLCELL*) MMfetch(m,MMfetch(m,node,NODE_STRUCT)>>1,NODESTRUCT_STRUCT);
			if (sonnode != NIL)
				FreeNodeStruct(m,sonnode);
			if (brothernode != NIL)
				FreeNodeStruct(m,brothernode);
			if (currentHTMLCELL == NULL)
				return 0;	
			delete currentHTMLCELL;
			MMstore(m,node,NODE_STRUCT,NULL);			
			break;

		case NODE_TYPHTML:
			currentHTML = (HTML*) MMfetch(m,MMfetch(m,node,NODE_STRUCT)>>1,NODESTRUCT_STRUCT);
			if (sonnode != NIL)
				FreeNodeStruct(m,sonnode);
			if (brothernode != NIL)
				FreeNodeStruct(m,brothernode);
			if (currentHTML == NULL)
				return 0;	
			delete currentHTML;
			MMstore(m,node,NODE_STRUCT,NULL);			
			break;

		default:
			break;
	}
	return 0;
}

/*
 * DestroyHtmlH
 */
int DestroyHtmlH(mmachine m,int handsys,int objm)
{
	int		objhtml;
	int		node;

	objhtml = objm >> 1;
	node = MMfetch(m,objhtml,OBJHTML_NODE)>>1;
	FreeNodeStruct(m,node);
	MMechostr(MSKTRACE,"Html destroyed...%i\n",handsys);
  return 0;
}

// **************

char* mHTMLname[NHTMLPKG]=
{"_CRhtml","_DShtml","_GETrequiredFilesHtml","_GIVEbitmapHtml","_DRAWhtml","_GETlinkHtml",
 "ObjHtml"
};

int (*mHTMLfun[NHTMLPKG])(mmachine m)=
{_CRhtml,_DShtml,_GETrequiredFilesHtml,_GIVEbitmapHtml,_DRAWhtml,_GETlinkHtml,
 NULL
};

int mHTMLnarg[NHTMLPKG]=
{2,1,1,3,6,3,
 TYPTYPE
};

char* mHTMLtype[NHTMLPKG]=
{"fun [Chn S] ObjHtml","fun [ObjHtml] I","fun [ObjHtml] [[S I] r1]","fun [ObjHtml S ObjBitmap] I","fun [ObjHtml ObjBitmap I I I I] ObjHtml","fun [ObjHtml I I] S",
 NULL
};

#endif