#include <ctype.h>
#include "g_visu.h"
#include "v_view.h"
#include "v_extern.h"
#include "c_menu.h"
#include "c_glob.h"
#include "c_struct.h"

extern Font V_menuFont;
static FILE *C_File;
static YRectangle *C_icon_pos;
static int C_PeekValue, C_ViewValue;
int C_atomicValue = 0;

static char *C_menu[] = {
			"SAVE RAM",
			"READ RAM",
			"SAVE DISK",
			"READ DISK",
			"NO ATOMIC PEEK",
			"OK",
			"CANCEL",
			"VIEW :\0        ", /* need static room for later on */
			"PEEK :\0        ",
			"% SCROLL :\0    ",
			"ALL VISIBLE",
			"ALL INVISIBLE"
};

void C_setMenu()
{
static int first;

	if (first == 0) {
		C_icon_pos = (YRectangle *)mbkalloc(12 * sizeof(YRectangle));
		first++;
	}
	C_icon_pos[C_SR].x = C_SR_X;
	C_icon_pos[C_SR].y = C_SR_Y;
	C_icon_pos[C_SR].width = C_SR_DX;
	C_icon_pos[C_SR].height = C_SR_DY;
	C_icon_pos[C_SR].t = C_SR_X + C_SR_T;

	C_icon_pos[C_RR].x = C_RR_X;
	C_icon_pos[C_RR].y = C_RR_Y;
	C_icon_pos[C_RR].width = C_RR_DX;
	C_icon_pos[C_RR].height = C_RR_DY;
	C_icon_pos[C_RR].t = C_RR_X + C_RR_T;

	C_icon_pos[C_SD].x = C_SD_X;
	C_icon_pos[C_SD].y = C_SD_Y;
	C_icon_pos[C_SD].width = C_SD_DX;
	C_icon_pos[C_SD].height = C_SD_DY;
	C_icon_pos[C_SD].t = C_SD_X + C_SD_T;

	C_icon_pos[C_RD].x = C_RD_X;
	C_icon_pos[C_RD].y = C_RD_Y;
	C_icon_pos[C_RD].width = C_RD_DX;
	C_icon_pos[C_RD].height = C_RD_DY;
	C_icon_pos[C_RD].t = C_RD_X + C_RD_T;

	C_icon_pos[C_GEOM].x = C_GEOM_X;
	C_icon_pos[C_GEOM].y = C_GEOM_Y;
	C_icon_pos[C_GEOM].width = C_GEOM_DX;
	C_icon_pos[C_GEOM].height = C_GEOM_DY;
	C_icon_pos[C_GEOM].t = C_GEOM_X + C_GEOM_T;

	C_icon_pos[C_EX].x = C_EX_X;
	C_icon_pos[C_EX].y = C_EX_Y;
	C_icon_pos[C_EX].width = C_EX_DX;
	C_icon_pos[C_EX].height = C_EX_DY;
	C_icon_pos[C_EX].t = C_EX_X + C_EX_T;

	C_icon_pos[C_CA].x = C_CA_X;
	C_icon_pos[C_CA].y = C_CA_Y;
	C_icon_pos[C_CA].width = C_CA_DX;
	C_icon_pos[C_CA].height = C_CA_DY;
	C_icon_pos[C_CA].t = C_CA_X + C_CA_T;

	C_icon_pos[C_VI].x = C_VI_X;
	C_icon_pos[C_VI].y = C_VI_Y;
	C_icon_pos[C_VI].width = C_VI_DX;
	C_icon_pos[C_VI].height = C_VI_DY;
	C_icon_pos[C_VI].t = C_VI_X + C_VI_T;

	C_icon_pos[C_PE].x = C_PE_X;
	C_icon_pos[C_PE].y = C_PE_Y;
	C_icon_pos[C_PE].width = C_PE_DX;
	C_icon_pos[C_PE].height = C_PE_DY;
	C_icon_pos[C_PE].t = C_PE_X + C_PE_T;

	C_icon_pos[C_SC].x = C_SC_X;
	C_icon_pos[C_SC].y = C_SC_Y;
	C_icon_pos[C_SC].width = C_SC_DX;
	C_icon_pos[C_SC].height = C_SC_DY;
	C_icon_pos[C_SC].t = C_SC_X + C_SC_T;

	C_icon_pos[C_AV].x = C_AV_X;
	C_icon_pos[C_AV].y = C_AV_Y;
	C_icon_pos[C_AV].width = C_AV_DX;
	C_icon_pos[C_AV].height = C_AV_DY;
	C_icon_pos[C_AV].t = C_AV_X + C_AV_T;

	C_icon_pos[C_AI].x = C_AI_X;
	C_icon_pos[C_AI].y = C_AI_Y;
	C_icon_pos[C_AI].width = C_AI_DX;
	C_icon_pos[C_AI].height = C_AI_DY;
	C_icon_pos[C_AI].t = C_AI_X + C_AI_T;
}

void C_drawIcon(i, state)
int i, state;
{
	XFillRectangle(display, C_window, C_gcIcon, C_icon_pos[i].x,
						C_icon_pos[i].y, C_icon_pos[i].width, C_icon_pos[i].height);
	V_surround(C_window,C_icon_pos[i].x, C_icon_pos[i].y, C_icon_pos[i].width,
					C_icon_pos[i].height, state);
	XDrawImageString(display, C_window, C_gcIconText, C_icon_pos[i].t-state,
							C_icon_pos[i].y+C_DY_TXT-state,
							C_menu[i], strlen (C_menu[i]));
}

C_setVP(str,v)
char *str;
int v;
{
	switch (v) {
		case FILL:
			if (*str == 'V')
				C_icon_pos[C_VI].t = C_VI_X + C_VI_T + 9;
			else 
				C_icon_pos[C_PE].t = C_PE_X + C_PE_T + 9;
			strcat(str, "FILL  ");
			break;
		case PATTERN:
			if (*str == 'V')
				C_icon_pos[C_VI].t = C_VI_X + C_VI_T;
			else 
				C_icon_pos[C_PE].t = C_PE_X + C_PE_T;
			strcat(str, "PATTERN");
			break;
		case OUTLINE:
			if (*str == 'V')
				C_icon_pos[C_VI].t = C_VI_X + C_VI_T;
			else 
				C_icon_pos[C_PE].t = C_PE_X + C_PE_T;
			strcat(str, "OUTLINE");
			break;
	}
}

C_setValues()
{
	strcpy(C_menu[C_PE], "PEEK : ");
	C_setVP(C_menu[C_PE],C_PeekValue);
	strcpy(C_menu[C_VI], "VIEW : ");
	C_setVP(C_menu[C_VI], C_ViewValue);
	strcpy(C_menu[C_SC], "% SCROLL : ");
	strcat(C_menu[C_SC], C_ScrollValue);
	C_atomicValue ^= 1;
	C_atomic();
}


C_drawMenu()
{
register int i;

	XFillRectangle(display, C_window, C_gcBgnd, 0, 0, C_W_WIDTH, C_W_HEIGHT);

	C_setValues();

	for (i = 0; i <= C_AI; i++)
		C_drawIcon(i, OFF);

	for (i = 0; i < C_NB_OBJECT; i++)
		SwitchRefresh(i);
}

int C_clickedIcon(xClick, yClick)
int xClick, yClick;
{
register int i;

   for (i = 0; i <= 11; i++)
      if (((xClick > C_icon_pos[i].x) &&
            (xClick < C_icon_pos[i].x + C_icon_pos[i].width)) &&
            ((yClick > C_icon_pos[i].y) &&
            (yClick < C_icon_pos[i].y + C_icon_pos[i].height)))
         return i;
   return C_NO_ICON; /* INSCREEN */
}


SwitchRefresh (i)
int i;
{
register int y;

	y = C_Y_Switch + (i * C_DY_Switch);
	XFillRectangle (display, C_window, C_gcText, C_Xrect, y, C_DXrect, C_DYrect);
	XDrawImageString(display, C_window, C_ObjectGc[i], 
							C_ObjectVisibility[i] == C_SWITCH_ON ? C_Xon : C_Xoff, 
 							y + C_DYstr, C_ObjectName[i], strlen (C_ObjectName[i]));
}

C_AllVisible ()
{
register int i;

	for (i = 0; i < C_NB_OBJECT; i++) {
			C_ObjectVisibility[i] = C_SWITCH_ON;
			SwitchRefresh(i);
	}
}

C_AllInvisible ()
{
register int i;

	for (i = 0; i < C_NB_OBJECT; i++) {
			C_ObjectVisibility[i] = C_SWITCH_OFF;
			SwitchRefresh (i);
	}
}

C_ActionKey (car)
KeySym car;
{
register int i;

	if ((car == XK_Return) || (car == XK_Linefeed) || (car == XK_KP_Enter)) {
		if (strlen (C_NewScrollValue) < 3) {
			i = atoi (C_NewScrollValue);
			if ((i < 1) || (i > 99)) {
				XBell (display, 50);
				return;
			}
			strcpy (C_ScrollValue, C_NewScrollValue);
			strcpy (C_NewScrollValue, "");
			strcpy (C_menu[C_SC], "% SCROLL : ");
			strcat (C_menu[C_SC], C_ScrollValue);
			C_IconFlag = C_NO_ICON;
			C_drawIcon(C_SC, OFF);
			return;
		}
	}
	if ((car == XK_BackSpace) || (car == XK_Delete)) {
		i = strlen (C_NewScrollValue) - 1;
		if (i < 0) {
			i = 0;
			XBell (display, 50);
			return;
		}
		C_NewScrollValue[i] = '\0';
		strcpy (C_menu[C_SC], "NEW VALUE : ");
		strcat (C_menu[C_SC], C_NewScrollValue);
		C_drawIcon(C_SC, ON);
		return;
	}
	if (isdigit(car)) {
		if ((i = strlen (C_NewScrollValue)) < 2) {
			C_NewScrollValue[i] = car;
			C_NewScrollValue[i + 1] = '\0';
			strcpy (C_menu[C_SC], "NEW VALUE : ");
			strcat (C_menu[C_SC], C_NewScrollValue);
			C_drawIcon(C_SC, ON);
			return;
		} else {
			XBell (display, 50);
			return;
		}
	}
}


C_WriteDisk ()
{
register int i;

	if ((C_File = fopen(".genview.stp", "w")) == NULL) {
			printf("Cannot open .genview.stp\n");
			return;
	}
	fprintf(C_File, "%d %d %d %d",
				C_Config_List.C_VISIBLE,
				C_Config_List.C_SCROLL,
				C_Config_List.C_VIEW,
				C_Config_List.C_PEEK);
	fclose (C_File);
}

C_ReadDisk ()
{
register int i;

	if ((C_File = fopen(".genview.stp", "r")) == NULL) {
		for (i = 0; i < C_NB_OBJECT; i++)
			C_ObjectVisibility[i] = C_SWITCH_ON;
		strcpy(C_ScrollValue, "25");
		C_WriteConf();
		return C_SWITCH_ON;
	}
	fscanf(C_File, "%d%d%d%d",
				&C_Config_List.C_VISIBLE,
				&C_Config_List.C_SCROLL,
				&C_Config_List.C_VIEW,
				&C_Config_List.C_PEEK);
	fclose(C_File);
	return C_SWITCH_OFF;
}

C_WriteConf()
{
register int i;

	C_Config_List.C_VISIBLE = 0;
	for (i = 0; i < C_NB_OBJECT; i++)
		C_Config_List.C_VISIBLE |= C_ObjectVisibility[i] << i;
	C_Config_List.C_SCROLL = atoi (C_ScrollValue);
	C_Config_List.C_VIEW = C_ViewValue;
	C_Config_List.C_PEEK = C_PeekValue;
	if (dxWin < dyWin)
		V_pixDep = (long) ((dxWin * C_Config_List.C_SCROLL) / 100 - 1);
	else
		V_pixDep = (long) ((dyWin * C_Config_List.C_SCROLL) / 100 - 1);
}

C_ReadConf()
{
register int i;

	for (i = 0; i < C_NB_OBJECT; i++)
		C_ObjectVisibility[i] = 1 & (C_Config_List.C_VISIBLE >> i);
	sprintf(C_ScrollValue, "%d", C_Config_List.C_SCROLL);
	C_ViewValue = C_Config_List.C_VIEW;
	C_PeekValue = C_Config_List.C_PEEK;

	C_InitValues();

	C_setMenu();
	C_drawMenu();
}

C_getDiskInfo ()
{
register int i;

	if (C_ReadDisk() == C_SWITCH_OFF) {
		for (i = 0; i < C_NB_OBJECT; i++)
			C_ObjectVisibility[i] = 1 & (C_Config_List.C_VISIBLE >> i);
		sprintf(C_ScrollValue, "%d", C_Config_List.C_SCROLL);
		C_ViewValue = C_Config_List.C_VIEW;
		C_PeekValue = C_Config_List.C_PEEK;
	}
	C_InitValues ();
}


C_Peek()
{
	if (++C_PeekValue == 3)
		C_PeekValue = 0;
	strcpy(C_menu[C_PE], "PEEK : ");
	C_setVP(C_menu[C_PE],C_PeekValue);
}

C_View()
{
	if (++C_ViewValue == 3)
		C_ViewValue = 0;
	strcpy(C_menu[C_VI], "VIEW : ");
	C_setVP(C_menu[C_VI],C_ViewValue);
}

C_askScroll()
{
	strcpy(C_menu[C_SC], "NEW VALUE : ");
}

C_newScroll()
{
	strcpy(C_menu[C_SC], "% SCROLL : ");
	strcat(C_menu[C_SC], C_ScrollValue);
}

C_InitValues()
{
int i;

	for (i = 0; i < C_NB_OBJECT; i++)
		if ((C_ObjectVisibility[i] != C_SWITCH_ON) &&
				(C_ObjectVisibility[i] != C_SWITCH_OFF))
			C_ObjectVisibility[i] = C_SWITCH_ON;

	i = atoi (C_ScrollValue);
	if ((i < 1) || (i > 99))
		strcpy(C_ScrollValue, "25");

	if ((C_ViewValue != FILL) && (C_ViewValue != OUTLINE) &&
			(C_ViewValue != PATTERN))
		C_ViewValue = FILL;

	if ((C_PeekValue != FILL) && (C_PeekValue != OUTLINE) &&
			(C_PeekValue != PATTERN))
		C_PeekValue = PATTERN;
}

C_atomic()
{
int i;

	C_atomicValue ^= 1;
	if (C_atomicValue == 1) {
		strcpy(C_menu[C_GEOM], "ATOMIC PEEK");
		C_icon_pos[C_GEOM].t = C_GEOM_X + C_GEOM_T + 9;
		C_ObjectVisibility[8] = 0;
		C_ObjectVisibility[10] = 0;
		C_ObjectVisibility[17] = 0;
		C_ObjectVisibility[20] = 0;
		SwitchRefresh(8);
		SwitchRefresh(10);
		SwitchRefresh(17);
		SwitchRefresh(20);
	} else {
		strcpy(C_menu[C_GEOM], "NO ATOMIC PEEK");
		C_icon_pos[C_GEOM].t = C_GEOM_X + C_GEOM_T;
	}
}
