#include <conio.h>
#include <stdio.h>
#include <mem.h>
#include <string.h>
#include <bios.h>
#include <alloc.h>
#include <time.h>
#include <dos.h>

#define TRUE -1
#define FALSE 0

#include "smenu.h"

//----------------------------------------------------------------------------
//

void cursoroff()
{
asm	mov 	AH,0x01
asm	mov 	CH,0x20
asm	int	0x10
}

void cursoron()
{
asm 	mov 	AH,0x01
asm 	mov 	CL,0x07
asm 	mov 	CH,0x06
asm 	int	0x10
}


//----------------------------------------------------------------------------
//

void preparescreen(void)
{
char str[81];
int i;

textcolor(LIGHTGRAY);
textbackground(BLACK);
clrscr();
textbackground(BLACK);
str[80]=0;
gotoxy(1,24);
textcolor(WHITE);
cprintf("Ä");
textcolor(LIGHTGRAY);
cprintf("Ä");
textcolor(DARKGRAY);
memset(str,'Ä',76);
str[76]=0;
cprintf("%s",str);
textcolor(LIGHTGRAY);
cprintf("Ä");
textcolor(WHITE);
cprintf("Ä");

}

//----------------------------------------------------------------------------
//

void openbox(int left, int top, int right, int bot, char titre[])
{
int a;

char str[162];
char c[2],i;

textcolor(LIGHTCYAN);
textbackground(BLACK);
memset(str,'Ä',right-left-3);
str[right-left-3] = 0;
gotoxy(left,top);
textcolor(WHITE);
cprintf("Ú");
textcolor(LIGHTGRAY);
cprintf("Ä");
textcolor(DARKGRAY);
cprintf("%s",str); // ÙÚ  ¿ À  Ä
textcolor(LIGHTGRAY);
cprintf("Ä");
textcolor(WHITE);
cprintf("¿");

memset(str,' ',right-left-1);
str[right-left-1] = 0;
for(i=top+1,a=0;i<bot;i++,a++)
	{
	gotoxy(left,i);
    if (i==bot-1 || i == top+1)
		textcolor(LIGHTGRAY);
    else
		textcolor(DARKGRAY);
	cprintf("³");
	textcolor(WHITE);
	cprintf("%s",str);
    if (i == bot-1 || i == top+1)
		textcolor(LIGHTGRAY);
    else
		textcolor(DARKGRAY);
	cprintf("³");
	gettext(right+1,i,right+1,i,c);

	c[1] = (c[1] & 0xF0) + 8;
	puttext(right+1,i,right+1,i,c);
	}
memset(str,'Ä',right-left-3);
str[right-left-3]=0;
gotoxy(left,bot);
textcolor(WHITE);
cprintf("À");
textcolor(LIGHTGRAY);
cprintf("Ä");
textcolor(DARKGRAY);
cprintf("%s",str); // ÙÚ  ¿ À  Ä
textcolor(LIGHTGRAY);
cprintf("Ä");
textcolor(WHITE);
cprintf("Ù");
gettext(right+1,bot,right+1,bot,c);
c[1] = (c[1] & 0xF0) + 8;
puttext(right+1,bot,right+1,bot,c);

gettext(left+1,bot+1,right+1,bot+1,str);
for(i=0;i<right-left+1;i++)
	str[i*2+1] = (str[i*2+1] & 0xF0) + 8;
puttext(left+1,bot+1,right+1,bot+1,str);


textcolor(DARKGRAY);
gotoxy(right-strlen(titre)-4,top);
cprintf(" í ");
textcolor(CYAN);
cprintf("%s ",titre);
}

//----------------------------------------------------------------------------
//

void updateCD(int left, int top, int cd)
{
if (cd == 0)
	{
	textcolor(DARKGRAY);
	textbackground(BLACK);
	gotoxy(left+2,top-1);
	cprintf("Ä");
	}
else
	{
	textcolor(LIGHTGRAY);
	textbackground(BLACK);
	gotoxy(left+2,top-1);
	cprintf("%d",cd);
	textcolor(DARKGRAY);
	cprintf("Ä");
    }
}

int menu(int left, int top, int maxlen, char *item[], char *helpitem[], int sel, int countdown)
{
char str[80];
int i;
int nitems;
char c;
int functionkey;
clock_t last;

maxlen++;
textcolor(LIGHTGRAY);
textbackground(BLACK);
gotoxy(1,25);
memset(str,' ',79);
str[79]=0;
cprintf("%s",str);
for(i=0;;i++)
	{
	if (item[i] == NULL) break;
	gotoxy(left,i+top);
	memset(str,' ',maxlen-strlen(item[i]));
	str[maxlen-strlen(item[i])] = 0;
	cprintf(" %s%s",item[i],str);
	}
nitems = i-1;

_sel(left,top,sel,maxlen,item,helpitem,TRUE);

if (countdown != 0)
	{
	last = clock();
	updateCD(left, top, countdown);
    }
for(;;)
	{
	c = 0;
    if (countdown != 0 && clock() > last + 18)
    	{
		countdown--;
        updateCD(left, top, countdown);
        if (countdown==0)
			c = 13;
        last=clock();
        }
	if (bioskey(1))
		{
        if (countdown != 0)
        	{
	        countdown=0;
    	    updateCD(left, top, countdown);
            }
		c = getch();
		if (c == 0)
			{
			functionkey = TRUE;
			c = getch();
			}
		else functionkey = FALSE;
		}
	if (c == 0) continue;

	if ((c == 'P') && functionkey)
		{
		 if (sel < nitems)
			{
			_sel(left,top,sel,maxlen,item,helpitem,FALSE);
			sel++;
			_sel(left,top,sel,maxlen,item,helpitem,TRUE);
			}
		 }
	if ((c == 'H') && functionkey)
		{
		 if (sel > 0)
			{
			_sel(left,top,sel,maxlen,item,helpitem,FALSE);
			sel--;
			_sel(left,top,sel,maxlen,item,helpitem,TRUE);
			}
		 }
	if (c == 13) return(sel);
	if (c == 27) break;
	}
return(-1);
}

//----------------------------------------------------------------------------
//
void _sel(int left, int top, int sel, int maxlen, char *item[], char *helpitem[], int etat)
{
char str[81];

if (etat == TRUE)
	{
	textbackground(BLACK);
	gotoxy(1,25);
	textcolor(WHITE);
    if (*helpitem[sel] != 0)
	    {
		cprintf(" %c", *helpitem[sel]);
		textcolor(LIGHTGRAY);
	    if (helpitem[sel][1] != 0)
			cprintf("%s",&helpitem[sel][1]);
        }
	textcolor(WHITE);
	textbackground(CYAN);
	}
else
	{
	textcolor(LIGHTGRAY);
	textbackground(BLACK);
	gotoxy(1,25);
	memset(str,' ',79);
	str[79]=0;
	cprintf("%s",str);
	textcolor(LIGHTGRAY);
	textbackground(BLACK);
	}
gotoxy(left,top+sel);
memset(str,' ',maxlen-strlen(item[sel]));
str[maxlen-strlen(item[sel])] = 0;
cprintf(" %s%s",item[sel],str);
}

//----------------------------------------------------------------------------
//

void editfield(int left, int top, char str[], int maxlen)
{
char str2[80];
char str3[80];
int c,functionkey;
int len,curs,delall,codeok;

strcpy(str2,str);
curs = strlen(str);
printstr(left,top,str,maxlen,curs);

delall = TRUE;
len = strlen(str);

for(;;)
	{
	c = 0;
	if (bioskey(1))
		{
		c = getch();
		if (c == 0)
			{
			functionkey = TRUE;
			c = getch();
			}
		else functionkey = FALSE;
		if (c == '')
			{
			codeok = TRUE;
			c = getch();
			}
		else	codeok = FALSE;
		}
	if (c == 0) continue;

	if ((((c >=32) && !functionkey) || codeok) && (c != '\b') && (c != 13))
		{
		if (delall)
			{
			strcpy(str,"");
			len = 0;
			curs = 0;
			}
		if (len < maxlen)
			{
			if ((curs == len) && (curs > 0))
				{
				str[len] = c;
				str[len+1] = 0;
				}
			if (curs == 0)
				{
				strcpy(str3,str);
				strcpy(&str[1],str3);
				str[0] = c;
				}
			if ((curs > 0) && (curs < len))
				{
				strcpy(str3, &str[curs]);
				strcpy(&str[curs+1],str3);
				str[curs] = c;
				}
			len++;
			curs++;
			printstr(left,top,str,maxlen,curs);
			}
		}
	delall = FALSE;
	if ((c == 'K') && functionkey)
		{
		if (curs > 0) curs--;
		gotoxy(left+curs,top);
		}

	if ((c == 'M') && functionkey)
		{
		if (curs < len) curs++;
		gotoxy(left+curs,top);
		}

	if ((c == '\b') && !codeok)
		{
		if ((len > 0) && (curs > 0))

			{
			if (curs == len)
				str[len-1]=0;
			if (curs < len)
				strcpy(&str[curs-1],&str[curs]);
			len--;
			curs--;
			printstr(left,top,str,maxlen,curs);
			}
		}
	if ((c == 'S') && functionkey)
		{
		if (curs < len)
			{
			strcpy(&str[curs],&str[curs+1]);
			len--;
			printstr(left,top,str,maxlen,curs);
			}
		}

	if ((c == 'G') && functionkey)
		{
		curs = 0;
		printstr(left,top,str,maxlen,curs);
		}
	if ((c == 'O') && functionkey)
		{
		curs = len;
		printstr(left,top,str,maxlen,curs);
		}
	if ((c == 13) && !codeok)
		{
		cursoroff();
		textcolor(CYAN);
		textbackground(BLACK);
		gotoxy(left,top);
		memset(str3,' ',maxlen+1-strlen(str));
		str3[maxlen+1-strlen(str)] =0;
		cprintf("%s%s",str,str3);
		return;
		}
	if ((c == 27) && !codeok)
		{
		cursoroff();
		strcpy(str,str2);
		textcolor(CYAN);
		textbackground(BLACK);
		gotoxy(left,top);
		memset(str3,' ',maxlen+1-strlen(str));
		str3[maxlen+1-strlen(str)] =0;
		cprintf("%s%s",str,str3);
		return;
		}
	}
}

void printstr(int left, int top, char str[], int maxlen, int curs)
{
char str3[80];

cursoroff();
textcolor(BLUE);
textbackground(GREEN);
gotoxy(left, top);
memset(str3,'°',maxlen+1-strlen(str));
str3[maxlen+1-strlen(str)] =0;
cprintf("%s%s",str,str3);
gotoxy(left+curs,top);
cursoron();
}

//--------------------------------------------Message Box---------------------
char messagebox(char *msg, char *title)
{
int i;
char *buf1;
char k;

i = strlen(msg);

buf1 = (char *)malloc(((((80-i)/2)+i+4)-(80-i)/2)*2*(13-10+2));
gettext((80-i)/2,10,((80-i)/2)+i+4,13,buf1);
openbox((80-i)/2,10,((80-i)/2)+i+3,12,title);
textcolor(CYAN);
textbackground(BLACK);
gotoxy((80-i)/2+2,11);
cprintf("%s",msg);
k = getch();
puttext((80-i)/2,10,((80-i)/2)+i+4,13,buf1);
free(buf1);
return(k);
}

//----------------------------------------------------------------------------
// SCROLL UNE FENETRE AVEC C1,L1,C2,L2,COULEUR,DIR

void scroll(int left, int top, int right, int bot, int color, int direction)
{
union REGS inregs, outregs;
struct SREGS segregs;

inregs.h.ah = direction;
inregs.h.al = 1;
inregs.h.bh = color<<4;
inregs.h.ch = top;
inregs.h.cl = left;
inregs.h.dh = bot;
inregs.h.dl = right;
int86x(0x10, &inregs, &outregs, &segregs);
}

sMenuClass::sMenuClass(void)
{
int i;

backBuffer = NULL;
item = (char **)malloc(25*4);
hlp = (char **)malloc(25*4);
title=NULL;
maxlen=0;
nobj=0;
x1=0;
x2=0;
y1=0;
y2=0;
countdown=0;
}

sMenuClass::~sMenuClass(void)
{
char str[81];
if (backBuffer != NULL)
	{
    puttext(x1,y1,x2,y2,backBuffer);
	free(backBuffer);
    }
for(int i=0;;i++)
	{
	if (item[i] == NULL) break;
    free(item[i]);
    free(hlp[i]);
	}
free(item);
free(hlp);
if (title != NULL) free(title);

textcolor(LIGHTGRAY);
textbackground(BLACK);
gotoxy(1,25);
memset(str,' ',79);
str[79]=0;
cprintf("%s",str);
textcolor(LIGHTGRAY);
textbackground(BLACK);
}

int sMenuClass::run(int s)
{
return menu(x1+1,y1+1,maxlen+2,item, hlp, s, countdown);
}

void sMenuClass::addItem(char *itemName, char *itemHelp)
{
if (nobj == 24)
	return;
item[nobj] = strdup(itemName);
hlp[nobj] = strdup(itemHelp);
item[++nobj]=NULL;
}

void sMenuClass::setPos(int x, int y)
{
x1 = x-1;
y1 = y-1;
}

void sMenuClass::setTitle(char *t)
{
title = strdup(t);
}

void sMenuClass::draw(void)
{
for(int i=0;;i++)
	{
	if (item[i] == NULL) break;
    if (strlen(item[i]) > maxlen) maxlen = strlen(item[i]);
	}
nobj = i;

x2 = x1+maxlen+6;
y2 = y1+nobj+2;

backBuffer=(char*)malloc((x2-x1+1)*(y2-y1+1)*2);
gettext(x1, y1, x2, y2, backBuffer);
openbox(x1, y1, x2-1, y2-1, title);
}

void sMenuClass::setCountdown(int secs)
{
countdown=secs;
}
