
#define INCL_WINMESSAGEMGR
#define INCL_DOSPROCESS
#define INCL_DOS
#define INCL_DOSERRORS
#define INCL_DOSQUEUES


#include "xheaders.h"


#include XApplication_i
#include XResourceLibrary_i
#include XRect_i
#include XFrame_i
#include XFrameWindow_i
#include XString_i

#include <stdlib.h>


LONG XProcess :: ExecuteProg( char * path, char * args, char * env, ULONG flag, LONG * result)
{
   RESULTCODES rc;
   char error[100];
   XString arg, buffer = path;
   ULONG r;
/*
   if( buffer.FindRev( r, search))
      arg = buffer.Right( buffer.GetLength() - r);
   else*/
   arg = path;

   char set[512];
   strcpy( set, arg);

   char * s = set;
   s += arg.GetLength();
   *s = 0;
   s++;
   *s = ' ';
   s++;
   *s=0;
   if(args)
      strcat( s, args);

   LONG ret = DosExecPgm( error, 100, flag, (PSZ) (char*) set, (PSZ) env, &rc, (PSZ) path);
   if( ret )
      *result = ret;
   else
      *result = rc.codeResult;
   return rc.codeTerminate;
}


BOOL XProcess :: ScanEnvironment( char * valueToSearch, XString * buffer)
{
   PSZ st = (PSZ) "";
   SHORT res = DosScanEnv( (PSZ) valueToSearch,(unsigned char**) &st);
   *buffer = (char*) st;
   return ( res == 0) ? TRUE : FALSE;
}


/*DOC
CLASS XProcess
FUNCTION LoadIcon
REMARKS Load file-related icon.

Parameters:    char * theFile            The filename of the icon to be loaded
               BOOL copy                 If TRUE you get a copy of the icon so changes
                                         have no effect.
                                         Default is TRUE.
Returns:       OOL_ICONHANDLE            The handle of the icon.
*/
OOL_ICONHANDLE XProcess :: LoadIcon ( char * p, BOOL copy)
{
   return WinLoadFileIcon( (PSZ) p, copy);
}


/*DOC
CLASS XProcess
FUNCTION Beep
GROUP misc
REMARKS generates sound
Parameters: LONG frequency               frequency in hertz
            LONG duration                duration in milliseconds
*/
void XProcess :: Beep (LONG f, LONG d)
{
   DosBeep( f, d);
}


/*DOC
CLASS XProcess
FUNCTION Sleep
GROUP misc
REMARKS the current process is suspended for the given time
Parameters: LONG duration                time to sleep
*/
void XProcess :: Sleep (LONG d)
{
   DosSleep( d);
}

/*DOC
CLASS XApplication
FUNCTION XApplication
GROUP constructors/destructors
REMARKS The constructor of XApplication initializes a stand-alone process an creates
a XResourceLibrary with the resources which are linked to the exe-file.
The XResourceLibrary can be accessed with GetResourceLibrary(). If a XApplication
is constructed und youïve set up your mainwindow, call Start() to run the application.
*/
XApplication :: XApplication()
{
   hab = WinInitialize(0);
   queue = WinCreateMsgQueue( hab, 0);
   resLib = new XResourceLibrary( this );
}


/*DOC
CLASS XApplication
FUNCTION ~XApplication
GROUP constructors/destructors
REMARKS destructs the application and the resource library.
WARNING: to terminate an application, call Terminate(), never the destructor!
*/
XApplication :: ~XApplication()
{
   delete resLib;
}


/*DOC
CLASS XApplication
FUNCTION GetResourceLibrary
REMARKS An application creates a resource library when the application is constructed
out of the resources which are binded to the exe-file. GetResourceLibrary returns
the pointer to this resource library.
Returns:     XResourceLibrary *          The XResourceLibrary the application
                                         created when it starts up
*/
/*
XResourceLibrary * XApplication :: GetResourceLibrary(void)
{
   return resLib;
}
*/

/*DOC
CLASS XProcess
FUNCTION QueryForQuit
GROUP initiate/terminate a process
REMARKS if the user try to close this prcess with the tasklist or a system shutdown
is requested this function is called automaticaly. If you want to make a security-check
(for example with XMessageBox), override this method.
Returns:      BOOL canTerminate          return TRUE if the process can be terminated,
                                         otherwise return FALSE. If you return FALSE
                                         a possible system shutdown is canceled.
*/
BOOL XProcess :: QueryForQuit( void )
{
   return TRUE;
}


void XProcess :: Terminate( void )
{
   SHORT i;
   for(i=0; i < windows; i++)
      delete frames[i];
   free ( frames );
   WinDestroyMsgQueue(queue);
   WinTerminate(hab);
}


/*DOC
CLASS XApplication
FUNCTION Terminate
GROUP initiate/terminate a process
REMARKS With this method an application can be terminated. If you
call Terminate() the method QueryForQuit() will not be called.
*/
void XApplication :: Terminate( void )
{
   XProcess::Terminate();
   _exit(0);
}


XProcess :: XProcess( void )
{
   windows = 0;
   frames = NULL;
}


void XProcess :: AddWindow( XFrameWindow * w)
{
   windows += 1;
   frames = (XFrameWindow**) realloc( frames, windows*sizeof(void*));
   frames[windows-1] = w;
}


void XProcess :: RemoveWindow( XFrameWindow * w)
{
   SHORT i;
   BOOL swap = FALSE;

   for(i=0; i < windows - 1; i++)
     {
        if( frames[i] == w)
           swap = TRUE;
        if(swap == TRUE)
           frames[i] = frames[i+1];
     }
   windows -= 1;

   if( windows == 0)
      Terminate();
}


/*DOC
CLASS XProcess
FUNCTION Start
GROUP initiate/terminate a process
REMARKS after a process (XApplication/XThread) is constructed und you have
setup your code, call Start() to make the process work.
*/
void XProcess :: Start( void )
{

   while ( hab )
      {
         WinGetMsg( hab, (PQMSG) &messagequeue, 0, 0, 0);
         if( messagequeue.msg == WM_QUIT)
           {
              if( QueryForQuit() == TRUE)
                  goto out;
              else
                  WinCancelShutdown( queue, FALSE);
           }

         WinDispatchMsg( hab, (PQMSG) &messagequeue );
      }
   out:
      Terminate();
}

