#include "kant build window.h"
#include "kant build meat.h"
#include "kant build gui.h"
#include "kant build files.h"
#include "kant load-save.h"
#include "environment.h"
#include "util.h"
#include "menus.h"
#include "main.h"
#include "dialogs.h"
#include "text twiddling.h"
#include "generic window handlers.h"
#include "window layer.h"
#include "program globals.h"

#define kGrowBoxSize		15

enum { key_LeftArrow=0x1c, key_RightArrow, key_UpArrow, key_DownArrow };

static	void PutDataIntoTEFields(WindowPtr theWindow);

static	TEClickLoopUPP	gClickLoopUPP;
static	Boolean			gSetupDone=FALSE;

void SetupTheBuildWindow(WindowPtr theWindow)
{
	unsigned char	*titleStr="\puntitled";
	Point			topLeft;
	FSSpec			fs;
	
	SetWindowHeight(theWindow, qd.screenBits.bounds.bottom-qd.screenBits.bounds.top-LMGetMBarHeight()-48);
	SetWindowWidth(theWindow, qd.screenBits.bounds.right-qd.screenBits.bounds.left-70);
	SetWindowType(theWindow, zoomDocProc);
	topLeft.v=qd.screenBits.bounds.top+LMGetMBarHeight()+40;
	topLeft.h=qd.screenBits.bounds.left+30;
	SetWindowTopLeft(theWindow, topLeft);
	SetWindowHasCloseBox(theWindow, TRUE);
	SetWindowMaxDepth(theWindow, 1);
	SetWindowDepth(theWindow, 1);
	SetWindowIsFloat(theWindow, FALSE);
	SetWindowTitle(theWindow, titleStr);
	SetWindowAutoCenter(theWindow, FALSE);
	fs.name[0]=0x00;
	fs.vRefNum=0;
	fs.parID=0;
	SetWindowFS(theWindow, fs);
	SetWindowIsModified(theWindow, FALSE);
	
	if (gSetupDone)
		return;
	
	gClickLoopUPP=NewTEClickLoopProc(MyClikLoop);
	gSetupDone=TRUE;
	gNeedToOpenWindow=FALSE;
}

void ShutDownTheBuildWindow(void)
{
	if (gClickLoopUPP!=0L)
		DisposeRoutineDescriptor(gClickLoopUPP);
}

void OpenTheBuildWindow(WindowPtr theWindow)
{
	TEHandle		hTE;
	FontInfo		theFontInfo;
	Rect			vScrollBarRect, hScrollBarRect;
	Rect			destRect, viewRect;
	
	hTE=GetWindowTE(theWindow);
	if (hTE==0L)
	{
		SetRect(&vScrollBarRect, GetWindowWidth(theWindow)-kGrowBoxSize, -1,
			GetWindowWidth(theWindow)+1, GetWindowHeight(theWindow)+1-kGrowBoxSize);
		SetRect(&hScrollBarRect, -1, GetWindowHeight(theWindow)-kGrowBoxSize,
			GetWindowWidth(theWindow)-kGrowBoxSize+1, GetWindowHeight(theWindow)+1);
		SetWindowVScrollBar(theWindow,
			NewControl(theWindow, &vScrollBarRect, "\p", TRUE, 0, 0, 0, scrollBarProc, 0));
		SetWindowHScrollBar(theWindow,
			NewControl(theWindow, &hScrollBarRect, "\p", TRUE, 0, 0, 1000, scrollBarProc, 0));
		
		GetTERect(theWindow, &destRect, TRUE);
		viewRect=destRect;
		destRect.right+=1000;
		hTE=TENew(&destRect, &viewRect);
		SetWindowTE(theWindow, hTE);
		TextFont((**hTE).txFont=geneva);
		TextSize((**hTE).txSize=9);
		TextFace((**hTE).txFace=0);
		GetFontInfo(&theFontInfo);
		(**hTE).fontAscent=theFontInfo.ascent;
		(**hTE).lineHeight=theFontInfo.ascent+theFontInfo.descent+theFontInfo.leading;
		AdjustViewRect(hTE);
		TEAutoView(TRUE, hTE);
		(**hTE).clickLoop=gClickLoopUPP;
		PutDataIntoTEFields(theWindow);
	}
	
	SetWindowIsActive(theWindow, TRUE);
	AdjustVScrollBar(GetWindowVScrollBar(theWindow), hTE);
	AdjustMenus();
}

void KeyPressedInBuildWindow(WindowPtr theWindow, unsigned char theChar)
{
	TEHandle		hTE;
	ControlHandle	vScrollBar;
	short			lineNum;
	
	hTE=GetWindowTE(theWindow);
	vScrollBar=GetWindowVScrollBar(theWindow);
	
	switch (theChar)
	{
		case key_UpArrow:
			if (AnyHighlightedQQ(theWindow))
			{
				lineNum=CurrentLineNumber(hTE);
				if (lineNum==0)
					lineNum=TotalNumberOfLines(hTE)-1;
			}
			else lineNum=TotalNumberOfLines(hTE)-1;
			
			HighlightLine(hTE, lineNum-1);
			break;
		case key_DownArrow:
			if (AnyHighlightedQQ(theWindow))
			{
				lineNum=CurrentLineNumber(hTE);
				if (lineNum==TotalNumberOfLines(hTE)-2)
					lineNum=-1;
			}
			else lineNum=-1;
			
			HighlightLine(hTE, lineNum+1);
			break;
		case '\r':
			if (RefHighlightedQQ(theWindow))
				DoEditRef(theWindow);
			else
				DoEditInstantiation(theWindow);
			break;
		case 0x08:
			if (RefHighlightedQQ(theWindow))
				DoDeleteRef(theWindow);
			else
				DoDeleteInstantiation(theWindow);
			break;
		default:
			break;
	}
	
	AdjustVScrollBar(vScrollBar, hTE);
}

void MouseUpInBuildWindow(WindowPtr theWindow, Point thePoint)
{
	TEHandle		hTE;
	
	if (gInProgress)
		return;
	
	hTE=GetWindowTE(theWindow);
	
	if (PtInRect(thePoint, &((**hTE).viewRect)))
	{
		DealWithBuildMouseUp(theWindow, thePoint);
	}
}

Boolean MouseClickedInBuildWindow(WindowPtr theWindow, Point thePoint)
{
	short			partCode;
	ControlHandle	theControl;
	short			scrollDistance;
	short			oldSetting;
	ControlActionUPP	scrollActionUPP=NewControlActionProc(ScrollActionProc);
	ControlActionUPP	hScrollActionUPP=NewControlActionProc(HScrollActionProc);
	TEHandle		hTE;
	
	if (gInProgress)
		return TRUE;
	
	hTE=GetWindowTE(theWindow);
	
	if (PtInRect(thePoint, &((**hTE).viewRect)))
	{
		DealWithBuildContentClick(theWindow, thePoint);
		return TRUE;
	}
	else
	{
		partCode=FindControl(thePoint, theWindow, &theControl);
		if (theControl==GetWindowVScrollBar(theWindow))
		{
			switch (partCode)
			{
				case inThumb:
					oldSetting=GetControlValue(theControl);
					partCode=TrackControl(theControl, thePoint, 0L);
					if (partCode==inThumb)
					{
						scrollDistance=oldSetting-GetControlValue(theControl);
						if (scrollDistance!=0)
							TEPinScroll(0, scrollDistance*(**hTE).lineHeight, hTE);
					}
					break;
				case inUpButton:
				case inDownButton:
				case inPageUp:
				case inPageDown:
					partCode=TrackControl(theControl, thePoint, scrollActionUPP);
					break;
			}
			
			return TRUE;
		}
		else if (theControl==GetWindowHScrollBar(theWindow))
		{
			switch (partCode)
			{
				case inThumb:
					oldSetting=GetControlValue(theControl);
					partCode=TrackControl(theControl, thePoint, 0L);
					if (partCode==inThumb)
					{
						scrollDistance=oldSetting-GetControlValue(theControl);
						if (scrollDistance!=0)
							TEPinScroll(scrollDistance, 0, hTE);
					}
					break;
				case inUpButton:
				case inDownButton:
				case inPageUp:
				case inPageDown:
					partCode=TrackControl(theControl, thePoint, hScrollActionUPP);
			}
		}
	}
	
	return FALSE;
}

void DisposeTheBuildWindow(WindowPtr theWindow)
{
	TEHandle		hTE;
	
	hTE=GetWindowTE(theWindow);
	if (hTE!=0L)
	{
		TEDispose(hTE);
		SetWindowTE(theWindow, 0L);
	}
}

static	void PutDataIntoTEFields(WindowPtr theWindow)
{
	TEHandle		hTE;
	
	hTE=GetWindowTE(theWindow);
	TESetSelect(0, 0, hTE);
	TEKey(0x00, hTE);
	TEKey(0x08, hTE);
}
