/*
             Siemens AG
         Mobile Radio Terminals
          Munich, Germany

.AUTHOR         B. Baier, PN KE T CP 33

.SHORT_DESCR    Haupt-MMI fuer PC

.SW_COMPONENT

.SW_TYPE        Support-File

.VERSION        04.32.00 

.DATE           %date_created: 2004-11-22 09:47:04 %

.STATUS         FIRST VERSION

.CHANGE_CONTROL
Version |  Date  | Changed by | Reason for Change
-------------------------------------------------------------------------------------------
1.0    ??.??.??  ?.?          file created......
1.1    21.03.96  B. Baier     Update
1.2    25.03.96  B. Baier     print_d eingefuehrt
1.3    18.10.96  A. Gräupel   aus _far far gemacht, damit das define aus global.h greift.
_EasyWinInit nur für WIN16.
1.4    10.12.96  A. Gräupel   für W32 zusätzliches Attribut für Messagesboxes ergänzt.
1.5    30.01.97  B. Baier     Console Debug Output eingeführt
1.6    20.03.97  B. Baier     LOG_FILE wird im Byte-Mode geschrieben
1.7    28.03.97  B. Baier     new exit handling
1.8    04.04.97  B. Baier     better cooperation GBS<->Win32 (if GBS is idle -> sleep 10 ms)
activate display window per default
1.9    13.05.97  B. Baier     call GBS timers only if display window has keyboard focus (debugging!)
2.0    08/15/97  A. Graeupel  log file will be created in %TMP% directory, rather than in absolute C:\tmp !
2.0.1  22.06.98 M.Riedinger   compiler warnings removed
2.1    08.08.98  B. Adameit   workaround for switch-off bug: MMI process trying to kill itself
2.2    15.10.98 M.Riedinger   DebugBreak instead of exit, when exiting MMI (function mmi_abort)
2.3    25.02.99  B. Adameit   GbsPollInterrupts now prevented from indirect recursion
-------------------------------- P35 ------------------------------------------------------
1.0    01.07.99  N. Haiduk     p35-version
1.1    23.08.99  T. Kreßler    OMA_Exit() and SMARTIE_Exit() added.
1.2    25.10.99  T. Kreßler    SMARTIE_Exit() removed.
1.3    26.11.99  G.Stöckl      SMO_OMA processes added , added smohproc.h
1.4    02.03.00  A.Leontarakis print_d2f added
1.5    20.04.00  H.Sauer       EX_Exit() added.
1.6    05.04.00  N.Faisst      changed program startup using MFC Application object
1.7    02.06.00  N Faisst      UnloadTastenKlickWaveForm( ) added.
1.8    04.08.2k  H.Sauer       EX_Exit() before OMA_Exit() now.
1.8.1  05.09.00  T. Kreßler    Comment for EX_Exit() closed, OMA_Exit() will be working now again.
1.9    21.09.00  N Faisst      SaveOnBitmaps and SaveWaitBitmaps added.
1.9.1  27.09.00  T. Kreßler    Warnings removed (danke Anke).
2.0    30.10.00  R. Peters     BVP_Exit added
2.1    18.12.00  R. Peters     MHP_Exit added
2.2    13.02.01  R. Peters     VCF_Exit/VCS_Exit added
2.3    22.02.01  R. Peters     GLV_Exit added
2.4    27.02.01  R. Peters     DDL_Exit added
2.5    27.02.01  D. Bruns      mmi_abort removed from assert_fail
2.6    28.12.00  B. Weimer     added print_x for temporary debugging
2.4    23.03.01  U. Meyer      BMD_Exit added
2.5    08.05.01  U. Meyer      NiTZ_Exit
2.6    14.05.01  U. Meyer      NiTZ_Exit moved to csmkinit
2.7    10.09.01  L. Sillge     NO_PROCESS -> NOPROCESS_PID
2.8    28.09.01  T.Herrmann    merge from gen7k(.z1)
2.9    16.11.01  T. Kreßler    EMSAL_EXITProcess() added.
3.0    02.01.02  R. Peters     Change print_d2f so that it will use everytime the same file in temp directory
-------------------------------- K45 step 3 -----------------------------------------------
3.1.1  2002-02-26  Norbert Haiduk      (KLF)   cleanup, logfile-flag "/F" added
-------------------------------- L55 ------------------------------------------------------
3.2.0  2001-11-14  A. Groos            (KLF)   replaced ex_proch.h by ex_proih.h
3.2.1  2001-11-14  D.Ambras            (MCH)   safer handling of cmd line options
3.2.2  2001-11-23  D.Ambras            (MCH)   allow simulation to run in background, too
3.2.3  2002-03-13  A.Staudacher        (MCH)   inserted exit routine of EMS CODEC process
4.0.0  2002-03-21  GS                  (MCH)   CONTINUUS migration: emsdechh.h
4.0.1  2002-03-21  R. Supper           (MCH)   gXtraceOn added (preparation for the future xtrace functionality)
4.3.1  2002-05-02  B. Duemler          (KLF)   Do initialize the mode in which we start the simulation
4.4.0  2002-05-06  D. Ambras           (MCH)   moved command line processing stuff to new file "wincmdl.cpp"
4.5.0  2002-05-22  R. Vretska          (MCH)   added XTRACE handling
4.6.0  2002-05-23  A. Tennert          (SAL)   SMIL_Exit() added.
4.7.0  2002-06-25  Uwe Schmitz         (KLF)   Added function warm_boot
4.8.0  2002-10-26  Norbert Haiduk      (KLF)   change: headline of exit-messagebox changed to full exitcode display
4.9.0  2002-11-04  Christoph Scharenberg (KLF) Added function exitprint_extd()
4.9.1  2002-11-19  Jan Eichholz (MCH)          heap sharing moved from mmi_k2 into this file
4.10.1 2002-11-28  C. Holzhey                  dummy variant of scatter tracer txttrace added
4.10.2 2003-02-05  Alexander Nagy (Bardenheuer) introduced WFS_InitSimuDrives() for the filesystem simulation
4.10.3 2003-02-06  Herman Keuchel      (KLF)   Remove Battlemail and Gamelevel handler.
4.10.4 2003-02-05  Alexander Nagy (Bardenheuer) introduced Simu_GetExeInstallPath() and Simu_GetFilePath()
4.10.5 2003-04-29  Walter Stroell (VIE) adaptations for MOPI
-------------------------------------------------------------------------------------------
04.10.06 2003-06-13 Thomas Herrmann (Mch)
         Adaptions for Visual Studio .NET 2003
04.11.00 2003-06-14 Murat Korkmaz  (Bardenheuer) New UI for PC-Simulation
04.11.01 2003-07-03 Dirk Ambras (Mch)
         Activation of command line parsing in Visual Studio .NET 2003
04.12.01 2003-07-15 Jens Scharnow (KLF)
         Added MTT Activation
2003-07-25 Yingfan Lei, Murat Korkmaz
         added function for getting and setting pointer for clamp shell window
04.13.01 2003-07-18 A.Staudacher (Mch Con)
         bugfixes for exit routines for EMSAL Admin Process and UDIAL Process
04.13.02 2003-07-21 W. Stroell (VIE)
         MOPI_ExecuteFunction used now 
04.14.00 2003-08-26 A.Stelzer (ULM)
         Added camera device layer and CameraAE process shutdown
         Added camera simulation thread create/destroy
04.15.00 2003-09-08 Jens Scharnow (KLF)
         Replaced VCF and VCS by officehandler and callrecords
04.16.00 2003-09-11 Murat Korkmaz
         Set focus in functions exit_message, info_message
04.17.00 2003-09-30 A. Nagy
         added NULLP check to exit_message() and info_message()
04.18.00 2003-09-31 Klaus Staudenmaier (ULM)
         Introduced Ca_CommunicationProcess_Delete() for Paul Swarts
04.18.01 2003-10-21 Klaus Staudenmaier (ULM)
         Removed SharedHeap_DestroyAllHeaps
04.19.00 2003-10-23 Murat Korkmaz
         Removing of old PC-SIMU UI sources  
04.20.00 2003-11-21 Walter Stroell
         MR0060 - user defined operators new and delete added  
04.21.00 2003-12-02 Norbert Barisits
         initialize sound simulation
04.22.00 2003-12-11 Marian Kremnican (BTS)
         Changes for use of modeman
04.23.00 2003-12-18 Alexander Nagy (Bardenheuer SW)
         removed dummy implementation of txttrace()
	 changed FFS shutdown
	 expanded Simu_GetExeInstallPath() parameter list
04.23.01 2004-01-10 Norbert Barisits (VIE)
         CMFC_Simulation_App::InitInstance - use malloc instead of _tcsdup
         to avoid memory context problems during shutdown
         Application_Initialize() - Mobsim_RegisterSQRHandler() for Alert/Charge Mode (Marian)
04.23.02 2004-01-22 Frantisek Irman (BTS)
         CR_AE_ProcessDestroy, OH_DestroyProcess and MMI_GSMMode_exit moved to ap_caf.c
04.24.00 2004-01-30 Marian Kremnican (BTS)
         Cleaning up, removing SysInit and UserInit, deleting SimuShutdown_Mopi
04.25.00 2004-02-19  zhang qifan(PEK)
	     change window title
04.25.01 2004-02-20 Walter Stroell (VIE)
         allow process to run on the first CPU only
04.26.00 2004-03-01 Marian Kremnican (BTS)
         Variable g_MMIMode replaced by mg_MMIMode, SetSimulationMode() deleted
         new procedure ShowRestartInfoMessage introduced.
04.26.01 2004-03-09 Marian Kremnican (BTS)
         obsolete call of msmlow_SwitchOff in GbsPollInterrupts removed
04.26.02 2004-03-11 Walter Stroell (VIE)
         MOPI_ShowMemoryLeaks() added at shutdown
04.26.03 2004-03-24 Walter Stroell (VIE)
         not needed dummy function removed         
04.26.04 2004-03-31 Zhang qi fan(PEK)
	 Init Mainfrm window title according to product name
04.26.05 2004-04-30 Zhang qi fan(PEK)
	 update SMTK emulator title	
04.26.06 2004-05-28 Sun Min(PEK)
         change the error message to more user friendly when a second 
	     instance of emulator is started, and exit the emulator in a correct way 
04.27.00 2004-06-08 Murat Korkmaz (Mch)
         modification of function CMFC_Simulation_App::Run and function
         CMFC_Simulation_App::Exitinstance added.
04.27.01 2004-06-08 Murat Korkmaz (Mch)
         modification of function CMFC_Simulation_App::ExitInstance().
04.27.02 2004-06-15 Alexander Nagy (Bardenheuer SW)
         prepared SddAudio integration to PC-MMI
04.27.02 2004-06-17 Fang Yunchao(PEK)
	 Add UNICODE Support
04.27.03 2004-06-28 Fang Yunchao(PEK)
	 Modification for SMTK Localization support
04.28.00 2004-07-08 Murat Korkmaz
         Unused includes removed
04.29.00 2004-08-13 Alex Nagy
         activated genplayer/sound simulation
04.29.01 2004-08-20  U.Kapala
         inc_private_alias is replaced with C2C concept and is removed. (only relevant for PCMMI)
04.30.00 2004-09-01 Murat Korkmaz
         MassageBox calls are called from Mainwindow
04.30.01 2004-11-16 Alexander Nagy
         removed USE_SDDAUDIO_ADD_SIMU compiler switch
04.31.00 2004-11-25 Norbert Barisits (VIE)
         MOPI_Enter/Leave/ExternalSection() added to function print_d2f()
04.32.00 2004-11-26 Norbert Barisits (VIE)
         Additional MOPI_Enter/Leave/ExternalSection() calls in exit functions

**************************************Jerry*********************************
05.00.00  2006-03-17  Gurpreet Sabharwal(SISL ,India)
                      Removed Java Support And Functionality


*/

#include "smsafxh.h"

extern "C"
{
#include <global.h>
#include <io.h>
#include "mmi.h"
#include "gbs.h"
#include "gbsext.h"
#include "oma.h"
#include "smohproc.h"
#include "ddl_prch.h"
#include "bmpvprch.h"
#include "melhprch.h"
#include "appim_callrecords_ae.h"
#include "appim_officehandler.h"
//#include "jenv.h"
#include "emsalprh.h"
#include "emsdechh.h"
#include "emsal_admin_proch.h"
#include "utf.h"
#include "siretype.h"
#include "sire.h"
#include "smil.h"
#include "mopiext.h"
#include "udial_proc_interfaceh.h"
//#include "inc_private_alias.h"
#include "ffs_startuph.h"
#include "wfs_api.h"
}

#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#include "gbs.h"
#include "winmain.h"
#include "mob2winh.h"
#include "sim_regh.h"
#include "simu_inith.h"
#include "vcdbgout.h"
#include "simuapph.h"
#include "mainfrmh.h"
//#include "camaed_h.h"            // CameraAE process
#include "camera_add_sim.h"      // camera device layer simulation
#include "modeman_ci.h"
#include "modeman_sm.h"     // next mode > ShowRestartInfoMessage

#ifdef JAVA_SDK
#include "info_main.h"
#include "mmiconf.h"
#include "Mobileinfo_cmt.h"
#endif

#include "simdsthread.h"

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//
//      IMPORT
//
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
extern bool ProcessCommandLine(LPSTR lpCmdLine);
extern void LCDWindowInit(void);
extern void InitMTTInterface(void);
extern void MMIWindowPoll();
extern "C" HWND DispGetWinHandle(void);
extern "C" void GbsTimerInterrupt(unsigned int);
extern "C" HWND CmdGetWinHandle(void);
extern "C" void KeyboardKeyDown(unsigned char scancode);
extern "C" void KeyboardKeyUp(unsigned char scancode);
extern "C" bool CSMIsMMIExited(void);
extern "C" void msmlow_SwitchOff(void);

extern int mg_ShowErrorMessages;
extern int mg_ShowInfoMessages;

extern "C" E_MODEMAN_MOBILE_STATION_MODE MobsimNextMode = E_MODEMAN_MSM_POWER_DOWN;

static void LogFileInit(void);



//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//
//      GLOBALS
//
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//static  FILE    *rf;
static char logfilename[100];
static int file_created;

#if ( defined __WIN32__) || ( defined _WIN32)
HANDLE /*hStdIn, */hStdOut; /* standard input, output handles */
#endif

static unsigned long start_ms_timestamp;
int mg_nPrintDScreenOutput = 0;
int mg_nPrintDLogfile = 0;

//static bool fastmode = False;
static clock_t ctZeit;
extern "C" int quit_msg_posted = 0; //@Str 

static int quit_shutdown_pending = 0; //@Str

// XTRACE parameters
extern char xtraceFileName[];
extern char xtraceUserName[];
extern char xtraceGenName[];
extern void OpenTraceFile(char *tracefilename, char *username, char *GenName);
extern void CloseTraceFile(void);

extern "C" bool gXTraceOn = FALSE;
// end XTRACE



//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//
//      PRIVATE
//
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

/*static void open_record_file(const char *filename)
{
    if ((rf = fopen(filename, "r")) == NULLP)
    {
        print_d("Recordfile 's%' nicht gefunden!\n", filename);
        return;
    }
    print_d("Reading Recordfile 's%'!\n", filename);

}


static const char *get_next_record(void)
{
    static char rec_buffer[500];
    if (rf == NULL) return NULL;
    if (fgets(rec_buffer, 501, rf) == NULL)
    {
        fclose(rf);
        rf = NULL;
        return NULL;
    }
    return rec_buffer;
} */



static void PollTimer(void)
{
    clock_t ctDelta, ctNeueZeit;
    ctNeueZeit = clock();
    ctDelta = ctNeueZeit - ctZeit;

    if (ctDelta > 0)
    {
        ctZeit = ctNeueZeit; // CLOCKS_PER_SECOND = 18.2 mal per Sekunde
        // if (GetForegroundWindow() == DispGetWinHandle() || GetForegroundWindow() == CmdGetWinHandle())

        while (ctDelta--)
            GbsTimerInterrupt((unsigned int) (1000000L / CLOCKS_PER_SEC));
    }
}



/*
static void RecordPoll(void)
{
    static int waiting = False;
    static const char *rec_line;
    static const char *ptimestamp;
    static unsigned long timestamp;

    if (!waiting)
    {
        rec_line = get_next_record();
        if (rec_line == NULL) return;

        if (!fastmode)
        {
            ptimestamp = strstr(rec_line, "Timestamp:");
            if (ptimestamp == NULLP) return;
            timestamp = atol(ptimestamp + strlen("Timestamp:"));
        }
        else
            timestamp = get_ms_timestamp() + 200;
    }
    if (get_ms_timestamp() < timestamp)
    {
        waiting = True;
        return;
    }
    waiting = False;
    const char *pmsg1 = strstr(rec_line, "KeyboardKeyDown(");
    const char *pmsg2 = strstr(rec_line, "KeyboardKeyUp(");
    if (pmsg1 != NULL)
    {
        unsigned int keycode;
        keycode = atoi(pmsg1 + strlen("KeyboardKeyDown("));
        KeyboardKeyDown(keycode);

    }
    if (pmsg2 != NULL)
    {
        unsigned int keycode;
        keycode = atoi(pmsg2 + strlen("KeyboardKeyUp("));
        KeyboardKeyUp(keycode);
    }
} */




//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//
//      PUBLIC
//
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

extern "C" unsigned long get_abs_ms_timestamp(void)
{
    return (unsigned long) ((double) clock() / CLOCKS_PER_SEC * 1000.0);
}

extern "C" unsigned long get_ms_timestamp(void)
{
    return get_abs_ms_timestamp() - start_ms_timestamp;
}


extern "C" void GbsIdle()
{
    Sleep( 20 /* milliseconds */); // for better cooperation with windows!
}


extern "C" void Mobsim_RegisterSQRHandler( void );

extern "C" void Application_Initialize( VOID * first_available_memory )
{
#if PC_SIMU_USE_NEW_UI
    ((CMainFrame*) GET_APP()->m_pMainWnd)->ShowWindow(SW_SHOW);
    ((CMainFrame*) GET_APP()->m_pMainWnd)->UpdateWindow();
#else
    ASSERT(FALSE);
#endif

    InitMTTInterface(); // initialize communication interface to MTT
    
    Modeman_Startup();
    Mobsim_RegisterSQRHandler();
}

extern "C" void SetQuitMsgPosted(void)
{
    PostThreadMessage(AfxGetApp()->m_nThreadID,WM_QUIT,0,0);
    quit_msg_posted = 1;
}

extern "C" void GbsPollInterrupts(void)
{
    SetThreadPriority( GetCurrentThread(),THREAD_PRIORITY_HIGHEST ); 
    
    MMIWindowPoll();

    if (quit_shutdown_pending) return;

    if (CSMIsMMIExited() && !quit_msg_posted)
    {
        quit_shutdown_pending = 1;

        PostQuitMessage(0);

    }
}

void mmi_abort(void)
{
    //exit (1);
        // jump to debugger!
        DebugBreak();
}

#define LOG_FILE_NAME "mmi.log"
#define LOG_FILE_DIR "c:\\tmp"

static void LogFileInit(void)
{
        char *ep = getenv("TMP");

    if (ep == 0)
                strcpy(logfilename,LOG_FILE_DIR);
        else
                strcpy(logfilename,ep);

        strcat(logfilename,"\\"LOG_FILE_NAME);
}


//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
extern "C" void print_d2f(const char *logfile, const char *fmt, ...)
{
    if (mg_nPrintDLogfile > 0)      // debug-level 2 or above
    {
        FILE *printMmiStream;
        char buf[500];
        char logfilename[256];
        char *ep;

        MOPI_EnterExternalSection();

        ep = getenv("TMP");

        va_list va;
        va_start(va, fmt);
        vsprintf(buf, fmt, va);
        va_end(va);

        if (ep == 0)
            strcpy( logfilename, LOG_FILE_DIR );
        else
            strcpy( logfilename, ep );

        strcat( logfilename, "\\");
        strcat( logfilename, logfile );

        printMmiStream = fopen(logfilename,"a");
        if ( printMmiStream != NULLP )
        {
            fprintf(printMmiStream,buf);
            fclose(printMmiStream);
        }

        MOPI_LeaveExternalSection();
    }
}


//extern bool dlg_delay_state;
void print_d(const char *fmt, ...)
{
    char buffer[500];

    va_list va;

    va_start(va, fmt);
    vsprintf(buffer, fmt, va);
    va_end(va);

    if (mg_nPrintDScreenOutput)
    {
#if ( defined __WIN32__) || ( defined _WIN32)
        DWORD cCharsWritten;
        /* write the string to the console */
        WriteConsole(hStdOut, buffer, strlen(buffer), &cCharsWritten, NULL);
        //PERR(bSuccess, "WriteConsole");
#else
        printf("%s", buffer);
#endif
    }

    if ( mg_nPrintDLogfile > 1 )
    {
        FILE *fh;

        if (file_created == 0)
        {
                    LogFileInit();
            fh = fopen(logfilename, "wb");
            file_created = 1;
        }
        else
        {
            fh = fopen(logfilename, "ab");
        }

        if (fh != NULL)
        {
            fprintf(fh, "%s", buffer);
            fclose(fh);
        }
    }
}


/**
 * Writes debug information to "mmi.log" and console.
 * Use this function only temporary, don't check in
 * modules that make use of this function!
 */
extern "C" void print_x(const char *fmt, ...)
{
    char buffer[500];
    va_list va;
    DWORD cCharsWritten;
    FILE *fh;

    MOPI_EnterExternalSection();

    va_start(va, fmt);
    vsprintf(buffer, fmt, va);
    va_end(va);

    if(!hStdOut)
    {
        AllocConsole();
        SetConsoleTitle(_T("Debug Output"));
        hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    }

    WriteConsole(hStdOut, buffer, strlen(buffer), &cCharsWritten, NULL);

    if (file_created == 0)
    {
        LogFileInit();
        fh = fopen(logfilename, "wb");
        file_created = 1;
    }
    else
    {
        fh = fopen(logfilename, "ab");
    }

    if (fh != NULL)
    {
        static long sticks;
        long ticks;

        if(sticks == 0)
            sticks = GetTickCount();
        ticks = GetTickCount() - sticks;

        fprintf(fh, "%9.3f %s", (double)ticks/1000, buffer);
        fclose(fh);
    }

    MOPI_LeaveExternalSection();
}


extern "C" void exit_message(const char *message, const char *head)
{
    if (mg_ShowErrorMessages)
    {
#if ( defined __WIN32__) || ( defined _WIN32)
        GET_APP()->m_pMainWnd->MessageBox(message, head, MB_ICONSTOP | MB_OK | MB_SETFOREGROUND);
#else
        GET_APP()->m_pMainWnd->MessageBox(message, head, MB_ICONSTOP | MB_OK );
#endif
    if (NULL != GET_APP()->GetMMIDispWindow())
       GET_APP()->GetMMIDispWindow()->MakeActiveWnd();
    }
}

extern "C" void info_message(const char *message, const char *head)
{
    if (mg_ShowInfoMessages)
    {
#if ( defined __WIN32__) || ( defined _WIN32)
        GET_APP()->m_pMainWnd->MessageBox(message, head, MB_ICONEXCLAMATION | MB_OK  | MB_SETFOREGROUND );
#else
        GET_APP()->m_pMainWnd->MessageBox(message, head, MB_ICONEXCLAMATION | MB_OK);
#endif
        if (NULL != GET_APP()->GetMMIDispWindow())
            GET_APP()->GetMMIDispWindow()->MakeActiveWnd();
    }
}

extern "C" void exitprint( const char *text)
{
    MOPI_EnterExternalSection();
    print_d("exitprint: %s\n", text);
#ifndef JAVA_SDK
    info_message(text, "EXITPRINT");
#endif
    MOPI_LeaveExternalSection();
}

void ShowRestartInfoMessage( void )
{
    BOOL showInfo = True;
    char  msg[100] = "Now the SW is down.\nThe next mode after switch-on will be: ";
    char *eomsg = &msg[strlen(msg)];

    switch( MobsimNextMode )
    {
        case E_MODEMAN_MSM_NORMAL_GSM:
            memcpy(eomsg,"NORMAL GSM",10);
            break;
        case E_MODEMAN_MSM_CHARGEONLY:
            memcpy(eomsg,"CHARGE ONLY",11);
            break;
        case E_MODEMAN_MSM_ALARM:
            memcpy(eomsg,"ALARM ONLY",10);
            break;
        default:
            showInfo = False;
    }

    if( showInfo )
        info_message( msg, "MOBSIM Restart Info" );
}

// Function for exit strings up to 16 characters.
// Untested for now; implemented to make the linker happy.
// The code has been copied from above (exitprint) and adapted.
extern "C" void exitprint_extd( const char *text, size_t length )
{
    MOPI_EnterExternalSection();
    print_d("exitprint_extd: %s\n", text);
#ifndef JAVA_SDK
    info_message(text, "EXITPRINT_EXTD");
#endif
    MOPI_LeaveExternalSection();
}


/**
    Function to RESTART the mobile.
    In PC-Simu this function is identical to an EXIT. The PC-Simu will terminate.
*/
extern "C" void warm_boot( unsigned int modul, unsigned int task, unsigned int nr, unsigned char level, char *file, int line)
{
    char buffer[1000];
    char head[100];

    sprintf(head, "RESTART(%02Xh)", nr);
    sprintf(buffer, "Modul %02Xh, Task %02Xh, Level %02Xh (File %s, Zeile %d)", modul, task, level, file, line);
    MOPI_EnterExternalSection();
    print_d("RESTART:\n%s\n", buffer);
    exit_message(buffer, head);
    MOPI_LeaveExternalSection();
    mmi_abort();
}


extern "C" void hard_exit( unsigned int nModul, unsigned int nTask, unsigned int nNr, char *pszFile, int nLine )
{
    char szBuffer[1000];
    char szHead[100];

    sprintf( szHead, "HARD EXIT %02X%01X%01X", nModul, nTask, nNr );
    sprintf( szBuffer, "Modul %02Xh, Task %02Xh (File %s, Zeile %d)", nModul, nTask, pszFile, nLine );
    MOPI_EnterExternalSection();
    print_d( "hard_exit:\n%s\n", szBuffer );
    exit_message( szBuffer, szHead );
    MOPI_LeaveExternalSection();

    mmi_abort();
}


extern "C" void soft_exit( unsigned int nModul, unsigned int nTask, unsigned int nNr, char *pszFile, int nLine )
{
    char szBuffer[1000];
    char szHead[100];

    sprintf( szHead, "SOFT EXIT %02X%01X%01X", nModul, nTask, nNr );
    sprintf( szBuffer, "Modul %02Xh, Task %02Xh (File %s, Zeile %d)", nModul, nTask, pszFile, nLine);
    MOPI_EnterExternalSection();
    print_d( "soft_exit:\n%s\n", szBuffer );
#ifndef JAVA_SDK
    exit_message( szBuffer, szHead );
#endif
    MOPI_LeaveExternalSection();
}

extern "C" void assert_fail( const char *pszText, const char *pszExpr, const char *pszFile, int nLineNo, const char *pszExitval, int nExitcode )
{
    char szBuffer[1000];

    sprintf( szBuffer, "%s:\n%s\nin File %s, Zeile %d\nExitcode %s (%d)\n", pszText, pszExpr, pszFile, nLineNo, pszExitval, nExitcode);
    MOPI_EnterExternalSection();
    print_d( "assert_fail:\n%s\n", szBuffer );
#ifndef JAVA_SDK
    exit_message( szBuffer, "ASSERT FAIL" );
    // mmi_abort();
#endif
    MOPI_LeaveExternalSection();
}



#if ( defined __WIN32__) || ( defined _WIN32)
void resizeConBufAndWindow(HANDLE hConsole, SHORT xSize, SHORT ySize)
{
    CONSOLE_SCREEN_BUFFER_INFO csbi; /* hold current console buffer info */
    BOOL bSuccess;
    SMALL_RECT srWindowRect; /* hold the new console size */
    COORD coordScreen;

    bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
//  PERR(bSuccess, "GetConsoleScreenBufferInfo");
    /* get the largest size we can size the console window to */
    coordScreen = GetLargestConsoleWindowSize(hConsole);
//  PERR(coordScreen.X | coordScreen.Y, "GetLargestConsoleWindowSize");
    /* define the new console window size and scroll position */
    srWindowRect.Right = (SHORT) (min(xSize, coordScreen.X) - 1);
    srWindowRect.Bottom = (SHORT) (min(ySize, coordScreen.Y) - 1);
    srWindowRect.Left = srWindowRect.Top = (SHORT) 0;
    /* define the new console buffer size */
    coordScreen.X = xSize;
    coordScreen.Y = ySize;
    /* if the current buffer is larger than what we want, resize the */
    /* console window first, then the buffer */
    if ((DWORD) csbi.dwSize.X * csbi.dwSize.Y > (DWORD) xSize * ySize)
    {
        bSuccess = SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect);
//      PERR(bSuccess, "SetConsoleWindowInfo");
        bSuccess = SetConsoleScreenBufferSize(hConsole, coordScreen);
//      PERR(bSuccess, "SetConsoleScreenBufferSize");
    }
    /* if the current buffer is smaller than what we want, resize the */
    /* buffer first, then the console window */
    if ((DWORD) csbi.dwSize.X * csbi.dwSize.Y < (DWORD) xSize * ySize)
    {
        bSuccess = SetConsoleScreenBufferSize(hConsole, coordScreen);
//      PERR(bSuccess, "SetConsoleScreenBufferSize");
        bSuccess = SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect);
//      PERR(bSuccess, "SetConsoleWindowInfo");
    }
    /* if the current buffer *is* the size we want, don't do anything! */
    return;
#pragma warn -aus // bsuccess is assigned a value, that is never used
}
#pragma warn +aus
#endif

/*****************************************************************************
* Name: Simu_GetExeInstallPath - Set the path of the executable
*
* Entries:
*       char    *pExePath points to the path of the executable
*       strLen  max path length 
* Returns:
******************************************************************************/
void Simu_GetExeInstallPath(char* pExePath,  UINT16 strLen)
{
    char exePath[WFS_MAX_PATH];
    char *ptrOld;
    char *ptrNew;

    GetModuleFileNameA( NULL, exePath, sizeof( exePath));

    ptrOld = exePath;
    ptrNew = (char*) strrchr( (char*) ptrOld, '\\' );
    *ptrNew = '\0';

    _snprintf( pExePath, strLen, "%s", exePath);
}

/*****************************************************************************
* Name: Simu_GetFilePath - Search a file in the root directory tree and
*                         build the whole path if the file was found.
*
* Description:
*           defaultRoot==True the file is searched in the INSTALL_PATH
*
* Entries:
*       char *name     points to the filename for which the path should be determinated
*       char *path     points to the path of a given filename
*       char *root     points to the root directory in which the file should be searched
*       bool defaultRoot true means that the INSTALL_PATH will be taken as rootpath
* Returns:
*       Returns true if the the file could found and the path could be
*       determinated otherwise false
******************************************************************************/
bool find_path(char * pRootPath, char *pRootQuery, char *path, char *name)
{
    char rootpath[WFS_MAX_PATH];
    char rootquery[WFS_MAX_PATH];
    char subRootpath[WFS_MAX_PATH];
    char subRootQuery[WFS_MAX_PATH];
    char dirPath[WFS_MAX_PATH];
    struct _finddata_t fdata;
    long fd,subfd;
    long retval;

    strcpy(path,pRootPath);
    strcat(path,"\\");
    strcat(path,name);

    retval = _findfirst ( path, &fdata );

    if(retval!=-1)
    { // file is found
        return TRUE;
    }

    strcpy(rootpath,pRootPath);
    strcpy(rootquery,pRootQuery);

    fd = _findfirst ( rootquery, &fdata );

    do
    {
        if( strcspn( fdata.name, ".") > 0 )
        {
            if(fdata.attrib & _A_SUBDIR)
            {//subdirectory
                strcpy(dirPath,rootpath);
                strcat(dirPath,"\\");
                strcat(dirPath,fdata.name);
                subfd = _findfirst ( dirPath, &fdata );
                if(subfd!=-1)
                {
                    _findclose(subfd);

                    strcpy(subRootpath,rootpath);
                    strcat(subRootpath,"\\");
                    strcat(subRootpath,fdata.name);

                    strcpy(subRootQuery,rootpath);
                    strcat(subRootQuery,"\\");
                    strcat(subRootQuery,fdata.name);
                    strcat(subRootQuery,"\\");
                    strcat(subRootQuery,"*.*");

                    strcpy(path,subRootpath);
                    //call the recursiv function for the subdirectory
                    if(find_path(subRootpath, subRootQuery, path, name))
                    {
                        _findclose(fd);
                        return TRUE;
                    }
                }
            }
        }
    }
    while(_findnext(fd, &fdata)!=-1 );
    _findclose(fd);

    return FALSE;
}


bool Simu_GetFilePath(char *path, char *name, char *root, bool defaultRoot)
{
    char rootpath[WFS_MAX_PATH];
    char rootquery[WFS_MAX_PATH];
    int result;

    if (defaultRoot)
    {
        ReadSimulatorRegistryString( "INSTALL_PATH", rootpath, &result);
        if ( result != 0) return FALSE;
    }
    else
    {
        strcpy(rootpath,root);
    }

    strcpy(rootquery,rootpath);
    strcat(rootquery,"\\");
    strcat(rootquery,"*.*");

    if(find_path(rootpath, rootquery, path, name))
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}



BEGIN_MESSAGE_MAP(CMFC_Simulation_App, CWinApp)
    //{{AFX_MSG_MAP(CMFC_Simulation_App)

    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMFC_Simulation_App Konstruktion

CMFC_Simulation_App::CMFC_Simulation_App()
{
}

/////////////////////////////////////////////////////////////////////////////
// Das einzige CMFC_Simulation_App-Objekt

CMFC_Simulation_App theApp;


/////////////////////////////////////////////////////////////////////////////
// CMFC_Simulation_App Initialization

BOOL CMFC_Simulation_App::InitInstance()
{
#ifdef JAVA_SDK
    ::CreateMutexA(NULL,TRUE,RDPINFO_PRODUCT_NAME);
    if(ERROR_ALREADY_EXISTS == GetLastError())//if try to start a second instance of this emulator,exit
    {
        ::MessageBox(NULL,_T("Another Emulator already running. Cannot start a second instance.\n"),
	_T("Emulator start-up Error!"), MB_ICONEXCLAMATION | MB_OK  | MB_SETFOREGROUND);
        return FALSE;
    }
#endif

   // allow process to run on the first CPU only
    SetProcessAffinityMask( GetCurrentProcess(), 1 );

#if PC_SIMU_USE_NEW_UI == 0
    ::AfxMessageBox("The old UI is not Supported anymore!\nPlease set the define 'PC_SIMU_USE_NEW_UI=1'",
                    MB_ICONINFORMATION);
    return FALSE;
#endif
#if _MSC_VER > 1200 // means VC++ 7.0 or higher version

    // Enable3dControls and Enable3dControlsStatic are no longer necessary.
    MainApp::Init(m_hInstance, NULL, m_nCmdShow);  // m_hPrevInstance was omitted in VisualStudio .NET

#else  // means VC++ 6.0 or lower version

    // standard initialization
#ifndef _AFX_NO_CTL3D_SUPPORT
    Enable3dControls();        // use CTL3D32.DLL for 3D controls in dialogs
#ifndef _AFXDLL
    Enable3dControlsStatic();  // statically link CTL3D.LIB instead
#endif
#endif

    MainApp::Init(m_hInstance, m_hPrevInstance, m_nCmdShow);

#endif // _MSC_VER


#ifndef _UNICODE
	if ( !ProcessCommandLine(m_lpCmdLine))
#else
	USES_CONVERSION;
	if ( !ProcessCommandLine(W2A(m_lpCmdLine)))
#endif   
        return FALSE;

    if (mg_nPrintDScreenOutput)
    {
        AllocConsole();
        SetConsoleTitle(_T("Debug Output"));
        hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
        resizeConBufAndWindow(hStdOut, 80, 25);
    }
#if PC_SIMU_USE_NEW_UI
    // To create the main window, this code creates a new frame window
    // object and then sets it as the application's main window object.

    // Initialize OLE libraries
	if (!AfxOleInit())
	{
		return FALSE;
	}

    m_pcMMIDispWindow = NULL;
    m_pcCSDispWindow  = NULL;

    TCHAR*        pszAppName;
    CMainFrame  *pFrame;
    pFrame     = new CMainFrame;
    m_pMainWnd = pFrame;

    // create and load the frame with its resources
    pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW|FWS_ADDTOTITLE, NULL, NULL);

     // Change the name of Simulation
#ifndef JAVA_SDK
    pszAppName = "PC-SIMU";
#else
    TCHAR pszAppNameTmp[128];
    unsigned char * ProductName = Info_GetProductName();
    pszAppName = pszAppNameTmp;
    if(ProductName != NULL){
#if MMI_CHINESE_UI_AVAILABLE
	_stprintf(pszAppName,"Siemens %s (Chinese) Phone Emulator",ProductName);
#else   

#ifndef _UNICODE
	_stprintf(pszAppName,"Siemens %s (International) Phone Emulator",ProductName);
#else
	USES_CONVERSION;
	_stprintf(pszAppName,_T("Siemens %s (International) Phone Emulator"),A2W((LPCSTR)ProductName));
#endif

#endif
    }
    else
        pszAppName = _T("SMTK Phone Emulator");

//    pszAppName = "Siemens Ulysses(International) Phone Simulator";
#endif // JAVA_SDK
#ifndef _UNICODE 
	free((void*)m_pszAppName);
    //@Ba use malloc instead of _tcsdup
    m_pszAppName = (TCHAR*)malloc(_tcslen(pszAppName)+1);

    strcpy( (char*)m_pszAppName, pszAppName );

#endif
    pFrame->SetWindowText(pszAppName);
 
#endif // PC_SIMU_USE_NEW_UI

    return TRUE;
}

extern "C" unsigned __stdcall OS_Start( void* );
extern "C" unsigned OS_Cleanup( void );
extern "C" void OS_Stop( void );

int CMFC_Simulation_App::Run( )
{
    ASSERT_VALID(this);

    // for tracking the idle time state
    BOOL bIdle = TRUE;
    LONG lIdleCount = 0;
    MSG  msg;


// Open XTRACE File
#ifndef JAVA_SDK
    if (xtraceFileName[0] && xtraceUserName[0] && xtraceGenName[0])
    {
        gXTraceOn = TRUE;
        OpenTraceFile( xtraceFileName, xtraceUserName, xtraceGenName );
    }
#endif // JAVA_SDK
   
    OS_Start(0);

    // create camera simulation thread
    CamDevLayer_CreateMainThread();
    
    // start sound simulation thread
    simADD_Startup();

    SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);

    for (;;)
    {
        while (bIdle && !::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE))
        {
            if (!OnIdle(lIdleCount++))
                bIdle = FALSE; 
        }
        do
        {
            // pump message, but quit on WM_QUIT please use the function
            // SetQuitMsgPosted to quit!! (M. Korkmaz)
            if (!::GetMessage(&msg, NULL, NULL, NULL))
                return ExitInstance();
            else
            if (msg.message != WM_KICKIDLE /*&& !AfxPreTranslateMessage(&msg)*/)
            {
                ::TranslateMessage(&msg);
                ::DispatchMessage(&msg);
            }
          
            if (IsIdleMessage(&msg))
            {
                bIdle = TRUE;
                lIdleCount = 0;
            }

        } while (::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE));
    }
    return 0;
}

int CMFC_Simulation_App::ExitInstance()
{
    // stop sound simulation thread
    simADD_Shutdown();

    // end camera simulation thread
    CamDevLayer_ExitMainThread();

    OS_Stop();

    // Close XTRACE File if necessary
#ifndef JAVA_SDK
    if (gXTraceOn == TRUE)
    {
        CloseTraceFile();
    }

    // show memory leaks
    MOPI_ShowMemoryLeaks();
#endif // JAVA_SDK

    OS_Cleanup();

    ShowRestartInfoMessage();

    if (m_pMainWnd != NULL)
        delete m_pMainWnd;

    return CWinApp::ExitInstance();
}

/**
 *  Function to store pointer of MMIDipsWindow object.
 *
 *  @param   *pcMMIDisp: \ref MMIDispWindow
 */
void CMFC_Simulation_App::SetMMIDispWindow(CMMIDispWindow *pcMMIDisp)
{
    m_pcMMIDispWindow = pcMMIDisp;
}

/**
 *  Function to get pointer of MMIDipsWindow object.
 *
 *  @return  *pcMMIDisp: \ref MMIDispWindow
 */
CMMIDispWindow* CMFC_Simulation_App::GetMMIDispWindow(void) const
{
    return m_pcMMIDispWindow;
}

/**
 *  Function to store pointer of ClampShellDipsWindow object.
 *
 *  @param   *pcCSDisp: \ref ClampShellDispWindow
 */
void CMFC_Simulation_App::SetClampShellDispWindow(CClampShellDispWindow *pcCSDisp)
{
    m_pcCSDispWindow = pcCSDisp;
}

/**
 *  Function to get pointer of ClampShellWindow object.
 *
 *  @return  *pcCSDisp: \ref ClampShellDispWindow
 */
CClampShellDispWindow* CMFC_Simulation_App::GetClampShellDispWindow(void) const
{
    return m_pcCSDispWindow;
}

/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////


// User-defined operator new.
void *operator new( size_t stAllocateBlock )
{
    return MOPI_Alloc( stAllocateBlock );
}
void* __cdecl operator new[](size_t nSize)
{
	return ::operator new(nSize);
}
void* __cdecl operator new(size_t nSize, LPCSTR lpszFileName, int nLine)
{
	return ::operator new(nSize);
}
void* __cdecl operator new[](size_t nSize, LPCSTR lpszFileName, int nLine)
{
	return ::operator new(nSize);
}
void* __cdecl operator new(size_t nSize, int nType, LPCSTR lpszFileName, int nLine)
{
	return ::operator new(nSize);
}
void* __cdecl operator new[](size_t nSize, int nType, LPCSTR lpszFileName, int nLine)
{
	return ::operator new(nSize);
}


// User-defined operator delete.
void operator delete( void *pvMem )
{
    MOPI_Free( pvMem );
}
void __cdecl operator delete[](void* p)
{
	::operator delete(p);
}

/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////




