#include "drawwin.h"
#include "datatype.h"
#include "gui.h"
#include "bitmap.h"

#include<string.h>
#include<stdio.h>

#include<datatypes/pictureclass.h>
#include<intuition/icclass.h>

#include<clib/datatypes_protos.h>
#include<clib/graphics_protos.h>
#include<clib/intuition_protos.h>

extern struct Library* DataTypesBase;

static void setcolours(struct ViewPort*, ULONG*, int);

int useDT()
{
	return DataTypesBase != NULL;
}

int loadDT(char* filename)
{
	struct Window* win = getDrawWin();
	Object* dto;
	SetWindowPointer(win, WA_BusyPointer, TRUE, TAG_DONE);
	if(dto = NewDTObject((APTR)filename,
											 PDTA_Remap, FALSE,
											 TAG_DONE))
	{
		struct gpLayout gpl;
		gpl.MethodID = DTM_PROCLAYOUT;
		gpl.gpl_GInfo = NULL;
		gpl.gpl_Initial = 1;
		if(DoDTMethodA(dto, NULL, NULL, (Msg)&gpl))
		{
			struct dtFrameBox dtf;
			struct FrameInfo fri;
			/* Clear the frame structures */
			memset(&dtf, 0, sizeof(struct dtFrameBox));
			memset(&fri, 0, sizeof(struct FrameInfo));
			/* Initialise DataType method */
			dtf.MethodID = DTM_FRAMEBOX;
			dtf.dtf_FrameInfo = &fri;
			dtf.dtf_ContentsInfo = &fri;
			dtf.dtf_SizeFrameInfo = sizeof(struct FrameInfo);
			if(DoDTMethodA(dto, NULL, NULL, (Msg)&dtf))
			{
				int needScreen = FALSE;
				ULONG* cregs = NULL;
				struct BitMapHeader* bmh = NULL;
				struct BitMap* bm = NULL;
				ULONG modeid = INVALID_ID;
				GetDTAttrs(dto,
									 /* Get the video mode id */
									 PDTA_ModeID, &modeid,
									 /* Get the size info */
									 PDTA_BitMapHeader, &bmh,
									 /* Get the picture */
									 PDTA_BitMap, &bm,
									 /* Get the colours */
									 PDTA_CRegs, &cregs,
									 TAG_DONE);
				/* Do we need to have a new screen? */
				if(bmh->bmh_Width > win->Width)
					needScreen = TRUE;
				else if(bmh->bmh_Height > win->Height)
					needScreen = TRUE;
				else if(bmh->bmh_Depth > win->WScreen->BitMap.Depth)
					needScreen = TRUE;
				else if(fri.fri_PropertyFlags)
				{
					if(fri.fri_PropertyFlags & (DIPF_IS_HAM | DIPF_IS_EXTRAHALFBRITE))
						needScreen = TRUE;
				}
				else if((modeid != INVALID_ID) && (modeid & 0x800))
					needScreen = TRUE;
				/* Allow the user to request a screen change */
				if(!needScreen)
				{
					struct EasyStruct myreq = { sizeof(struct EasyStruct),
																			0,
																			"Screen Change Confirmation",
																			"The selected image is %ldx%ldx%ld.\n"
																				"Do you wish to change the current\n"
																				"screen to match this?",
																			"Yes|No" };
					/* Only change the GUI if the user wants to */
					if(EasyRequest(win, &myreq, NULL,
												 bmh->bmh_Width,
												 bmh->bmh_Height,
												 bmh->bmh_Depth))
						needScreen = TRUE;
				}
				/* Reset the GUI if required or requested */
				if(needScreen)
				{
					closeGUI();
					/* If this fails, our local win will then be set to NULL */
					openGUI(bmh->bmh_Depth,
									bmh->bmh_Width,
									bmh->bmh_Height,
									modeid == INVALID_ID ? 0 : modeid);
					win = getDrawWin();
				}
				if(win)
				{
					/* Change screen colours */
					setcolours(&(win->WScreen->ViewPort), cregs, 1<<bmh->bmh_Depth);
					/* Copy the picture to our window */
					BltBitMapRastPort(bm, 0, 0,
														win->RPort, 0, 0,
														bmh->bmh_Width, bmh->bmh_Height, 0xc0);
					WaitBlit();
				}
			}
		}
		DisposeDTObject(dto);
	}
	else
		printf("Error: could not open DT object\n");
	SetWindowPointer(win, WA_BusyPointer, FALSE, TAG_DONE);
	return TRUE;
}

static void setcolours(struct ViewPort* vp, ULONG* cregs, int count)
{
	if(cregs)
	{
		int i;
		for(i = 0; i<count; i++)
		{
			SetRGB32(vp,i,cregs[0],cregs[1],cregs[2]);
			cregs += 3;
		}
	}
}
