#include <xpk/xpk.h>
#include <clib/xpkmaster_protos.h>
#include <pragmas/xpkmaster_lib.h>
#include <string.h>

extern struct Library *XpkBase;
struct Remember *rem_key1=NULL;

/*************************************************************************/
/*                                                                       */
/*   Includes                                                            */
/*                                                                       */
/*************************************************************************/

#include "NewGUI_Includes.h"
#include "XpkGUI.h"


/**** MIE DEFINIZIONI ****/

struct List lista_packers;

extern STRPTR packMethod;
extern LONG   PackMode;

/*------------------------------------*/


/*************************************************************************/
/*                                                                       */
/*   Variables and Structures                                            */
/*                                                                       */
/*************************************************************************/

extern struct IntuitionBase   *IntuitionBase;
extern struct GfxBase         *GfxBase;

extern struct Library *GadToolsBase ;
extern struct Library *AslBase      ;
extern struct Library *DataTypesBase;

/*************************************************************************/
/*                                                                       */
/*   Defines                                                             */
/*                                                                       */
/*************************************************************************/

#define RASTERX (GfxBase->DefaultFont->tf_XSize)
#define RASTERY (GfxBase->DefaultFont->tf_YSize/2+4)

#define XSIZE(x)  ((x)*RASTERX)
#define YSIZE(x)  ((x)*RASTERY)

#define XPOS(x)   (XSIZE(x)+customscreen->WBorLeft)
#define YPOS(x)   (YSIZE(x)+customscreen->BarHeight+1)

#define ERROR_NO_WINDOW_OPENED      1001L
#define ERROR_NO_PUBSCREEN_LOCKED   1002L
#define ERROR_NO_GADGETS_CREATED    1003L
#define ERROR_NO_VISUALINFO         1004L
#define ERROR_NO_PICTURE_LOADED     1005L
#define ERROR_NO_GADGETLIST_CREATED 1006L
#define ERROR_NO_WINDOW_MENU        1007L
#define ERROR_SCREEN_TOO_SMALL      1008L
#define ERROR_LIST_NOT_INITIALIZED  1009L
struct XpkWindowData
	{
	BOOL    gd_Disabled_ListPackers;
	struct List *gd_Labels_ListPackers;
	UWORD   gd_Selected_ListPackers;
	UWORD   gd_Top_ListPackers;
	BOOL    gd_Disabled_SliderMode;
	UWORD   gd_Level_SliderMode;
	UWORD   gd_Max_SliderMode;
	UWORD   gd_Min_SliderMode;
	BOOL    gd_Disabled_TextPackers;
	char    gd_Text_TextPackers[256];
	BOOL    gd_Disabled_Gadget3;
	char    gd_Text_Gadget3[256];
	};


/*************************************************************************/
/*                                                                       */
/*   Routines to handle gadgets                                          */
/*                                                                       */
/*************************************************************************/


void HandleGadgetsXpkWindow(struct Window *win,struct Gadget *wingads[],ULONG gadgetid,ULONG messagecode,struct XpkWindowData *gadgetdata,void *userdata)
{
	switch(gadgetid)
		{
		case ListPackGadget:
			Gadget1Clicked(win,wingads,gadgetid,messagecode,(struct XpkPackerList *)userdata);
			break;
		case SlideModeGadget:
			SliderClicked(win,wingads,gadgetid,messagecode,userdata);
			break;
		}
}


/*************************************************************************/
/*                                                                       */
/*   Routines to create gadgets                                          */
/*                                                                       */
/*************************************************************************/

struct Gadget *CreateGadgetsXpkWindow(struct Gadget **gadgetlist,struct NewGadget newgad[],struct Gadget *wingads[],struct XpkWindowData *gadgetdata)
{
	struct Gadget *gadget=CreateContext(gadgetlist);
	if (gadget)
		{
		wingads[ListPackGadget]=gadget=CreateGadget(LISTVIEW_KIND,gadget,&newgad[ListPackGadget],GA_Disabled,gadgetdata->gd_Disabled_ListPackers,GTLV_Labels,&lista_packers,GTLV_ReadOnly,FALSE,GTLV_Selected,gadgetdata->gd_Selected_ListPackers,GTLV_ShowSelected,NULL,GTLV_Top,gadgetdata->gd_Top_ListPackers,LAYOUTA_Spacing,0,TAG_END);
		wingads[SlideModeGadget]=gadget=CreateGadget(SLIDER_KIND,gadget,&newgad[SlideModeGadget],GA_Disabled,gadgetdata->gd_Disabled_SliderMode,GA_Immediate,TRUE,GA_RelVerify,TRUE,GTSL_Level,gadgetdata->gd_Level_SliderMode,GTSL_LevelFormat,"%ld",GTSL_LevelPlace,PLACETEXT_RIGHT,GTSL_Max,gadgetdata->gd_Max_SliderMode,GTSL_Min,gadgetdata->gd_Min_SliderMode,GTSL_MaxLevelLen,5,PGA_Freedom,LORIENT_HORIZ,TAG_END);
		wingads[TextPackGadget]=gadget=CreateGadget(TEXT_KIND,gadget,&newgad[TextPackGadget],GA_Disabled,gadgetdata->gd_Disabled_TextPackers,GTTX_Border,TRUE,GTTX_CopyText,TRUE,GTTX_Text,gadgetdata->gd_Text_TextPackers,TAG_END);
		wingads[LAID_Gadget12]=gadget=CreateGadget(TEXT_KIND,gadget,&newgad[LAID_Gadget12],GT_Underscore,'_',GTTX_Border,FALSE,TAG_END);
		wingads[LAID_Gadget1]=gadget=CreateGadget(TEXT_KIND,gadget,&newgad[LAID_Gadget1],GT_Underscore,'_',GTTX_Border,FALSE,TAG_END);
		wingads[Desc_Gadget]=gadget=CreateGadget(TEXT_KIND,gadget,&newgad[Desc_Gadget],GA_Disabled,gadgetdata->gd_Disabled_Gadget3,GTTX_Border,TRUE,GTTX_CopyText,TRUE,GTTX_Text,gadgetdata->gd_Text_Gadget3,TAG_END);
		return gadget;
		}
	else return NULL;
}


/*************************************************************************/
/*                                                                       */
/*   Routines to handle windows                                          */
/*                                                                       */
/*************************************************************************/


void HandleXpkWindow(struct Screen *customscreen,LONG left,LONG top,APTR userdata)
{
   struct XpkPackerList packersList;
   struct XpkPackerInfo packerInfo;
   struct Node *nodo;
   int i;

	APTR visualinfo;
	visualinfo=GetVisualInfo(customscreen,TAG_DONE);

   NewList(&lista_packers);
   XpkQueryTags(XPK_PackersQuery, &packersList,
                TAG_DONE);
   for(i=0;i<packersList.xpl_NumPackers;i++){
       nodo = (struct Node *)AllocRemember(&rem_key1,sizeof(struct Node),MEMF_CLEAR);
       nodo->ln_Name=(STRPTR)AllocRemember(&rem_key1,6,NULL);
       strcpy(nodo->ln_Name,packersList.xpl_Packer[i]);
       AddTail(&lista_packers,nodo);
   }



	if (visualinfo)
		{
		struct Gadget  *gadgetlist = NULL;
		ULONG height=17,width=64,maxheight=1024,maxwidth=1280;

		struct Gadget *wingads[6];

		char * title                  = "Xpk Prefs copyright Antonio Cervo";
		struct Window     *win        = NULL;

		struct TextAttr   textattr;

		struct NewGadget  newgad[]    = {
													 0,0,0,0,NULL,NULL,ListPackGadget,PLACETEXT_ABOVE,NULL,NULL,
													 0,0,0,0,NULL,NULL,SlideModeGadget,PLACETEXT_LEFT,NULL,NULL,
													 0,0,0,0,NULL,NULL,TextPackGadget,PLACETEXT_LEFT,NULL,NULL,
													 0,0,0,0,"Packer",NULL,LAID_Gadget12,PLACETEXT_IN,NULL,NULL,
													 0,0,0,0,"Mode",NULL,LAID_Gadget1,PLACETEXT_IN,NULL,NULL,
													 0,0,0,0,NULL,NULL,Desc_Gadget,PLACETEXT_LEFT,NULL,NULL,
												  };


		struct XpkWindowData gadgetdata = {
													 /* belongs to a listview gadget */
													 FALSE,
													 (struct List *)~0,
													 0,
													 0,
													 /* belongs to a slider gadget */
													 FALSE,
													 0,
													 100,
													 0,
													 /* belongs to a text gadget */
													 FALSE,
													 "",
													 /* belongs to a text gadget */
													 FALSE,
													 "",
												  };


		textattr.ta_Name =GfxBase->DefaultFont->tf_Message.mn_Node.ln_Name;
		textattr.ta_YSize=GfxBase->DefaultFont->tf_YSize;
		textattr.ta_Style=FS_NORMAL;
		textattr.ta_Flags=FPF_DISKFONT;

		newgad[ 0].ng_LeftEdge  =XPOS(2);
		newgad[ 0].ng_TopEdge   =YPOS(1);
		newgad[ 0].ng_Width     =XSIZE(18);
		newgad[ 0].ng_Height    =YSIZE(13);
		newgad[ 0].ng_TextAttr  =&textattr;
		newgad[ 0].ng_VisualInfo=visualinfo;
		newgad[ 1].ng_LeftEdge  =XPOS(23);
		newgad[ 1].ng_TopEdge   =YPOS(8);
		newgad[ 1].ng_Width     =XSIZE(21);
		newgad[ 1].ng_Height    =YSIZE(2);
		newgad[ 1].ng_TextAttr  =&textattr;
		newgad[ 1].ng_VisualInfo=visualinfo;
		newgad[ 2].ng_LeftEdge  =XPOS(23);
		newgad[ 2].ng_TopEdge   =YPOS(3);
		newgad[ 2].ng_Width     =XSIZE(39);
		newgad[ 2].ng_Height    =YSIZE(2);
		newgad[ 2].ng_TextAttr  =&textattr;
		newgad[ 2].ng_VisualInfo=visualinfo;
		newgad[ 3].ng_LeftEdge  =XPOS(34);
		newgad[ 3].ng_TopEdge   =YPOS(1);
		newgad[ 3].ng_Width     =XSIZE(13);
		newgad[ 3].ng_Height    =YSIZE(2);
		newgad[ 3].ng_TextAttr  =&textattr;
		newgad[ 3].ng_VisualInfo=visualinfo;
		newgad[ 4].ng_LeftEdge  =XPOS(27);
		newgad[ 4].ng_TopEdge   =YPOS(6);
		newgad[ 4].ng_Width     =XSIZE(13);
		newgad[ 4].ng_Height    =YSIZE(2);
		newgad[ 4].ng_TextAttr  =&textattr;
		newgad[ 4].ng_VisualInfo=visualinfo;
		newgad[ 5].ng_LeftEdge  =XPOS(2);
		newgad[ 5].ng_TopEdge   =YPOS(14);
		newgad[ 5].ng_Width     =XSIZE(60);
		newgad[ 5].ng_Height    =YSIZE(2);
		newgad[ 5].ng_TextAttr  =&textattr;
		newgad[ 5].ng_VisualInfo=visualinfo;




		height= YSIZE(height);
		width = XSIZE(width) ;
		if (left == -1) left  = (customscreen->Width-width)/2;
		if (top  == -1) top   = (customscreen->Height-height)/2;

		if (CreateGadgetsXpkWindow(&gadgetlist,newgad,wingads,&gadgetdata) != NULL)
			{
			if (height>customscreen->Height || width>customscreen->Width) GUIC_ErrorReport(NULL,ERROR_SCREEN_TOO_SMALL);
			win=OpenWindowTags(NULL,WA_Activate,         TRUE,
											WA_CloseGadget,      TRUE,
											WA_DepthGadget,      TRUE,
											WA_SizeGadget,       TRUE,
											WA_DragBar,          TRUE,
											WA_Gadgets,          gadgetlist,
											WA_InnerHeight,      height,
											WA_InnerWidth,       width,
											WA_IDCMP,            IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE|IDCMP_VANILLAKEY|IDCMP_REFRESHWINDOW|IDCMP_GADGETUP|SLIDERIDCMP|LISTVIEWIDCMP,
											WA_Left,             left,
											WA_Top,              top,
											WA_MaxHeight,        maxheight,
											WA_MinHeight,        height,
											WA_MaxWidth,         maxwidth,
											WA_MinWidth,         width,
											WA_SizeBRight,       FALSE,
											WA_SizeBBottom,      TRUE,
											WA_SmartRefresh,     TRUE,
											WA_CustomScreen,     customscreen,
											WA_Title,            title,
											WA_NewLookMenus,     TRUE,
											TAG_END);
			if (win)
				{
							struct IntuiMessage  *imessage   = NULL;
							struct Gadget        *idcmpgad   = NULL;
							struct NewGadget     ngcopy[6];
							long   double        xscale      = 1.0;
							long   double        yscale      = 1.0;
							char * stringpointer             = NULL;
							ULONG                i           = 0;
							ULONG                gadgetcount = 6;
							ULONG  idcmpclass                = 0;
							UWORD  messagecode               = 0;
							BOOL   running                   = TRUE;
							ULONG  signal                    = 0;
							ULONG  longpointer1              = 0;
							ULONG  longpointer2              = 0;

							CopyMem(newgad,ngcopy,sizeof(ngcopy));

							SetFont(win->RPort,GfxBase->DefaultFont);

                                          DrawBevelBox(win->RPort,
                                                       win->BorderLeft,
                                                       win->BorderTop,win->Width-win->BorderRight-win->BorderLeft,
                                                       win->Height-win->BorderBottom-win->BorderTop,
                                                       GT_VisualInfo, visualinfo,
                                                       TAG_DONE);

							GT_RefreshWindow(win,NULL);

							/* User-Setup */

                     if(strcmp(packMethod,"----")){
                        GT_SetGadgetAttrs(wingads[ListPackGadget], win, NULL,
                                          GTLV_Selected, ~0,
                                          TAG_DONE);             
                        XpkQueryTags(XPK_PackMethod, packMethod,
                                     XPK_PackerQuery,  &packerInfo,
                                     TAG_DONE);
                     }
                     else{
                        XpkQueryTags(XPK_PackMethod, (STRPTR)packersList.xpl_Packer[0],
                                     XPK_PackerQuery,  &packerInfo,
                                     TAG_DONE);
                        strcpy(packMethod,packersList.xpl_Packer[0]);
                     }

                     GT_SetGadgetAttrs(wingads[Desc_Gadget], win, NULL,
                                       GTTX_Text, (STRPTR)packerInfo.xpi_Description,
                                       TAG_DONE);             
                     GT_SetGadgetAttrs(wingads[TextPackGadget], win, NULL,
                                       GTTX_Text, (STRPTR)packerInfo.xpi_LongName,
                                       TAG_DONE);             
                     GT_SetGadgetAttrs(wingads[SlideModeGadget], win, NULL,
                                       GTSL_Level, (WORD)packerInfo.xpi_DefMode,
                                       TAG_DONE);             
   
                     if(PackMode<0) PackMode=packerInfo.xpi_DefMode;

							do
								{
								WindowLimits(win,width+win->BorderLeft+win->BorderRight,height+win->BorderTop+win->BorderBottom,maxwidth,maxheight);
								if (running) signal=Wait(SIGBREAKF_CTRL_C | 1L << win->UserPort->mp_SigBit);
								if (signal & SIGBREAKF_CTRL_C) running=FALSE;
								WindowLimits(win,win->Width,win->Height,win->Width,win->Height);
								while (running && (imessage=GT_GetIMsg(win->UserPort)))
									{
									idcmpgad=(struct Gadget *)imessage->IAddress;
									idcmpclass=imessage->Class;
									messagecode =imessage->Code;

									GT_ReplyIMsg(imessage);

									switch(idcmpclass)
										{
										case IDCMP_REFRESHWINDOW:
											GT_BeginRefresh(win);
                                                                  DrawBevelBox(win->RPort,
                                                                               win->BorderLeft,
                                                                               win->BorderTop,win->Width-win->BorderRight-win->BorderLeft,
                                                                               win->Height-win->BorderBottom-win->BorderTop,
                                                                               GT_VisualInfo, visualinfo,
                                                                               TAG_DONE);
											GT_EndRefresh(win,TRUE);
											break;
										case IDCMP_NEWSIZE:
											GT_GetGadgetAttrs(wingads[ListPackGadget],win,NULL,GA_Disabled,&longpointer1,GTLV_Labels,&longpointer2,TAG_END);
											gadgetdata.gd_Disabled_ListPackers=(longpointer1 == 0)?FALSE:TRUE;
											gadgetdata.gd_Labels_ListPackers=(struct List *)longpointer2;
											GT_GetGadgetAttrs(wingads[ListPackGadget],win,NULL,GTLV_Top,&longpointer1,GTLV_Selected,&longpointer2,TAG_END);
											gadgetdata.gd_Top_ListPackers=longpointer1;
											gadgetdata.gd_Selected_ListPackers=longpointer2;
											GT_GetGadgetAttrs(wingads[SlideModeGadget],win,NULL,GA_Disabled,&longpointer1,GTSL_Level,&longpointer2,TAG_END);
											gadgetdata.gd_Disabled_SliderMode=(longpointer1 == 0)?FALSE:TRUE;
											gadgetdata.gd_Level_SliderMode=longpointer2;
											GT_GetGadgetAttrs(wingads[SlideModeGadget],win,NULL,GTSL_Min,&longpointer1,GTSL_Max,&longpointer2,TAG_END);
											gadgetdata.gd_Min_SliderMode=longpointer1;
											gadgetdata.gd_Max_SliderMode=longpointer2;
											GT_GetGadgetAttrs(wingads[TextPackGadget],win,NULL,GA_Disabled,&longpointer1,GTTX_Text,&stringpointer,TAG_END);
											gadgetdata.gd_Disabled_TextPackers=(longpointer1 == 0)?FALSE:TRUE;
											strcpy(gadgetdata.gd_Text_TextPackers,stringpointer);
											GT_GetGadgetAttrs(wingads[Desc_Gadget],win,NULL,GA_Disabled,&longpointer1,GTTX_Text,&stringpointer,TAG_END);
											gadgetdata.gd_Disabled_Gadget3=(longpointer1 == 0)?FALSE:TRUE;
											strcpy(gadgetdata.gd_Text_Gadget3,stringpointer);

											RemoveGList(win,gadgetlist,-1);
											SetAPen(win->RPort,0L);
											RectFill(win->RPort,win->BorderLeft,win->BorderTop,win->Width-win->BorderRight-1,win->Height-win->BorderBottom-1);
											RefreshWindowFrame(win);

											xscale=(long double)win->Width /(long double)(width+win->BorderLeft+win->BorderRight);
											yscale=(long double)win->Height/(long double)(height+win->BorderTop+win->BorderBottom);
											for (i=0;i<gadgetcount;i++)
												{
												ngcopy[i].ng_LeftEdge=(WORD)((long double)newgad[i].ng_LeftEdge*xscale);
												ngcopy[i].ng_TopEdge =(WORD)((long double)newgad[i].ng_TopEdge *yscale);
												ngcopy[i].ng_Width   =(WORD)((long double)newgad[i].ng_Width   *xscale);
												ngcopy[i].ng_Height  =(WORD)((long double)newgad[i].ng_Height  *yscale);
												}

											FreeGadgets(gadgetlist);
											gadgetlist=NULL;

											CreateGadgetsXpkWindow(&gadgetlist,ngcopy,wingads,&gadgetdata);
											AddGList(win,gadgetlist,-1,-1,NULL);
											RefreshGList(gadgetlist,win,NULL,-1);
											GT_RefreshWindow(win,NULL);
                                                                  DrawBevelBox(win->RPort,
                                                                               win->BorderLeft,
                                                                               win->BorderTop,win->Width-win->BorderRight-win->BorderLeft,
                                                                               win->Height-win->BorderBottom-win->BorderTop,
                                                                               GT_VisualInfo, visualinfo,
                                                                               TAG_DONE);
											break;
										case IDCMP_VANILLAKEY:
											switch(messagecode)
												{
												case 27:
													running=FALSE;
													break;
												}
											break;
										case IDCMP_CLOSEWINDOW:
											running=FALSE;
											break;
										case IDCMP_GADGETUP:
										case MXIDCMP:
											HandleGadgetsXpkWindow(win,wingads,idcmpgad->GadgetID,messagecode,&gadgetdata,(void *)&packersList);
											break;
										}
									/* end-switch */
									}
								/* end-while */
								}
							while (running);
				if (win) CloseWindow(win);
				}
			else GUIC_ErrorReport(win,ERROR_NO_WINDOW_OPENED);
			if (gadgetlist) FreeGadgets(gadgetlist);
			}
		else GUIC_ErrorReport(NULL,ERROR_NO_GADGETS_CREATED);
		if (visualinfo) FreeVisualInfo(visualinfo);
		}
	else GUIC_ErrorReport(NULL,ERROR_NO_VISUALINFO);
   FreeRemember(&rem_key1,TRUE);
}

void Gadget1Clicked(struct Window *win,struct Gadget *wingads[],ULONG gadgetid,ULONG messagecode,struct XpkPackerList *packersList)
{
   struct XpkPackerInfo packerInfo;
   
   XpkQueryTags(XPK_PackMethod, (STRPTR)packersList->xpl_Packer[messagecode],
                XPK_PackerQuery,  &packerInfo,
                TAG_DONE);
   
   GT_SetGadgetAttrs(wingads[Desc_Gadget], win, NULL,
                     GTTX_Text, (STRPTR)packerInfo.xpi_Description,
                     TAG_DONE);             

   GT_SetGadgetAttrs(wingads[TextPackGadget], win, NULL,
                     GTTX_Text, (STRPTR)packerInfo.xpi_LongName,
                     TAG_DONE);             

   GT_SetGadgetAttrs(wingads[SlideModeGadget], win, NULL,
                     GTSL_Level, (WORD)packerInfo.xpi_DefMode,
                     TAG_DONE);             

   strcpy(packMethod,packersList->xpl_Packer[messagecode]);
   PackMode=packerInfo.xpi_DefMode;

}   

void SliderClicked(struct Window *win,struct Gadget *wingads[],ULONG gadgetid,ULONG messagecode,APTR userdata)
{
   PackMode=messagecode;
}