#include "xapp.h"
#include "xreslib.h"
#include "xrect.h"
#include "xframe.h"
#include "xfrmwnd.h"
#include "xstring.h"
#include "xmsgbox.h"
#include "xcountry.h"
#include "xexcept.h"

#include <stdlib.h>

//for emx only
#if !defined(__IBMCPP__) && !defined(__WATCOMC__)
void terminate(void)
{

}

#endif


/*@ 
@class XProcess
@type overview
@symbol _
@remarks XProcess is the parent class for XApplication and XThread, you cannot create an instance
of XProcess, you have to chose one the child classes. This classes should only be used if you need
window-management.<BR>
XProcess and derived is killed automaticaly if you use windows and/or dialogs: it counts the opened dialogs
and windows, if the last window/dialog is closed the thread/application is terminated. If you dont open dialogs
or windows you need to terminate the application/thread yourself.
*/

void XProcess:: LeaveCriticSection()
{
	ULONG rc = DosExitCritSec();
	if(rc)
		OOLThrow( "Error in critical section", rc);
}


void XProcess:: EnterCriticSection()
{
	ULONG rc = DosEnterCritSec();
	if(rc)
		OOLThrow( "Error in critical section", rc);
}


/*@ XProcess :: ExecuteProg( const char * path, const char * args, const char * env, const ULONG flag, LONG * result)
@group misc
@remarks Executes a program
@parameters <t 'ø' c=2>
				øchar * path				øpath/file to execute
            øchar * args				øarguments (can be NULL)
				øchar * environment	øenviroment for the program (can be NULL)
				øULONG flags				øflags (see DosExecPgm)
				øLONG * buffer			øbuffer for return-code of the program
				</t>
@returns    LONG return-code 		from the system
*/
LONG XProcess::ExecuteProg(const char *path, const char *args, const char *env, const ULONG flag, LONG * result)
{
	RESULTCODES rc;
	char error[100];
	XString buffer = path;

	char set[512];

	strcpy(set, path);

	char *s = set;

	s += strlen(path);
	*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;
}


/*@ XProcess :: ScanEnvironment( const char * valueToSearch, XString * buffer)
@group misc
@remarks Scan a value from the environment ( SET-entry of the config.sys )
@parameters <t 'ø' c=2>
				øchar * valueToSearch    øthe name of the value (eg. PATH)
            øXString * buffer        øbuffer to hold the data
				</t>
@returns    BOOL success
*/
BOOL XProcess::ScanEnvironment(const char *valueToSearch, XString * buffer)
{
	PSZ st = (PSZ) "";
	SHORT res = DosScanEnv((PSZ) valueToSearch, (PCSZ *) & st);

	if (res == 0)
		*buffer = (char *) st;
	return (res == 0) ? TRUE : FALSE;
}


/*@ XProcess :: Beep( const LONG f, const LONG d)
@group misc
@remarks Make some noise
@parameters <t 'ø' c=2>
			  øLONG frequency               øfrequency in hertz
           øLONG duration                øduration in milliseconds
				</t>
*/
void XProcess::Beep(const LONG f, const LONG d)
{
	DosBeep(f, d);
}


/*@ XProcess :: Sleep( const LONG d)
@group misc
@remarks The current process is suspended for the given time
@parameters LONG duration                time to sleep in milliseconds
*/
void XProcess::Sleep(const LONG d)
{
	DosSleep(d);
}


/*@
@class XApplication
@parent XProcess
@type overview
@symbol _
*/


/*@ XApplication :: 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);
}


/*@ XApplication :: ~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;
}


/*@ XApplication :: 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
*/


/*@ XProcess :: QueryForQuit( void )
@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;
}


/*@ XProcess::Terminate()
@group initiate/terminate a process
@remarks Terminate a running process
*/
void XProcess::Terminate(void)
{
	SHORT i;

	for (i = 0; i < windows - 1; i++)
		delete frames[i];

	if (frames)
		free(frames);

	windows = 0;

	WinDestroyMsgQueue(queue);
	WinTerminate(hab);
}


/*@ XApplication :: Terminate( void )
@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(const XWindow * w)
{
	windows += 1;
	frames = (XWindow **) realloc(frames, windows * sizeof(void *));
	frames[windows - 1] = (XWindow *) w;
}


void XProcess::RemoveWindow(const XWindow * 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();
}


/*@ XProcess :: Start( void )
@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 (1)
	{
		WinGetMsg(hab, &messagequeue, 0, 0, 0);
		if (messagequeue.msg == WM_QUIT)
		{
			if (QueryForQuit() == TRUE)
				goto out;
			else
				WinCancelShutdown(queue, FALSE);
		}
		WinDispatchMsg(hab, &messagequeue);
	};
out:
	Terminate();
}


/*@ XCountryInfo :: XCountryInfo()
@group constructors/destructors
@remarks Query information about the country from the system
*/
XCountryInfo :: XCountryInfo()
{
	COUNTRYCODE countryCode = {0};
	ULONG infoLen = 0;

	DosQueryCtryInfo(sizeof(cInfo), &countryCode, &cInfo, &infoLen);
}


//Docs only

/*@ XCountryInfo::GetDateFormat
@remarks  Query the format of a date value
@returns 0	format is ddmmyy<BR>
		  1	format is ddmmyy<BR>
		  2	format is yymmdd
*/


/*@ XCountryInfo::GetCountry
@remarks Query the country
@returns ID of the country:
<t 'ø' 2>
øAsian English                 ø099       
øAustralia                     ø061       
øBelgium                       ø032       
øCanadian French               ø002       
øCzechoslovakia                ø042       
øDenmark                       ø045       
øFinland                       ø358       
øFrance                        ø033       
øGermany                       ø049       
øHungary                       ø036       
øIceland                       ø354       
øItaly                         ø039       
øJapan                         ø081       
øJapan  SAA                    ø081       
øKorea                         ø082       
øKorea  SAA                    ø082       
øLatin America                 ø003       
øNetherlands                   ø031       
øNorway                        ø047       
øPeople's Republic of China    ø086       
øPoland                        ø048       
øPortugal                      ø351       
øSpain                         ø034       
øSweden                        ø046       
øSwitzerland                   ø041       
øTaiwan                        ø088       
øTurkey                        ø090       
øUnited Kingdom                ø044       
øUnited States                 ø001       
øYugoslavia                    ø038       	  
</t>
*/


/*@ XCountryInfo::XCountryInfo()
@remarks Constructor needed to query some information about the current country.
*/

/*@ XPoint::XPoint(LONG, LONG)
@remarks Construct a coordinate
@parameters LONG xPosition<BR>
LONG yPosition
*/


/*@ XPoint::GetX()
@remarks Query the x-position
@returns LONG xPosition
*/

/*@ XPoint::GetY()
@remarks Query the y-position
@returns LONG yPosition
*/

/*@ XPoint::SetX(LONG)
@remarks Set the x-position
@parameters LONG xPosition
*/

/*@ XPoint::SetY(LONG)
@remarks Set the y-position
@parameters LONG yPosition
*/


/*@
@class XRect
@parent XPoint
@type overview
@symbol _
*/

/*@ XRect::XRect(LONG, LONG, LONG, LONG)
@remarks Construct a rectangle
@parameters LONG xPosition<BR>LONG yPosition<BR>LONG width<BR>LONG height
*/

/*@ XRect::SetHeight(LONG)
@remarks Set the height
@parameters LONG height
*/

/*@ XRect::SetWidth(LONG)
@remarks Set the width
@parameters LONG width
*/

/*@ XRect::GetWidth()
@remarks Query the width
@returns LONG width
*/

/*@ XRect::GetHeight()
@remarks Query the height
@returns LONG heigth
*/

/*@ XSize::XSize(LONG width, LONG height)
@remarks Construct a size-description
@parameters LONG width<BR>LONG height
*/

/*@ XSize::GetWidth()
@remarks Query the width
@returns LONG width
*/

/*@ XSize::GetHeight()
@remarks Query the height
@returns LONG heigth
*/

/*@ XSize::SetHeight(LONG)
@remarks Set the height
@parameters LONG height
*/

/*@ XSize::SetWidth(LONG)
@remarks Set the width
@parameters LONG width
*/

