/*
	class MessageHandler
	type	message description
	0		login
	1		creat game
	2		game list request
	3		game list
	4		orientation and position
	5		

 */

#include "MessageHandler.h"

using namespace std;

MessageHandler::MessageHandler() {
	formattedMessage = new char[MAX_MESSAGE_LENGTH];
	orientationAndPosition = new float[12];
}
MessageHandler::~MessageHandler() {
	delete formattedMessage;
	delete orientationAndPosition;
}

/////////////////////////////////////////////////////////
//  MESSAGE CREATION
/////////////////////////////////////////////////////////
char *MessageHandler::createLoginMessage(char *name, char *pwd){
	ZeroMemory(formattedMessage, MAX_MESSAGE_LENGTH);
	int messageType = 0;	
	sprintf(formattedMessage, "%d/0/0/%s %s", messageType, name, pwd);
	return formattedMessage;
}
char *MessageHandler::createGameListRequestMessage(int playerid){
	//This message is from the client
	ZeroMemory(formattedMessage, MAX_MESSAGE_LENGTH);
	int messageType = 2;
	sprintf(formattedMessage, "%d/%d/0/request", messageType, playerid);
	return formattedMessage;
}
char *MessageHandler::createGameListMessage(char *theList){
	//This message is from the server
	ZeroMemory(formattedMessage, MAX_MESSAGE_LENGTH);
	int messageType = 2;
	sprintf(formattedMessage, "%d/0/0/%s", messageType, theList);
	return formattedMessage;
}
char *MessageHandler::createGameJoinMessage(int playerID, int packetID, int gameID){
	ZeroMemory(formattedMessage, MAX_MESSAGE_LENGTH);
	int messageType = 3;
	sprintf(formattedMessage, "%d/%d/%d/%d", messageType, playerID, packetID, gameID);
	return formattedMessage;
}
char *MessageHandler::createOPMessage(int id, int pid, float o[4][4], float v[3]){
	/* 
		Requires: id of the sender, packetid
				  3x3 orientation array, vector position
		Modifies: formattedMessage variable
	*/
	int messageType = 6;		//6 indicates an orientation and position message
	ZeroMemory(formattedMessage, MAX_MESSAGE_LENGTH);

	float m11 = o[0][0];
	float m12 = o[0][1];
	float m13 = o[0][2];
	float m21 = o[1][0];
	float m22 = o[1][1];
	float m23 = o[1][2];
	float m31 = o[2][0];
	float m32 = o[2][1];
	float m33 = o[2][2];
	float pX  = v[0];
	float pY  = v[1];
	float pZ  = v[2];
	sprintf(formattedMessage, "%d/%d/%d/%.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f", 
		messageType, id, pid, m11, m12, m13, m21, m22, m23, m31, m32, m33, pX, pY, pZ);
	return formattedMessage;
}
char *MessageHandler::createSCMessage(int id, int teamid, int state){
	int messageType = 7;
	ZeroMemory(formattedMessage, MAX_MESSAGE_LENGTH);
	sprintf(formattedMessage, "%d/%d/%d/%d", messageType, id, teamid, state);
	return formattedMessage;
}
char *MessageHandler::createEndGameMessage(int id, int teamid, int state){
	int messageType = 8;
	ZeroMemory(formattedMessage, MAX_MESSAGE_LENGTH);
	sprintf(formattedMessage, "%d/%d/%d/%d", messageType, id, teamid, state);
	return formattedMessage;
}
char *MessageHandler::createGameExitMessage(int playerID, int teamID, int posID){
	ZeroMemory(formattedMessage, MAX_MESSAGE_LENGTH);
	int messageType = 9;
	sprintf(formattedMessage, "%d/%d/%d/%d", messageType, playerID, teamID, posID);
	return formattedMessage;
}

/////////////////////////////////////////////////////////
//  MESSAGE PARSING
/////////////////////////////////////////////////////////
bool MessageHandler::parseMessage(char *msg, Message &m){
	char temp[MAX_MESSAGE_LENGTH];
	ZeroMemory(temp, MAX_MESSAGE_LENGTH);
	strcpy(temp, msg);
	char delim[] = "/";
	char *token;
	int t;
	token = strtok(temp, delim);
	if (token != NULL){	
		t = atoi(token);
		//cout<<"the first token is "<<t<<endl;
		if (t >= 0) m.setType(t);
	}
	else return false;
	token = strtok(NULL, delim);
	if (token != NULL){			
		t = atoi(token);
		if (t >= 0) m.setClientID(t);
	}
	else return false;
	token = strtok(NULL, delim);
	if (token != NULL){	
		t = atoi(token);
		if (t >= 0) m.setPacketID(t);
	}
	else return false;
	token = strtok(NULL, delim);
	if (token != NULL){
		m.setData(token);
	}
	else return false;
	
	return true;
}
char *MessageHandler::parseName(char *m){
	char temp[MAX_MESSAGE_LENGTH];
	ZeroMemory(temp, MAX_MESSAGE_LENGTH);
	strcpy(temp, m);
	ZeroMemory(string, 20);
	char *token;
	token = strtok(temp, " ");
	if (token != NULL){
		strcpy(string, token);
	}
	return string;
}
char *MessageHandler::parsePwd(char *m){
	char temp[MAX_MESSAGE_LENGTH];
	ZeroMemory(temp, MAX_MESSAGE_LENGTH);
	strcpy(temp, m);
	ZeroMemory(string, 20);
	char *token;
	token = strtok(temp, " ");
	if (token != NULL){
		token = strtok(NULL, " ");
		if (token != NULL){
			strcpy(string, token);
		}
	}
	return string;
}
float *MessageHandler::parseOrientationAndPosition(char *msg){
	char temp[MAX_MESSAGE_LENGTH];
	ZeroMemory(temp, MAX_MESSAGE_LENGTH);
	strcpy(temp, msg);
	char delims[] = " \n";
	char *token;
	int i;
	token = strtok(temp, delims);
	for (i = 0; i < 12; i++){
		if(token != NULL){
			orientationAndPosition[i] = atof(token);
			token = strtok(NULL, delims);
		}
		else 
			break;
	}
	//first 9 are a 3x3 orientation matrix
	//last 3 are position vector
	return orientationAndPosition;
}

int MessageHandler::parseState(char *msg){
	return atoi(msg);
}