/* 
	A Space Game version 0.1(ASGv0_1)

	Main program

*/
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <iomanip>
#include <fstream>
#include <iostream>
#include <cstring>
#include <process.h>
#include <conio.h>
#include <ctype.h>
#include <stdio.h>
#include "..\ASGcommon\UDPClient.h"
#include "..\ASGcommon\MessageHandler.h"

#define MAX_MSG_LENGTH 4096
#define RTD 180/3.14159
#define DTR 3.14159/180

using namespace std;

//function declarations
void printTheGameList(char*);
void startGame();

UDPClient ucAdmin;
UDPClient ucGame;
MessageHandler mh;
Message m;
int playerid = 0;
int playerstate = 0;
char ipAddress[] = "127.0.0.1";			//we either have to know these or
int serverport = 10000;					// let the user tell us

int adminport;					//we need the server to 
char gameAddress[16];			
int gameport;					// tell us these

bool ClientLogin(){
	char *msgPtr;
	char name[20];
	char pwd[20];
	int i, ch;
	ZeroMemory(pwd, 20);
	bool validLogin = false;
	
	int connectOK = ucAdmin.startClient(ipAddress, serverport);
	if(connectOK) {
		//login 
		while(!validLogin){
			//lets get user name and password
			cout<<"Name...->";
			cin>>name;
			cout<<"Password...->";
			i = 0;
			//get the password without showing it
			while (true)
			{
				ch = _getch();
				if (ch == '\r' || i > 19) break;
				else {
					cout<<" ";
					pwd[i] = (char)ch;
					i++;
				}
			}
			cout<<endl;
			msgPtr = mh.createLoginMessage(name,pwd);
			ucAdmin.sendtoserver(msgPtr);
			if (ucAdmin.receivefromserver()){
				mh.parseMessage(ucAdmin.buffer, m);
				cout<<m.getTheData()<<endl;
				if (m.getType() > serverport){
					playerid = m.getClientID();
					adminport = m.getType();
					validLogin = true;
				}
				else {
					cout<<"Invalid login"<<endl;
				}
			}
		}
	}
	if(validLogin) playerstate = 1;	//talking to admin now
	return validLogin;
}

void CreateOrJoin(){
	int ans;
	cout<<"1. Create a game"<<endl;
	cout<<"2. Join a game"<<endl;
	cout<<"3. Exit"<<endl;
	cout<<">";	//prompt
	while (true){
		ans = _getche();
		cout<<endl;
		if (ans == '1'){
			playerstate = 2;
			break;
		}
		else if (ans == '2') {
			playerstate = 3;
			break;
		}
		else if (ans == '3') {
			exit(0);
		}
		else 
			cout<<"Please enter 1,2 or 3"<<endl<<">";
	}
}

void CreateAGame(){
	//Message m;
	int numberofHumanteams, numberofAIteams;
	int numberofHumanplayers, numberofAIplayers;
	int arenatype;
	char nameofgame[20];

	while(true){
		cout<<"Enter the number of human teams(2-4)->";
		cin>>numberofHumanteams;
		if (numberofHumanteams > 1 && numberofHumanteams < 5) break;
	}
	while(true){
		cout<<"Enter the number of human players(2-12)->";
		cin>>numberofHumanplayers;
		if (numberofHumanplayers > 1 && numberofHumanplayers < 13) break;
	}
	while(true){
		cout<<"Enter the number of AI teams(0-3)->";
		cin>>numberofAIteams;
		if (numberofAIteams >= 0 && numberofAIteams < 4) break;
	}
	while(true){
		cout<<"Enter the number of AI players(0-10)->";
		cin>>numberofAIplayers;
		if (numberofAIplayers >= 0 && numberofAIplayers < 11) break;
	}
	while(true){
		cout<<"Enter the arena type(1-5)->";
		cin>>arenatype;
		if (arenatype > 0 && arenatype < 6) break;
	}
	cout<<"Enter the name of the game->";
	cin>>nameofgame;
	//create the message and send it to the server
}

void JoinAGame(){
	cout<<"entering 'join a game'"<<endl;
	int gameChoice;
	char *msg;
	char *token;

	//create a gamelist request message and send it
	msg = mh.createGameListRequestMessage(playerid);

	ucAdmin.sendtoserver(msg);
	//now wait for the list from the server
	if (ucAdmin.receivefromserver()){
		mh.parseMessage(ucAdmin.buffer, m);
		printTheGameList(m.getTheData());
	}
	cout<<"Select a game to play->";
	cin>>gameChoice;		
	//validate choice

	//if a valid choice send which game we want back
	ZeroMemory(msg, MAX_MSG_LENGTH);
	//temporarily force game choice to 0
	gameChoice = 0;
	msg = mh.createGameJoinMessage(playerid,0,gameChoice);
	ucAdmin.sendtoserver(msg);
	if (ucAdmin.receivefromserver()){	//we are expecting ipaddress and port
		
		token = strtok(ucAdmin.buffer, " ");
		strcpy(gameAddress, token);
		cout<<gameAddress<<endl;
		token = strtok(NULL, " ");
		gameport = atoi(token);
		cout<<gameport<<endl;

	}
	playerstate = 4;
}

void printTheGameList(char *theList){
	cout<<theList<<endl;
}

void ControlPlayerThroughState(){
	cout<<"player state is "<<playerstate<<endl;
	switch (playerstate){
	case 1:		//admin main menu
		CreateOrJoin();
		break;
	case 2:		//creating a game
		CreateAGame();
		break;
	case 3:		//joining a game
		JoinAGame();
		break;
	case 4:		//playing a game
		startGame();
		//this will block until game is exited
		//when this happens start player at beginning
		playerstate = 1;
		break;
	default:
		break;
	}
	cout<<endl;
}

void startGame(){
	// start the game.exe and pass
	// the necessary information
	cout<<"entering start game..."<<endl;
	//char theProgram[] = "C:\\WINDOWS\\System32\\calc.exe";
	char theProgram[] = "../A Space Game/Debug/A Space Game.exe";
	char port[6];
	char pid[3];
	if (gameport > 0) _itoa(gameport, port, 10);
	else gameport = 12000;
	if (playerid > 0) _itoa(playerid, pid, 10);
	else playerid = 3;
	cout<<"Starting game, connected to "<<ipAddress<<" "<<port<<", user id:"<<pid<<endl;
	//_spawnl(_P_WAIT,theProgram, 0);
	_spawnl(_P_WAIT,theProgram, ipAddress, port, pid);
}

void ASG(){
	//startGame();
	if (ClientLogin()){
		//client has logged in successfully 
		//so lets talk to administration
		int connectOK = ucAdmin.startClient(ipAddress, adminport);
		if(connectOK) {
			//stay connected to admin until logging off
			while (true){	
				ControlPlayerThroughState();

			}			
		}
	} 
}

//////////////////////////////////////////////////////////////////////
//  MAIN                                                      ////////
//////////////////////////////////////////////////////////////////////
int main(int argc, char **argv) {
	ASG();
	return 0;
}

