#include "Initalisation.h"
#include "HexWindow.h"
#include "Events.h"
#include "HexUtility.h"

globals g;
prefs p;

  /************************/
 /* EDITOR INITALIZATION */
/************************/

/*** INITALISE GLOBALS ***/
OSStatus InitGlobals( void )
{
	// get system version
	OSStatus error = Gestalt( gestaltSystemVersion, &g.systemVersion );
	if( error ) return error;
	
	// set up colours
	SetColour( &g.white,		0xFFFF, 0xFFFF, 0xFFFF );
	SetColour( &g.bgColour,		0xEEEE, 0xEEEE, 0xEEEE );
	SetColour( &g.sortColour,	0xDDDD, 0xDDDD, 0xDDDD );
	SetColour( &g.bevelColour,	0xAAAA, 0xAAAA, 0xAAAA );
	SetColour( &g.textColour,	0x7777, 0x7777, 0x7777 );
	SetColour( &g.frameColour,	0x5555, 0x5555, 0x5555 );
	SetColour( &g.black,		0x0000, 0x0000, 0x0000 );
	
	// check appearance availablilty
#if TARGET_API_MAC_CARBON
	g.useAppearance = true;
#else
	ProcessSerialNumber psn;
	error = GetCurrentProcess( &psn );
	if( error ) g.useAppearance = false;
	else g.useAppearance = IsAppearanceClient( &psn );
#endif
	
	// initalise preferences
	p.version = kHexEditorCurrentVersion;
	p.lowChar = 0x20;
	p.highChar = 0x7F;
	p.GWorldDepth = 8;
	
	return error;
}

/*** INITALISE NEW EDITOR INSTANCE ***/
OSStatus Plug_InitInstance( Plug_PlugInRef plug, Plug_ResourceRef resource )
{
	WindowRef window;
	OSStatus error = InitGlobals();
	if( error ) return error;
	
#if USE_NIBS
	// create a nib reference (only searches the application bundle)
	IBNibRef nibRef = null;
	error = CreateNibReference( CFSTR("Hex Editor"), &nibRef );
	if( error != noErr || nibRef == null )
	{
//		Host_DisplayError( "\pThe nib file reference could not be obtained.", "\p", 0 );
		return error;
	}
	
	// create window
	error = CreateWindowFromNib( nibRef, CFSTR("Hex Window"), &window );
	if( error != noErr || window == null )
	{
//		Host_DisplayError( "\pA file window could not be obtained from the nib file.", "\p", 0 );
		return error;
	}
	
	// dispose of nib ref
	DisposeNibReference( nibRef );
#elif TARGET_API_MAC_CARBON
	// create window
	Rect creationBounds;
	SetRect( &creationBounds, 0, 0, kDefaultWindowWidth, kDefaultWindowHeight );
	OffsetRect( &creationBounds, 8, 48 );
	WindowAttributes					attributes = kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute | kWindowInWindowMenuAttribute;
	if( g.systemVersion >= kMacOSX )	attributes |= kWindowLiveResizeAttribute;
	error = CreateNewWindow( kDocumentWindowClass, attributes, &creationBounds, &window );
#else
/*	if( g.useAppearance && g.systemVersion >= kMacOSEight )
	{
		window = GetNewCWindow( kFileWindow8, null, kFirstWindowOfClass );
		themeSavvy = true;
	}
	else
	{
*/		window = GetNewCWindow( kFileWindow7, null, kFirstWindowOfClass );
		DrawGrowIcon( window );
/*		themeSavvy = false;
	}	*/
	SizeWindow( window, kDefaultWindowWidth, kDefaultWindowHeight, false );
#endif
	
	// register mac window with host and retrieve plug window
	Plug_WindowRef plugWindow = Host_RegisterWindow( plug, resource, window );
	
	// cerate new hex window class
	HexWindowPtr hexWindow = new HexWindow( window );
	
	// set window refCon to my class
	Host_SetWindowRefCon( plugWindow, (UInt32) hexWindow );
	
	// load resource data into handle
	hexWindow->data = Host_GetResourceData( resource );	// handle disposed of by calling Host_ReleaseResData()
	
	// window is not yet active, will receive activate event soon
	hexWindow->activeWindow = false;
	
	// set window's background to default for theme
	if( g.useAppearance )
		SetThemeWindowBackground( window, kThemeBrushModelessDialogBackgroundActive, false );
	
#if TARGET_API_MAC_CARBON
	// install window event handler
	EventHandlerRef	ref			= null;
	EventHandlerUPP	handler		= NewEventHandlerUPP( CarbonWindowEventHandler );
	EventTypeSpec	events[]	= {	{ kEventClassWindow, kEventWindowClose },
									{ kEventClassWindow, kEventWindowActivated },
									{ kEventClassWindow, kEventWindowDeactivated },
									{ kEventClassWindow, kEventWindowBoundsChanging },
									{ kEventClassWindow, kEventWindowBoundsChanged },
									{ kEventClassWindow, kEventWindowHandleContentClick },
									{ kEventClassWindow, kEventWindowDrawContent },
									{ kEventClassKeyboard, kEventRawKeyDown },
									{ kEventClassKeyboard, kEventRawKeyRepeat } };
	InstallWindowEventHandler( window, handler, GetEventTypeCount(events), events, plug, &ref );
	
	// install HI event handler
					ref			= null;
					handler		= NewEventHandlerUPP( CarbonHIEventHandler );
	EventTypeSpec	HIevents[]	= {	{ kEventClassMenu, kEventMenuEnableItems },
									{ kEventClassCommand, kEventCommandProcess } };
	InstallWindowEventHandler( window, handler, GetEventTypeCount(HIevents), HIevents, null, &ref );
#else
	ClassicEventHandlerUPP handler = NewClassicEventHandlerUPP( ClassicWindowEventHandler );
	Host_InstallClassicWindowEventHandler( plugWindow, handler );
#endif
	
	// get window rect
	Rect windowBounds;
	GetWindowPortBounds( window, &windowBounds );
		
#if USE_NIBS
	// get text edit controls which were created from the nib
#elif TARGET_API_MAC_CARBON
	// create header
	ControlID id;
	Rect bounds = windowBounds;
	InsetRect( &bounds, -1, -1 );
	bounds.bottom = bounds.top + kHeaderHeight +1;
	CreateWindowHeaderControl( window, &bounds, false, &hexWindow->header );
	
	id.id = 0;
	id.signature = kHeaderSignature;
	SetControlID( hexWindow->header, &id );
	
	// set up header font information
	ControlFontStyleRec fontStyle = {};
	fontStyle.flags = kControlUseFontMask + kControlUseJustMask;
	fontStyle.font = kControlFontSmallSystemFont;
	fontStyle.just = teJustLeft;
	
	// create header static text controls
	GetWindowPortBounds( window, &windowBounds );
	SetRect( &bounds, windowBounds.left +4, 2, (windowBounds.right - windowBounds.left) /2, kHeaderHeight -2 );
	CreateStaticTextControl( window, &bounds, CFSTR("left side"), &fontStyle, &hexWindow->left );
	id.id = 0;
	id.signature = kLeftTextSignature;
	SetControlID( hexWindow->left, &id );
	
	fontStyle.just = teJustRight;
	SetRect( &bounds, (windowBounds.right - windowBounds.left) /2, 2, windowBounds.right -4, kHeaderHeight -2 );
	CreateStaticTextControl( window, &bounds, CFSTR("right side"), &fontStyle, &hexWindow->right );
	id.id = 0;
	id.signature = kRightTextSignature;
	SetControlID( hexWindow->right, &id );
//	SetHeaderText();
	
	// embed text controls within header
	EmbedControl( hexWindow->left, hexWindow->header );
	EmbedControl( hexWindow->right, hexWindow->header );
#else
	// only create a scroll bar, draw everything else
	DrawWindow( window );
#endif
	
#if TARGET_API_MAC_CARBON
	// install blinking timer
	EventLoopTimerUPP timerProc = NewEventLoopTimerUPP( BlinkInsertionPoint );
	InstallEventLoopTimer( GetMainEventLoop(), 0, kEventDurationSecond /3, timerProc, window, &hexWindow->timer );
#endif
	
	// set scrollbar globals
	hexWindow->UpdateHexInfo();
		
	// add menu to menu bar
	Host_AppendMenuToBar( plug, kEditorMenu );
	
	// show window
	ShowWindow( window );	// this is the plug's responsibility
	SelectWindow( window );
	BringToFront( window );
	return error;
}