/***************************************************************************
**
**    $Header$
**
**    $Log$
** 
****************************************************************************/

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

#include "stdafx.h"
#include "ep196.h"

#include "mainfrm.h"
#include "ctl3d.h"
#include "srcdef.h"
#include "init196.h"
#include "abiextfn.h"
#include "initapi.h"

// Variable window.
#include "varpane.h"
#include "varfrm.h"
#include "vardoc.h"
#include "varview.h"
// Stack window.
#include "stkfrm.h"
#include "stkdoc.h"
#include "stkview.h"
#include "stklocal.h"
#include "uicom2.h"
#include "logo.h"
// Peripheral window
#include "per6doc.h"
#include "per6view.h"
#include "perwin.h"
#include "ldrexp.h"

#include "mapdlg.h"
//GETID
#include "tstid.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
//LOGO
static DWORD        dwLabelTime;
static CLogoWnd *g_pLogoWnd=0;

void CloseFire(void)
{                               
#ifndef _DEBUG                 
    if(g_pLogoWnd) {
	   g_pLogoWnd->CloseLogoWnd();   
	}
#endif
}

void CreateFire(void)
{
#ifndef _DEBUG
	if( (g_pLogoWnd = new CLogoWnd(15000,(DWORD *)&g_pLogoWnd))==NULL )
	{
	   AfxMessageBox("Can not Locate window memory!");
	}         
#ifdef _PLUS_              
	else g_pLogoWnd->CreateWnd("EasyPack/SLD Plus for 80C196F","Version 1.0", 32,20);
#else   
	else g_pLogoWnd->CreateWnd("EasyPack/SLD for 80C196F","Version 1.0", 32,20);
#endif

#endif
}



/////////////////////////////////////////////////////////////////////////////
// CEp196App

BEGIN_MESSAGE_MAP(CEp196App, CWinApp)
	//{{AFX_MSG_MAP(CEp196App)
	ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
	ON_COMMAND_EX(ID_FILE_MRU_FILE1, OnOpenRecentFile)
	ON_COMMAND_EX(ID_FILE_MRU_FILE2, OnOpenRecentFile)
	ON_COMMAND_EX(ID_FILE_MRU_FILE3, OnOpenRecentFile)
	ON_COMMAND_EX(ID_FILE_MRU_FILE4, OnOpenRecentFile)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEp196App construction

CEp196App::CEp196App()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
	//added by john  96.3
    m_bCanTimer = TRUE;
    m_bWaiting = FALSE;      
    m_nCpuStatus = m_nCpuStatusBak = STATUS_HALT;
    m_isInit = FALSE;   
    m_bTraceOn = FALSE;
}

CEp196App::~CEp196App()
{
	// TODO: add destruction code here,
	// Place all significant clean codes in ExitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CEp196App object

CEp196App NEAR theApp;

char szAppPath[_MAX_PATH+1];


/////////////////////////////////////////////////////////////////////////////
// CEp196App initialization

BOOL CEp196App::InitInstance()
{              
	CString strCmd = m_lpCmdLine;
	if (-1 != strCmd.Find("/s")) {
		SetDialogBkColor();        // Set dialog background color to gray
		LoadStdProfileSettings();  // Load standard INI file options (including MRU)
		EnableVBX();               // Initialize VBX support
		
		//init comset dialog and relink dialog                   
		Init196DLL();

    	//init abi dll
    	InitABIDLL();                                  
    	
   		// Initial loader
	   	//InitDLLLoad();
   	    
   	    //initialize load manager
		//InitLdr();
		
    	if(!NewABIDLL(MAKE_REAL_196_ABI_FIRSTTIME)) {
    		//DelLdr();
    		return FALSE;
    	}	
    	
    	AfxMessageBox("Communication Set Ok!");
    	
    	ExitABIDLL();    
    	//DelLdr();
		return FALSE;
	}
	
	// Only one instance
    if ( m_hPrevInstance ) {
	AfxMessageBox(IDS_ERR_ONE_INSTANCE);
	return FALSE;
    }                     
		
	// Get the applicaton path
    strcpy(::szAppPath, m_pszHelpFilePath);
    int nLen = strlen(::szAppPath);
    while ( nLen ) {
	if ( '\\' == ::szAppPath[--nLen] ) {
	    break;
	}
    }
    ::szAppPath[++nLen] = '\0';

	// 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.

	SetDialogBkColor();        // Set dialog background color to gray
	LoadStdProfileSettings();  // Load standard INI file options (including MRU)
	EnableVBX();               // Initialize VBX support

    // Register 3D control
    if ( Ctl3dRegister(HANDLE(m_hInstance)) ) {
	Ctl3dAutoSubclass(HANDLE(m_hInstance));
	m_bCtl3D = TRUE;
    }
    else {
	m_bCtl3D = FALSE;
    }                
    
    // register dll
    if(!::RegisterDll()) {
	return FALSE;
    }

	// Initial routine
	DoWaitCursor(1);
	if ( !::InitProject() ) {
		DoWaitCursor(-1);
	CloseFire();
	AfxMessageBox("ERROR INIT!");
	return FALSE;
	}
    DoWaitCursor(-1); 
    
    // Register the application's document templates.  Document templates
	//  serve as the connection between documents, frame windows and views.
	
	// Register Source window & Browse window
	::SrcRegisterWindow();

	// create main MDI Frame window
	CMainFrame* pMainFrame = new CMainFrame;
	if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
		return FALSE;
	m_pMainWnd = pMainFrame;
    
    // Register the Variable's document, frame and view.
    extern CMultiDocTemplate* pVarDocTemplate;
    pVarDocTemplate = new CMultiDocTemplate(
	IDR_VARIABLE,
	RUNTIME_CLASS(CVarDoc),
	RUNTIME_CLASS(CVarFrame),
	RUNTIME_CLASS(CVarView));
    AddDocTemplate(pVarDocTemplate);
    
    // Peripheral document, frame and view
    extern CMultiDocTemplate* pPeriDocTemplate;
    pPeriDocTemplate = new CMultiDocTemplate(
	IDR_PERIPHERAL,
	RUNTIME_CLASS(CPer6Doc),
	RUNTIME_CLASS(CPerWin),        // standard MDI child frame
	RUNTIME_CLASS(CPer6View));
    AddDocTemplate(pPeriDocTemplate);

    // Register the Stack's document, frame and view.
    extern CMultiDocTemplate* pStkDocTemplate;
    pStkDocTemplate = new CMultiDocTemplate(
	IDR_STACK,
	RUNTIME_CLASS(CStackDoc),
	RUNTIME_CLASS(CStackFrame),
	RUNTIME_CLASS(CStackView));
    AddDocTemplate(pStkDocTemplate);

    AddDocTemplate(new CMultiDocTemplate(IDR_STACK,
	RUNTIME_CLASS(CStackDoc),
	RUNTIME_CLASS(CStackFrame),
	RUNTIME_CLASS(CStackLocalView)));

    DoReset();
    
	if(!RestoreWindowPlacement()) {
	// The main window has been initialized, so show and update it.
	pMainFrame->ShowWindow(m_nCmdShow);
	pMainFrame->UpdateWindow();    
    }
    
    // enable close the label                    
    ::dwLabelTime = ::GetCurrentTime();
    m_isInit = TRUE;
    
    CMapDlg mapDlg; 
    extern BOOL DoMapRestore();
	if(!mapDlg.FindMapSave()) {
		CloseFire();
		mapDlg.DoModal();
	} else {
		if(!DoMapRestore()) {
			CloseFire();
			mapDlg.DoModal();
		}	
	}	
    
    return TRUE;
}

int CEp196App::ExitInstance()
{
    // Unregister 3D control.
    if ( m_bCtl3D ) {
	Ctl3dUnregister(m_hInstance);
    }
    
	// Exit routine
	ExitProject();

    return CWinApp::ExitInstance();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   CXviewApp::PreTranslateMessage
//
//  Description: Destroy the label when input from the user
//
//  Input:  None
//
//  Output: None
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CEp196App::PreTranslateMessage(MSG* pMsg)
{                              
    
    
     if(g_pLogoWnd!=NULL && g_pLogoWnd->IsWindowOpen())
	  {            
	     if(g_pLogoWnd->ProcessMsg(pMsg))
		return TRUE;
	  }         

    ( (((CMainFrame *)m_pMainWnd)->m_wndToolBar) ).FilterTipMessage(pMsg);
    
/*          
    //#ifndef _ZDEBUG          
//    if (m_isInit && ::pLabel && ::pLabel->m_hWnd != NULL &&
    if (m_isInit && nFireFlag &&
	(pMsg->message == WM_KEYDOWN ||
	 pMsg->message == WM_SYSKEYDOWN ||
	 pMsg->message == WM_LBUTTONDOWN ||
	 pMsg->message == WM_RBUTTONDOWN ||
	 pMsg->message == WM_MBUTTONDOWN ||
	 pMsg->message == WM_NCLBUTTONDOWN ||
	 pMsg->message == WM_NCRBUTTONDOWN ||
	 pMsg->message == WM_NCMBUTTONDOWN)) 
    {
		CloseFire();
		nFireFlag = 0;
    }             
    //#endif
*/
    
    
    BOOL bResult = CWinApp::PreTranslateMessage(pMsg);
	
	return bResult;
}

BOOL CEp196App::OnOpenRecentFile(UINT nID)
{
	// TODO: Add your command handler code here

	// Get MRU file
    ASSERT_VALID(this);

    ASSERT(nID >= ID_FILE_MRU_FILE1);
    ASSERT(nID < ID_FILE_MRU_FILE1 + _AFX_MRU_COUNT);
    ASSERT(m_strRecentFiles[nID - ID_FILE_MRU_FILE1].GetLength() != 0);

	// Run loader
	::SrcLoadTargetFile(m_strRecentFiles[nID - ID_FILE_MRU_FILE1]);

    return TRUE;
}

void CEp196App::GetLatestFile(CString& strFile)
{
	if (m_strRecentFiles[0].GetLength() != 0)
		strFile = m_strRecentFiles[0];
	else strFile.Empty();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   CEp196App::OnIdle
//
//  Description: Destroy the label when time is on
//
//  Input:  None
//
//  Output: None
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CEp196App::OnIdle(LONG lCount)
{
    BOOL bResult = CWinApp::OnIdle(lCount);
	  
    //#ifndef _ZDEBUG          
    // then do our work
/*    
    if (m_isInit && ::pLabel && ::pLabel->m_hWnd != NULL) {
	if (::GetCurrentTime() - ::dwLabelTime > 3000L) {
	    // timeout expired, destroy the label window
	    ::pLabel->DestroyWindow();
	    delete ::pLabel;
	    ::pLabel = 0;

	    // NOTE: don't set bResult to FALSE,
	    //  CWinApp::OnIdle may have returned TRUE
	} else {
	    // check again later...
	    bResult = TRUE;
	}
    }             
*/    
    
    if (m_isInit && g_pLogoWnd) {                       
	if (::GetCurrentTime() - ::dwLabelTime > 2000L) {
	    // timeout expired, destroy the label window
			CloseFire();
			
	    // NOTE: don't set bResult to FALSE,
	    //  CWinApp::OnIdle may have returned TRUE
	} else {
	    // check again later...
	    bResult = TRUE;
	}
    }             
    
    
    //#endif

    return bResult;
}


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

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

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	CListBox        m_listName;
	CString m_strBaud;
	CString m_strPort;
	//}}AFX_DATA

private:
	CBitmapButton m_btnAbout;

	BOOL m_bShowName;

	enum { tmEvent = 1, tmElapse = 450 };
    UINT m_uTimerID;

// Implementation
protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//{{AFX_MSG(CAboutDlg)
	virtual BOOL OnInitDialog();
	afx_msg void OnDoubleclickedButtonAbout();
	afx_msg void OnTimer(UINT nIDEvent);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD),
	m_bShowName(FALSE), m_uTimerID(0)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	m_strBaud = "";
	m_strPort = "";
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	DDX_Control(pDX, IDC_LIST_ABOUT_NAME, m_listName);
	DDX_Text(pDX, IDC_ABOUT_BAUD, m_strBaud);
	DDX_Text(pDX, IDC_ABOUT_PORT, m_strPort);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
	ON_BN_DOUBLECLICKED(IDC_ABOUT, OnDoubleclickedButtonAbout)
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

// App command to run the dialog
void CEp196App::OnAppAbout()
{
	CAboutDlg aboutDlg;
	aboutDlg.DoModal();
}

/////////////////////////////////////////////////////////////////////////////
// VB-Event registration
// (calls to AfxRegisterVBEvent will be placed here by ClassWizard)

//{{AFX_VBX_REGISTER_MAP()
//}}AFX_VBX_REGISTER_MAP

/////////////////////////////////////////////////////////////////////////////
// CEp196App commands

BOOL CAboutDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here

	// Center the dialog.
    CenterWindow();                          
    GetSerialBaudRateStr(m_strBaud);   
    GetSerialPortNumStr(m_strPort);
    UpdateData(FALSE);
    // Show version information                                              
    CString strDos, strWindows, strVer, strFWVer, strCPU;
						      
    TstIdentify(strCPU, strFWVer, strVer, strDos, strWindows);
    SetDlgItemText(IDC_ABOUT_VER, strVer);
    SetDlgItemText(IDC_ABOUT_CPU, strCPU);
    SetDlgItemText(IDC_ABOUT_DOS, strDos);
    SetDlgItemText(IDC_ABOUT_WINDOWS, strWindows);
    SetDlgItemText(IDC_ABOUT_FWVER, strFWVer);

	// Draw the bitmap.
	m_btnAbout.AutoLoad(IDC_ABOUT, this);
	
	// Hide the list box.
	GetDlgItem(IDC_LIST_ABOUT_NAME)->ShowWindow(SW_HIDE);

    return TRUE;  // return TRUE  unless you set the focus to a control
}

void CAboutDlg::OnDoubleclickedButtonAbout() 
{
	// TODO: Add your control notification handler code here

	// Hide some cotrols.
	m_bShowName = !m_bShowName;
	if ( m_bShowName ) {
		GetDlgItem(IDC_LIST_ABOUT_NAME)->ShowWindow(SW_SHOW);
		
		// Show the engineers' names.
		m_listName.ResetContent();

		m_listName.AddString("EP/SLD Development Team: ");
		m_listName.AddString("");

        m_listName.AddString("Lab Manager:");
		m_listName.AddString("Hercules Yao");

		m_listName.AddString("Program Manager:");
		m_listName.AddString("Dome Liu");
		m_listName.AddString("");

        m_listName.AddString("Manual Editor & Layout:");
        m_listName.AddString("Cynthia Zhow");
		m_listName.AddString("");

		m_listName.AddString("Test Engineers:");
		m_listName.AddString("Daniel Lin");
		//m_listName.AddString("Shirley Dong");
		m_listName.AddString("Cathy Yang");
		m_listName.AddString("Jeff Bing");
		m_listName.AddString("Bomb Li");
		m_listName.AddString("Lynn Xing");
		m_listName.AddString("Gorge");    
		m_listName.AddString("");

		m_listName.AddString("Hardware Engineers:");
        m_listName.AddString("Xu shuqing");
		m_listName.AddString("Johnson");    
		m_listName.AddString("");

		m_listName.AddString("Software Engineers:");
		m_listName.AddString("Dragon Long");
		m_listName.AddString("Richard Guo");
		m_listName.AddString("Annie Yi");
		m_listName.AddString("Chris Fang");
		m_listName.AddString("John Zhou");
		m_listName.AddString("Jerry Yan");
		m_listName.AddString("Chen Jun");

		// Set timer.
		if ( 0 != m_uTimerID ) {
			// If outstanding timer, kill it.
			KillTimer(m_uTimerID);
		}
		// Set a timer for 200 milliseconds.
		m_uTimerID = SetTimer(tmEvent, tmElapse, NULL);
	}
	else {
		GetDlgItem(IDC_LIST_ABOUT_NAME)->ShowWindow(SW_HIDE);

		// Kill one-shot timer.
		if ( 0 != m_uTimerID ) {
			KillTimer(m_uTimerID);
			m_uTimerID = 0;
		}
	}
}

void CAboutDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	
	// Not our timer.
	if ( m_uTimerID != nIDEvent ) {
		CDialog::OnTimer(nIDEvent);
		return;
	}

	// Scroll the list box contents.
	m_listName.SendMessage(WM_VSCROLL, SB_LINEDOWN);
}

//add for export cpu status routine   
#ifdef __cplusplus
extern "C" {
#endif  // __cplusplus  
BYTE WINAPI GetCanTimer(){
	return ((CEp196App*)AfxGetApp())->m_bCanTimer;
}

BYTE WINAPI GetWaiting(){
	return ((CEp196App*)AfxGetApp())->m_bWaiting;
}
     
int WINAPI GetCpuStatus2(){
	return ((CEp196App*)AfxGetApp())->m_nCpuStatus;
}
     
int WINAPI GetCpuStatusBak(){
	return ((CEp196App*)AfxGetApp())->m_nCpuStatusBak;
}
     
BYTE WINAPI GetTraceOn(){
	return ((CEp196App*)AfxGetApp())->m_bTraceOn;
}    

void WINAPI GetGoArg(ADDR& GoArg) {
	GoArg.addr = ((CEp196App*)AfxGetApp())->m_GoArg.addr;   
	GoArg.addrType = ((CEp196App*)AfxGetApp())->m_GoArg.addrType;   
} 

void WINAPI SetCanTimer(BYTE bCanTimer){
	((CEp196App*)AfxGetApp())->m_bCanTimer = bCanTimer;
}                                

void WINAPI SetWaiting(BYTE bWaiting){
	((CEp196App*)AfxGetApp())->m_bWaiting = bWaiting;
}
     
void WINAPI SetCpuStatus2(int nCpuStatus){
	((CEp196App*)AfxGetApp())->m_nCpuStatus = nCpuStatus;
}
     
void WINAPI SetCpuStatusBak(int nCpuStatusBak){
	((CEp196App*)AfxGetApp())->m_nCpuStatusBak = nCpuStatusBak;
}
     
void WINAPI SetTraceOn(BYTE bTraceOn){
	((CEp196App*)AfxGetApp())->m_bTraceOn = bTraceOn;
}

void WINAPI SetGoArg(ADDR GoArg) {
	 ((CEp196App*)AfxGetApp())->m_GoArg.addr = GoArg.addr;  
	 ((CEp196App*)AfxGetApp())->m_GoArg.addrType = GoArg.addrType;  
} 

void WINAPI UpdateStatusBar(int n,CString str) {
	((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_wndStatusBar.UpdateStatusBar(n,str);    
}   

void WINAPI UpdateStatusBarAll() {
	((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_wndStatusBar.UpdateWindow();    
}   

#ifdef __cplusplus
}
#endif  // __cplusplus  
     

