/*
    Name:           PlayGate Framework Header
    Version:        1.0.0.0
    Header version: 1.0
    Copyright:      Copyright © 2008-2009 PlayGate by PsichiX. All rights reserved.
    Author:         PsichiX
    Description:    PlayGate - GML Security System Framework Header

    PLAYGATE:
              Initiation
              Execute
              ExecuteResult
              ExecuteSuspend
              ExecuteResume
              ReturnDouble
              ReturnChar
              GetResultDouble
              GetResultChar
              ResultCount
              ResultClear
              CheckAllThreads

    Built-in:
              Wait
              C2D
              D2C
              MergeChar
              CheckErrors

    Exported:
              PlayGateReturnDouble
              PlayGateReturnChar
*/

#ifndef _PLAYGATE_H
#define _PLAYGATE_H

#include <windows.h>
#include <windowsx.h>
#include <math.h>
#include <stdarg.h>
#include <list>
//#include "CodeCaroline.h"
#include "GMThreads.h"

#define exportdll extern "C" __declspec(dllexport)

using namespace std;

HWND GMappHandle;
list<double>Tlist;
void Wait(bool statement,int time){
do{Sleep(time);}while(statement==true);}
double _prototype_C2D(char* value){
double val=0;
int i=0;
char chr=255;
while(chr!=0)chr=value[i++];
int len=i;
bool dot=0;
int rest=0;
bool sign=0;
for(i=0;i<len;i++){
chr=value[len-i-1];
if(chr==46)rest=i;
if(chr==45)sign=1;
if(chr>=48)if(chr<=57)val+=pow(10,i)+(chr-48);}
if(sign)val=-val;
if(dot)if(rest>0)val/=pow(10,rest);
return(val);}
double C2D(char* value){
return(strtod(value,NULL));}
char* D2C(char* buff,double value,int length){
return(gcvt(value,length,buff));}
char* MergeChar(char* buff,int count,...){
int i;
int j;
int len=0;
char chr;
char* str;
va_list vl;
va_start(vl,count);
for(i=0;i<count;i++){
str=va_arg(vl,char*);
chr=255;
j=0;
while(chr!=0){
chr=str[j++];
len++;}}
va_end(vl);
buff[0]=0;
va_start(vl,count);
for(i=0;i<count;i++){
strcat(buff,va_arg(vl,char*));}
va_end(vl);
return(buff);}
void CheckErrors(void){
double lerror=GMLThreadLastError();
if(lerror==1)MessageBox(GMappHandle,"Syntax error\nCannot compile given GML code","PlayGate: ERROR!",MB_OK);
if(lerror==2)MessageBox(GMappHandle,"Other game maker error\n(not existing variables/objects, array index out of bounds, etc)","PlayGate: ERROR!",MB_OK);
if(lerror==3)MessageBox(GMappHandle,"Thread exception","PlayGate: ERROR!",MB_OK);}
class PLAYGATE{
public:
list<double> result_double;
list<char*> result_char;
PLAYGATE(void){
result_double.clear();
result_char.clear();}
bool Initiation(double handle){
int _hwnd=(int)handle;
GMappHandle=(HWND)_hwnd;
GMLThreadInit(handle);}
double Execute(int priority,bool suspended,char* code){
double thread=GMLThreadCreate(code);
GMLThreadSetPriority(thread,(double)priority);
if((double)suspended)GMLThreadSuspend(thread);
Tlist.push_back(thread);
CheckErrors();
return(thread);}
bool ExecuteResult(int priority,int _time,char* code){
double rthread=GMLThreadCreate(code);
GMLThreadSetPriority(rthread,(double)priority);
Wait((bool)GMLThreadIsRunning(rthread),1);
Sleep(_time);
CheckErrors();}
double ExecuteSuspend(double thread){
GMLThreadSuspend(thread);}
double ExecuteResume(double thread){
GMLThreadResume(thread);}
double GetResultDouble(void){
list<double>::iterator iterd=result_double.begin();
double resd=*iterd;
result_double.erase(iterd++);
return(resd);}
char* GetResultChar(void){
list<char*>::iterator iterc=result_char.begin();
char* resc=*iterc;
result_char.erase(iterc++);
return(resc);}
double ResultCount(bool type){
if(type==true)return(result_double.size());
if(type==false)return(result_char.size());}
double ResultClear(bool type){
if(type==true)result_double.clear();
if(type==false)result_char.clear();}
double CheckAllThreads(void){
bool active=false;
for(list<double>::iterator itert=Tlist.begin();itert!=Tlist.end();){
if(GMLThreadIsRunning(*itert)==1){
active=true;
itert++;}
else
Tlist.erase(itert++);}
return(active);}
}PlayGate;
exportdll double PlayGateReturnDouble(double value){
PlayGate.result_double.push_back(value);
return(value);}
exportdll char* PlayGateReturnChar(char* value){
PlayGate.result_char.push_back(value);
return(value);}

#endif
