#include "PostPre.h"
#include "Global.h"
#include "PostWin.h"

#include <intuition/icclass.h>

BOOL	gadgets = FALSE;

struct DrawInfo	*drinfo = NULL;
struct Gadget		*uparrowg = NULL, *downarrowg = NULL, *leftarrowg = NULL,
						*rightarrowg = NULL, *vertscrollg = NULL, *boopsig = NULL;
struct Image		*upimage = NULL, *downimage = NULL, *leftimage = NULL,
						*rightimage = NULL;

struct TagItem	arrows2me[] = {
    {GA_ID, GA_ID},
    {TAG_END, }};

/* Horizontal scroll proportional gadget */
struct	PropInfo	hscrollinfo =
{
	AUTOKNOB | FREEHORIZ | PROPNEWLOOK | PROPBORDERLESS,
	-1, -1, -1, -1
};
struct	Image		hscrollimage;
struct	Gadget	hscrollgadg =
{
	NULL, 0, -6, -12, 9,
	GRELBOTTOM | GRELWIDTH, BOTTOMBORDER | RELVERIFY | GACT_FOLLOWMOUSE | GACT_IMMEDIATE, PROPGADGET,
	(APTR)&hscrollimage, NULL, NULL, 0, (APTR)&hscrollinfo, HORIZ_SCROLLER, NULL
};

/* Vertical scroll proportional gadget */
struct	PropInfo	vscrollinfo =
{
	AUTOKNOB | FREEVERT | PROPNEWLOOK | PROPBORDERLESS,
	-1, -1, -1, -1
};
struct	Image		vscrollimage;
struct	Gadget	vscrollgadg =
{
	&hscrollgadg, -10, 0, 8, -7,
	GRELRIGHT | GRELHEIGHT, RIGHTBORDER | RELVERIFY | GACT_FOLLOWMOUSE | GACT_IMMEDIATE, PROPGADGET,
	(APTR)&vscrollimage, NULL, NULL, 0, (APTR)&vscrollinfo, VERT_SCROLLER, NULL
};

struct	Menu		*menu0=NULL, *menu1=NULL, *menu2=NULL;
struct	Process	*process;
struct	Window	*syswindow=NULL;

void	openwindow(void)
{
	UWORD		hidden;
	struct	Gadget *tmpgad;
	int		sysi_size, sysi_aupheight, sysi_ariwidth, sysi_vscwidth;

	GetVisual();
	menu0 = CreateMenus(MenuNewMenu, TAG_END);
	LayoutMenus(menu0, my_VisualInfo, GTMN_NewLookMenus, TRUE, TAG_END);
	menu1 = menu0->NextMenu;
	menu2 = menu1->NextMenu;

	if(Options.OutputWnd.WndWidth > Options.PostOpts.width)
		Options.OutputWnd.WndWidth = Options.PostOpts.width;
	if(Options.OutputWnd.WndHeight > Options.PostOpts.height)
		Options.OutputWnd.WndHeight = Options.PostOpts.height;
	OutputWnd = OpenWindowTags(NULL,
			WA_Left,				Options.OutputWnd.WndLeft,
			WA_Top,				Options.OutputWnd.WndTop,
			WA_InnerWidth,		Options.OutputWnd.WndWidth,
			WA_InnerHeight,	Options.OutputWnd.WndHeight,
			WA_MinWidth,		100,
			WA_MaxWidth,		Options.PostOpts.width,
			WA_MinHeight,		100,
			WA_MaxHeight,		Options.PostOpts.height,
			WA_AutoAdjust,		TRUE,
			WA_IDCMP,			IDCMP_REFRESHWINDOW | IDCMP_NEWSIZE |
									IDCMP_GADGETUP | IDCMP_GADGETDOWN |
									IDCMP_IDCMPUPDATE | IDCMP_CLOSEWINDOW |
									IDCMP_MOUSEMOVE | IDCMP_SIZEVERIFY |
									IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW |
									IDCMP_MENUVERIFY | IDCMP_CHANGEWINDOW | 
									IDCMP_MENUPICK | IDCMP_RAWKEY | IDCMP_VANILLAKEY,
			WA_Flags,			WFLG_DRAGBAR | WFLG_DEPTHGADGET |
									WFLG_CLOSEGADGET | WFLG_SIMPLE_REFRESH |
									WFLG_ACTIVATE | WFLG_SIZEGADGET |
									WFLG_SIZEBRIGHT | WFLG_SIZEBBOTTOM,
			WA_Title,			(ULONG) windowtitle,
			WA_ScreenTitle,	(ULONG) windowtitle,
			WA_PubScreen,		(ULONG) screen,
			WA_NewLookMenus,	TRUE,
			WA_Zoom,				(ULONG) &(Options.OutputWnd.WndZoomLeft),
			TAG_DONE);
	if (OutputWnd == NULL)
	{
		okmsg("can't open window");
		errorende();
		exit(20);
	}

/* Locate the visible part of the bitmap within its window, adjusting	*
 * for the borders 																		*/

	winxbase = OutputWnd->BorderLeft;
	winybase = OutputWnd->BorderTop;
	winxsize = OutputWnd->Width - OutputWnd->BorderLeft - OutputWnd->BorderRight;
	winysize = OutputWnd->Height - OutputWnd->BorderTop-OutputWnd->BorderBottom;
/*	winxpos = 0;
	winypos = Options.PostOpts.height - winysize;*/

	WindowLimits(OutputWnd, 100, 100,
		Options.PostOpts.width + OutputWnd->BorderRight + OutputWnd->BorderLeft,
		Options.PostOpts.height + OutputWnd->BorderTop + OutputWnd->BorderBottom);

	if(OutputWnd->BorderRight <= 13)
	{
		sysi_size		= SYSISIZE_LOWRES;
		sysi_aupheight	= 11;
		sysi_ariwidth	= 16;
		sysi_vscwidth	= 7;
	}
	else
	{
		sysi_size = SYSISIZE_MEDRES;
		sysi_aupheight	= 11;
		sysi_ariwidth	= 16;
		sysi_vscwidth	= 10;
	}
	vscrollgadg.LeftEdge = -OutputWnd->BorderRight + 1 + (OutputWnd->BorderRight - sysi_vscwidth) / 2;
	vscrollgadg.TopEdge = OutputWnd->BorderTop + 1;
	vscrollgadg.Height = -OutputWnd->BorderTop - OutputWnd->BorderBottom - 2 * sysi_aupheight - 2;
	vscrollgadg.Width = sysi_vscwidth;

	hscrollgadg.LeftEdge = OutputWnd->BorderLeft;
	hscrollgadg.TopEdge = -OutputWnd->BorderBottom + 3;
	hscrollgadg.Height =  OutputWnd->BorderBottom - 4;
	hscrollgadg.Width = -OutputWnd->BorderLeft - OutputWnd->BorderRight - 2 * sysi_ariwidth - 1;

	hidden = max(Options.PostOpts.width - winxsize, 0);
	if(winxpos > hidden) winxpos = hidden;
	if(hidden > 0)
	{
		hscrollinfo.HorizBody = (UWORD) (((ULONG) winxsize * MAXBODY) / (Options.PostOpts.width));
		hscrollinfo.HorizPot = (UWORD) (((ULONG) winxpos * MAXBODY) / hidden);
	}
	else
	{
		hscrollinfo.HorizBody = MAXBODY;
		hscrollinfo.HorizPot = 0;
	}
	hidden = max(Options.PostOpts.height - winysize, 0);
	if(winypos > hidden) winypos = hidden;
	if(hidden > 0)
	{
		vscrollinfo.VertBody = (UWORD) (((ULONG) winysize * MAXBODY) / (Options.PostOpts.height));
		vscrollinfo.VertPot = (UWORD) (((ULONG) winypos * MAXBODY) / hidden);
	}
	else
	{
		vscrollinfo.VertBody = MAXBODY;
		vscrollinfo.VertPot= 0;
	}
	AddGadget(OutputWnd, &hscrollgadg, -1);
	AddGadget(OutputWnd, &vscrollgadg, -1);
	RefreshGadgets(&hscrollgadg, OutputWnd, NULL);

	drinfo = GetScreenDrawInfo(OutputWnd->WScreen);
	upimage = (struct Image *) NewObject( NULL, "sysiclass",
				SYSIA_Size, sysi_size, SYSIA_Which, UPIMAGE,
				SYSIA_DrawInfo, (ULONG) drinfo, TAG_END );
	downimage = (struct Image *) NewObject( NULL, "sysiclass",
				SYSIA_Size, sysi_size, SYSIA_Which, DOWNIMAGE,
				SYSIA_DrawInfo, (ULONG) drinfo, TAG_END );
	leftimage = (struct Image *) NewObject( NULL, "sysiclass",
				SYSIA_Size, sysi_size, SYSIA_Which, LEFTIMAGE,
				SYSIA_DrawInfo, (ULONG) drinfo, TAG_END );
	rightimage = (struct Image *) NewObject( NULL, "sysiclass",
				SYSIA_Size, sysi_size, SYSIA_Which, RIGHTIMAGE,
				SYSIA_DrawInfo, (ULONG) drinfo, TAG_END );

	tmpgad = (struct Gadget *) &boopsig;
	uparrowg = (struct Gadget *) NewObject( NULL, "buttongclass",
				GA_IMAGE, 	(ULONG) upimage, GA_ID, GAD_UP,
				ICA_TARGET, ICTARGET_IDCMP, ICA_MAP, (ULONG) &arrows2me[0],
				GA_PREVIOUS, (ULONG) tmpgad, /*GA_RELVERIFY, TRUE, */GA_IMMEDIATE, TRUE,
				GA_RelRight, -OutputWnd->BorderRight + 1, GA_RelBottom, -OutputWnd->BorderBottom - 2*sysi_aupheight + 1, TAG_END);
	downarrowg = (struct Gadget *) NewObject( NULL, "buttongclass",
				GA_IMAGE, (ULONG) downimage, GA_ID, GAD_DOWN,
				ICA_TARGET, ICTARGET_IDCMP, ICA_MAP, (ULONG) &arrows2me[0],
				GA_PREVIOUS, (ULONG) tmpgad, /*GA_RELVERIFY, TRUE, */GA_IMMEDIATE, TRUE,
				GA_RelRight, -OutputWnd->BorderRight + 1, GA_RelBottom, -OutputWnd->BorderBottom - sysi_aupheight + 1, TAG_END );
	leftarrowg = (struct Gadget *) NewObject( NULL, "buttongclass",
				GA_IMAGE, 	(ULONG) leftimage, GA_ID, GAD_LEFT,
				ICA_TARGET, ICTARGET_IDCMP, ICA_MAP, (ULONG) &arrows2me[0],
				GA_PREVIOUS, (ULONG) tmpgad, /*GA_RELVERIFY, TRUE, */GA_IMMEDIATE, TRUE,
				GA_RelRight, -OutputWnd->BorderRight - 2 * sysi_ariwidth + 1, GA_RelBottom, -OutputWnd->BorderBottom + 1, TAG_END);
	rightarrowg = (struct Gadget *) NewObject( NULL, "buttongclass",
				GA_IMAGE, 	(ULONG) rightimage, GA_ID, GAD_RIGHT,
				ICA_TARGET, ICTARGET_IDCMP, ICA_MAP, (ULONG) &arrows2me[0],
				GA_PREVIOUS, (ULONG) tmpgad, /*GA_RELVERIFY, TRUE, */GA_IMMEDIATE, TRUE,
				GA_RelRight, -OutputWnd->BorderRight - sysi_ariwidth + 1, GA_RelBottom, -OutputWnd->BorderBottom + 1, TAG_END);

	if(!(drinfo && upimage && downimage && leftimage && rightimage &&
		downarrowg && uparrowg && leftarrowg && rightarrowg))
	{
		okmsg("can't get BOOPSI images & gadgets!");
		errorende();
		exit(20);
	}
	gadgets = TRUE;
	AddGList(OutputWnd, boopsig, -1, -1, NULL);
	RefreshGList(boopsig, OutputWnd, NULL, -1);

	process = (struct Process *) FindTask(NULL);
	syswindow = (struct Window *) process->pr_WindowPtr;
	process->pr_WindowPtr = (APTR) OutputWnd;
	if(pubscrcontext.ps_lock)
	{
		UnlockPubScreen(NULL, pubscrcontext.pubscreen);
		pubscrcontext.ps_lock = FALSE;
	}
	SetMenuStrip(OutputWnd, menu0);
	setmenu();
	blit_to_window = TRUE;
}

void	closewindow(void)
{
	Forbid();
	blit_to_window = FALSE;
	if(intmsg)
	{
		do
		{
			ReplyMsg((struct Message *) intmsg);
		} while( intmsg = (struct IntuiMessage *) GetMsg(OutputWnd->UserPort));
	}
	if(menu0)
	{
		ClearMenuStrip(OutputWnd);
		FreeMenus(menu0);
		menu0 = NULL;
	}
	if(gadgets)
	{
		RemoveGList(OutputWnd, boopsig, -1);
		boopsig = NULL;
		gadgets = FALSE;
	}
	if(drinfo)
	{
		FreeScreenDrawInfo(OutputWnd->WScreen, drinfo);
		drinfo = NULL;
	}
	if(uparrowg)
	{
		DisposeObject(uparrowg);
		uparrowg = NULL;
	}
	if(downarrowg)
	{
		DisposeObject(downarrowg);
		downarrowg = NULL;
	}
	if(leftarrowg)
	{
		DisposeObject(leftarrowg);
		leftarrowg = NULL;
	}
	if(rightarrowg)
	{
		DisposeObject(rightarrowg);
		rightarrowg = NULL;
	}
	if(upimage)
	{
		DisposeObject(upimage);
		upimage = NULL;
	}
	if(downimage)
	{
		DisposeObject(downimage);
		downimage = NULL;
	}
	if(leftimage)
	{
		DisposeObject(leftimage);
		leftimage = NULL;
	}
	if(rightimage)
	{
		DisposeObject(rightimage);
		rightimage = NULL;
	}

	if (OutputWnd)
	{
		process->pr_WindowPtr = (APTR) syswindow;
		CloseWindow(OutputWnd);
		OutputWnd = NULL;
	}
	if(pubscrcontext.got_pens)
	{
		ReleaseNeededPens(&pubscrcontext);
	}
	FreeVisual();
	Permit();
}