/* keyPanel.c 
 *
 *  defines the GUIFront characteristics of the keyfile panel 
 */
  
#include <stdio.h>  
#include <intuition/gadgetclass.h>
#include "amiCheck.h"
#include "regGadget.h"
#include "dataBase.h"
#include "keyPanel.h"
#include <string.h>

/* Key Globals */
usrkey *ptrKey, tempkey, usrKey = {
	0x0,
	NULL,
	"",
};

/* prototypes */
BOOL KeyHandleGadget(struct IntuiMessage *);
void KeyInit(void);
long KeyCRC (long byte, long lastcrc);


ExtErrorData KeyExtData;
GUIFront *keyGUI;

struct TagItem strKeyTags[] =
{
	/*{STRINGA_ExitHelp,TRUE},*/
	{GTIN_Number, 1},
	{GTIN_MaxChars,20},
	{TAG_DONE},
};


/* define gadgetspec */
GadgetSpec KEYgadgetspecs[] = 
{

        {INTEGER_KIND,30,0,{0,0,0,0,"User _ID", NULL, GID_KEYID,         
                PLACETEXT_LEFT}, strKeyTags, GS_DefaultTags},

        {STRING_KIND,30,0,{0,0,0,0,"User _Name", NULL, GID_KEYNAME,         
                PLACETEXT_LEFT}, strNameTags, GS_DefaultTags},

        {BUTTON_KIND,6,0,{0,0,0,0,"_Cancel", NULL, GID_KEYCANCEL,         
                PLACETEXT_IN}, NULL, GS_DefaultTags},

        {BUTTON_KIND,6,0,{0,0,0,0,"_Register", NULL, GID_KEYREG,         
                PLACETEXT_IN}, NULL, GS_DefaultTags}, 
};

/* set up array of pointers to our specs */
GadgetSpec *KEY_KeySpecs[] =
{
        &KEYgadgetspecs[0],
        &KEYgadgetspecs[1],
        &KEYgadgetspecs[2],
        &KEYgadgetspecs[3],
        NULL,
};


/* define the layout of this panel */
ULONG KEY_KeyPanel[] =
{
   GUIL_Flags, GUILF_PropShare | GUILF_EqualWidth | GUILF_LabelAlign,

   GUIL_HorizGroup,1,
   	GUIL_FrameType, GUILFT_Recess,
   	GUIL_VertGroup, 1,
 		GUIL_Flags, GUILF_PropShare | GUILF_LabelAlign,
		GUIL_GadgetSpecID, GID_KEYID,
		GUIL_GadgetSpecID, GID_KEYNAME,
   	TAG_DONE,
   TAG_DONE,
        
   GUIL_HorizGroup,1,
        GUIL_Flags, GUILF_EqualSize | GUILF_EqualWidth,
        GUIL_GadgetSpecID, GID_KEYREG,
	GUIL_GadgetSpecID, GID_KEYCANCEL,
   TAG_DONE,   
           
TAG_DONE,
};


/****************************************************
* KeyGUI ()
*
*	Creates the GUI for the key panel.
*****************************************************/
void  KeyGUI(void)
{
 BOOL done = FALSE;
 UWORD ordinal;
 ULONG signal;
     
 AmiLock();

 
 GF_SetGUIAttr(keyGUI, GUI_OpenGUI, TRUE, TAG_DONE);
 KeyInit();

 /* Process input events */
 while (!done)   {
   struct IntuiMessage *imsg;

                    /* Wait for an event to occur */

                    signal = GF_Wait(guiapp,AmigaGuideSignal(agc));
		    if (signal & AmigaGuideSignal(agc)) {
			AmiHelpMsg();
			continue;
		    }
	
                    /* We only bother to listen for CLOSEWINDOW events.
                     * Of course, in a real application, you would be
                     * examining the Class field for IDCMP_GADGETUP
                     * messages and act accordingly.
                     */

                    while (imsg = GF_GetIMsg(guiapp))
                    {
                        switch (imsg->Class) {
                                case IDCMP_CLOSEWINDOW:
					done = TRUE;
                                        break;

				case IDCMP_RAWKEY:
					AmiHelpKey(imsg,KEY_PANEL);
					break;

				case IDCMP_GADGETUP:
					done=KeyHandleGadget(imsg);
					break;

				case IDCMP_REFRESHWINDOW:
					RegRefresh(TRUE);
					break;
                        }
                                                 
                        GF_ReplyIMsg(imsg);
               }
        }

   GF_SetGUIAttr(keyGUI, GUI_OpenGUI, FALSE, TAG_DONE);               
   AmiUnlock();
}

/***************************************************
* KeyHandleGadget()
*
*	Handles gadget events for this panel
****************************************************/
BOOL KeyHandleGadget(struct IntuiMessage *imsg)
{
 BOOL done = FALSE;
 struct Gadget *gad = (struct Gadget *)(imsg->IAddress);
 UWORD code = imsg->Code;

 switch (gad->GadgetID) {

	case GID_KEYNAME:
		strncpy(tempkey.id_name,((struct StringInfo *)gad->SpecialInfo)->Buffer, STRINGSIZE);
		break;

	case GID_KEYID:
		tempkey.id=((struct StringInfo *)gad->SpecialInfo)->LongInt;
		break;

	case GID_KEYREG:
		/* grab final values */
		strncpy(tempkey.id_name,
			((struct StringInfo *)(KEY_KeySpecs[GID_KEYNAME]->gs_Gadget)->SpecialInfo)->Buffer,
			STRINGSIZE);
		tempkey.id = ((struct StringInfo *)(KEY_KeySpecs[GID_KEYID]->gs_Gadget)->SpecialInfo)->LongInt;

		if (KeyWriteFile(&tempkey)) {
			memcpy(&usrKey,&tempkey,sizeof(usrkey));
			AmiAnnounce("Keyfile updated.  Restart amiCheck");
		}
		else	AmiAnnounce("Trouble writing keyfile");

			/* FALL THROUGH */

	case GID_KEYCANCEL:
		done = TRUE;	
		break;
 }

 return (done);
}

/****************************************************
* KeyInit()
*
*	Set up some globals
*****************************************************/
void KeyInit(void)
{
 memcpy(&tempkey, &usrKey,sizeof(usrkey));

 GF_SetGadgetAttrs (keyGUI, KEY_KeySpecs[GID_KEYID]->gs_Gadget,
	GTIN_Number,tempkey.id,
	TAG_DONE);
 
 GF_SetGadgetAttrs (keyGUI, KEY_KeySpecs[GID_KEYNAME]->gs_Gadget,
	GTST_String,tempkey.id_name,
	TAG_DONE);
}

/****************************************************
* KeyWriteFile()
*
*	Writes out usrKey data to PROGDIR:keyfile
****************************************************/
BOOL KeyWriteFile(usrkey *temp)
{
 FILE *key;
 
 if ( (key=fopen("PROGDIR:keyfile","w")) != NULL) {
	fprintf(key,"%u\n", temp->id);
	fprintf(key,"%s\n", temp->id_name);
	
	fclose(key);
	return (TRUE);
 }

 return (FALSE);
}

/*****************************************************
* KeyReadFile()
*
*	Reads in the usrKey data from PROGDIR:keyfile
******************************************************/
BOOL KeyReadFile(void)
{
 FILE *key;
 
 if ( (key=fopen("PROGDIR:keyfile","r")) != NULL) {
	fscanf(key,"%u\n", &usrKey.id);
	fgets(usrKey.id_name, STRINGSIZE, key);
	if (strlen(usrKey.id_name) > 0)
		usrKey.id_name[strlen(usrKey.id_name)-1] = 0;
	
	fclose(key);
	return (TRUE);
 }

 /* DMD - Damn Im generous :) */
 return (TRUE);
}

/*****************************************************
* KeyCheck()
*
*	Returns TRUE if OK
******************************************************/
BOOL KeyCheck(void)
{
 /* DMD - give this all away to the good public :) */
 return (TRUE /*usrKey.id == usrKey.verify*/);
}

/*****************************************************
* KeyVerify()
*
*	Verifies the usrKey data
******************************************************/
void KeyVerify(usrkey *temp)
{
 int x,y = strlen(temp->id_name);

 temp->verify = 0xbabe;
 for (x=0;x< ((y<5)?5:y) ;x++)
	temp->verify = KeyCRC(temp->id_name[x],temp->verify);	
}

/****************************************************
* KeyCRC()
*
*	Calculate the CRC 
*****************************************************/
long KeyCRC (long byte, long lastcrc)
{
 long  n;
 long  crc = lastcrc;

 crc ^= byte;

 for (n=0; n<=7; n++) {
     if (crc & 0x1)  {
           crc >>= 1;
           crc ^=  0x900A001;
     }
                else
     crc >>= 1;
 }

 return crc;
}
