#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <ctime>

#ifdef _WIN32
#include <windows.h>
#else
#include <sys/types.h>
#include <dirent.h>
#endif

#include "seeGScript.h"

//extern void query_keyboard(unsigned char,int,int);
//extern void query_mouse(int,int,int,int);

using namespace std;

/**************
 * Convienent list of function and variable names
**************/

const char *GSC[] =
    {"For",      //0
     "EndFor",
     "If",
	 "ElseIf",
	 "Else",     //4
	 "EndIf",
	 "Load",
	 "Screenshot",
	 "Quit",
	 "writeKaryo", //9
	 "Increment",
	 "getMinMax",
	 "local0",     //locals 12
	 "local1",
	 "local2",     //14
	 "local3",
	 "local4",
	 "local5",
	 "local6",
	 "local7",   //19
	 "local8",
	 "local9",
	 "displayThresh",
	 "saveAndExit",
	 "scriptWaitTime", //24
	 "currentQuery",
	 "fltQuery",
	 "zoom",
	 "featureColors",
	 "numQueries", //29
	 "Mouse",
	 "KeyBoard", 
	 "threshold",
	 "SpecialKeyboard",
	 "QueryKeyboard", //34
	 "QueryMouse"};

bool isScripting = false;
bool RecordActions = false;
clock_t ScriptStartTime = 0;
float scriptWaitTime = 3;
structScriptData SD;
bool firstLoad = false;

//Helpers
int CreateArgs(char *, char***);
void SetVar(char *,float);
/**********************
 * SetVar
 * --Used to set variables within SeeGraph,
 *  this function must be changed when wanting
 *  to set variables via scripts.
 *  ***********************/
float GetValue(char *);
/**********************
 * GetValue
 * --This looks up values of variables 
 *  before assuming the input is a float
 *  This must be changed if you want to use
 *  variables as values in the script
************************/

void InitRecordScript()
{
	ofstream fptr;
	//Maybe we should add a timestamp to the filename
	fptr.open("recorded.sgs",ios::out | ios::trunc);
	fptr.close();
	RecordActions = true;
}

void RecordScript_SpecialKeyboard(int value, int x, int y)
{
	ofstream fptr;
	fptr.open("recorded.sgs",ios::out | ios::app);
	if(fptr.is_open())
	{
		fptr << "SpecialKeyboard " << value << " " << x << " " << y << "\n";
		fptr.close();
	}
}
void RecordScript_QueryKeyboard(unsigned char key, int x, int y)
{
	ofstream fptr;
	fptr.open("recorded.sgs",ios::out | ios::app);
	if(fptr.is_open())
	{
		fptr << "QueryKeyboard " << key << " " << x << " " << y << "\n";
		fptr.close();
	}
}
void RecordScript_QueryMouse(int button, int state, int x, int y)
{
	ofstream fptr;
	fptr.open("recorded.sgs",ios::out | ios::app);
	if(fptr.is_open())
	{
		fptr << "QueryMouse " << button << " " << state << " " << x << " " << y << "\n";
		fptr.close();
	}
}

void RecordScript_Load(char **argv, int argc, int f)
{
	int x;
	ofstream fptr;
	fptr.open("recorded.sgs",ios::out | ios::app);
	if(fptr.is_open())
	{
		fptr << argv[f] << "\n";
		fptr << "Load ";
		for(x=1;x<argc;x++)
		{
			if(x == f)
				fptr << "0 ";
			else
				fptr << argv[x] << " ";
		}
		fptr << "\n";
		fptr.close();
	}
}

void RecordScript_Keyboard(unsigned char key, int x, int y)
{
	ofstream fptr;
	fptr.open("recorded.sgs",ios::out | ios::app);
	if(fptr.is_open())
	{
		fptr << "Keyboard " << key << " " << x << " " << y << "\n";
		fptr.close();
	}
}

void RecordScript_Mouse(int button, int bstate, int x, int y)
{
	ofstream fptr;
	fptr.open("recorded.sgs",ios::out | ios::app);
	if(fptr.is_open())
	{
		fptr << "Mouse " << button << " " << bstate << " " << x << " " << y << "\n";
		fptr.close();
	}
}

void seeGraphScript()
{
	int x;
	char **args;

	
	if(SD.CurrentLine >= SD.numLines)
	{ isScripting = false; return; }
	
	if(SD.argCount[SD.CurrentLine] == 0)
	{SD.PreviousLine = SD.CurrentLine; SD.CurrentLine++; return;}
	
	//Display Script Line
	for(x=0;x<SD.argCount[SD.CurrentLine];x++)
		cout << SD.Lines[SD.CurrentLine][x] << " ";
	cout << endl;

	//Flow Control Processing
	/*---For---*/
	if(!strcmp(SD.Lines[SD.CurrentLine][0],GSC[0])) //"For var start end step"
	{
		if(SD.argCount[SD.CurrentLine] > 4)
		{
			if(SD.PreviousLine<SD.CurrentLine)
				SetVar(SD.Lines[SD.CurrentLine][1],GetValue(SD.Lines[SD.CurrentLine][2]));
			else
				SetVar(SD.Lines[SD.CurrentLine][1],GetValue(SD.Lines[SD.CurrentLine][1]) + GetValue(SD.Lines[SD.CurrentLine][4]));
			if( (GetValue(SD.Lines[SD.CurrentLine][1]) > GetValue(SD.Lines[SD.CurrentLine][3]) && 
				 GetValue(SD.Lines[SD.CurrentLine][4]) > 0.0) ||  
				(GetValue(SD.Lines[SD.CurrentLine][1]) < GetValue(SD.Lines[SD.CurrentLine][3]) &&
				 GetValue(SD.Lines[SD.CurrentLine][4]) < 0.0))
			{
				SD.PreviousLine = SD.CurrentLine;
				SD.CurrentLine = SD.LineJump[SD.CurrentLine]; 
				return;
			}
			else
			{
				SD.PreviousLine = SD.CurrentLine;
				SD.CurrentLine++;
				return;
			}
		}
			
	}
	/*---EndFor---*/
	else if(!strcmp(SD.Lines[SD.CurrentLine][0],GSC[1]))
	{
		SD.PreviousLine = SD.CurrentLine;
		SD.CurrentLine = SD.LineJump[SD.CurrentLine]; 
		return;
	}
	/*---If---ElseIf---*/
	else if(!strcmp(SD.Lines[SD.CurrentLine][0],GSC[2]) || !strcmp(SD.Lines[SD.CurrentLine][0],GSC[3])) //If Var {<,=,>} Var
	{
		if(SD.argCount[SD.CurrentLine] > 3)
		{
			if(!strcmp(SD.Lines[SD.CurrentLine][2],"<"))
			{
				if(!(GetValue(SD.Lines[SD.CurrentLine][1]) < GetValue(SD.Lines[SD.CurrentLine][3])))
				{
					SD.PreviousLine = SD.CurrentLine;
					SD.CurrentLine = SD.LineJump[SD.CurrentLine]; 
					return;
				}
			}
			else if(!strcmp(SD.Lines[SD.CurrentLine][2],"="))
			{
				if(!(GetValue(SD.Lines[SD.CurrentLine][1]) == GetValue(SD.Lines[SD.CurrentLine][3])))
				{
					SD.PreviousLine = SD.CurrentLine;
					SD.CurrentLine = SD.LineJump[SD.CurrentLine]; 
					return;
				}
			}
			else
			{
				if(!(GetValue(SD.Lines[SD.CurrentLine][1]) > GetValue(SD.Lines[SD.CurrentLine][3])))
				{
					SD.PreviousLine = SD.CurrentLine;
					SD.CurrentLine = SD.LineJump[SD.CurrentLine]; 
					return;
				}
			}
			SD.PreviousLine = SD.CurrentLine;
			SD.CurrentLine++;
			return;
		}
	}

	//Functions
	/*---Load---*/
	else if(!strcmp(SD.Lines[SD.CurrentLine][0],GSC[6]))
	{
		if(firstLoad == false)
			firstLoad = true;
		
		//Create Args
		args = (char **) malloc(sizeof(char *) * (SD.argCount[SD.CurrentLine]));
		if(args == NULL)
		{
			perror("malloc");
			exit(1);
		}
		args[1] = SD.DataSets[(int)GetValue(SD.Lines[SD.CurrentLine][1])];
		for(x = 2; x<SD.argCount[SD.CurrentLine];x++)
			args[x] = SD.Lines[SD.CurrentLine][x];
		initData(SD.argCount[SD.CurrentLine], args);
		free(args);
	}
	/*---Screenshot---*/
	else if(!strcmp(SD.Lines[SD.CurrentLine][0],GSC[7]))
	{
		if(pixFile!=NULL) free(pixFile);
		if(SD.argCount[SD.CurrentLine] > 1)
			pixFile = (char*)malloc((11+strlen(SD.Lines[SD.CurrentLine][1]))*sizeof(char));
		else
			pixFile = (char*)malloc(10*sizeof(char));
		if(pixFile == NULL)
			perror("pixfile");
		if(SD.argCount[SD.CurrentLine] > 1)
			sprintf(pixFile,"%s.%d.bmp",SD.Lines[SD.CurrentLine][1],pixCount);
		else
			sprintf(pixFile,"%d.bmp",pixCount);
		takeScreenshot(pixFile);
		pixCount++;
		free(pixFile);											  
	}
	/*---quit---*/
	else if(!strcmp(SD.Lines[SD.CurrentLine][0],GSC[8]))
		exit(0);
	/*---writeKaryo---*/
	else if(!strcmp(SD.Lines[SD.CurrentLine][0],GSC[9]))
	{
		if(karFile!=NULL) free(karFile); 
		if(SD.argCount[SD.CurrentLine] > 1)
			karFile = (char*)malloc((64+strlen(SD.Lines[SD.CurrentLine][1]))*sizeof(char));
		else
			karFile = (char*)malloc(64*sizeof(char));
		if(karFile == NULL)
			perror("karfile");
		if(SD.argCount[SD.CurrentLine] > 1)
			sprintf(karFile,"%s.%d.bmp",SD.Lines[SD.CurrentLine][1],karCount);
		else
			sprintf(karFile,"%d.bmp",karCount);
		writeKaryo(karFile,g,tlut,featureColors);
		karCount++;
		free(karFile);
		karFile = NULL;
	}
	/*---Increment---*/
	else if(!strcmp(SD.Lines[SD.CurrentLine][0],GSC[10]))
	{
		if(SD.argCount[SD.CurrentLine] > 2)
			SetVar(SD.Lines[SD.CurrentLine][1], GetValue(SD.Lines[SD.CurrentLine][1]) + GetValue(SD.Lines[SD.CurrentLine][2]));
	}
	/*---getMinMax---*/
	else if(!strcmp(SD.Lines[SD.CurrentLine][0],GSC[11]))
	{
		if(SD.argCount[SD.CurrentLine] > 1)
			getMinMax(g,(int)GetValue(SD.Lines[SD.CurrentLine][1]),&(SD.localVariables[8]),&(SD.localVariables[9]));
	}
	/*---fltQuery---*/
	else if(!strcmp(SD.Lines[SD.CurrentLine][0],GSC[26]))
	{
		if(SD.argCount[SD.CurrentLine] > 3)
		{
			g->fltQuery[(int)GetValue(SD.Lines[SD.CurrentLine][1])][(int)GetValue(SD.Lines[SD.CurrentLine][2])] = GetValue(SD.Lines[SD.CurrentLine][3]);
			queryChanged();
		}

	}
	/*---Mouse---*/
	else if(!strcmp(SD.Lines[SD.CurrentLine][0],GSC[30]))
	{
		if(SD.argCount[SD.CurrentLine] > 4)
			mouseHandler((int) GetValue(SD.Lines[SD.CurrentLine][1]), 
					     (int) GetValue(SD.Lines[SD.CurrentLine][2]),
						 (int) GetValue(SD.Lines[SD.CurrentLine][3]), 
						 (int) GetValue(SD.Lines[SD.CurrentLine][4]));
	}
	/*---Keyboard---*/
	else if(!strcmp(SD.Lines[SD.CurrentLine][0],GSC[31]))
	{
		if(SD.argCount[SD.CurrentLine] > 3)
			glutKeyboard(SD.Lines[SD.CurrentLine][1][0],
					(int) GetValue(SD.Lines[SD.CurrentLine][2]), 
					(int) GetValue(SD.Lines[SD.CurrentLine][3]));
	}
	/*---SpecialKeyboard---*/
	else if(!strcmp(SD.Lines[SD.CurrentLine][0],GSC[33]))
	{
		if(SD.argCount[SD.CurrentLine] > 3)
			glutSpecial((int) GetValue(SD.Lines[SD.CurrentLine][1]),
					(int) GetValue(SD.Lines[SD.CurrentLine][2]), 
					(int) GetValue(SD.Lines[SD.CurrentLine][3]));
	}
	/*---QueryKeyboard---*/
	/*else if(!strcmp(SD.Lines[SD.CurrentLine][0],GSC[34]))
	{
		if(SD.argCount[SD.CurrentLine] > 3)
			query_keyboard(SD.Lines[SD.CurrentLine][1][0],
					(int) GetValue(SD.Lines[SD.CurrentLine][2]), 
					(int) GetValue(SD.Lines[SD.CurrentLine][3]));
	}*/
	/*---QueryMouse---*/
	/*else if(!strcmp(SD.Lines[SD.CurrentLine][0],GSC[35]))
	{
		if(SD.argCount[SD.CurrentLine] > 4)
			query_mouse((int) GetValue(SD.Lines[SD.CurrentLine][1]), 
					     (int) GetValue(SD.Lines[SD.CurrentLine][2]),
						 (int) GetValue(SD.Lines[SD.CurrentLine][3]), 
						 (int) GetValue(SD.Lines[SD.CurrentLine][4]));
	}*/
	/*---Variables---*/
	else if(SD.argCount[SD.CurrentLine] > 1)
		SetVar(SD.Lines[SD.CurrentLine][0],GetValue(SD.Lines[SD.CurrentLine][1]));

	//Update Current Line
	SD.PreviousLine = SD.CurrentLine;
	if(SD.LineJump[SD.CurrentLine] == 0)
		SD.CurrentLine++;
	else
		SD.CurrentLine = SD.LineJump[SD.CurrentLine];
	if(SD.CurrentLine >= SD.numLines) //End of script
		isScripting = false;
}

void InitSeeGScript(char *filename)
{
	int x,y;
	char scriptCommand[256];
	char **args;
	int argCount;
	ifstream fptr;

	/*Init ScriptData Struct*/

	fptr.open(filename);
	
	//How many Lines
	SD.numLines = 0;
	while(fptr.getline(scriptCommand,256))
		SD.numLines++;

	SD.Lines = (char ***) malloc(SD.numLines * sizeof(char **));
	if(SD.Lines == NULL)
	{
		perror("malloc");
		exit(1);
	}
	SD.argCount = (int *) malloc(SD.numLines * sizeof(int));
	if(SD.argCount == NULL)
	{
		perror("malloc");
		exit(1);
	}
	SD.LineJump = (int *) malloc(SD.numLines * sizeof(int));
	if(SD.LineJump == NULL)
	{
		perror("malloc");
		exit(1);
	}

	//Rewind and start reading
	fptr.close();
	fptr.open(filename);
	x = 0; y = 0;
	while(fptr.getline(scriptCommand,256))
	{
		x++;
		argCount = CreateArgs(scriptCommand, &args);
		SD.Lines[x-1] = args;
		SD.argCount[x-1] = argCount;
		//Read Data Sets		
		if(x == 1)
		{
			SD.numDataSets = 0;
#ifdef _WIN32
			WIN32_FIND_DATA f;
			HANDLE h;
			int z,z1;
			for(z=0;z<argCount;z++)
			{
				h = FindFirstFile(args[z],&f);
				if(h == INVALID_HANDLE_VALUE) //File
					SD.numDataSets++;
				else //Directory
				{
					do
					{SD.numDataSets++;}
					while(FindNextFile(h,&f));
				}

			}
			SD.DataSets = (char **) malloc(sizeof(char *) * SD.numDataSets);
			if(SD.DataSets == NULL)
			{
				perror("malloc");
				exit(1);
			}
			z1 = 0;
			for(z=0;z<argCount;z++)
			{
				h = FindFirstFile(args[z],&f);
				if(h == INVALID_HANDLE_VALUE) //File
				{
					SD.DataSets[z1] = (char *) malloc(sizeof(char) * 256);
					if(SD.DataSets[z1] == NULL)
					{
						perror("malloc");
						exit(1);
					}
					strncpy(SD.DataSets[z1],args[z],256);
					SD.DataSets[z1] = args[z];
					z1++;
				}
				else //Directory
				{
					do
					{
						SD.DataSets[z1] = (char *) malloc(sizeof(char) * 256);
						if(SD.DataSets[z1] == NULL)
						{
							perror("malloc");
							exit(1);
						}
						strncpy(SD.DataSets[z1],f.cFileName,256);
						z1++;
					}
					while(FindNextFile(h,&f));
				}

			}
#else
			DIR *dir;
			int z,z1;
			struct dirent *ent;
			for(z=0;z<argCount;z++)
			{
				dir = opendir(args[z]);
				if(dir == NULL) //File
					SD.numDataSets++;
				else //Directory
				{
					while((ent = readdir(dir)) !=NULL)
						SD.numDataSets++;
					closedir(dir);
				}

			}
			SD.DataSets = (char **) malloc(sizeof(char *) * SD.numDataSets);
			if(SD.DataSets == NULL)
			{
				perror("malloc");
				exit(1);
			}
			z1 = 0;
			for(z=0;z<argCount;z++)
			{
				dir = opendir(args[z]);
				if(dir == NULL) //File
				{
					SD.DataSets[z1] = (char *) malloc(sizeof(char) * 256);
					if(SD.DataSets[z1] == NULL)
					{
						perror("malloc");
						exit(1);
					}
					strncpy(SD.DataSets[z1],args[z],256);
					SD.DataSets[z1] = args[z];
					z1++;
				}
				else //Directory
				{
					while((ent = readdir(dir)) != NULL)
					{
						SD.DataSets[z1] = (char *) malloc(sizeof(char) * 256);
						if(SD.DataSets[z1] == NULL)
						{
							perror("malloc");
							exit(1);
						}
						strncpy(SD.DataSets[z1],ent->d_name,256);
						z1++;
					}
					closedir(dir);
				}
			}

#endif
			continue;
		}
		if(!strcmp(args[0],GSC[0])) //For
		{SD.LineJump[x-1]=--y;}
		else if(!strcmp(args[0],GSC[1])) //EndFor
		{SD.LineJump[x-1]=y++;}
		else if(!strcmp(args[0],GSC[2])) //If
		{SD.LineJump[x-1]=--y;}
		else if(!strcmp(args[0],GSC[3])) //ElseIf
		{SD.LineJump[x-1]=y; SD.LineJump[x-2]=y;}
		else if(!strcmp(args[0],GSC[4])) //Else
		{SD.LineJump[x-1]=y; SD.LineJump[x-2]=y;}
		else if(!strcmp(args[0],GSC[5])) //EndIf
		{SD.LineJump[x-1]=y++;}
		else
		{SD.LineJump[x-1]=0;} //Everything Else
	}
	fptr.close();
	if(y!=0) cerr << "Scripting Error\n";

	//Assign Jumps
	for(x=0;x<SD.numLines;x++)
	{
		if(SD.LineJump[x]<0)
		{
			for(y=x+1;y<SD.numLines;y++)
			{
				if(SD.LineJump[y]==SD.LineJump[x])
				{
					if(strcmp(SD.Lines[x][0],GSC[0]) &&
							strcmp(SD.Lines[x][0],GSC[2]) &&
							strcmp(SD.Lines[x][0],GSC[3]) &&
							strcmp(SD.Lines[x][0],GSC[4]))
					{
						if(!strcmp(SD.Lines[y][0],GSC[5]))
						{
							SD.LineJump[x]=y+1;
							break;
						}
						else
							continue;
					}
					if(!strcmp(SD.Lines[x][0],GSC[0]))
					{SD.LineJump[x]=y+1; SD.LineJump[y]=x;}
					else if(!strcmp(SD.Lines[y][0],GSC[3]))
					{SD.LineJump[x]=y;}
					else if(!strcmp(SD.Lines[y][0],GSC[4]))
					{SD.LineJump[x]=y+1;}
					else if(!strcmp(SD.Lines[y][0],GSC[5]))
					{SD.LineJump[x]=y+1; SD.LineJump[y]=0;}
					else
						continue;
					break;
				}
			}
		}
	}

	SD.CurrentLine = 1;
	SD.PreviousLine = 0;
	isScripting = true;
	scriptWaitTime = 3; //Can be changed via the script
	firstLoad = false;
	while(!firstLoad)
		seeGraphScript();
}

float GetValue(char *value)
{
	int x;
	for(x=0;x<10;x++)
	{
		if(!strcmp(value,GSC[x+12]))
			return SD.localVariables[x];
	}
	if(!strcmp(value,GSC[22]))
		return (float) displayThresh;
	if(!strcmp(value,GSC[23]))
		return (float) saveAndExit;
	if(!strcmp(value,GSC[24]))
		return scriptWaitTime;
	if(!strcmp(value,GSC[25]))
		return (float) currentQuery;
	if(!strcmp(value,GSC[27]))
		return view.zoom;
	if(!strcmp(value,GSC[28]))
		return (float)featureColors;
	if(!strcmp(value,GSC[29]))
		return (float)g->numQueries;
	return (float)atof(value);
}

void SetVar(char *var,float value)
{
	int x;
	if(!strcmp(var,GSC[22]))
	{
		displayThresh = (int) value;
		numDisplayVerts=RunVertQuery(g);
		if(viewOption==OPT_MULTIGVL) 
			updateVoxelPosition(displayThresh, g);
		else if (viewOption==OPT_SINGLEGVLSTEP) 
			updateDisplayVars(g);
	}
   else if(!strcmp(var, GSC[23])) {
      if(value>0.5f) saveAndExit=1;
      else saveAndExit=0;
   }
	else if(!strcmp(var, GSC[24]))
		scriptWaitTime = value;
	else if(!strcmp(var, GSC[25]))
			currentQuery = (int) value;
	else if(!strcmp(var, GSC[27]))
		view.zoom = value;
	else if(!strcmp(var, GSC[28]))
		featureColors = (int) value;
	else if(!strcmp(var,GSC[29]))
		g->numQueries = (int)value;
	else if(!strcmp(var,GSC[32]))
	{
		displayThresh = (int) ((value - startThresh) / stepThresh);
		numDisplayVerts=RunVertQuery(g);
		if(viewOption==OPT_MULTIGVL) 
			updateVoxelPosition(displayThresh, g);
		else if (viewOption==OPT_SINGLEGVLSTEP) 
			updateDisplayVars(g);
	}
	else
	{
		for(x = 0;x<10;x++)
		{
			if(!strcmp(var,GSC[x+12]))
			{
				SD.localVariables[x] = value;
				break;
			}
		}
	}
	/*
	if(!strcmp(var, "degreeRot"))
		degreeRot = value;
	else if(!strcmp(var, "degreeStep"))
		degreeStep = value;
	else if(!strcmp(var, "textColor0"))
		textColor[0] = value;
	else if(!strcmp(var, "textColor1"))
		textColor[1] = value;
	else if(!strcmp(var, "textColor2"))
		textColor[2] = value;
	else if(!strcmp(var, "resX"))
		resX = (int) value;
	else if(!strcmp(var, "resY"))
		resY = (int) value;
	else if(!strcmp(var, "GL_WIN_WIDTH"))
		GL_WIN_WIDTH = (int) value;
	else if(!strcmp(var, "GL_WIN_HEIGHT"))
		GL_WIN_HEIGHT = (int) value;
	else if(!strcmp(var, "threshold"))
		threshold = value;
	else if(!strcmp(var, "absoluteValue"))
		absoluteValue = (int) value;
	else if(!strcmp(var, "numDisplayVerts"))
		numDisplayVerts = (int) value;
	else if(!strcmp(var, "numDisplayEdges"))
		numDisplayEdges = (int) value;
	else if(!strcmp(var, "geneNodeColor"))
		geneNodeColor = (int) value;
	else if(!strcmp(var, "geneNodeColorQ1"))
		geneNodeColorQ1 = (int) value;
	else if(!strcmp(var, "geneNodeColorQ2"))
		geneNodeColorQ2 = (int) value;
	else if(!strcmp(var, "geneTransparentColor"))
		geneTransparentColor = (int) value;
	else if(!strcmp(var, "geneTransparentAlpha"))
		geneTransparentAlpha = (int) value;
	else if(!strcmp(var, "geneNodeSelectColor"))
		geneNodeSelectColor = (int) value;
	else if(!strcmp(var, "geneNodeUnSelectColor"))
		geneNodeUnSelectColor = (int) value;
	else if(!strcmp(var, "blackBackground"))
		blackBackground = (bool) value;
	else if(!strcmp(var, "fullScreen"))
		fullScreen = (bool) value;
	else if(!strcmp(var, "showText"))
		showText = (bool) value;
	else if(!strcmp(var, "calcFrameRate"))
		calcFrameRate = (bool) value;
	else if(!strcmp(var, "showNormals"))
		showNormals = (bool) value;
	else if(!strcmp(var, "updateNormals"))
		updateNormals = (bool) value;
	else if(!strcmp(var, "showDisconnected"))
		showDisconnected = (bool) value;
	else if(!strcmp(var, "showUnselected"))
		showUnselected = (bool) value;
	else if(!strcmp(var, "showVertHalos"))
		showVertHalos = (bool) value;
	else if(!strcmp(var, "showEdges"))
		showEdges = (bool) value;
	else if(!strcmp(var, "showEdgesVisibleVerts"))
		showEdgesVisibleVerts = (bool) value;
	else if(!strcmp(var, "normalizeEdgeColors"))
		normalizeEdgeColors = (bool) value;
	else if(!strcmp(var, "separateEdgeColors"))
		separateEdgeColors = (bool) value;
	else if(!strcmp(var, "showOnlyLCC"))
		showOnlyLCC = (bool) value;
	else if(!strcmp(var, "showFullEdges"))
		showFullEdges = (bool) value;
	else if(!strcmp(var, "showFullVerts"))
		showFullVerts = (bool) value;
	else if(!strcmp(var, "activeQuery"))
		activeQuery = (bool) value;
	else if(!strcmp(var, "allowPicking"))
		allowPicking = (bool) value;
	else if(!strcmp(var, "loadBTDMatrixPGM"))
		loadBTDMatrixPGM = (bool) value;
	else if(!strcmp(var, "showBTDMatrix"))
		showBTDMatrix = (bool) value;
	else if(!strcmp(var, "showBTDMatrixBelt"))
		showBTDMatrixBelt = (bool) value;
	else if(!strcmp(var, "showBTDMatrixStretch"))
		showBTDMatrixStretch = (bool) value;
	else if(!strcmp(var, "showBTDasLOD"))
		showBTDasLOD = (bool) value;
	else if(!strcmp(var, "showSeeEdit"))
		showSeeEdit = (bool) value;
	else if(!strcmp(var, "showVertLabels"))
		showVertLabels = (bool) value;
	else if(!strcmp(var, "saveAndExit"))
		saveAndExit = (bool) value;
	else if(!strcmp(var, "useTwoDLayout"))
		useTwoDLayout= (bool) value;
	else if(!strcmp(var, "useCustomLUT"))
		useCustomLUT = (bool) value;
	*/
}

int CreateArgs(char *command, char ***args)
{
	char *a = 0;
	int b = 0;
	for(char *c = command;c<command+strlen(command);c++)
	{
		if(c[0] != ' ')
		{
			b++;
			a = c;
			c = strstr(c+1," ");
			if(!c)
				c = command + strlen(command);
			*args = (char **)realloc(*args,b * sizeof(char *));
			if(*args == NULL)
			{
				perror("malloc");
				exit(-1);
			}
			(*args)[b-1] = (char *)malloc(256 * sizeof(char));
			if((*args)[b-1] == NULL)
			{
				perror("malloc");
				exit(-1);
			}
			strncpy((*args)[b-1],a,c-a);
		}
	}
	return b;
}
