//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Copyright  1998  Microsoft Corporation.  All Rights Reserved.

Module Name:

     tuxmain.cpp  
 
Abstract:
 
	This is file contains the the function needed to set up the
	TUX test enviroment.

 
--*/
#include <windows.h>
#include <tchar.h>
#include <tux.h>
#include <katoex.h>

#include "errmacro.h"

//********************************************************************************************************

extern TESTPROCAPI testUSKeyMapping( UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE );
extern TESTPROCAPI testJapKeyMapping( UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE ); //a-rajtha
extern TESTPROCAPI test_AllKeyboardsinImage( UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE );

extern TESTPROCAPI testARAKeyMapping( UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE );
extern TESTPROCAPI testARA102KeyMapping( UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE );
extern TESTPROCAPI testHEBKeyMapping( UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE );
extern TESTPROCAPI testHINKeyMapping( UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE );
extern TESTPROCAPI testTHAKeyMapping( UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE );

extern TESTPROCAPI Instructions_T( UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE ); //a-rajtha


#define BVT_BASE 10

FUNCTION_TABLE_ENTRY g_lpFTE[] = 
{
    { TEXT("Keyboard Mapping Test"          ), 0,   0,  0,              NULL },
    { TEXT("English Keymap"                 ), 1,   0,  BVT_BASE+40,	testUSKeyMapping },
	{ TEXT("Japanese Keymap"                ), 1,   0,  BVT_BASE+50,    testJapKeyMapping},
    { TEXT("All Keyboards in OS image"      ), 1,   0,  BVT_BASE+60,	test_AllKeyboardsinImage},

	{ TEXT("Arabic (101) Keymap"            ), 1,   0,  BVT_BASE+70,	testARAKeyMapping},
	{ TEXT("Arabic (102) Keymap"            ), 1,   0,  BVT_BASE+71,	testARA102KeyMapping},
	{ TEXT("Hebrew Keymap"                  ), 1,   0,  BVT_BASE+80,	testHEBKeyMapping},
	{ TEXT("Hindi Keymap"                   ), 1,   0,  BVT_BASE+90,	testHINKeyMapping},
	{ TEXT("Thai Keymap"                    ), 1,   0,  BVT_BASE+100,	testTHAKeyMapping},

    { NULL,                                    0,   0,  0,              NULL }  // marks end of list
};


//********************************************************************************************************


#ifdef      UNDER_CE
#define     DebugLog   NKDbgPrintfW
#else
#include    <stdio.h>
#define     DebugLog   printf
#endif

static const LPTSTR cszThisFile = TEXT("TUXMAIN.CPP");
static const LPTSTR cszThisTest = TEXT("Keyboard Mapping Test");


#define     gcszThisFile    cszThisFile




// Global CKato logging object.  Set while processing SPM_LOAD_DLL message.
CKato *g_pKato = NULL;

// Global shell info structure.  Set while processing SPM_SHELL_INFO message.
SPS_SHELL_INFO  g_spsShellInfo;
BOOL            g_fAbortTesting = FALSE;


//#define DEBUG_DLLMAIN
#ifdef  DEBUG_DLLMAIN
 
BOOL WINAPI DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpRes)
{
   switch ( dwReason )
   {
      case DLL_PROCESS_ATTACH:
         DebugLog( TEXT("%s: DLL_PROCESS_ATTACH, hModule = 0x%lx\r\n"), gcszThisFile, hModule);
         break;

      case DLL_THREAD_ATTACH:
         DebugLog( TEXT("%s: DLL_THREAD_ATTACH, hModule = 0x%lx\r\n"), gcszThisFile, hModule);
         break;

      case DLL_PROCESS_DETACH:
         DebugLog( TEXT("%s: DLL_PROCESS_DETACH, hModule = 0x%lx\r\n"), gcszThisFile, hModule);
         break;

      case DLL_THREAD_DETACH:
         DebugLog( TEXT("%s: DLL_THREAD_DETACH, hModule = 0x%lx\r\n"), gcszThisFile, hModule);
         break;

      default:
         DebugLog( TEXT("%s: DllMain default case -- should never happen\r\n"), gcszThisFile, hModule);
         return FALSE;
   }
   return TRUE;
}

#else

BOOL WINAPI DllMain(HANDLE hInstance, ULONG dwReason, LPVOID lpReserved) {
   return TRUE;
} // end BOOL WINAPI DllMain

#endif

/*++
 
ShellProc:
 
	This function provides the interface with the tux shell
 
Arguments:
 
	Standard Tux Shell Arguments
 
Return Value:
 
	Standard Tux Shell return codes
 
Author:

    Unknown (unknown) 
 
Notes:

    Addapted 1/23/97 by Uknown (unknown)
 
--*/

//#define DEBUG_SHELLPROC
#ifdef  DEBUG_SHELLPROC

LPTSTR          ShellMsg2String ( LPTSTR lpMsg, UINT uMsg );
LPTSTR          ShellRet2String ( LPTSTR lpRet, UINT iRet );
SHELLPROCAPI    DebugShellProc  ( UINT uMsg, SPPARAM spParam );

SHELLPROCAPI ShellProc(UINT uMsg, SPPARAM spParam) 
{
    INT iRet;

    DebugLog( TEXT("%s: ENTER ShellProc(), uMsg=%u (%s), spParam=0x%08X.\n\r"),
        gcszThisFile,
        uMsg,
        ShellMsg2String(NULL,uMsg),
        spParam
        );

    iRet = DebugShellProc( uMsg, spParam );

    DebugLog( TEXT("%s: LEAVE ShellProc(), uMsg=%u (%s), spParam=0x%08X, iRet=%u (%s).\n\r"),
        gcszThisFile,
        uMsg,
        ShellMsg2String(NULL,uMsg),
        spParam,
        iRet,
        ShellRet2String(NULL,iRet)
        );

    return iRet;
}

LPTSTR  ShellMsg2String( LPTSTR lpMsg, UINT uMsg )
{
    LPTSTR lpStr;

    switch (uMsg) 
    {
        case SPM_LOAD_DLL:      lpStr = TEXT("SPM_LOAD_DLL    ");    break;
        case SPM_UNLOAD_DLL:    lpStr = TEXT("SPM_UNLOAD_DLL  ");    break;
        case SPM_SHELL_INFO:    lpStr = TEXT("SPM_SHELL_INFO  ");    break;
        case SPM_REGISTER:      lpStr = TEXT("SPM_REGISTER    ");    break;
        case SPM_START_SCRIPT:  lpStr = TEXT("SPM_START_SCRIPT");    break;
        case SPM_STOP_SCRIPT:   lpStr = TEXT("SPM_STOP_SCRIPT ");    break;
        case SPM_BEGIN_GROUP:   lpStr = TEXT("SPM_BEGIN_GROUP ");    break;
        case SPM_END_GROUP:     lpStr = TEXT("SPM_END_GROUP   ");    break;
        case SPM_BEGIN_TEST:    lpStr = TEXT("SPM_BEGIN_TEST  ");    break;
        case SPM_END_TEST:      lpStr = TEXT("SPM_END_TEST    ");    break;
        case SPM_EXCEPTION:     lpStr = TEXT("SPM_EXCEPTION   ");    break;
        default:                lpStr = TEXT("UNKNOWN         ");    break;
   }

   if ( lpMsg )
   {
        _tcscpy( lpMsg, lpStr );
        lpStr = lpMsg;
   }

   return lpStr;
}

LPTSTR  ShellRet2String( LPTSTR lpRet, UINT iRet )
{
    LPTSTR lpStr;

    switch (iRet) 
    {
        case SPR_NOT_HANDLED:  lpStr = TEXT("SPR_NOT_HANDLED ");    break;
        case SPR_HANDLED    :  lpStr = TEXT("SPR_HANDLED     ");    break;
        case SPR_SKIP       :  lpStr = TEXT("SPR_SKIP        ");    break;
        case SPR_FAIL       :  lpStr = TEXT("SPR_FAIL        ");    break;
        default:               lpStr = TEXT("UNKNOWN         ");    break;
   }

   if ( lpRet )
   {
        _tcscpy( lpRet, lpStr );
        lpStr = lpRet;
   }

   return lpStr;
}

SHELLPROCAPI DebugShellProc(UINT uMsg, SPPARAM spParam) 
{
#else

SHELLPROCAPI ShellProc(UINT uMsg, SPPARAM spParam) 
{
#endif

    BOOL    fRtn    = FALSE;
    
    switch (uMsg) 
    {

    case SPM_LOAD_DLL:

        #ifdef UNICODE
        ((LPSPS_LOAD_DLL)spParam)->fUnicode = TRUE;
        #endif
       
        /* ----------------------------------------------------------------
            Get a kato object to do system logging	
        ---------------------------------------------------------------- */
        /*
        *   NOTE: Kato excepts when using new (handled)
        */
//        g_pKato = new CKato( cszThisTest );
        g_pKato = (CKato*)KatoGetDefaultObject();

        if( NULL == g_pKato )
        {
            OutputDebugString( TEXT("FATIAL ERROR: Couldn't get Kato Logging Object") );
            return SPR_FAIL;

        } // end if( NULL == g_pKato )

        //KatoDebug(1, KATO_MAX_VERBOSITY,KATO_MAX_VERBOSITY,KATO_MAX_LEVEL);

        g_pKato->Log( LOG_DETAIL, 
                      TEXT("In %s @ line %d:  %s built on %hs @ %hs ****"), 
                      cszThisFile, __LINE__, 
                      cszThisTest, __DATE__, __TIME__ );

        return SPR_HANDLED;

    case SPM_UNLOAD_DLL:
        return SPR_HANDLED;

    case SPM_SHELL_INFO:
        g_spsShellInfo = *(LPSPS_SHELL_INFO)spParam;
       
        return SPR_HANDLED;

    case SPM_REGISTER:

        ((LPSPS_REGISTER)spParam)->lpFunctionTable = g_lpFTE;
       
        return SPR_HANDLED;

      case SPM_START_SCRIPT:
         return SPR_HANDLED;

      case SPM_STOP_SCRIPT:
         return SPR_HANDLED;

      case SPM_BEGIN_GROUP:
         g_pKato->BeginLevel(0, TEXT("BEGIN GROUP: %s"), cszThisTest );

         return SPR_HANDLED;

      case SPM_END_GROUP:
         g_pKato->EndLevel(TEXT("END GROUP: %s"), cszThisTest );
         
         return SPR_HANDLED;

      case SPM_BEGIN_TEST:

         /* ---------------------------------------------------------------
         	if testing aborted skip all tests.
         --------------------------------------------------------------- */
         g_pKato->BeginLevel(((LPSPS_BEGIN_TEST)spParam)->lpFTE->dwUniqueID, 
                                TEXT("BEGIN TEST: \"%s\", Threads=%u, Seed=%u"),
                                ((LPSPS_BEGIN_TEST)spParam)->lpFTE->lpDescription,
                                ((LPSPS_BEGIN_TEST)spParam)->dwThreadCount,
                                ((LPSPS_BEGIN_TEST)spParam)->dwRandomSeed);

         if( g_fAbortTesting ) return SPR_SKIP;
                                
                                         
         return SPR_HANDLED;

        case SPM_END_TEST:

            g_pKato->EndLevel( TEXT("END TEST: \"%s\" result == %d"),
                                   ((LPSPS_END_TEST)spParam)->lpFTE->lpDescription,
                                   ((LPSPS_END_TEST)spParam)->dwResult );

            if( TPR_ABORT == ((LPSPS_END_TEST)spParam)->dwResult )
            {
                g_pKato->Log( LOG_DETAIL, TEXT("Aborting on %d == %d"),
                              TPR_ABORT, ((LPSPS_END_TEST)spParam)->dwResult );
                g_fAbortTesting = TRUE;

            }

         return SPR_HANDLED;

      case SPM_EXCEPTION:
         g_pKato->Log(LOG_EXCEPTION, TEXT("Exception occurred!"));
         return SPR_HANDLED;
   }

   return SPR_NOT_HANDLED;

} // end ShellProc( ... )
