/*
 *  CRSciView.cpp
 *  sci4osx_test
 *
 *  Created by serg on 7/20/08.
 *  Copyright 2008 __MyCompanyName__. All rights reserved.
 *
 */

#include "CRSciView.h"

#include "TView.h"
#include "TCarbonEvent.h"
#include "ScintillaMacOSX.h"

extern "C" HIViewRef scintilla_new(void);

using namespace Scintilla;

/* XPM */
static char *ac_class[] = {
/* columns rows colors chars-per-pixel */
"18 12 24 1",
"  c black",
". c #403030",
"X c #473636",
"o c #4E3C3C",
"O c #474141",
"+ c #5F4C4C",
"@ c #756362",
"# c #98342C",
"$ c #A0392F",
"% c #B24235",
"& c #B2443C",
"* c #B34E3E",
"= c #B54E44",
"- c #B65146",
"; c #B7584F",
": c #B8554C",
"> c #B75A50",
", c #B95852",
"< c #B96259",
"1 c #B89B9B",
"2 c #BCA0A0",
"3 c #C1A5A5",
"4 c gray100",
"5 c None",
/* pixels */
"555555555555555555",
"55553$$$$$$$#@5555",
"55552;%&&==;=o5555",
"55551>&&*=;:=.5555",
"55551>&*=;::=.5555",
"55551>*==:::-X5555",
"55551>==:::,;.5555",
"55551<==:;,<>.5555",
"55551<;;;;<<;.5555",
"55551;-==;;;;X5555",
"55555+XX..X..O5555",
"555555555555555555"
};

const char keywords[]="alter and and_eq asm auto bitand bitor bool break "
"case catch char class compl const const_cast continue create "
"default delete do double drop dynamic_cast else enum explicit export extern false float for "
"friend from goto if inline insert int long mutable namespace new not not_eq "
"operator or or_eq private protected public "
"register reinterpret_cast return select short signed sizeof static static_cast struct switch "
"template this throw true try typedef typeid typename union unsigned update using "
"virtual void volatile wchar_t while xor xor_eq";

CRSciView::CRSciView()
:
_sciView(NULL)
{
}

HIViewRef CRSciView::create()
{
	return _sciView = scintilla_new();
}

void CRSciView::init()
{
	// some scintilla init
	GetControlProperty( _sciView, scintillaMacOSType, 0, sizeof( _scintilla ), NULL, &_scintilla );
	
	_scintilla->WndProc( SCI_SETLEXER, SCLEX_CPP, 0);
	_scintilla->WndProc( SCI_SETSTYLEBITS, 5, 0);
	
	_scintilla->WndProc(SCI_STYLESETFORE, 0, 0x808080);	// White space
	_scintilla->WndProc(SCI_STYLESETFORE, 1, 0x007F00);	// Comment
	_scintilla->WndProc(SCI_STYLESETITALIC, 1, 1);	// Comment
	_scintilla->WndProc(SCI_STYLESETFORE, 2, 0x007F00);	// Line comment
	_scintilla->WndProc(SCI_STYLESETITALIC, 2, 1);	// Line comment
	_scintilla->WndProc(SCI_STYLESETFORE, 3, 0x3F703F);	// Doc comment
	_scintilla->WndProc(SCI_STYLESETITALIC, 3, 1);	// Doc comment
	_scintilla->WndProc(SCI_STYLESETFORE, 4, 0x7F7F00);	// Number
	_scintilla->WndProc(SCI_STYLESETFORE, 5, 0x7F0000);	// Keyword
	_scintilla->WndProc(SCI_STYLESETBOLD, 5, 1);	// Keyword
	_scintilla->WndProc(SCI_STYLESETFORE, 6, 0x7F007F);	// String
	_scintilla->WndProc(SCI_STYLESETFORE, 7, 0x7F007F);	// Character
	_scintilla->WndProc(SCI_STYLESETFORE, 8, 0x804080);	// UUID
	_scintilla->WndProc(SCI_STYLESETFORE, 9, 0x007F7F);	// Preprocessor
	_scintilla->WndProc(SCI_STYLESETFORE,10, 0x000000);	// Operators
	_scintilla->WndProc(SCI_STYLESETBOLD,10, 1);	// Operators
	_scintilla->WndProc(SCI_STYLESETFORE,11, 0x000000);	// Identifiers
	
	
	_scintilla->WndProc(SCI_SETKEYWORDS, 0, (sptr_t)(char *)keywords);	// Keyword
	
	/*
	 these fail compilation on osx now
	 _scintilla->WndProc( SCI_SETPROPERTY, "fold", (long int)"1");
	 _scintilla->WndProc( SCI_SETPROPERTY, "fold.compact", (long int)"0");
	 _scintilla->WndProc( SCI_SETPROPERTY, "fold.comment", (long int)"1");
	 _scintilla->WndProc( SCI_SETPROPERTY, "fold.preprocessor", (long int)"1");
	 */
	
	_scintilla->WndProc( SCI_REGISTERIMAGE, 0, (long int)ac_class);
	
	_scintilla->WndProc( SCI_SETMARGINTYPEN, 0, (long int)SC_MARGIN_NUMBER);
	_scintilla->WndProc( SCI_SETMARGINWIDTHN, 0, (long int)30);
	_scintilla->WndProc( SCI_SETMARGINTYPEN, 1, (long int)SC_MARGIN_SYMBOL);
	_scintilla->WndProc( SCI_SETMARGINMASKN, 1, (long int)SC_MASK_FOLDERS);
	_scintilla->WndProc( SCI_SETMARGINWIDTHN, 1, (long int)20);
	_scintilla->WndProc( SCI_SETMARGINTYPEN, 2, (long int)SC_MARGIN_SYMBOL);
	_scintilla->WndProc( SCI_SETMARGINWIDTHN, 2, (long int)16);
	//_scintilla->WndProc( SCI_SETWRAPMODE, SC_WRAP_WORD, 0);
	//_scintilla->WndProc( SCI_SETWRAPVISUALFLAGS, SC_WRAPVISUALFLAG_END | SC_WRAPVISUALFLAG_START, 0);
}

OSStatus CRSciView::handleWindowEvent( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData)
{
	WindowRef window = GetControlOwner(_sciView);
	ScintillaMacOSX* scintilla;
	GetControlProperty( _sciView, scintillaMacOSType, 0, sizeof( scintilla ), NULL, &scintilla );
	TCarbonEvent event( inEvent );
	
	// If the window is not active, let the standard window handler execute.
	if ( ! IsWindowActive( window ) ) return eventNotHandledErr;
	
	const HIViewRef rootView = HIViewGetRoot( window );
	assert( rootView != NULL );
	
	if ( event.GetKind() == kEventMouseDown )
	{
		UInt32 inKeyModifiers;
		event.GetParameter( kEventParamKeyModifiers, &inKeyModifiers );
		
		EventMouseButton inMouseButton;
		event.GetParameter<EventMouseButton>( kEventParamMouseButton, typeMouseButton, &inMouseButton );
		if (inMouseButton == kEventMouseButtonTertiary) {
			if (inKeyModifiers & optionKey) {
				const char *test = "\001This is a test calltip This is a test calltip This is a test calltip";
				_scintilla->WndProc( SCI_CALLTIPSHOW, 0, (long int)test );
			} else {
				char *list = "test_1?0 test_2 test_3 test_4 test_5 test_6 test_7 test_8 test_9 test_10 test_11 test_12";
				_scintilla->WndProc( SCI_AUTOCSHOW, 0, (long int)list );
			}
			return noErr;
		}
	}
	
	return eventNotHandledErr;
}


void CRSciView::set_text(const char *text)
{
  _scintilla->WndProc(SCI_SETTEXT, 0, (sptr_t)text);
}

