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

#include "NewGUI_Includes.h"
#include "NewGUI_Structures.h"


/*************************************************************************/
/*                                                                       */
/*   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)

#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)

/*************************************************************************/
/*                                                                       */
/*   SleepWindow() und WakenWindow()                                     */
/*                                                                       */
/*************************************************************************/

static struct Requester waitrequest;

void SleepWindow(struct Window *win)
{
	InitRequester(&waitrequest);
	if (win->FirstRequest == NULL ) Request(&waitrequest,win);
	SetWindowPointer(win,WA_BusyPointer,1L,TAG_DONE);
}

void WakenWindow(struct Window *win)
{
	if (win->FirstRequest != NULL) EndRequest(&waitrequest,win);
	SetWindowPointer(win,WA_Pointer,0L,TAG_DONE);
}

/*************************************************************************/
/*                                                                       */
/*   GUIC_ErrorReport()                                             */
/*                                                                       */
/*************************************************************************/

void GUIC_ErrorReport(struct Window *win,ULONG type)
{
	char error[256];
	struct EasyStruct easystruct;
	easystruct.es_StructSize    = sizeof(struct EasyStruct);
	easystruct.es_Flags         = 0;
	easystruct.es_Title         = "Caution:";
	easystruct.es_TextFormat    = error;
	easystruct.es_GadgetFormat  = "OK";

	if (type == ERROR_NO_WINDOW_OPENED)
		strcpy(error,"Could not open window (no memory?)");
	else if (type == ERROR_NO_PUBSCREEN_LOCKED)
		strcpy(error,"Could not lock pubscreen");
	else if (type == ERROR_NO_GADGETS_CREATED)
		strcpy(error,"Could not create gadgets");
	else if (type == ERROR_NO_GADGETLIST_CREATED)
		strcpy(error,"Could not create gadgetlist");
	else if (type == ERROR_NO_VISUALINFO)
		strcpy(error,"Could not read visualinfo from screen");
	else if (type == ERROR_NO_PICTURE_LOADED)
		strcpy(error,"Could not read picture data");
	else if (type == ERROR_NO_WINDOW_MENU)
		strcpy(error,"Could not create menu");
	else if (type == ERROR_SCREEN_TOO_SMALL)
		strcpy(error,"This screen is too small for the window");
	else if (type == ERROR_LIST_NOT_INITIALIZED)
		strcpy(error,"The attached list is not initialized!");
	else Fault(type,"Error",error,sizeof(error));

	if (win && !win->FirstRequest)
		{
		SleepWindow(win);
		EasyRequestArgs(win,&easystruct,NULL,NULL);
		WakenWindow(win);
		}
	else EasyRequestArgs(win,&easystruct,NULL,NULL);

}

/*************************************************************************/
/*                                                                       */
/*   CreateBevelFrames()                                                 */
/*                                                                       */
/*************************************************************************/

void CreateBevelFrames(struct Window *win,APTR visualinfo,ULONG bevelcount,struct BevelFrame bevels[])
{
	ULONG i;
	for (i=0;i<bevelcount;i++)
		{
		DrawBevelBox(win->RPort,bevels[i].bb_LeftEdge,bevels[i].bb_TopEdge,bevels[i].bb_Width,bevels[i].bb_Height,GT_VisualInfo,visualinfo,GTBB_Recessed,TRUE,TAG_END);
		DrawBevelBox(win->RPort,bevels[i].bb_LeftEdge+2,bevels[i].bb_TopEdge+1,bevels[i].bb_Width-4,bevels[i].bb_Height-2,GT_VisualInfo,visualinfo,TAG_END);
		if (bevels[i].bb_Title)
			{
			char title[64];
			sprintf(title," %s ",bevels[i].bb_Title);
			Move(win->RPort,bevels[i].bb_LeftEdge+(bevels[i].bb_Width-XSIZE(strlen(title)))/2,bevels[i].bb_TopEdge+2);
			SetAPen(win->RPort,bevels[i].bb_Color);
			Text(win->RPort,title,strlen(title));
			}
		/* end-if */
		}
	/* end-for */
}

/*************************************************************************/
/*                                                                       */
/*   CreateLines()                                                       */
/*                                                                       */
/*************************************************************************/

void CreateLines(struct Window *win,int linecount,struct Line lines[])
{
	ULONG i;
	for (i=0;i<linecount;i++)
		{
		SetAPen(win->RPort,lines[i].li_Color);
		Move(win->RPort,lines[i].li_LeftEdge,lines[i].li_TopEdge);
		Draw(win->RPort,lines[i].li_Width>0?lines[i].li_LeftEdge+lines[i].li_Width-1:lines[i].li_LeftEdge+lines[i].li_Width,lines[i].li_Height>0?lines[i].li_TopEdge+lines[i].li_Height-1:lines[i].li_TopEdge+lines[i].li_Height);
		}
	/* end-for */
}

/*************************************************************************/
/*                                                                       */
/*   CreateTexts()                                                       */
/*                                                                       */
/*************************************************************************/

void CreateTexts(struct Window *win,int textcount,struct Text texts[], long double xscale,long double yscale)
{
	ULONG i;
	for (i=0;i<textcount;i++)
		{
		SetAPen(win->RPort,texts[i].tx_Color);
		Move(win->RPort,texts[i].tx_LeftEdge,texts[i].tx_TopEdge+(ULONG)(yscale*GfxBase->DefaultFont->tf_Baseline));
		Text(win->RPort,texts[i].tx_Text,strlen(texts[i].tx_Text));
		}
	/* end-for */
}

/*************************************************************************/
/*                                                                       */
/*   ShowGadget()                                                        */
/*                                                                       */
/*************************************************************************/

#define GADGET_DOWN  0
#define GADGET_UP    1

void ShowGadget(struct Window *win, struct Gadget *gad, int type)
{
	if ((gad->Flags & GFLG_DISABLED) == 0)
		{
		int gadpos = RemoveGadget(win, gad);

		if (type == GADGET_DOWN)
			gad->Flags |= GFLG_SELECTED;
		else
			gad->Flags &= ~GFLG_SELECTED;

		AddGadget(win, gad, gadpos);
		RefreshGList(gad, win, NULL, 1);
	}
}

/*************************************************************************/
/*                                                                       */
/*   About()                                                             */
/*                                                                       */
/*************************************************************************/

void About(struct Window *hostwin,struct Gadget **wingads,APTR userdata)
{
	APTR visualinfo;
	visualinfo=GetVisualInfo(hostwin->WScreen,TAG_DONE);
	if (visualinfo)
		{
		Object *o;
		o=NewDTObject("About.IFF",DTA_SourceType,DTST_FILE,DTA_GroupID,GID_PICTURE,TAG_DONE);
		if (o)
			{
			struct Gadget  *gadgetlist   = NULL;
			struct Screen  *customscreen = NULL;
			struct Gadget  *gadget       = NULL;
			customscreen = hostwin->WScreen;
			gadget       = CreateContext(&gadgetlist);
			if (gadget)
				{
				ULONG height=25,width=34,left=0,top=0;
				ULONG textcount=18;

				struct Gadget *wingad;

				char * title                  = "About";
				struct Window     *win        = NULL;

				struct TextAttr   textattr;
				struct NewGadget  newgad;
				struct Text       texts[18];

				textattr.ta_Name =(char *)(&GfxBase->DefaultFont->tf_Message.mn_Node);
				textattr.ta_YSize=GfxBase->DefaultFont->tf_YSize;
				textattr.ta_Style=FS_NORMAL;
				textattr.ta_Flags=FPF_DISKFONT;

				newgad.ng_LeftEdge   = XPOS(1);
				newgad.ng_TopEdge    = YPOS(22);
				newgad.ng_Width      = XSIZE(32)+200;
				newgad.ng_Height     = YSIZE(2);
				newgad.ng_GadgetText = "_OK";
				newgad.ng_TextAttr   = &textattr;
				newgad.ng_GadgetID   = 2;
				newgad.ng_Flags      = PLACETEXT_IN;
				newgad.ng_VisualInfo = visualinfo;
				newgad.ng_UserData   = NULL;
				texts[ 0].tx_LeftEdge=200+XPOS(4);
				texts[ 0].tx_TopEdge =YPOS(2);
				texts[ 0].tx_Text    ="";
				texts[ 0].tx_Color   =1;
				texts[ 1].tx_LeftEdge=200+XPOS(4);
				texts[ 1].tx_TopEdge =YPOS(3);
				texts[ 1].tx_Text    ="";
				texts[ 1].tx_Color   =1;
				texts[ 2].tx_LeftEdge=200+XPOS(4);
				texts[ 2].tx_TopEdge =YPOS(4);
				texts[ 2].tx_Text    ="";
				texts[ 2].tx_Color   =1;
				texts[ 3].tx_LeftEdge=200+XPOS(4);
				texts[ 3].tx_TopEdge =YPOS(5);
				texts[ 3].tx_Text    ="";
				texts[ 3].tx_Color   =1;
				texts[ 4].tx_LeftEdge=200+XPOS(4);
				texts[ 4].tx_TopEdge =YPOS(6);
				texts[ 4].tx_Text    ="";
				texts[ 4].tx_Color   =1;
				texts[ 5].tx_LeftEdge=200+XPOS(4);
				texts[ 5].tx_TopEdge =YPOS(7);
				texts[ 5].tx_Text    ="";
				texts[ 5].tx_Color   =1;
				texts[ 6].tx_LeftEdge=200+XPOS(4);
				texts[ 6].tx_TopEdge =YPOS(8);
				texts[ 6].tx_Text    ="";
				texts[ 6].tx_Color   =1;
				texts[ 7].tx_LeftEdge=200+XPOS(4);
				texts[ 7].tx_TopEdge =YPOS(9);
				texts[ 7].tx_Text    ="";
				texts[ 7].tx_Color   =1;
				texts[ 8].tx_LeftEdge=200+XPOS(4);
				texts[ 8].tx_TopEdge =YPOS(10);
				texts[ 8].tx_Text    ="";
				texts[ 8].tx_Color   =1;
				texts[ 9].tx_LeftEdge=200+XPOS(4);
				texts[ 9].tx_TopEdge =YPOS(11);
				texts[ 9].tx_Text    ="";
				texts[ 9].tx_Color   =1;
				texts[10].tx_LeftEdge=200+XPOS(4);
				texts[10].tx_TopEdge =YPOS(12);
				texts[10].tx_Text    ="";
				texts[10].tx_Color   =1;
				texts[11].tx_LeftEdge=200+XPOS(4);
				texts[11].tx_TopEdge =YPOS(13);
				texts[11].tx_Text    ="";
				texts[11].tx_Color   =1;
				texts[12].tx_LeftEdge=200+XPOS(4);
				texts[12].tx_TopEdge =YPOS(14);
				texts[12].tx_Text    ="";
				texts[12].tx_Color   =1;
				texts[13].tx_LeftEdge=200+XPOS(4);
				texts[13].tx_TopEdge =YPOS(15);
				texts[13].tx_Text    ="";
				texts[13].tx_Color   =1;
				texts[14].tx_LeftEdge=200+XPOS(4);
				texts[14].tx_TopEdge =YPOS(16);
				texts[14].tx_Text    ="";
				texts[14].tx_Color   =1;
				texts[15].tx_LeftEdge=200+XPOS(4);
				texts[15].tx_TopEdge =YPOS(17);
				texts[15].tx_Text    ="";
				texts[15].tx_Color   =1;
				texts[16].tx_LeftEdge=200+XPOS(4);
				texts[16].tx_TopEdge =YPOS(18);
				texts[16].tx_Text    ="";
				texts[16].tx_Color   =1;
				texts[17].tx_LeftEdge=200+XPOS(4);
				texts[17].tx_TopEdge =YPOS(19);
				texts[17].tx_Text    ="";
				texts[17].tx_Color   =1;

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

				wingad = gadget = CreateGadget(BUTTON_KIND,gadget,&newgad,GT_Underscore,'_',TAG_END);

				if (height>customscreen->Height || width>customscreen->Width) GUIC_ErrorReport(hostwin,ERROR_SCREEN_TOO_SMALL);
				win=OpenWindowTags(NULL,WA_Activate,         TRUE,
												WA_CloseGadget,      TRUE,
												WA_DepthGadget,      TRUE,
												WA_SizeGadget,       FALSE,
												WA_DragBar,          TRUE,
												WA_Gadgets,          gadgetlist,
												WA_InnerHeight,      height,
												WA_InnerWidth,       width,
												WA_IDCMP,            IDCMP_CLOSEWINDOW|BUTTONIDCMP|IDCMPUPDATE|IDCMP_VANILLAKEY,
												WA_Left,             left,
												WA_Top,              top,
												WA_SmartRefresh,     TRUE,
												WA_Title,            title,
												WA_CustomScreen,     customscreen,
												TAG_END);
				if (win)
					{
					struct IntuiMessage  *imessage   = NULL;
					struct Gadget        *idcmpgad   = NULL;
					struct BitMap        *bmcopy     = NULL;
					struct TagItem       *tag        = NULL;
					struct TagItem       *tstate     = NULL;
					ULONG  idcmpclass                = 0;
					UWORD  messagecode               = 0;
					BOOL   running                   = TRUE;

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

					DrawBevelBox(win->RPort,XPOS(1),YPOS(1),204,102,GT_VisualInfo,visualinfo,GTBB_Recessed,TRUE,TAG_END);
					DrawBevelBox(win->RPort,XPOS(3)+200,YPOS(1),XSIZE(30),YSIZE(20),GT_VisualInfo,visualinfo,GTBB_Recessed,TRUE,TAG_END);

					SetDTAttrs(o,NULL,NULL,GA_Left,XPOS(1)+2,GA_Top,YPOS(1)+1,GA_Width,200,GA_Height,100,PDTA_Remap,TRUE,PDTA_DestBitMap,&bmcopy,ICA_TARGET,ICTARGET_IDCMP,TAG_DONE);
					AddDTObject(win,NULL,o,-1L);

					CreateTexts(win,textcount,texts,1.0,1.0);

					GT_RefreshWindow(win,NULL);

					while (running)
						{
						Wait(1L << win->UserPort->mp_SigBit);
						while (imessage=GT_GetIMsg(win->UserPort))
							{
							idcmpgad=(struct Gadget *)imessage->IAddress;
							idcmpclass=imessage->Class;
							messagecode =imessage->Code;

							GT_ReplyIMsg(imessage);

							switch(idcmpclass)
								{
								case IDCMP_VANILLAKEY:
									if (messagecode == 27 || messagecode == 'o' || messagecode == 'O') running=FALSE;
									break;
								case IDCMP_REFRESHWINDOW:
									GT_BeginRefresh(win);
									GT_EndRefresh(win,TRUE);
									break;
								case IDCMP_CLOSEWINDOW:
									running=FALSE;
									break;
								case BUTTONIDCMP:
									running=FALSE;
									break;
								case IDCMP_IDCMPUPDATE:
									tstate=(struct TagItem*)imessage->IAddress;
									while (tag=NextTagItem(&tstate)) if (tag->ti_Tag == DTA_Sync) RefreshDTObjectA(o,win,NULL,NULL);
									break;
								}
							/* end-switch */

							}
						/* end-while */
						}
					/* end-while */

					CloseWindow(win);
					WakenWindow(hostwin);
					}
				else GUIC_ErrorReport(hostwin,ERROR_NO_WINDOW_OPENED);
				FreeGadgets(gadgetlist);
				}
			else GUIC_ErrorReport(hostwin,ERROR_NO_GADGETLIST_CREATED);
			DisposeDTObject(o);
			}
		else GUIC_ErrorReport(hostwin,ERROR_NO_PICTURE_LOADED);
		FreeVisualInfo(visualinfo);
		}
	else GUIC_ErrorReport(hostwin,ERROR_NO_VISUALINFO);

}
