//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <System.IOUtils.hpp>
#include <Winerror.h>

#include "GlobalUnit.h"
#include "SplashFormUnit.h"
#include "MessageFormUnit.h"
//---------------------------------------------------------------------------

USEFORM("SplashFormUnit.cpp", SplashForm);
USEFORM("MainFormUnit.cpp", MainForm);
USEFORM("MessageFormUnit.cpp", MessageForm);
//---------------------------------------------------------------------------
HWND hWnd = NULL;
HINSTANCE u_hMMDll = NULL,
		u_hCMDll = NULL,
		u_hCSDll = NULL,
		u_hQRDll = NULL;

void InitUserPath()
{
	SplashForm->ShowProgress( "配置用户路径..." );

	String strAppPath = TPath::GetFullPath(ExtractFilePath(Application->ExeName));
	g_strExecutePath = strAppPath.c_str();

	TCHAR filePath[MAX_PATH];
	SHGetSpecialFolderPath(NULL, filePath, CSIDL_LOCAL_APPDATA, TRUE);

	String strLocPath = filePath;
	strLocPath += L"\\iChangzuo";

	if(!DirectoryExists( strLocPath, false)){
		ForceDirectories( strLocPath );
	}

#ifdef _LITE_
	strLocPath += L"\\Ac_ProLite\\";
#else
	strLocPath += L"\\Ac_Pro\\";
#endif
	g_strUserPath = strLocPath.c_str();

	if(!DirectoryExists( strLocPath, false)){
		ForceDirectories( strLocPath );
	}

	if(!DirectoryExists( strLocPath + L"Help", false)){
		ForceDirectories( strLocPath + L"Help" );
	}

	if(!DirectoryExists( strLocPath + L"header", false)){
		ForceDirectories( strLocPath + L"header" );
		String strSrc = strAppPath + L"Header\\default.jpg",
				strDest = strLocPath + L"Header\\default.jpg";

		if( FileExists( strSrc, false ) )
			CopyFile( strSrc.c_str(), strDest.c_str(), FALSE );
	}

	strLocPath += L"Profile\\";
	strAppPath += L"Profile\\";

	bool bCover = false;

	if( DirectoryExists( strAppPath, false ) ){
		if( !DirectoryExists( strLocPath, false) ){
			ForceDirectories( strLocPath );
			bCover = true;
		}
	}
	else{
		return;
	}

	String strSubPathShort[3] = { "dt_eerp", "ml_bursa", "sf_lyres" },
		strDefaultFile[3][2] = { {"uflid.jst","lidshr.lux"},
								{"frm0000.lmd","shr0000.lmd"},
								{"Lcyh00000.dhy","Lcyh00001.dhy"} };

	for( int i=0; i<3; i++ ){
		String strOriPath = strAppPath + strSubPathShort[i],
			strSubPath = strLocPath + strSubPathShort[i];

		if( DirectoryExists( strOriPath, false ) ){
			if( !DirectoryExists( strSubPath, false ) ){
				ForceDirectories( strSubPath );
				bCover = true;
			}
			else{
				for( int j=0; j<2; j++ ){
					String strExistFile = strOriPath + L"\\" + strDefaultFile[i][j],
							strNewFile = strSubPath + L"\\" + strDefaultFile[i][j];

					HANDLE hOriFile = CreateFile( strExistFile.c_str(), GENERIC_READ, FILE_SHARE_READ,
																	NULL, OPEN_EXISTING, 0, NULL );

					if( hOriFile && hOriFile!=INVALID_HANDLE_VALUE ){
						HANDLE hNewFile = CreateFile( strNewFile.c_str(), GENERIC_READ, FILE_SHARE_READ,
																	NULL, OPEN_EXISTING, 0, NULL);

						if( hNewFile && hNewFile!=INVALID_HANDLE_VALUE ){
							DWORD dwSizeOri = GetFileSize( hOriFile, NULL ),
								dwSizeNew = GetFileSize( hNewFile, NULL );
							FILETIME ftModifyOri, ftModifyNew;
							GetFileTime( hOriFile, NULL, NULL, &ftModifyOri );
							GetFileTime( hNewFile, NULL, NULL, &ftModifyNew );

							if( dwSizeOri>dwSizeNew || CompareFileTime( &ftModifyOri, &ftModifyNew )>0 )
								bCover = true;

							CloseHandle( hNewFile );
						}
						else{
							bCover = true;
						}

						CloseHandle( hOriFile );
					}
					else if( j==0 ){
						return;
					}
				}
			}
		}
		else{
			return;
        }
	}

	TSearchRec sr;
	int iAttr = 0;

	for( int i=0; i<3; i++ ){
		String strOriPath = strAppPath + strSubPathShort[i],
			strSubPath = strLocPath + strSubPathShort[i];

		if (FindFirst(strOriPath + L"\\*.*", iAttr, sr) == 0) {
			do {
				String strExistFile = strOriPath + L"\\" + sr.Name,
					strNewFile = strSubPath + L"\\" + sr.Name;
				bool bCopy = true;

				if( !sr.Name.Compare(strDefaultFile[i][0]) || !sr.Name.Compare(strDefaultFile[i][1]) ){
					bCopy = bCover;
				}
				else if( FileExists( strNewFile, false ) ){
					HANDLE hOriFile = CreateFile( strExistFile.c_str(), GENERIC_READ, FILE_SHARE_READ,
																	NULL, OPEN_EXISTING, 0, NULL );
					if( hOriFile && hOriFile!=INVALID_HANDLE_VALUE ){
						HANDLE hNewFile = CreateFile( strNewFile.c_str(), GENERIC_READ, FILE_SHARE_READ,
																	NULL, OPEN_EXISTING, 0, NULL);
						if( hNewFile && hNewFile!=INVALID_HANDLE_VALUE ){
							FILETIME ftModifyOri, ftModifyNew;
							GetFileTime( hOriFile, NULL, NULL, &ftModifyOri );
							GetFileTime( hNewFile, NULL, NULL, &ftModifyNew );
							CloseHandle( hNewFile );

							if( CompareFileTime( &ftModifyNew, &ftModifyOri )>=0 ){
								bCopy = false;
							}
						}

						CloseHandle( hOriFile );
					}
					else{
						bCopy = false;
					}
				}

				if( bCopy ){
					CopyFile( strExistFile.c_str(), strNewFile.c_str(), FALSE );

					if( !sr.Name.Compare(L"smtd.dhy") ){ //本地风格需处理时间戳
						HANDLE hOriFile = CreateFile( strExistFile.c_str(), GENERIC_READ, FILE_SHARE_READ,
																	NULL, OPEN_EXISTING, 0, NULL );

						if( hOriFile && hOriFile!=INVALID_HANDLE_VALUE ){
							HANDLE hNewFile = CreateFile( strNewFile.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE,
																			NULL, OPEN_EXISTING, 0, NULL);
							if( hNewFile && hNewFile!=INVALID_HANDLE_VALUE ){
								FILETIME ftCreate;
								GetFileTime( hOriFile, &ftCreate, NULL, NULL );
								SetFileTime( hNewFile, &ftCreate, NULL, NULL );
								CloseHandle( hNewFile );
							}

							CloseHandle( hOriFile );
						}
					}
				}
			}
			while( FindNext(sr)==0 );

			FindClose(sr);
		}
	}
}

int LoadDlls()
{
	SplashForm->ShowProgress( "加载媒体模块..." );
	u_hMMDll = LoadLibrary(L"MediaModule.dll");
	if( u_hMMDll==NULL ){
		return 1;
	}
	else if( GetMMFunctions(u_hMMDll)==S_FALSE ) {
		return 2;
	}

	SplashForm->ShowProgress( "加载编曲模块..." );
	u_hCMDll = LoadLibrary(L"CompModule.dll");
	if( u_hCMDll==NULL ){
		int err = GetLastError();
		return 3;
	}
	else if( GetCMFunctions(u_hCMDll)==S_FALSE ) {
		return 4;
	}

	SplashForm->ShowProgress( "加载网络模块..." );
	u_hCSDll = LoadLibrary(L"ClientService.dll");
	if( u_hCSDll==NULL ){
		return 5;
	}
	else if( GetCSFunctions(u_hCSDll)==S_FALSE ) {
		return 6;
	}

	u_hQRDll = LoadLibrary(L"QRcode.dll");
	if( u_hQRDll ){
		GetQRFunctions(u_hQRDll);
	}

	return 0;
}

void FreeDlls()
{
	if( u_hCMDll ){
		FreeLibrary( u_hCMDll );
		u_hCMDll = NULL;
	}

	if( u_hMMDll ){
		FreeLibrary( u_hMMDll );
		u_hMMDll = NULL;
	}

	if( u_hCSDll ){
		FreeLibrary( u_hCSDll );
		u_hCSDll = NULL;
	}

	if( u_hQRDll ){
		FreeLibrary( u_hQRDll );
		u_hQRDll = NULL;
	}
}

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
	hWnd = FindWindow( (LPCTSTR)APPNAME, NULL );
	if( hWnd ){
		SendMessage( hWnd, UM_RESTORE, 0, 0 );

		if( !ParamStr(1).IsEmpty() ){
			int BUF_SIZE = 256;
			TCHAR szName[]=TEXT("MyFileMappingObject");
			LPTSTR pBuf;
			HANDLE hMapFile = CreateFileMapping(
										INVALID_HANDLE_VALUE,    // use paging file
										NULL,                    // default security
										PAGE_READWRITE,          // read/write access
										0,                       // max. object size
										BUF_SIZE,                // buffer size
										szName);                 // name of mapping object

			if( hMapFile ){
				pBuf = (LPTSTR) MapViewOfFile(hMapFile,   // handle to map object
									FILE_MAP_ALL_ACCESS, // read/write permission
									0,
									0,
									BUF_SIZE);

				if( pBuf ){
					wcscpy( pBuf, ParamStr(1).c_str() );
					SendMessage( hWnd, UM_LOADPROJECT, 0, wcslen(pBuf) );
					UnmapViewOfFile(pBuf);
				}

				CloseHandle(hMapFile);
			}
		}

		return 0;
	}

	try
	{
		Application->Initialize();
		Application->MainFormOnTaskBar = true;
		Application->Title = APPNAME;

		// 获取DPI
		HDC hdc = GetDC(NULL);
		if (hdc != NULL) {
			g_xDpi = GetDeviceCaps(hdc, LOGPIXELSX);
			g_yDpi = GetDeviceCaps(hdc, LOGPIXELSY);
			ReleaseDC(NULL, hdc);
		}

		g_szFont7 = int(7 * 96.0 / g_yDpi + 0.5);
		g_szFont8 = int(8 * 96.0 / g_yDpi + 0.5);
		g_szFont9 = int(9 * 96.0 / g_yDpi + 0.5);
		g_szFont10 = int(10 * 96.0 / g_yDpi + 0.5);
		g_szFont11 = int(11 * 96.0 / g_yDpi + 0.5);
  		g_szFont12 = int(12 * 96.0 / g_yDpi + 0.5);
		g_szFont16 = int(16 * 96.0 / g_yDpi + 0.5);

		//显示启动图片
		SplashForm = new TSplashForm(Application);
		SplashForm->Show();

		InitUserPath();

		String strErr;
		switch(LoadDlls()){
			case 1:
				strErr = "加载媒体模块失败！";
				break;

			case 2:
				strErr = "获取媒体模块函数失败！";
				break;

			case 3:
				strErr = "加载编曲模块失败！";
				break;

			case 4:
				strErr = "获取编曲模块函数失败！";
				break;

			case 5:
				strErr = "加载网络服务模块失败！";
				break;

			case 6:
				strErr = "获取网络服务函数失败！";
				break;

			default:
				break;
		}

		MessageForm = new TMessageForm(Application);
		MessageForm->Position = poDesktopCenter;

		if( !strErr.IsEmpty() ){
			delete SplashForm;
			FreeDlls();

			MessageForm->ShowMessage( strErr, MB_ICONERROR|MB_OK );
			delete MessageForm;
			return 0;
		}

		Word Saved8087CW = Default8087CW;
		System::Set8087CW(0x133f);

		Application->CreateForm(__classid(TMainForm), &MainForm);
		Application->MainForm->Visible = false;

		delete SplashForm;
		SplashForm = NULL;

		if( !g_lstFonts.empty() ){
			Application->MainForm->Visible = true;
			MessageForm->Position = poMainFormCenter;

			Application->Run();
		}

		delete MessageForm;
		FreeDlls();

		System::Set8087CW(Saved8087CW);
	}
	catch (Exception &exception)
	{
		Application->ShowException(&exception);
	}
//	catch (...)
//	{
//		try
//		{
//			throw Exception("");
//		}
//		catch (Exception &exception)
//		{
//			Application->ShowException(&exception);
//		}
//	}
	return 0;
}
//---------------------------------------------------------------------------
