// DLoader.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "DLoader.h"

#include "MainFrm.h"
#include "DLoaderDoc.h"
#include "DLoaderView.h"
#include "XAboutDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

class CDLCmdLine : public CCommandLineInfo
{
public:
	CDLCmdLine() 
	{ 
		m_strPrdVersion = _T("");
		m_nParaCount = 0; 
		m_nMaxParaCount = 3; 
		m_bWait = FALSE;
	}
	virtual void ParseParam( LPCTSTR lpszParam, BOOL bFlag, BOOL bLast );

	CString m_strPrdVersion;

	BOOL    m_bWait;

protected:
	int m_nParaCount;
	int m_nMaxParaCount;
};



void CDLCmdLine::ParseParam( LPCTSTR lpszParam, BOOL bFlag, BOOL bLast )
{
	UNREFERENCED_PARAMETER(bLast);
//	if( bFlag )
//	{
		// Do not support any flag now
//		return;
//	}

//	if( m_nParaCount > m_nMaxParaCount )
//	{
//		// Only support three parameters
//		return;
//	}

	CString strParam = lpszParam;
	strParam.TrimLeft();
	strParam.TrimRight();

	if( 0 == m_nParaCount )
	{
		m_strFileName = strParam;
	}
	else if( 1 == m_nParaCount )
	{
		m_strPrdVersion = strParam;
	}
	else
	{
		if(bFlag && strParam.CompareNoCase(_T("w")) == 0)
		{
			m_bWait = TRUE;
		}	
	}
	m_nParaCount++;
}



/////////////////////////////////////////////////////////////////////////////
// CDLoaderApp

BEGIN_MESSAGE_MAP(CDLoaderApp, CWinApp)
	//{{AFX_MSG_MAP(CDLoaderApp)
	ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
	// Standard file based document commands
	ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
	ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDLoaderApp construction

CDLoaderApp::CDLoaderApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
	m_pBMAFramework = NULL;
	m_bScriptCtrl = FALSE;
	m_bResultPathWithPort = FALSE;

#if defined(_SPUPGRADE) || defined(_DOWNLOAD_FOR_PRODUCTION)
	m_bShowOtherPage = FALSE;
#else
	m_bShowOtherPage = TRUE;
#endif
	
	m_bColorFlag = FALSE;
	m_bClosePortFlag = TRUE;
	m_bResultHolding = TRUE;
	m_bManual = FALSE;

	m_bCMDPackage = FALSE;
	m_strPacPath = _T("");
	m_strPrdVersion = _T("");

}

/////////////////////////////////////////////////////////////////////////////
// The one and only CDLoaderApp object

CDLoaderApp g_theApp;

/////////////////////////////////////////////////////////////////////////////
// CDLoaderApp initialization

BOOL CDLoaderApp::InitInstance()
{
	AfxEnableControlContainer();

    CString strErrMsg;

	if(!CreateBMAFramework( &m_pBMAFramework))
	{
		AfxMessageBox(_T("Create BMAFramework fail."));    
        return FALSE;
	}
/*    HRESULT hr = OleInitialize( NULL );
	
    if(SUCCEEDED(hr))
	{
		hr = m_pBMAFramework->BMAF_RegisterBMPDll(_T("BootModePlatform.dll"));
		if( FAILED( hr ) )
		{
			AfxMessageBox(_T("Register BootModePlatform.dll fail.")); 			 
			//return FALSE;
		}
		hr = m_pBMAFramework->BMAF_RegisterBMPDll(_T("UartManager.dll"));
		if( FAILED( hr ) )
		{
			AfxMessageBox(_T("Register UartManager.dll fail.")); 				 
			//return FALSE;
		}

		OleUninitialize( );	
	}
	else
	{
		AfxMessageBox(_T("Call OleInitialize() fail."));    
        return FALSE;
	}*/
/*
    if( SUCCEEDED(hr) )
    {
#ifndef DEBUG_BM_LIBRARY
        HINSTANCE hLib = LoadLibrary( "BootModePlatform.dll" );
#else
        HINSTANCE hLib = LoadLibrary( "BootModePlatformd.dll" );
#endif
        if ( hLib >= (HINSTANCE)HINSTANCE_ERROR)
        {
            FARPROC lpDllEntryPoint = NULL;
            // Find the entry point.
            (FARPROC&)lpDllEntryPoint = GetProcAddress( hLib, _T("DllRegisterServer"));
            if(lpDllEntryPoint != NULL)
            {
                hr = (*lpDllEntryPoint)();
                if( FAILED( hr ) )
                {
                    strErrMsg.Format( "Call DllRegisterServer fail (BootModePlatform.dll).[ErrorCode:0x%08X]", hr );
                    AfxMessageBox( strErrMsg );
                }
            }
            else
            {
                AfxMessageBox(_T("Get process address  fail (BootModePlatform.dll )."));
            }            
        }
        else
        {
            AfxMessageBox(_T("Load BootModePlatform.dll fail."));
        }

#ifndef DEBUG_BM_LIBRARY
        hLib = LoadLibrary( _T("UartManager.dll") );
#else
        hLib = LoadLibrary( _T("UartManager.dll") );
#endif
        
        if ( hLib >= (HINSTANCE)HINSTANCE_ERROR)
        {
            FARPROC lpDllEntryPoint = NULL;
            // Find the entry point.
            (FARPROC&)lpDllEntryPoint = GetProcAddress( hLib, _T("DllRegisterServer"));
            if(lpDllEntryPoint != NULL)
            {
                hr = (*lpDllEntryPoint)();
                if( FAILED( hr ) )
                {
                    strErrMsg.Format( _T("Call DllRegisterServer fail (UartManager.dll).[ErrorCode:0x%08X]"), hr );
                    AfxMessageBox( strErrMsg );
                }
            }
            else
            {
                AfxMessageBox(_T("Get process address  fail (UartManager.dll )."));
            }            
        } 
        else
        {
            AfxMessageBox(_T("Load UartManager.dll fail."));            
        }

        OleUninitialize( );	        
    }
    else
    {
        AfxMessageBox(_T("Call OleInitialize() fail."));    
        return FALSE;
    }
*/    

	// Standard initialization
	// If you are not using these features and wish to reduce the size
	//  of your final executable, you should remove from the following
	//  the specific initialization routines you do not need.

#ifdef _AFXDLL
	Enable3dControls();			// Call this when using MFC in a shared DLL
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

	// Change the registry key under which our settings are stored.
	// TODO: You should modify this string to be something appropriate
	// such as the name of your company or organization.
	SetRegistryKey(_T("Spreadtrum"));

	LoadStdProfileSettings();  // Load standard INI file options (including MRU)

    //@ Liu Kai 2004-8-23
    GetVersion();

	
	_TCHAR szConfigPath[_MAX_PATH]={0};
	DWORD dwRet = ::GetModuleFileName(this->m_hInstance,szConfigPath,_MAX_PATH);
	if(dwRet == 0)
	{
		AfxMessageBox(_T("Load configure ini file failed!"));
		return FALSE;
	}
    LPTSTR pResult = _tcsrchr(szConfigPath,_T('.'));
    *pResult = 0;
    _tcscat(szConfigPath,_T(".ini"));

#if defined(_SPUPGRADE) || defined(_DOWNLOAD_FOR_PRODUCTION)	
	m_bShowOtherPage = GetPrivateProfileInt(_T("GUI"),_T("ShowOtherPage"),0,szConfigPath);
	m_bManual = GetPrivateProfileInt(_T("GUI"),_T("Manual"),0,szConfigPath);
	m_bResultHolding = GetPrivateProfileInt(_T("GUI"),_T("ResultHolding"),1,szConfigPath);
#else
	m_bShowOtherPage = GetPrivateProfileInt(_T("GUI"),_T("ShowOtherPage"),1,szConfigPath);
#endif	

	m_bColorFlag = GetPrivateProfileInt(_T("GUI"),_T("MarkLastState"),0,szConfigPath);
	m_bClosePortFlag = GetPrivateProfileInt(_T("GUI"),_T("ClosePortFlag"),1,szConfigPath);

	m_bScriptCtrl = GetPrivateProfileInt(_T("GUI"),_T("ScriptControl"),0,szConfigPath);
	m_bCMDPackage = GetPrivateProfileInt(_T("GUI"),_T("CmdPackage"),0,szConfigPath);

	m_bResultPathWithPort = GetPrivateProfileInt(_T("GUI"),_T("ResultPathWithPort"),0,szConfigPath);
	m_strResultPath = szConfigPath;
	int nFind = m_strResultPath.ReverseFind('\\');
	m_strResultPath = m_strResultPath.Left(nFind);
	m_strResultPath += _T("\\result.txt");

	// Register the application's document templates.  Document templates
	//  serve as the connection between documents, frame windows and views.

	CSingleDocTemplate* pDocTemplate;
	pDocTemplate = new CSingleDocTemplate(
		IDR_MAINFRAME,
		RUNTIME_CLASS(CDLoaderDoc),
		RUNTIME_CLASS(CMainFrame),       // main SDI frame window
		RUNTIME_CLASS(CDLoaderView));
	AddDocTemplate(pDocTemplate);

	// Parse command line for standard shell commands, DDE, file open
	CDLCmdLine cmdInfo;
	ParseCommandLine(cmdInfo);


	// Dispatch commands specified on the command line
	if (!ProcessShellCommand(cmdInfo))
		return FALSE;

	// The one and only window has been initialized, so show and update it.	
	if(m_bCMDPackage)
	{
		m_pMainWnd->ShowWindow(SW_HIDE);
	}
	else
	{
		m_pMainWnd->ShowWindow(SW_SHOW);
	}
	m_pMainWnd->UpdateWindow();


	if(m_bScriptCtrl)
	{
		PostMessage(m_pMainWnd->m_hWnd,WM_COMMAND,ID_START,0);
	}
	else if(m_bCMDPackage)
	{
		m_strPacPath = cmdInfo.m_strFileName;
		m_strPrdVersion = cmdInfo.m_strPrdVersion;
		if(!m_strPacPath.IsEmpty() && !m_strPrdVersion.IsEmpty())
		{
			PostMessage(m_pMainWnd->m_hWnd,WM_COMMAND,ID_SETTINGS,0);
		}
		else
		{
			AfxMessageBox(_T("Usage: DloaderR.exe <pac path> <product version>"));
			return FALSE;
		}
	}

	return TRUE;
}


/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	virtual BOOL OnInitDialog();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

// App command to run the dialog
void CDLoaderApp::OnAppAbout()
{
	CXAboutDlg aboutDlg;

#ifdef _SPUPGRADE
	aboutDlg.SetProductName(_T("SPUpgrade"));
#elif defined _DOWNLOAD_FOR_PRODUCTION 
	aboutDlg.SetProductName( _T("Download"));
#else
	aboutDlg.SetProductName( _T("DLoaderR"));
#endif
	aboutDlg.DoModal();
}

/////////////////////////////////////////////////////////////////////////////
// CDLoaderApp message handlers


BOOL CAboutDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();

    //@ Liu Kai 2004-08-23
    GetDlgItem( IDC_STATIC_VERSION )->SetWindowText( g_theApp.m_strVersion );
    GetDlgItem( IDC_STATIC_BUILD )->SetWindowText( g_theApp.m_strBuild );
#ifdef _SPUPGRADE
	GetDlgItem( IDC_STATIC_PRODUCT_NAME )->SetWindowText(_T("Spreadtrum SPUpgrade"));
	SetWindowText(_T("About Spreadtrum SPUpgrade")); 
#elif defined _DOWNLOAD_FOR_PRODUCTION
    GetDlgItem( IDC_STATIC_PRODUCT_NAME )->SetWindowText(_T("Spreadtrum Download"));
	SetWindowText(_T("About Spreadtrum Download")); 
#else
	GetDlgItem( IDC_STATIC_PRODUCT_NAME )->SetWindowText(_T("Spreadtrum DLoaderR"));
	SetWindowText(_T("About Spreadtrum DLoaderR")); 
#endif
	
	return TRUE;
}

void CDLoaderApp::GetVersion()
{
    _TCHAR szFileName[_MAX_PATH];
    ::GetModuleFileName(AfxGetApp()->m_hInstance,szFileName,_MAX_PATH);
    
    DWORD dwSize,dwHandle;
    dwSize = ::GetFileVersionInfoSize(szFileName,&dwHandle);	
    if( dwSize == 0 )
    {
        return;
    }
    
    _TCHAR* pVer = new _TCHAR[dwSize];
    BOOL bRet = ::GetFileVersionInfo(szFileName,dwHandle,dwSize,pVer);
    if(!bRet)
    {
        delete [] pVer;
        return;
    }
    
    struct LANGANDCODEPAGE {
        WORD wLanguage;
        WORD wCodePage;
    } *lpTranslate;
    
    
    UINT cbTranslate;
    
    // Read the list of languages and code pages.    
    VerQueryValue(pVer, 
        TEXT("\\VarFileInfo\\Translation"),
        (LPVOID*)&lpTranslate,
        &cbTranslate);
    
    _TCHAR SubBlock[_MAX_PATH];
    void* lpBuffer;
    
    // Read the file version
    wsprintf( SubBlock, 
        TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"),
        lpTranslate[0].wLanguage,
        lpTranslate[0].wCodePage);
    
    // Retrieve file description for language and code page "i". 
    bRet = VerQueryValue(pVer, 
        SubBlock, 
        &lpBuffer, 
        &cbTranslate); 
    if( bRet )
    {
        m_strVersion = (_TCHAR*)lpBuffer;
        m_strVersion.Replace( _T(","),_T(".") );
        m_strVersion.Replace( _T(" "),_T("") );
    }
    
    // Read the build information
    wsprintf( SubBlock, 
        _T("\\StringFileInfo\\%04x%04x\\PrivateBuild"),
        lpTranslate[0].wLanguage,
        lpTranslate[0].wCodePage);
    
    // Retrieve file description for language and code page "i". 
    bRet = VerQueryValue(pVer, 
        SubBlock, 
        &lpBuffer, 
        &cbTranslate); 
    if( bRet )
    {
        m_strBuild = (_TCHAR*)lpBuffer;
        m_strBuild.Replace( _T(", "),_T(".") );
    }
    
//    m_strVersion = m_strVersion.Left( m_strVersion.GetLength() - 2 );
	
	CString m_strTemp = m_strVersion;
    int nFind = m_strTemp.ReverseFind(_T('.'));
	m_strVersion = m_strTemp.Left(nFind);
	
	m_strBuild = m_strTemp.Right(m_strTemp.GetLength()-nFind -1);
	int nBuidNum = _ttoi(m_strBuild);
	m_strBuild.Format(_T("%03d"),nBuidNum);
    
    delete [] pVer;
}
