/*  Project Tec3270

         Copyright © 1998-2005. All Rights Reserved.

         SUBSYSTEM:    Tec_WHllApi.ddl library
         FILE:         tec_whllapi.h
         AUTHOR:       Alcindo Ferreira Filho


         OVERVIEW
         ========
         Source file for implementing Tec3270 Win HLL Api library.
*/
/***************************************************************************\
*              Windows HLLAPI functions, types, and definitions            *
*                           Version 1.0                                    *
****************************************************************************/

#include "whllall.h"

// Diagnostics
//DIAG_DEFINE_GROUP(WHllapi32,1,0);

/*
 *  static definitions
 */
static bool initialized = false;
static bool already     = false;
static TecWHllClient* pWHllClient = NULL;
/*
static TModule        tec40Module("Tec40r.dll");
static TApplication*  wHllApiApp   = NULL;
static HINSTANCE  apiInstance = NULL;


extern "C"
{
#ifdef __BORLANDC__
  #pragma argsused
#endif

  // WHLLAPI EntryPoint:
  int WINAPI DllEntryPoint(
             HINSTANCE hInstance,     // Library instance handle.
             unsigned long fdwReason, // Reason this function is being called.
             void * lpReserved )      // Not used.
  {
    int rCode;

    // Perform actions based on the reason for calling.
    switch( fdwReason )
     {
       case DLL_PROCESS_ATTACH:
       // Initialize once for each new process.
       // Return FALSE to fail DLL load.
       apiInstance = hInstance;
       //TRACEX(WHllapi32,0,"WHLLApi32 Win32 DLL was attached ...");

       // If you provide your own version of DLL EntryPoint, make sure
       // you call OwlInitUserDLL to allow OWL to initialize '::Module'
       //

       ::Module   = new TModule(0, hInstance);

       wHllApiApp = new TApplication("WHllApi32", ::Module);

       rCode = OWLInitUserDLL(hInstance, _T("")) ? 1 : 0;

       return rCode;

       case DLL_THREAD_ATTACH:
       // Do thread-specific initialization.
       break;

       case DLL_THREAD_DETACH:
       // Do thread-specific cleanup.
       break;

       case DLL_PROCESS_DETACH:
       // Perform any necessary cleanup.

       //TRACEX(WHllapi32,0,"WHLLApi32 Win32 DLL was detached ...");
       break;
     }
    return 1;
  }
} // extern "C"
*/

/*
 * Initialize WHLLAPI32
 */
int WINAPI
WinHLLAPIStartup(WORD wVersionRequired, LPWHLLAPIDATA lpData)
{
#define MINVERSION  10
#define MAXVERSION  11
  int majorVersion = LOBYTE(wVersionRequired);
  int minorVersion = HIBYTE(wVersionRequired);
  int askedVersion = (majorVersion*10)+minorVersion;
  if ( askedVersion  <=  MAXVERSION )
   {
     if (askedVersion >= MINVERSION)
      {
       if (pWHllClient == NULL)
       {
         HMODULE wHllApiModule = ::GetModuleHandle(WHLLAPINAME);
#if (PORTUGUES == 1)
          pWHllClient = new TecWHllClient(wHllApiModule, ALFFDate::pt_BR);
#elif (ENGLISH == 1)
  			 pWHllClient = new TecWHllClient(wHllApiModule,ALFFDate::en_US);
#else
#error (WHLLAPI.CPP) Language must be defined to PORTUGUES=1 or ENGLISH=1.
#endif
       }
      }
     else return WHLLINVALID;
   }
  else return WHLLVERNOTSUPPORTED;

  if (!pWHllClient->Connect())
    return WHLLSYSNOTREADY;

  lpData->wVersion = pWHllClient->GetVersion();
  lstrcpy(lpData->szDescription,pWHllClient->GetDescription());

  initialized = true;

 return 0;
}

/*
 * WHLLAPI Cleanup
 */
BOOL WINAPI
WinHLLAPICleanup()
{
 if (initialized)
  {
    pWHllClient->WHllCleanup();
    delete pWHllClient;
    pWHllClient = NULL;
    initialized = false;
    return true;
  }
 else return false;
}

/*
 *  WHLLApi commands
 */
void WINAPI
WinHLLAPI(LPWORD lpwCommand, LPSTR lpbyString, LPWORD lpwLength, LPWORD lpwReturnCode)
{
 if (initialized)
  {
         if (!already)
          {
            already = true;
            pWHllClient->WHllCommand(lpwCommand,lpbyString,lpwLength,lpwReturnCode);
            already = false;
          }
         else if (lpwReturnCode)
                  *lpwReturnCode = WHLLALREADY;
         else return;
  }
 else if (lpwReturnCode)
         *lpwReturnCode = WHLLSYSNOTREADY;
 else return;
}

/*
 *  WHLLApi Extended Error
 */
int  WINAPI
WinHLLAPIGetExtendedError(void)
{
 return pWHllClient->WHllGetExtendedError();
}

/*
 *  WHLLApi Asynchronous call (Not yet available)
 */
HANDLE WINAPI
WinHLLAPIAsync(HWND, LPWORD, LPSTR, LPWORD, LPWORD)
{
 // Not available on Tec3270 current version
 return NULL;
}

/*
 *  WHLLApi API Blocking check
 */
BOOL WINAPI
WinHLLAPIIsBlocking(void)
{
 return already; // Shoul restrict to PAUSE, CONNECTPS & similars ?
}

/*
 *  WHLLApi Asynchronous call (Not yet available)
 */
int WINAPI
WinHLLAPICancelAsyncRequest(HANDLE, WORD)
{
 return WHLLALREADY;
}

/*
 *  WHLLApi Cancel previous call that is blocked
 */
int WINAPI
WinHLLAPICancelBlockingCall(void)
{
 if (!already)
  return  WHLLINVALID;
 else
  {
   if (pWHllClient->CancelCurrentTransaction())
     return WHLLCANCEL;
   else return WHLLSYSERROR;
  }
}

/*
 *  WHLLApi Blocking Hooks (Not yet available)
 */
FARPROC WINAPI
WinHLLAPISetBlockingHook(FARPROC)
{
 return NULL;
}

/*
 *  WHLLApi Blocking Hooks (Not yet available)
 */
BOOL WINAPI
WinHLLAPIUnhookBlockingHook(void)
{
 return false;
}


