
//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
//	FILE	: Main.cpp
//	AUTHOR	: Catalin Cocos
//__________________________________________________________________________________________________

#include "stdinc.h"
#include "resource.h"
#include "app.h"
#include "list.h"
#include "Tree.h"
#include "Process.h"


//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
//	DESC.	: main 
//	AUTHOR	: Catalin Cocos
//__________________________________________________________________________________________________
int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	hInstance = hInst;
	InitCommonControls();	// initialize common controls
	HANDLE reDLL = LoadLibrary("RICHED32.DLL");
	if(!reDLL)	return MessageBox( NULL, "Unable to load RICHED32.DLL", "Fatal error!", MB_ICONHAND|MB_OK);

	RECT r = {30, 40, 480, 65};
	RGBQUAD clr = {100, 60, 255 };
	CSplashScreen* pSS = new CSplashScreen(hInstance, IDB_SPLASHBITMAP, 1500,  24, &r, "Courier new Bold", &clr);

	pSS->SetText("Initializing conversion Engine...");
	{
		char* szPath = GetAppPathPlus( "Translation\\" ); // the conversion rules 
		char PathBuffer[_MAX_PATH];
		strcpy(PathBuffer, szPath);
		strcat(PathBuffer, "*.cvt");
		int error = 0;
		unsigned line;
		WIN32_FIND_DATA fd;
		HANDLE hSearch = FindFirstFile( PathBuffer, &fd );
		for(BOOL Found = (hSearch != INVALID_HANDLE_VALUE); Found; Found = FindNextFile( hSearch, &fd))
		{
			strcpy(PathBuffer, szPath);
			strcat(PathBuffer, fd.cFileName);
			if( error = CnvEng.SetRules(PathBuffer, &line)) break;
		}
		if( hSearch != INVALID_HANDLE_VALUE ) FindClose( hSearch );
		delete[] szPath;
		
		if( error )
		{
			char Text[2000];
			switch (error)
			{
			case SB_ERR_UNKNOWN: strcpy( Text, "Unknown Internal Error - Please contact your distributor!"); break;
			case SB_ERR_FILEOPEN: strcpy( Text, "Unable to open file."); break;
			case SB_ERR_UNKNOWN_KEYWORD: strcpy( Text, "Unknown Keyword."); break;
			case SB_ERR_MISPLACED_KEYWORD: strcpy( Text, "Misplaced Keyword."); break;
			case SB_ERR_UNKNOWN_TYPE: strcpy( Text, "Unknown Parameter Type."); break;
			case SB_ERR_TAG_VALUE_MISSING: strcpy( Text, "Missing Entry Tag Value."); break;
			case SB_ERR_ILLEGAL_ASSIGNEMENT: strcpy( Text, "Illegal Assignement."); break;
			case SB_ERR_VOID_ENTRY_DESCRIPTION: strcpy( Text, "Empty Entry Description."); break;
			case SB_ERR_UNEXPECTED_EOF: strcpy( Text, "Unexpected End of File reached."); break;
			}
			strcat( Text, "\r\n File :");
			strcat( Text, fd.cFileName);
			strcat( Text, "\r\n Line :");
			itoa( line, Text + strlen(Text), 10);
			pSS->Close();
			FreeLibrary( reDLL );
			return MessageBox( NULL, Text, "Fatal error!", MB_ICONHAND|MB_OK);
		}
	}
	hProcessSemaphore = CreateSemaphore( NULL, 0, 1, "S2B_Process_Semaphore" );
	hStopSemaphore = CreateSemaphore( NULL, 0, 1, "S2B_StopProcess_Semaphore" );
	pSS->SetText("Initializing...");
	// set the current cfg file
	char* szIni = GetAppPathPlus( INIFILE ); // get configuration file name
	HANDLE iniFile = CreateFile(szIni,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL); // open thefile
	char* fname;
	if( iniFile  != INVALID_HANDLE_VALUE)
	{
		LoadFileName(iniFile, fname, szIni);
		CloseHandle(iniFile);
	}
	else fname = GetAppPathPlus( DEFCFG ); // get configuration file name
	strcpy(CrtCfg, fname);
	delete[] fname;
	delete[] szIni; // we don't need it anymore

	// create the application Window
	WNDCLASS wcls =
    { 0, AppWndProc, 0, 0, hInstance,
      LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1)),
      NULL,//LoadCursor(NULL, MAKEINTRESOURCE(IDC_CURSOR1)),
      (HBRUSH)((long)COLOR_BTNFACE+1),
      MAKEINTRESOURCE(IDR_MENU1),"WinS2BFrame"
    };
	RegisterClass(&wcls);
	
	// create the main window
	hWApp = CreateWindowEx (0,"WinS2BFrame",APPNAME,                   
    WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,CW_USEDEFAULT,0,CW_USEDEFAULT,0,
    NULL,NULL,hInstance,NULL);

	// create the toolbar
	MakeToolbar( hWApp );

	// create the status bar
	hWStatusbar = CreateStatusWindow( WS_CLIPSIBLINGS|WS_CHILD|WS_VISIBLE|SBARS_SIZEGRIP, "Ready", hWApp,IDW_STATUSBAR);

	// compute the client rectangle corrections
	GetWindowRect(hWToolbar, &r);
	ToolbarHeight = r.bottom -r.top;
	GetWindowRect(hWStatusbar, &r);
	StatusHeight =  r.bottom -r.top;	

	// create the output window
	hWOut = CreateWindowEx (WS_EX_CLIENTEDGE,"RichEdit" , "",                   
     WS_HSCROLL|WS_VSCROLL|WS_CLIPSIBLINGS|ES_READONLY|ES_MULTILINE|ES_AUTOVSCROLL | WS_CHILD | WS_VISIBLE, 0, ToolbarHeight, 100, 100,
    hWApp,(HANDLE)IDW_OUTPUT,hInstance,NULL);
	CHARFORMAT cf= { sizeof(CHARFORMAT) };
	cf.dwMask = CFM_BOLD|CFM_FACE|CFM_COLOR|CFM_SIZE;
	cf.dwEffects = 0;
	cf.yHeight = -10;
	cf.crTextColor = RGB(0, 255, 0);
	cf.bCharSet = DEFAULT_CHARSET;
	cf.bPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
	strcpy(cf.szFaceName, "Arial");
	SendMessage(hWOut, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cf );			// set the character format
	SendMessage(hWOut, EM_SETBKGNDCOLOR, 0, (LPARAM) RGB( 0, 0, 60 ));		// set the background color
	SendMessage(hWOut, EM_EXLIMITTEXT, 0, 0x200000 );
	OutIWP = (WNDPROC)SetWindowLong( hWOut, GWL_WNDPROC, (LONG)OutWndProc);	// change the window procedure
	SetTxtProp( RGB(255, 100, 0), CFE_BOLD);
	AddTxt(APPNAME);
	AddTxt(" initialized successfuly.");
	SetTxtProp();

	// create the filter list 
	hWFilter = CreateWindowEx (WS_EX_CLIENTEDGE,WC_LISTVIEW,APPNAME,                   
    LVS_SHOWSELALWAYS|LVS_SORTASCENDING|LVS_LIST|WS_CLIPSIBLINGS|WS_CHILD|WS_VISIBLE, 0, ToolbarHeight, 100, 100,
    hWApp,(HANDLE)IDW_FILTER,hInstance,NULL);
	ListView_SetImageList( hWFilter, ImageList_LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_FILTERSTATES  ), 16, 0, RGB( 0, 0, 0xFF ) ), LVSIL_STATE );
	ListView_SetBkColor( hWFilter, GetSysColor(COLOR_BTNFACE)); 
	ListView_SetTextBkColor( hWFilter, GetSysColor(COLOR_BTNFACE)); 
 	FilterIWP = (WNDPROC)SetWindowLong( hWFilter, GWL_WNDPROC, (LONG)FilterWndProc);	// change the window procedure
 

	// create the file list 
	hWList = CreateWindowEx (WS_EX_CLIENTEDGE,WC_LISTVIEW,APPNAME,                   
    LVS_SHOWSELALWAYS|LVS_SORTASCENDING|LVS_LIST|WS_CLIPSIBLINGS|WS_CHILD|WS_VISIBLE, 103, ToolbarHeight, 100, 100,
    hWApp,(HANDLE)IDW_LIST,hInstance,NULL);
	ListIWP = (WNDPROC)SetWindowLong( hWList, GWL_WNDPROC, (LONG)ListWndProc);	// change the window procedure
	DragAcceptFiles( hWList, TRUE);		//process dragged files
	ListView_SetImageList( hWList, ImageList_LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_FILESTATES  ), 16, 0, RGB( 0, 0, 0xFF ) ), LVSIL_STATE );
	pListTip = new CTip(hWApp);

	// create the tree view
	hWTree = CreateWindowEx (WS_EX_CLIENTEDGE,WC_TREEVIEW,APPNAME,                   
     WS_CLIPSIBLINGS|WS_CHILD|WS_VISIBLE|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_SHOWSELALWAYS, 0, ToolbarHeight+103, 100, 100,
    hWApp,(HANDLE)IDW_TREE,hInstance,NULL);
	TreeIWP = (WNDPROC)SetWindowLong( hWTree, GWL_WNDPROC, (LONG)TreeWndProc);	// change the window procedure
	HIMAGELIST htreeIL = ImageList_LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_FOLDERIMAGES), 16, 0, RGB( 0, 0, 0xFF ));
	ImageList_SetOverlayImage( htreeIL,2,1);
	TreeView_SetImageList( hWTree, htreeIL, TVSIL_NORMAL );
	TreeView_SetImageList( hWTree, ImageList_LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_FOLDERSTATES  ), 22, 0, RGB( 0, 0, 0xFF ) ), TVSIL_STATE );	
	InitTree();

	// create the list view
	hWListView = CreateWindowEx (WS_EX_CLIENTEDGE,WC_LISTVIEW,APPNAME,                   
     LVS_SHOWSELALWAYS|LVS_SORTASCENDING|LVS_LIST|WS_CLIPSIBLINGS|WS_CHILD|WS_VISIBLE, 103, ToolbarHeight+103, 100, 100,
    hWApp,(HANDLE)IDW_LISTVIEW,hInstance,NULL);
	ListView_SetImageList( hWListView, ImageList_LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_FILESTATES  ), 16, 0, RGB( 0, 0, 0xFF ) ), LVSIL_STATE );
	ViewIWP = (WNDPROC)SetWindowLong( hWListView, GWL_WNDPROC, (LONG)ViewWndProc);	// change the window procedure

	// load the application configuration
	pSS->SetText("Loading configuration...");
	UpdateAppName();
	ShowWindow( hWApp, LoadConfiguration()? SW_SHOWMAXIMIZED: nCmdShow );
//	ShowWindow( hWApp, nCmdShow );
	Refresh();
	UpdateWindow( hWApp );

	pSS->SetText("Welcome to");
	pSS->Close();

	// the message loop
	HACCEL hViewsAcc = LoadAccelerators( hInstance, MAKEINTRESOURCE(IDR_VIEWS_ACCEL));
	HACCEL hMainAcc = LoadAccelerators( hInstance, MAKEINTRESOURCE(IDR_MAIN_ACCEL));
	MSG msg;
	BOOL OnIdleEnabled = TRUE;
	BOOL Mode;
	HWND FocusW;
	for(;;)
	{
		Mode = 1;
		if( OnIdleEnabled )
		{
			// enter here if there are still messages in the meassage queue: no problem, PeekMessage will not stress the system
			if(!PeekMessage(&msg,NULL,0,0,PM_REMOVE))
				Mode = 0;	// this means the message queue is empty => next time we'll call GetMessage(),
							// which will return only when it will find a message in the queue => let  the system make it's stuff
			else if(msg.message == WM_QUIT) break;
		}
		else if(GetMessage(&msg,NULL,0,0) <=0 ) break; // call this when the message queue is empty
		if(Mode)
		{
			OnIdleEnabled = TRUE; // a message is processed (there was no idle time) => retrieve the next message with the PeekMessage() function
			if(msg.message == WM_QUIT) break;
			if(!TranslateAccelerator( hWApp, hMainAcc, &msg))
			{
				FocusW = GetFocus();
				if(	!FocusW || FocusW == hWOut || !TranslateAccelerator( FocusW, hViewsAcc, &msg))
				{
					if(msg.message == WM_SYSKEYDOWN) pListTip->Show(NULL,NULL);//SendMessage(hWApp, msg.message, msg.wParam, msg.lParam);
					TranslateMessage (&msg);
					DispatchMessage (&msg);
				}
			}
		}
		else 
		{
			OnIdle();
			OnIdleEnabled = FALSE; // the message queue is empty => use the GetMessage() function
		}
	}

	delete pListTip;
	FreeLibrary( reDLL );
	CloseHandle(hProcessSemaphore);
	CloseHandle(hStopSemaphore);
	return 0;
}

  
