#include <exec/types.h>
#include <intuition/intuition.h>
#include <libraries/dosextens.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "LoadILBM.h"
#include "struct.h"

extern ILBMFrame Frame;
extern struct BitMap bitmap;

struct TextAttr Topaz8=
{
	"topaz.font",8,
	0,0
};

struct NewScreen ScreenDef=
{
	0,0,
	640,200,
	4,
	1,0,
	HIRES,
	CUSTOMSCREEN,
	&Topaz8,
	"JASPA 1.00",
	NULL,
	NULL
};

struct NewWindow WindowDef=
{
	0,10,
	640,190,
	0,1,
	VANILLAKEY|MOUSEBUTTONS|GADGETUP|INTUITICKS,
	BORDERLESS|SMART_REFRESH|NOCAREREFRESH|ACTIVATE,
	NULL,	/* No gadgets yet */
	NULL,	/* default checkmark */
	NULL,	/* No title */
	NULL,	/* Filled in later */
	NULL,	/* No bitmap */
	0,0,640,200,	/* No resizes */
	CUSTOMSCREEN
};

extern long IntuitionBase;
extern long GfxBase;
struct Screen *ToolScreen;
struct Window *ToolWindow;
APTR ProcessVector;
struct Process *Us;


int CleanUp(int x)
{
	ILBMCleanup();
	if(ToolWindow)
	{
		if(ToolWindow->MenuStrip)
			ClearMenuStrip(ToolWindow);
		CloseWindow(ToolWindow);
	}
	if(ToolScreen)
		CloseScreen(ToolScreen);
	if(IntuitionBase)
		CloseLibrary(IntuitionBase);
	if(GfxBase)
		CloseLibrary(GfxBase);
	if(ProcessVector)
		Us->pr_WindowPtr=ProcessVector;
	return(x);
}

/*static struct Image __chip GreyBox=
{
	2,110,636,88,4,
	NULL,
	0,
	2,
	NULL
};*/

void DisplaySetup(void)
{
	int ct;
	onexit(CleanUp);
	Us=(struct Process *)FindTask(NULL);
	ProcessVector=Us->pr_WindowPtr;
	IntuitionBase=OpenLibrary("intuition.library",0);
	if(IntuitionBase==NULL)
		exit(1);
	GfxBase=OpenLibrary("graphics.library",0);
	if(GfxBase==NULL)
		exit(1);
	ToolScreen=(struct Screen *)OpenScreen(&ScreenDef);
	if(ToolScreen==NULL)
	{
		fprintf(stderr,"Can't open screen.\n");
		exit(1);
	}
	WindowDef.Screen=ToolScreen;
	SetRGB4(&ToolScreen->ViewPort,0,0,0,0);
	SetRGB4(&ToolScreen->ViewPort,1,15,15,15);
	SetRGB4(&ToolScreen->ViewPort,2,0xA,0x7,0x0);
	ToolWindow=(struct Window *)OpenWindow(&WindowDef);
	if(ToolWindow==NULL)
	{
		fprintf(stderr,"Can't open window.\n");
		exit(1);
	}
	ShowTitle(ToolScreen,FALSE);
	if((ct=LoadILBM("test.pic"))!=-2)
	{
		printf("ILBM Err %d\n",ct);
		exit(1);
	}
/* Draw the loaded bitmap */
	BltBitMapRastPort(&bitmap,0,0,ToolWindow->RPort,0,0,640,200,0xC0);
	LoadRGB4(&(ToolScreen->ViewPort),Frame.colorMap,16);
	ILBMCleanup();	
}

typedef struct
{
	short Number;
	short XPos,YPos,Height,Width;
	short Depth;
	short Flags;
	short Thing;
#define FL_USED			1
#define FL_TEXT			2
#define FL_AUTOCR		4
#define FL_FIRSTONLY		8
#define FL_ITEMTYPE		16
#define FL_TWOARGS		32
#define FL_CANDRAG		64
#define FL_DCLICK		128
#define FL_LOCKED		256
#define FL_DRAGTO		512
} Box;

static Box BoxList[100];		/* Number of boxes in system */
static int LastBox= -1;

static int AllocBox()
{
	short ct=0;
	while(ct<100)
	{
		if(!(BoxList[ct].Flags&FL_USED))
			return(ct);
		ct++;
	}
	log_error("BOXLIST is full\n");
	panic();
}

static int WhichBox(int x,int y)
{
	short ct=0;
	short top= -1;
	short box= -1;
	while(ct<100)
	{
		if(!(x<BoxList[ct].XPos||y<BoxList[ct].YPos  ||
			x>BoxList[ct].XPos+BoxList[ct].Width ||
			y>BoxList[ct].YPos+BoxList[ct].Height))
		{
			if(top<BoxList[ct].Depth)
			{
				top=BoxList[ct].Depth;
				box=ct;
			}
		}
		ct++;
	}
	if(box == -1)
		return(-1);
	if(BoxList[box].Flags&FL_LOCKED)
		return(-1);
	return(box);
}

static int FindBox(int n)
{
	short ct=0;
	while(ct<100)
	{
		if(BoxList[ct].Number==n)
			return(ct);
		ct++;
	}
	return(-1);
}

void C_TextBox()
{
	int num=Arg();
	int x=Arg();
	int y=Arg();
	int w=Arg();
	int h=Arg();
	int d=Arg();
	int f=Arg();
	int t=Arg();
	int boxid=AllocBox();
	BoxList[boxid].XPos=x;
	BoxList[boxid].YPos=y;
	BoxList[boxid].Height=h;
	BoxList[boxid].Width=w;
	BoxList[boxid].Depth=d;
	BoxList[boxid].Thing=t;
	BoxList[boxid].Number=num;
	BoxList[boxid].Flags=FL_USED|FL_TEXT|f;
}

void C_ItemBox()
{
	int num=Arg();
	int x=Arg();
	int y=Arg();
	int w=Arg();
	int h=Arg();
	int d=Arg();
	int f=Arg();
	int i=Arg();
	int boxid=AllocBox();
	BoxList[boxid].XPos=x;
	BoxList[boxid].YPos=y;
	BoxList[boxid].Height=h;
	BoxList[boxid].Width=w;
	BoxList[boxid].Depth=d;
	BoxList[boxid].Thing=i;
	BoxList[boxid].Number=num;
	BoxList[boxid].Flags=FL_USED|FL_ITEMTYPE|f;
}

void C_KillBox()
{
	int n=Arg();
	int boxid=FindBox(n);
	if(boxid!= -1)
	{
		if(LastBox==boxid)
			LastBox= -1;
		BoxList[boxid].Flags&=~FL_USED;
	}
}

void C_KillAll()
{
	short ct=0;
	while(ct<100)
		BoxList[ct++].Flags=0;
	LastBox= -1;
}

/* Graphical Misc */

void C_DrawInv()
{
	Arg();
	Arg();
}

void C_DrawImage()
{
	int n=Arg();
	int x=Arg();
	int y=Arg();
	int w=Arg();
	int h=Arg();
	char buf[128];
	sprintf(buf,"PIC.%d",n);
	if((n=LoadILBM(buf))!=-2)
	{
		log_error("ILBM Err %d\n",n);
	}
	else
	{
/* Draw the loaded bitmap */
		BltBitMapRastPort(&bitmap,0,0,ToolWindow->RPort,x,y,w,h,0xC0);
		LoadRGB4(&(ToolScreen->ViewPort),Frame.colorMap,16);
	}
	ILBMCleanup();
}

static int TextTop=0;
static int TextAcross;
static char TextBuffer[80];
char InputBuffer[80];
short PromptSize;
static int   CursorPos;

void TextPutLine(void)
{
	static struct IntuiText i=
	{
		1,0,JAM2,2,2,&Topaz8,
		TextBuffer,
		NULL
	};
	PrintIText(ToolWindow->RPort,&i,0,110+TextTop);
}

void InputPutLine(void)
{
	static struct IntuiText i=
	{
		1,0,JAM2,2,2,&Topaz8,
		InputBuffer,
		NULL
	};
	PrintIText(ToolWindow->RPort,&i,0,180);
}

void InputBegin(x)
char *x;
{
	strcpy(InputBuffer,"\
                                                                              ");
	InputPutLine();
	strcpy(InputBuffer,x);
	PromptSize=strlen(x);
	CursorPos=PromptSize;
	strcat(InputBuffer,"_");
	InputPutLine();
}

void InputEnd(void)
{
	strcpy(InputBuffer,"\
                                                                              ");
	InputPutLine();
}

static void InputAddString(x)
char *x;
{
	if(strlen(x)+strlen(InputBuffer)>77)
		return;
	strcpy(InputBuffer+CursorPos,x);
	CursorPos=strlen(InputBuffer);
	strcat(InputBuffer,"_");
}

static int FakeInput(int box)
{
	Box *b=&BoxList[box];
	if(CursorPos!=PromptSize &&
			InputBuffer[CursorPos-1]!=' ')
	{
		InputAddString(" ");
	}
	if(b->Flags&FL_ITEMTYPE)
	{
		char *t=NAME(b->Thing);
		InputAddString(t);
	}
	if(b->Flags&FL_TEXT)
	{
		extern char **Messages;
		char *t=Messages[b->Thing];
		InputAddString(t);
	}
	if(b->Flags&FL_AUTOCR)
	{
		InputAddString("\n");
		return(1);
	}
	return(0);
}

int InputLine(void)
{
	struct IntuiMessage *m;
	int box;
	while(1)
	{
		WaitPort(ToolWindow->UserPort);
		m=(struct IntuiMessage *)GetMsg(ToolWindow->UserPort);
		if(m->Class==INTUITICKS)
		{
			ReplyMsg(m);
			return(0);
		}
		if(m->Class==MOUSEBUTTONS&&m->Code==SELECTUP)
		{
/* Clicked a box maybe ? */
			box=WhichBox(m->MouseX,m->MouseY);
			ReplyMsg(m);
			if(box==-1)
				continue;
			if(BoxList[box].Flags&FL_FIRSTONLY &&CursorPos!=PromptSize)
				continue;
			if(BoxList[box].Flags&FL_ITEMTYPE &&CursorPos==PromptSize)
				continue;
			if(FakeInput(box))
			{
				InputBuffer[CursorPos]=' ';
				InputPutLine();
				InputBuffer[CursorPos]=0;
				return(1);
			}
		}
		if(m->Class!=VANILLAKEY)
		{
			ReplyMsg(m);
			continue;
		}
		if(m->Code=='\n'||m->Code=='\r')
		{
			ReplyMsg(m);
			InputBuffer[CursorPos]=' ';
			InputPutLine();
			InputBuffer[CursorPos]=0;
			return(1);
		}
		if((m->Code==8||m->Code==127)&&(CursorPos>PromptSize))
		{
			ReplyMsg(m);
			InputBuffer[CursorPos]=' ';
			InputPutLine();
			InputBuffer[CursorPos--]=0;
			InputBuffer[CursorPos]='_';
			InputPutLine();
			continue;
		}
		if(CursorPos==78||m->Code>126||m->Code<32)
		{
			ReplyMsg(m);
			continue;
		}
		InputBuffer[CursorPos++]=m->Code;
		InputBuffer[CursorPos]='_';
		InputBuffer[CursorPos+1]=0;
		ReplyMsg(m);
		InputPutLine();
	}
}

void ScrollIt(void)
{
	TextPutLine();
	TextTop+=8;
	if(TextTop>58)
	{
		SetBPen(ToolWindow->RPort,0);
		ScrollRaster(ToolWindow->RPort,0,8,2,112,638,181);
		TextTop-=8;
	}
	TextAcross=0;
	TextBuffer[0]=0;
}

void TextPrintChar(char c)
{
	static int ToScroll=0;
	if(ToScroll==1)
	{
		ScrollIt();
		ToScroll=0;
	}
	if(c=='\n')
	{
		TextPutLine();		
		ToScroll=1;
		return;
	}
	if(TextAcross==79)
	{
		ScrollIt();
		ToScroll=0;
	}
	TextBuffer[TextAcross++]=c;
	TextBuffer[TextAcross]=0;
	TextBuffer[TextAcross]=0;
}
	
void TextPrint(char *x)
{
	if(x==NULL)
	{
		TextPutLine();
		return;
	}
	while(*x)
	{
		TextPrintChar(*x);
		x++;
	}
}

#ifdef TESTIT
void main(int argc,char *argv[])
{
	static struct Image ig;
	extern struct BitMap bitmap;
	int ct;
	DisplaySetup();
	ct=0;
	while(ct<20)
	{
		TextPrint("Test Message................... Wheeee\n");
		InputBegin("_@/ ");
		InputLine();
		ct++;
	}
}
#endif