/*****************************************************************************
 *
 * File: vguilbox.c, Fredrik Kling 1997
 * Desc: Controls listboxes and so on....
 *
 * Updates:
 * -- Date -- | ----- Name ----- |-- Did what....
 * 1997-08-24 | Fredrik Kling    | Implementation
 *
 * Todo:
 *    Ska varje enskilt listobjekt f† en egen handle... eller ska de indexeras fr†n b”rjan ?
 *
 *
 ****************************************************************************/
#include "vgui/vgui.h"
#include "system/xstdio.h"
#include "vgui/vguilbox.h"

void vguilbox_init (VGUILISTBOX *lbox)
{
	lbox -> num = 0;
	lbox -> first = lbox -> last = lbox -> top = lbox -> bottom = lbox -> current = NULL;
}
void vguilbox_clear (int handle)
{
	VGUIGADGET *gad;
	VGUILISTBOX *lbox;
	VGUILBITEM *item,*next;

	gad = vguigad_gadfrmhand (handle);
	lbox = gad->lbox;

	if (lbox->first == NULL) return;

	item=lbox->first;
	while (item!=NULL)
	{
		next = item->next;
		xfree (item);
		item = next;
	}
	lbox -> num = 0;
	lbox -> first = lbox -> last = lbox -> top = lbox -> bottom = lbox -> current = NULL;
}
static void lbox_additem (VGUILISTBOX *lbox,char *str)
{
	VGUILBITEM *item;

	item = (VGUILBITEM *) xmalloc (sizeof (VGUILBITEM));
	sprintf (item->string,"%s",str);

	item -> next = NULL;
	item -> prev = lbox -> last;
	lbox -> last -> next = item;
	lbox -> last = item;
}
static void lbox_create (VGUILISTBOX *lbox, char *str)
{
	VGUILBITEM *item;

	item = (VGUILBITEM *) xmalloc (sizeof (VGUILBITEM));
	sprintf (item->string,"%s",str);

	item -> prev = item->next = NULL;

	lbox->first = item;
	lbox->last = item;
	lbox->top = item;
	lbox->bottom = NULL;		// Bottom pointer will be changed by drawing functions...
	//lbox->current = item;

	lbox -> num++;

}
void vguilbox_additem (int handle, char *str)
{
	VGUIGADGET *gad;
	VGUILISTBOX *lbox;

	gad = vguigad_gadfrmhand (handle);
	lbox = gad -> lbox;

	if (lbox->first!=NULL) lbox_additem (gad->lbox,str);
		else lbox_create (gad->lbox,str);


}
void vguilbox_draw (int x1, int y1, int x2, int y2, char *caption,VGUILISTBOX *lbox)
{
	int ys,yp;
	VGUILBITEM *item;

	vgui_printfxyc (x1,y1,VG_CBLACK,"%s",caption);

	y1+=8;
	vgui_line (x1, y1,x2,y1,VG_CDARK);
	vgui_line (x1, y1,x1,y2,VG_CDARK);
	vgui_line (x1, y2,x2+1,y2,VG_CLIGHT);
	vgui_line (x2, y1,x2,y2,VG_CLIGHT);
	vgui_bar (x1+1,y1+1,x2,y2,VG_CBLACK);

	ys = y2 - 4;

	if (lbox->top!=NULL)
	{
		for (item = lbox -> top, yp=y1+2; (yp<ys) && (item != NULL) ;yp+=10, item = item->next)
		{
			if (lbox->current==NULL) vgui_printfxyc (x1+2,yp,VG_CMEDIUM,"%s",item->string);
				else if (lbox->current == item) vgui_printfxyc (x1+2,yp,VG_CWHITE,"%s",item->string);
					else vgui_printfxyc (x1+2,yp,VG_CMEDIUM,"%s",item->string);
		}
	}

	//vgui_printfxyc (x1+2,y1+2,VG_CMEDIUM,"%s",str);
}

void vguilbox_highlight (int x1, int y1, int x2, int y2, char *caption,VGUILISTBOX *lbox)
{
	int ys,yp;
	VGUILBITEM *item;

	vgui_printfxyc (x1,y1,VG_CWHITE,"%s",caption);

	y1+=8;

	vgui_bar (x1+1,y1+1,x2,y2,VG_CBLACK);

	vgui_line (x1+1, y1+1,x2-1,y1+1,VG_CWHITE);
	vgui_line (x1+1, y1+1,x1+1,y2-1,VG_CWHITE);
	vgui_line (x1+1, y2-1,x2,y2-1,VG_CWHITE);
	vgui_line (x2-1, y1+1,x2-1,y2-1,VG_CWHITE);

	ys = y2 - 4;

	if (lbox->top!=NULL)
	{
		for (item = lbox -> top, yp=y1+2; (yp<ys) && (item != NULL) ;yp+=10, item = item->next)
			if (lbox->current==NULL) vgui_printfxyc (x1+2,yp,VG_CMEDIUM,"%s",item->string);
				else if (lbox->current == item) vgui_printfxyc (x1+2,yp,VG_CWHITE,"%s",item->string);
					else vgui_printfxyc (x1+2,yp,VG_CMEDIUM,"%s",item->string);
	}
}
void vguilbox_select (int x1, int y1, int x2, int y2, char *caption,VGUILISTBOX *lbox,int handle)
{
	int ys,yp,x,k2,k1,d,np,q,num_scroll,i;
	int y1s,sel;
	VGUILBITEM *item,*old;

	vgui_printfxyc (x1,y1,VG_CWHITE,"%s",caption);

	y1s = y1; // Save original for later use...
	y1+=8;
	vgui_line (x1, y1,x2,y1,VG_CDARK);
	vgui_line (x1, y1,x1,y2,VG_CDARK);
	vgui_line (x1, y2,x2+1,y2,VG_CLIGHT);
	vgui_line (x2, y1,x2,y2,VG_CLIGHT);
	vgui_bar (x1+1,y1+1,x2,y2,VG_CBLACK);

	ys = y2 - 4;

	// Print it out with current selection in white...
	old = lbox->current;
	if (lbox->current==NULL) lbox->current = lbox->first;
	if (lbox->top!=NULL)
	{
		for (item = lbox -> top, yp=y1+2; (yp<ys) && (item != NULL) ;yp+=10, item = item->next)
		{
			if (lbox->current==NULL) vgui_printfxyc (x1+2,yp,VG_CMEDIUM,"%s",item->string);
				else if (lbox->current == item) vgui_printfxyc (x1+2,yp,VG_CWHITE,"%s",item->string);
					else vgui_printfxyc (x1+2,yp,VG_CMEDIUM,"%s",item->string);
		}
	}

	q=np=FALSE;
	d = 1;

	// np = nopost_flag - if true we send a message to the user...
	// d = draw_flag - if true a new item has been selected lets redraw all
	while (!q)
	{
		while (vgui_kbhit())
		{
			k2 = 0;
			switch (k1=vgui_getkey())
			{
				case 0 :
					switch (k2 = vgui_getkey())
					{
						case VG_XKEYDOWN :
									if (lbox->current->next != NULL) lbox->current = lbox->current->next;
										else lbox->current = lbox->first;
									d=1;
									break;
					 	case VG_XKEYUP :
									if (lbox->current->prev!=NULL) lbox->current = lbox->current->prev;
										else lbox->current = lbox->last;
									d=1;
									break;
					} // switch k2..
					break;

				case VG_KEYESC :
					q = TRUE;
					np = TRUE;	// S„tt nopost flaggan..
					break;
				case VG_KEYSPACE :
				case VG_KEYENTER :
					q = TRUE;
					break;
			} //  switch k1
		} // while kbhit()
		// should we update the drawing stuff...
		if (d)
			if ((lbox->top!=NULL) && (lbox->current!=NULL))
			{
				lbox->top = lbox->first;
				num_scroll=0;
				for (item = lbox->top, yp=y1+2; (item!=NULL) && (item!=lbox->current->next); yp+=10, item=item->next)
					if (yp>=ys) num_scroll++;

				if (num_scroll>0) for (i=0,lbox->top = lbox->first;i<num_scroll;i++,lbox->top = lbox->top->next);

				for (item = lbox -> top, yp=y1+2; (yp<ys) && (item != NULL) ;yp+=10, item = item->next)
				{
					if (item != lbox->current) vgui_printfxyc (x1+2,yp,VG_CMEDIUM,"%s",item->string);
						else vgui_printfxyc (x1+2,yp,VG_CWHITE,"%s",item->string);
				}
				vgui_xmovebuff (x1,y1,x2,y2,VG_CBLACK);
			}
	} // while (q)


	if (np) lbox->current = old;
		else
			{
				for (sel=0,item = lbox->top; (item!=NULL) && (item!=lbox->current); item=item->next,sel++);
				vgui_postmessage (VG_COMMAND, VGC_LISTBOX, handle, sel);
			}

	vguilbox_highlight (x1,y1s,x2,y2,caption,lbox);
}


