#include <windows.h>
#include <winuser.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <cstring.h>
#include <dir.h>  // for fnsplit
#include <iostream.h>
#include <shellapi.h>

/*
  itccs.cpp  for Icetips SQL
*/


/*
  To compile for #RUNDLL set __RUNDLL__ to 1
  To compile for Clarion for testing set it to 0
*/
#define __RUNDLL__ 1


extern "C"
{
  // start of dll module
#ifdef __BORLANDC__
  #pragma argsused
#endif

  int WINAPI DllMain( HINSTANCE hInst, /* Library instance handle. */
  unsigned long reason, /* Reason this function is being called. */
  void * lpReserved ) /* Not used. */
  {
    return 1;
  }
  int WINAPI DllEntryPoint( HINSTANCE hInst, unsigned long reason, void * lpReserved )
  {
    return DllMain( hInst, reason, lpReserved );
  }

// end of dll module


/*
====================================================================
      Libray functions, not for use with #RUNDLL
====================================================================
*/


/*
--------------------------------------------------------------------
                   RunProcess
--------------------------------------------------------------------
*/

  int __stdcall __export  RunProcess(char* pE, int w)
  {
   PROCESS_INFORMATION pi;
   STARTUPINFO         si;
   char                cCmdLine[513];
   int                 RetVal;
   DWORD               ErrCode;
   HANDLE              hProc;
   bool                cp;
   #if __RUNDLL__ == 0
   OutputDebugString("RunProcess");
   #endif

   strcpy(cCmdLine,pE);
   ZeroMemory (&si, sizeof(si));
   si.cb = sizeof(si);
   // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/createprocess.asp

   if(CreateProcess(0, cCmdLine, 0, 0, FALSE, 0, 0, 0, &si, &pi))
   {
      // optionally wait for process to finish
      if (w==true){
        // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/waitforsingleobject.asp
        WaitForSingleObject(pi.hProcess, INFINITE);
      }
      CloseHandle(pi.hProcess);
      CloseHandle(pi.hThread);
      cp = true;
    }
    else
      cp = false;
    return(cp);
  }

/*
--------------------------------------------------------------------
                   UnquoteString
--------------------------------------------------------------------
*/

  void __stdcall __export  UnquoteString(char* pS)
  {
    #if __RUNDLL__ == 0
    OutputDebugString("UnquoteString");
    #endif
    char s[1024];
    int   l;
    int   b,e,i,x;

    strcpy(s,pS);
    l = strlen(s) - 1;
    b = 0;
    e = l;
    if (s[0] == 39)
      b = 1;
    if (s[l] == 39)
      e = l;
    x = 0;
    for (i=b; i<e ;i++){
      pS[x] = s[i];
      x++;
    }
    pS[x] = '\0';
    return;
  }


/*
--------------------------------------------------------------------
                   GetResourceMacro
--------------------------------------------------------------------
*/

  void __stdcall __export  GetResourceMacro(char* pS)
  {
    #define RT_ICON  MAKEINTRESOURCE(3);
    pS = RT_ICON;
    return;
    //return(RT_ICON);
  }





/*
====================================================================
      #RUNDLL functions used in Icetips products
====================================================================
*/


  /*
    For the Clarion #RUNDLL this MUST be prototyped as empty
    because the TS compiler passes the parameter address in
    the registry.
  */

/*
--------------------------------------------------------------------
                   RunAssociatedFile
--------------------------------------------------------------------
*/
  #if __RUNDLL__ == 1
  void __stdcall __export  RunAssociatedFile()
  #else
  void __stdcall __export  RunAssociatedFile(char* _InParam)
  #endif
  {
    #if __RUNDLL__ == 1
    int paramLen  = _EAX;
    int paramAddr = _EBX;
    char* _InParam;
    _InParam      = (char*)paramAddr;
    #else
    OutputDebugString("RunAssociatedFile");
    #endif

    char       s[4096];
    HINSTANCE  retcode;
    DWORD      GCD;
    char       lpBuffer[MAX_PATH];
    GCD =  GetCurrentDirectory(
      MAX_PATH,	// size, in characters, of directory buffer
      lpBuffer 	// address of buffer for current directory
    );
    retcode = ShellExecute(GetDesktopWindow(),
                           "open",
                           _InParam,
                           NULL,
                           lpBuffer,
                           SW_SHOWNORMAL);
    return;
  }


/*
--------------------------------------------------------------------
                   PutIniW
--------------------------------------------------------------------
*/

  #if __RUNDLL__ == 1
  void __stdcall __export  PutIniW()
  #else
  void __stdcall __export  PutIniW(char* _InParam)
  #endif
  {
    #if __RUNDLL__ == 1
    int paramLen  = _EAX;
    int paramAddr = _EBX;
    char* _InParam;
    _InParam      = (char*)paramAddr;
    #else
    OutputDebugString("PutIniW");
    #endif
    char *copy    = strdup(_InParam);
    char *section = strtok(copy,",");
    char *entry   = strtok(NULL,",");
    char *value   = strtok(NULL,",");
    char *filen   = strtok(NULL,",");
    WritePrivateProfileString(section,entry,value,filen);
    free(copy);
    return;
  }


/*
--------------------------------------------------------------------
                   SaveConfigFile
--------------------------------------------------------------------
*/

  #if __RUNDLL__ == 1
  void __stdcall __export  SaveConfigFile()
  #else
  void __stdcall __export  SaveConfigFile(char* _InParam)
  #endif
  {
    #if __RUNDLL__ == 1
    int paramLen  = _EAX;
    int paramAddr = _EBX;
    char* _InParam;
    _InParam      = (char*)paramAddr;
    #else
    OutputDebugString("SaveConfigFile");
    #endif

    WritePrivateProfileString("Preserve","Last scheme",_InParam,"itwizardpro.ini");
    return;
  }


/*
--------------------------------------------------------------------
                   SaveDictionaryFile
--------------------------------------------------------------------
*/

  #if __RUNDLL__ == 1
  void __stdcall __export  SaveDictionaryFile()
  #else
  void __stdcall __export  SaveDictionaryFile(char* _InParam)
  #endif
  {
    #if __RUNDLL__ == 1
    int paramLen  = _EAX;
    int paramAddr = _EBX;
    char* _InParam;
    _InParam      = (char*)paramAddr;
    #else
    OutputDebugString("SaveDictionaryFile");
    #endif

    WritePrivateProfileString("Program","Dictionary",_InParam,"itwizardpro.ini");
    return;
  }


/*
--------------------------------------------------------------------
                   GetFileName
--------------------------------------------------------------------
*/

  #if __RUNDLL__ == 1
  void __stdcall __export  GetFileName()
  #else
  void __stdcall __export  GetFileName(char* _InParam)
  #endif
  {
    #if __RUNDLL__ == 1
    int paramLen  = _EAX;
    int paramAddr = _EBX;
    char* _InParam;
    _InParam      = (char*)paramAddr;
    #else
    OutputDebugString("GetFileName");
    #endif

    char drive[1024];
    char dir[1024];
    char file[1024];
    char ext[1024];
    int   fnr;
    fnr = fnsplit(_InParam, drive, dir, file, ext);
    if (strlen(drive)==0 && strlen(dir)==0){
      strcpy(_InParam,".\\");
      strcat(_InParam,file);
      strcat(_InParam,ext);
    }
    else{
      strcpy(_InParam,drive);
      strcat(_InParam,dir);
      strcat(_InParam,file);
      strcat(_InParam,ext);
    }
    return;
  }


/*
--------------------------------------------------------------------
                   GetFileNameOnly
--------------------------------------------------------------------
*/
/*
  This function returns ONLY the filename part of the inputstring,
  i.e. c:\thispath\file.ext will return only "file"
*/

  #if __RUNDLL__ == 1
  void __stdcall __export  GetFileNameOnly()
  #else
  void __stdcall __export  GetFileNameOnly(char* _InParam)
  #endif
  {
    #if __RUNDLL__ == 1
    int paramLen  = _EAX;
    int paramAddr = _EBX;
    char* _InParam;
    _InParam      = (char*)paramAddr;
    #else
    OutputDebugString("GetFileNameOnly");
    #endif

    char drive[1024];
    char dir[1024];
    char file[1024];
    char ext[1024];
    int   fnr;
    fnr = fnsplit(_InParam, drive, dir, file, ext);
    strcpy(_InParam,file);
    return;
  }


/*
--------------------------------------------------------------------
                   ITWGetTempPath
--------------------------------------------------------------------
*/

  #if __RUNDLL__ == 1
  void __stdcall __export  ITWGetTempPath()
  #else
  void __stdcall __export  ITWGetTempPath(char* _InParam)
  #endif
  {
    #if __RUNDLL__ == 1
    int paramLen  = _EAX;
    int paramAddr = _EBX;
    char* _InParam;
    _InParam      = (char*)paramAddr;
    #else
    OutputDebugString("ITWGetTempPath");
    #endif

    const buflen = 1024;
    char  tempdir[buflen];
    int   ul;

    ul = GetTempPath(buflen,tempdir);
    OutputDebugString(tempdir);
    strcpy(_InParam,tempdir);

    return;
  }


/*
--------------------------------------------------------------------
                   ITWGetTempFilename
--------------------------------------------------------------------
*/

  #if __RUNDLL__ == 1
  void __stdcall __export  ITWGetTempFilename()
  #else
  void __stdcall __export  ITWGetTempFilename(char* _InParam)
  #endif
  {
    #if __RUNDLL__ == 1
    int paramLen  = _EAX;
    int paramAddr = _EBX;
    char* _InParam;
    _InParam      = (char*)paramAddr;
    #else
    OutputDebugString("ITWGetTempFilename");
    #endif

    const buflen = 1024;
    char  tempdir[buflen];
    int   ui,ul;
    char  temppre[4];
    int   tempu;
    char  tempfile[1024];

    char  drive[1024];
    char  dir[1024];
    char  file[1024];
    char  ext[1024];

    int   fnr;

    OutputDebugString("ITWGetTempFilename");
    tempu = 0;
    if (strlen(_InParam)== 0){
      strcpy(_InParam,"ITP");
    }
    strcpy(temppre,_InParam);
    ul = GetTempPath(buflen,tempdir);
    ui = GetTempFileName(tempdir, temppre, tempu, tempfile);
    fnr = fnsplit(tempfile, drive, dir, file, ext);
    strcpy(tempfile,drive);
    strcat(tempfile,dir);
    strcat(tempfile,file);
    strcpy(_InParam,tempfile);
    // returns the temp filename _without_ the extension.
    return;
  }


/*
--------------------------------------------------------------------
                   wDebug
--------------------------------------------------------------------
*/

  #if __RUNDLL__ == 1
  void __stdcall __export  wDebug()
  #else
  void __stdcall __export  wDebug(char* _InParam)
  #endif
  {
    #if __RUNDLL__ == 1
    int paramLen  = _EAX;
    int paramAddr = _EBX;
    char* _InParam;
    _InParam      = (char*)paramAddr;
    #else
    OutputDebugString("wDebug");
    #endif

    OutputDebugString(_InParam);
    return;
  }


/*
--------------------------------------------------------------------
                   ProCheckTXA
--------------------------------------------------------------------
*/

  #if __RUNDLL__ == 1
  void __stdcall __export  ProCheckTXA()
  #else
  void __stdcall __export  ProCheckTXA(char* _InParam)
  #endif
  {
    #if __RUNDLL__ == 1
    int paramLen  = _EAX;
    int paramAddr = _EBX;
    char* _InParam;
    _InParam      = (char*)paramAddr;
    #else
    OutputDebugString("ProCheckTXA");
    #endif
    const     BufSize = 1024;
    DWORD     gpfs;
    char      lpAppName[BufSize];
    char      lpKeyName[BufSize];
    char      lpDefault[BufSize];
    char      lpReturnedString[BufSize];
    DWORD     nSize = BufSize;
    char      lpFileName[BufSize];

    strcpy(lpAppName,"Program");
    strcpy(lpKeyName,"DataPath");
    strcpy(lpDefault,"");
    strcpy(lpFileName,"itwizardpro.ini");
    gpfs = GetPrivateProfileString(lpAppName,
                                   lpKeyName,
                                   lpDefault,
                                   lpReturnedString,
                                   nSize,
                                   lpFileName);
    strcat(lpReturnedString,"itwizpro.exe \"99\"");
    if (RunProcess(lpReturnedString, true)==false){
      MessageBox(0,"Could not run the wizard","Error",0);
      strcpy(lpKeyName,"DllReturn");
      char *value = "ERROR";
      WritePrivateProfileString(lpAppName,lpKeyName,value,lpFileName);
      strcpy(_InParam,"ERROR");
    }
    else{
      strcpy(_InParam,"");
    }
    return;
  }


  /*
  --------------------------------------------------------------------
                     ReporterSelectLayout
  --------------------------------------------------------------------
  */

    #if __RUNDLL__ == 1
    void __stdcall __export  ReporterSelectLayout()
    #else
    void __stdcall __export  ReporterSelectLayout(char* _InParam)
    #endif
    {
      #if __RUNDLL__ == 1
      int paramLen  = _EAX;
      int paramAddr = _EBX;
      char* _InParam;
      _InParam      = (char*)paramAddr;
      #else
      OutputDebugString("ReporterSelectLayout");
      #endif
      const     BufSize = 1024;

      FILE      *fp;
      char      fname[BufSize];
      DWORD     gpfs;
      char      lpAppName[BufSize];
      char      lpKeyName[BufSize];
      char      lpDefault[BufSize];
      char      lpReturnedString[BufSize];
      DWORD     nSize = BufSize;
      char      lpFileName[BufSize];

      strcpy(fname,_InParam);
      strcat(fname,".txa");

      strcpy(lpAppName,"Program");
      strcpy(lpKeyName,"Location");
      strcpy(lpDefault,"itrexe.exe");
      strcpy(lpFileName,"itreport.ini");
      gpfs = GetPrivateProfileString(lpAppName,
                                     lpKeyName,
                                     lpDefault,
                                     lpReturnedString,
                                     nSize,
                                     lpFileName);

      strcat(lpReturnedString," \"");
      strcat(lpReturnedString,_InParam);
      strcat(lpReturnedString," \"");
      if (RunProcess(lpReturnedString, true)==false){
        MessageBox(0,"The Icetips Wizard could not be run.  Please contact wizard@icetips.com if this condition persist.","Error executing program",0);
        if ((fp = fopen(fname,"w")) != NULL){
          strcpy(lpReturnedString,"CANCEL");
          fputs(lpReturnedString,fp);
          fclose(fp);
        }
      }
      strcpy(lpAppName,"Parameters");
      strcpy(lpKeyName,"Back");
      strcpy(lpDefault,"");
      strcpy(lpFileName,"itreport.ini");
      gpfs = GetPrivateProfileString(lpAppName,
                                     lpKeyName,
                                     lpDefault,
                                     lpReturnedString,
                                     nSize,
                                     lpFileName);
      strcpy(_InParam,lpReturnedString);
      return;
    }


/*
--------------------------------------------------------------------
                   UsingLargeFonts
--------------------------------------------------------------------
*/

  #if __RUNDLL__ == 1
  void __stdcall __export  UsingLargeFonts()
  #else
  void __stdcall __export  UsingLargeFonts(char* _InParam)
  #endif
  {
    #if __RUNDLL__ == 1
    int paramLen  = _EAX;
    int paramAddr = _EBX;
    char* _InParam;
    _InParam      = (char*)paramAddr;
    #else
    OutputDebugString("UsingLargeFonts");
    #endif
    char   IsLarge[1];
    HWND   hWnd;
    HDC    dc;
    int    res;

    hWnd = GetDesktopWindow();
    dc   = GetDC(hWnd);
    strcpy(IsLarge,"1");
    if (GetDeviceCaps(dc, LOGPIXELSX) == 96) {
      strcpy(IsLarge,"0");
    }
    res = ReleaseDC(hWnd, dc);
    strcpy(_InParam,IsLarge);
    return;
  }


  // end of dll module
}


