/* Set up the basic primitives for Layer control */

#include <stdio.h>
#include <string.h>
#include "\usr\include\intr_lib.h"
/* #include "\usr\include\intr_gr.h" */
#include "program.h"
#include "eelayer.h"


#define MAX_LAYERS 44
#define LAYER_OFF 0
#define LAYER_ON  1
#define LAYER_ENABLED 2
#define LAYER_UNUSED  4

#define BLACK		0
#define RED		4
#define GREEN		2
#define BLUE		1
#define YELLOW		14
#define CYAN		3
#define MAGENTA		5
#define WHITE		15


static char *UsedLayers[] ={
	"Wire",
	"Bus",
	"Gate",
	"IEEE",
	"PinFun",
	"PinNum",
	"PinNam",
	"RefDes",
	"Attr",
	"Device",
	"Notes",
	"NetNam",
	"Pin",
	"END"
};
static int LayerInfo[] ={
	 WHITE,0x8200,
	 YELLOW,0x0100,
	 CYAN,0x0100,
	 RED,0x0100, 
	 BLUE,0x0100, 
	 YELLOW,0x0100, 
	 BLUE,0x0100, 
	 YELLOW,0x0100, 
	 YELLOW,0x0100, 
	 CYAN,0x0100, 
	 BLUE,0x0100, 
	 RED,0x0100,
	 WHITE,0x0100
};
static int ColorSet[47];
static int BaseColorMap[8] ={
	WHITE,BLACK,RED,GREEN,BLUE,YELLOW,CYAN,MAGENTA
};
char ShowData[47][20];

void SetColorSet()
{
	int pt = 0;
	ColorSet[pt] = BaseColorMap[EELayerWire];
	pt++;
	ColorSet[pt] = BaseColorMap[EELayerBus];
	pt++;
	ColorSet[pt] = BaseColorMap[EELayerGate];
	pt++;
	ColorSet[pt] = BaseColorMap[EELayerIEEE];
	pt++;
	ColorSet[pt] = BaseColorMap[EELayerPinFun];
	pt++;
	ColorSet[pt] = BaseColorMap[EELayerPinNum];
	pt++;
	ColorSet[pt] = BaseColorMap[EELayerPinNam];
	pt++;
	ColorSet[pt] = BaseColorMap[EELayerRefDes];
	pt++;
	ColorSet[pt] = BaseColorMap[EELayerAttr];
	pt++;
	ColorSet[pt] = BaseColorMap[EELayerDevice];
	pt++;
	ColorSet[pt] = BaseColorMap[EELayerNotes];
	pt++;
	ColorSet[pt] = BaseColorMap[EELayerNetNam];
	pt++;
	ColorSet[pt] = BaseColorMap[EELayerPin];
	pt++;
	while(pt!=46)
		ColorSet[pt++]=BLACK;
}
void SeedLayers(Window)
EEWindowStruct *Window;
{
	int pt;
	
	Window->Layer = (LayerStruct *) MyMalloc(sizeof(LayerStruct));
	Window->Layer->CommonColor = WHITE;
	Window->Layer->Flags = 0;
	pt=0;
	Window->Layer->CurrentWidth = 1;
/* seed Up the Layer Strings and colours, set all user layers off */
	while((strcmp(UsedLayers[pt],"END"))!=0){
		/* set layer name up */
	 
		strcpy(Window->Layer->LayerNames[pt],UsedLayers[pt]);
		Window->Layer->LayerStatus[pt]=
			 (LayerInfo[(pt * 2) +1] & 0x0f00)/0x100;
	 
		Window->Layer->LayerColor[pt] = ColorSet[pt];
		if(LayerInfo[(pt * 2) +1] & 0x8200)
			Window->Layer->CurrentLayer=pt;
	 
		pt++;
	}
	 
	Window->Layer->NumberOfLayers=pt-1;
	while(pt!=MAX_LAYERS){
		sprintf(Window->Layer->LayerNames[pt],"User%d",pt);

		
		Window->Layer->LayerStatus[pt] = LAYER_UNUSED;
							/* layers clear */
							/* and Off */
		Window->Layer->LayerColor[pt] = INTR_COLOR_BLACK;
		/* Colours Black */ 
		pt++;
	}
	sprintf(Window->StatusL,"%8s",
		Window->Layer->LayerNames[Window->Layer->CurrentLayer]); 
	 
}
/*****************************************************************************
* Routine to Display Layer window drawing.				     *
*****************************************************************************/

void ShowLayers()
{
	int pt;
	
	char LayerMode[0x10];

	/* basic code to display the Layer data to user */
    

    
    pt=0;
	sprintf(ShowData[0],"       Quit");
	sprintf(ShowData[1],"  New Layer");
	while(pt!= ReturnLayerNumber() +1 ){
    	
	switch(ReturnLayerMode(pt)){
		case LAYER_OFF :
			sprintf(LayerMode,"Off");
			break;
		case LAYER_ON :
			sprintf(LayerMode,"On");
			break;
		case LAYER_ENABLED :
			sprintf(LayerMode,"Use");
			break;
		case LAYER_UNUSED :
			sprintf(LayerMode,"N/A");
			break;
	}

	if(pt == ReturnCurrentLayer())
		sprintf(ShowData[pt+2],"%8s %4s A",
			ReturnLayerName(pt),LayerMode);
	else
		sprintf(ShowData[pt+2],"%8s %4s  ",
			ReturnLayerName(pt),LayerMode);
	 pt++;


    }
}

/* Start of routines to change the Layer Setups, commands will be	*/
/* AddNewLayer	-	Add another usable layer to the list, (User)	*/
/* ChangeLayerMode	-	Change the Display Mode of a Layer	*/
/* ChangeLayerColor	-	Change the drawing colour of a Layer	*/
/* ChangeLayername	-	Change a defined LayerName, Watch for	*/
/*			Silly changes in the default names!		*/
/* QUIT		-	Quit back to draw mode from Layer Control	*/

static 	char	*Layerstr[] ={
	"Change Name      ",
	"Change Mode      ",
	"Change Colour    ",
	"Set Active Layer ", 
};
static char *LayerColor[] ={
	"Black",
	"Red",
	"Green",
	"Blue",
	"Yellow",
	"Cyan",
	"Magenta         ",
	"White"
};
static char *LayerMode[] ={
	"Off",
	"On",
	"Use",
	"Use and Active       "
};
static int LayerColorData[] ={
	BLACK,
	RED,
	GREEN,
	BLUE,
	YELLOW,
	CYAN,
	MAGENTA,
	WHITE
};

#define LAYER_MENU_SIZE (sizeof(Layerstr) / sizeof(char *))
#define COLOR_MENU_SIZE (sizeof(LayerColor) / sizeof(char *))
#define MODE_MENU_SIZE (sizeof(LayerMode) / sizeof(char *))
static IntrPopUpMenuStruct *LayerPopUpMenu;
static IntrPopUpMenuStruct *ColorPopUpMenu;
static IntrPopUpMenuStruct *ModePopUpMenu;
static IntrCursorShapeStruct Cursor;

int SetLayer()

{
    int PopPosition;
    int Layer,LayerData;
    char Line[LINE_LEN_SHORT];
    
    Line[0]=NULL;

    Cursor.CursorType = INTR_CURSOR_ARROW;
    ShowLayers();	/* seed up start data */
    while((Layer=SetLayerList())!=-1){
	if(Layer==0)
		return(0);
	else if(Layer==1){	/* New Layer Needed */
	 	NewLayer();
	}
	else {
		Layer=Layer-2;
		if (LayerPopUpMenu == NULL) {
        	LayerPopUpMenu =
            	IntrPopUpMenuCreate("Change Layer Data", (char **) Layerstr,
                	    	0, LAYER_MENU_SIZE, EEPopUpFrameColor,
                              	EEPopUpBackColor, EEPopUpForeColor,
                            	EEPopUpXorColor, EEWindowsFrameWidth, &Cursor);
   		}

    		PopPosition=INTR_WNDW_PLACE_RIGHT;
    		IntrPopUpMenu(LayerPopUpMenu, PopPosition);
	      	 
		switch (LayerPopUpMenu -> SelectedIndex) {
			case 0 :	/* Change Layer Name */
				 

				
					if(Layer==-1 || 
						Layer > ReturnLayerNumber()){
						/* Error */
						GRTone(1500,100);
						GRTone(500,200);
						break;
					}
				strcpy(Line,ReturnLayerName(Layer));
				IntrQueryLine("Enter New Layer Name:", Line,
					LINE_LEN_SHORT -1, EEPopUpFrameColor,
					EEPopUpBackColor,EEPopUpForeColor,
					EEWindowsFrameWidth,PopPosition);
				SetLayerName(Layer,Line);
					break;
			case 1 :	/* Change Layer Mode */
				 

				
			 		if(Layer==-1 || 
						Layer > ReturnLayerNumber()){
						/* Error */
						GRTone(1500,100);
						GRTone(500,200);
						break;
					}
				 	LayerData=SetMode();
					if(LayerData==-1)
						break;
					if(LayerData == 3){
						LayerPointer->CurrentLayer =
							Layer;
						LayerData=2;
					}
					if((Layer==LayerPointer->CurrentLayer) &
						(LayerData!=2))
		LayerPointer->CurrentLayer = ReturnNextUsableLayer(Layer);
					SetLayerMode(Layer,LayerData);
					break;
			case 2 :	/* Change Layer Color */
				 

			

			 		if(Layer==-1 || 
						Layer > ReturnLayerNumber()){
						/* Error */
						GRTone(1500,100);
						GRTone(500,200);
						break;
					}
					LayerData=SetColor();
					if(LayerData==-1)
						break;
					SetLayerColor(Layer,LayerData);
					break;
			case 3 :
		


					if(Layer==-1 ||
						Layer > ReturnLayerNumber()){
						/* Error */
						GRTone(1500,100);
						GRTone(500,200);
						break;
					}
					LayerPointer->CurrentLayer = Layer;
					SetLayerMode(Layer,2);
					break;

		 
			}

		}
		ShowLayers();
	}
	/* ShowStatus(EEActiveWindow,1); */
	return(0);
}
int SetColor(void)
{
    int PopPosition;
	int i;
    Cursor.CursorType = INTR_CURSOR_ARROW;
    if (ColorPopUpMenu == NULL) {
        ColorPopUpMenu =
            IntrPopUpMenuCreate("Change Color Data", (char **) LayerColor,
                	    0, COLOR_MENU_SIZE, EEPopUpFrameColor,
                              EEPopUpBackColor, EEPopUpForeColor,
                            EEPopUpXorColor, EEWindowsFrameWidth, &Cursor);
    }

    PopPosition=INTR_WNDW_PLACE_RIGHT;
    i=IntrPopUpMenu(ColorPopUpMenu, PopPosition);
    if(i)
    	return(LayerColorData[ColorPopUpMenu -> SelectedIndex]);
    else
	return(-1);
    
}
int SetMode(void)
{
    int PopPosition;
    int i;
    Cursor.CursorType = INTR_CURSOR_ARROW;
    if (ModePopUpMenu == NULL) {
        ModePopUpMenu =
            IntrPopUpMenuCreate("Change Layer Mode", (char **) LayerMode,
                	    0, MODE_MENU_SIZE, EEPopUpFrameColor,
                              EEPopUpBackColor, EEPopUpForeColor,
                            EEPopUpXorColor, EEWindowsFrameWidth, &Cursor);
    }

    PopPosition=INTR_WNDW_PLACE_RIGHT;
    	i=IntrPopUpMenu(ModePopUpMenu, PopPosition); 
	if(i)
		return(ModePopUpMenu -> SelectedIndex);
	else
		return(-1);
    
}
int ReturnCurrentWidth()
{
	return(LayerPointer -> CurrentWidth);
}
void SetCurrentWidth(int Width)
{
	LayerPointer -> CurrentWidth = Width;
}
int ReturnCurrentLayer()
{
	return(LayerPointer -> CurrentLayer);
}
void SetCurrentLayer(int Layer)
{
	LayerPointer->CurrentLayer = Layer;
}
char *ReturnLayerName(Layer)
int Layer;
{
	return(LayerPointer->LayerNames[Layer]);
}
void SetLayerName(Layer,Name)
int Layer;
char *Name;
{
	strcpy(LayerPointer->LayerNames[Layer],Name);
}
int ReturnLayerMode(Layer)
int Layer;
{
	return(LayerPointer->LayerStatus[Layer]);
}
void SetLayerMode(Layer,Mode)
int Layer,Mode;
{
	LayerPointer->LayerStatus[Layer]=Mode;
}
void SetCommonColor()
{
	if(LayerPointer->Flags == 0)
		LayerPointer->Flags = 1;
	else
		LayerPointer->Flags = 0;
}
int ReturnLayerColor(Layer)
int Layer;
{
	if(LayerPointer->Flags==0)
		return(LayerPointer->LayerColor[Layer]);
	else
		return(LayerPointer->CommonColor);
}
void SetLayerColor(Layer,Color)
int Layer,Color;
{
	LayerPointer->LayerColor[Layer]=Color;
}
int ReturnLayerNumber()
{
	return(LayerPointer->NumberOfLayers);
}
void SetLayerNumber(Number)
int Number;
{
	LayerPointer->NumberOfLayers=Number;
}
int ReturnNextUsableLayer(Layer)
int Layer;
{
	int a,b;
	a=Layer;
	a++;	/* take Layer counter to current layer +1 */
	while(a!=LayerPointer->NumberOfLayers +1){
		b=ReturnLayerMode(a);
		if(b==LAYER_ENABLED)
			return(a);
		else
			a++;
	}
	a=0;
	while(a!=LayerPointer->NumberOfLayers +1){
		b=ReturnLayerMode(a);
		if(b==LAYER_ENABLED) 
			return(a);
		else
			a++;
	}
	return(Layer);	/* should never get reached */
}
void LoadLayers(f)
FILE *f;	/* Load the Layer Structuer from a file */
{
	int cnt,Number;
	char Line[LINE_LEN];
	int Mode,Color,Layer;
	char Name[0x10];

	fgets(Line,LINE_LEN-1,f);	/* read line */
	sscanf(Line,"%s %d %d",Name,&Number,&LayerPointer->CurrentLayer);
	if((strcmp(Name,"EELAYER"))!=0){
		/* Error! */
	} else
		SetLayerNumber(Number);
	cnt=0;
	while(cnt!=Number+1){
		fgets(Line,LINE_LEN-1,f);	/* read line */
		sscanf(Line,"%s %d %d %d",Name,&Color,&Mode,&Layer);
		SetLayerName(Layer,Name);
		SetLayerColor(Layer,Color);
		SetLayerMode(Layer,Mode);
		cnt++;
	}
	fgets(Line,LINE_LEN-1,f);	/* read trailing Line */

}
void SaveLayers(f)
FILE *f;	/* Save a Layer Structure to a file */
{
	int a;
	fprintf(f,"EELAYER %2d %2d\n",
		ReturnLayerNumber(),LayerPointer->CurrentLayer);
	a=0;
	while(a!=(ReturnLayerNumber() + 1)){
		fprintf(f,"%8s %4d %2d %2d\n",
			ReturnLayerName(a),ReturnLayerColor(a),
			ReturnLayerMode(a),a);
		a++;
	}
	fprintf(f,"EELAYER END\n");
}
int SetLayerList(void)
{

	char **Names;
	
	char loop;
	int i;

	Cursor.CursorType = INTR_CURSOR_ARROW;

	Names = (char **) MyMalloc(sizeof(char *) * (ReturnLayerNumber() +4));
	
	loop=0;
	while(loop!=ReturnLayerNumber()+4){
		Names[loop]=ShowData[loop];
		loop++;
	}
	i=IntrQueryList("Layers",(char **) Names,0,
		ReturnLayerNumber() +3,EEListNumDisplayed,
		EEPopUpFrameColor, EEPopUpBackColor,EEPopUpForeColor,
		EEPopUpXorColor,EEWindowsFrameWidth, &Cursor,
		INTR_WNDW_PLACE_RIGHT);
	MyFree((VoidPtr)Names);
	return(i);
}
void ShowStatus(Window,flag)
EEWindowStruct *Window;
int flag;
{
	char Mod,HVL,Wid,Disp;
	if(Window->Modified)
		Mod='M';
	else
		Mod='O';
	if(EEHVLineDrawing)
		HVL='O';
	else
		HVL='A';
	if(Window->Layer->Flags == 0)
		Disp='N';
	else
		Disp='S';
	sprintf(Window->StatusR,"%c %c %d %d %c",Mod,HVL,
		EESnapDistance,Window->Layer->CurrentWidth,Disp);
	strcpy(Window->StatusL,ReturnLayerName(ReturnCurrentLayer()));
	IntrWndwSetStatus(Window -> IntrLibWindowID, 
	   Window->StatusL, Window->StatusR, /* TRUE */ FALSE);
	if(flag!=1)
 		IntrWndwPop(Window -> IntrLibWindowID, TRUE, FALSE); 
}
int NewLayer()
{

    int PopPosition;
    int Layer;
    int i;
    char Line[LINE_LEN_SHORT];
	Layer=ReturnLayerNumber() +1;
	SetLayerNumber(Layer);
	SetLayerMode(Layer,2);	/* Set Layer Usable */
	sprintf(Line,"User%02d",ReturnLayerNumber());
 	PopPosition=INTR_WNDW_PLACE_RIGHT;
	IntrQueryLine("Enter New Layer Name:", Line,
		LINE_LEN_SHORT -1, EEPopUpFrameColor,
		EEPopUpBackColor,EEPopUpForeColor,
		EEWindowsFrameWidth,PopPosition);
	SetLayerName(Layer,Line);
	i=SetColor();
	if(i==-1){
		Layer=ReturnLayerNumber() -1;
		SetLayerNumber(Layer);
		return(-1);
	} else
		SetLayerColor(Layer,i);
	return(ReturnLayerNumber());
}
