#include "ScriptUtils.h"

#include <crtdbg.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>


/*
	Misn17Mission
*/

static void GetRidOfSomeScrap(void);

class Misn17Mission {
public:
	Misn17Mission(void);
	~Misn17Mission();

	bool Load(void);
	bool PostLoad(void);
	bool Save(void);

	void Update(void);

	void AddObject(Handle h);
	
private:
	void Setup(void);
	void Execute(void);

struct movePoints { int x,y,z;
};
	
	
	int moveCameraRotate(movePoints *vec, int xDist, int yDist, int zDist, float speed);
	Vector currentLoc; //move this to the global declarations
	Vector distance; //move this to the global declarations
	Vector newLocation;
	Vector changePerFrame;
	Vector position;
	Vector direction;
	movePoints vec;
	void getDistanceToNextTarget(Vector toPosition);

	//	char takeThisPath[30];

	// bools
	union {
		struct {
			bool
				missionstart, cinDone, beginRotate, endCin, beginZoom, nextThing, 
				theEnd, dontRepeat, b_last;
		};
		bool b_array[8];
	};

	// floats
	union {
		struct {
			float
				r,damagecheck1, endCinI,
				f_last;
		};
		float f_array[3];
	};

	// handles
	union {
		struct {
			Handle
				target, cameraPlant, secondTarget, buildSite4, buildSite5, ip1, ip2, ip3, ip4,
				buildSite6, badman1, friend1, startFromHere,
				h_last;
		};
		Handle h_array[13];
	};

	// integers
	union {
		struct {
			int
				cutCounter, newTime, moveTime, moveDistance,
				i_last;
		};
		int i_array[4];
	};
};

bool missionSave;
Misn17Mission *mission;

void Misn17Mission::Setup(void)
{
	/*
		Initialize variables
	*/
	r= 0.0f;
	target = 0; 
	cameraPlant = 0; 
	secondTarget = 0; 
	buildSite4 = 0; 
	buildSite5 = 0;
	buildSite6 = 0;
	startFromHere = 0;
	badman1 = 0;
	ip1 = 0; 
	ip2 = 0;
	ip3 = 0;
	ip4 = 0;
	friend1 = 0;
	newTime = 0;
	moveTime = 0;
	moveDistance = 0;
	cutCounter = 0;
	beginRotate = false;
	missionstart = false;
	nextThing = false;
	theEnd = false;
	dontRepeat = false;
	
}

void Misn17Mission::AddObject(Handle h)
{
}

void addObjective(int count) { 
		
		//PurgeItem("misn1701.otf");
		FILE *fd=fopen("addon\\misn1701.otf","w+");
		fprintf(fd,"You have killed %d enemies.",count);
		fclose(fd);
		ClearObjectives();
		AddObjective("misn1701.otf", WHITE);

}
//movePoints is a structure of 3 integers defined above
// *vec creates a pointer to a movePoints structure
//vec->x sets the x value of the structure

int Misn17Mission::moveCameraRotate(movePoints *vec, int xDist, int yDist, int zDist, float speed) {
		//positive z will rotate right around object
		//negative z will rotate left around object
		//positive y will raise camera
		//negative y will lower camera

		vec->x = (int)(cos(r)*xDist);
		vec->y = (int)(sin(r)*yDist);
		vec->z = (int)(sin(r)*zDist);
		r = r+3.141f/2.0f/speed;  // 100 is 10 sec @ 10fps
		return 0;
		}

void Misn17Mission::getDistanceToNextTarget(Vector toPosition) {
		Vector position;
		Vector direction;
		GetCameraPosition(position, direction);
		distance.x = (toPosition.x - position.x);
		distance.y = (toPosition.y - position.y);
		distance.z = (toPosition.z - position.z);
}

void Misn17Mission::Execute(void) {

	if	(missionstart == false) {
		target = GetHandle ("repairBay");
		cameraPlant = GetHandle ("plant");
		secondTarget = GetHandle ("repairBay");
		ip1 = BuildObject("avtank", 1, "spawn_point");
		ip2 = GetHandle ("tank");
		Goto(ip1, cameraPlant);
		endCin = false;
		missionstart = true;
		cutCounter = 1;
		CameraReady();
	}
	
	if ((cutCounter == 1) && (r <= 2.0f)) {
		moveCameraRotate(&vec, 2500, 600, 2500, 50.0f);
		vec.y +=1000.0f;
		CameraObject(cameraPlant, vec.x, vec.y, vec.z, cameraPlant);
	}
	else if ((cutCounter == 1) && (r > 2.0f)) {
		r = 0.0f;
		cutCounter = 2;	
	}
//r determines how long you will zoom for. Half the speed = half way to the object

	else if ((cutCounter == 2) && (r <= 50.0f)) {
		if (r == 0.0f) { //This will do the setup for the pan
			Vector object2 = GetPosition(secondTarget);
			getDistanceToNextTarget(object2);
			distance = Normalize_Vector (distance);
			GetCameraPosition(position, direction);
			changePerFrame.x = ((distance.x - direction.x)/50);
			changePerFrame.y = ((distance.y - direction.y)/50);
			changePerFrame.z = ((distance.z - direction.z)/50);
			}
		
		GetCameraPosition(position, direction);
		direction.x += changePerFrame.x;
		direction.y += changePerFrame.y;
		direction.z += changePerFrame.z;
		SetCameraPosition(position, direction);
		r += 1;
	}
	else if ((cutCounter == 2) && (r > 50)) {
		r = 0.0f;
		cutCounter = 3;
	}
	
	else if ((cutCounter == 3) &&  (r <= 25.0f)) {
		if (r == 0.0f) { //this will do the setup for a camera zoom (get distance and the increment per frame)
			Vector object2 = GetPosition(secondTarget);
			getDistanceToNextTarget(object2);
			distance = Normalize_Vector (distance);
			changePerFrame.x = (distance.x/.50);
			changePerFrame.y = (distance.y/.50);
			changePerFrame.z = (distance.z/.50);
			}
		
		GetCameraPosition(position, direction);
		position.x += changePerFrame.x;
		position.y += changePerFrame.y;
		position.z += changePerFrame.z;
		SetCameraPosition(position, direction);
		r += 1;
		
	}
	else if ((cutCounter == 3) && (r > 25.0f)) {
		CameraFinish();
		r = 0.0f;
		cutCounter = 4;
	}
	else if (cutCounter == 4) {

	}

//This is the end of Misn17 Execute	
}



Misn17Mission::Misn17Mission(void)
{
}

Misn17Mission::~Misn17Mission()
{
}

bool Misn17Mission::Load(void)
{
	if (missionSave) {
		int i;

		// init bools
		int b_count = &b_last - b_array;
		_ASSERTE(b_count == SIZEOF(b_array));
		for (i = 0; i < b_count; i++)
			b_array[i] = false;

		// init floats
		int f_count = &f_last - f_array;
		_ASSERTE(f_count == SIZEOF(f_array));
		for (i = 0; i < f_count; i++)
			f_array[i] = 99999.0f;

		// init handles
		int h_count = &h_last - h_array;
		_ASSERTE(h_count == SIZEOF(h_array));
		for (i = 0; i < h_count; i++)
			h_array[i] = 0;

		// init ints
		int i_count = &i_last - i_array;
		_ASSERTE(i_count == SIZEOF(i_array));
		for (i = 0; i < i_count; i++)
			i_array[i] = 0;

		Setup();
		return true;
	}

	bool ret = true;

	// bools
	int b_count = &b_last - b_array;
	_ASSERTE(b_count == SIZEOF(b_array));
	ret = ret && in(b_array, sizeof(b_array));

	// floats
	int f_count = &f_last - f_array;
	_ASSERTE(f_count == SIZEOF(f_array));
	ret = ret && in(f_array, sizeof(f_array));

	// Handles
	int h_count = &h_last - h_array;
	_ASSERTE(h_count == SIZEOF(h_array));
	ret = ret && in(h_array, sizeof(h_array));

	// ints
	int i_count = &i_last - i_array;
	_ASSERTE(i_count == SIZEOF(i_array));
	ret = ret && in(i_array, sizeof(i_array));

	return ret;
}

bool Misn17Mission::PostLoad(void)
{
	if (missionSave)
		return true;

	bool ret = true;

	int h_count = &h_last - h_array;
	for (int i = 0; i < h_count; i++)
		h_array[i] = ConvertHandle(h_array[i]);

	return ret;
}

bool Misn17Mission::Save(void)
{
	if (missionSave)
		return true;

	bool ret = true;

	// bools
	int b_count = &b_last - b_array;
	_ASSERTE(b_count == SIZEOF(b_array));
	ret = ret && out(b_array, sizeof(b_array), "b_array");

	// floats
	int f_count = &f_last - f_array;
	_ASSERTE(f_count == SIZEOF(f_array));
	ret = ret && out(f_array, sizeof(f_array), "f_array");

	// Handles
	int h_count = &h_last - h_array;
	_ASSERTE(h_count == SIZEOF(h_array));
	ret = ret && out(h_array, sizeof(h_array), "h_array");

	// ints
	int i_count = &i_last - i_array;
	_ASSERTE(i_count == SIZEOF(i_array));
	ret = ret && out(i_array, sizeof(i_array), "i_array");

	return ret;
}

void Misn17Mission::Update(void)
{
	Execute();
}

bool Save(bool misnSave)
{
	missionSave = misnSave;
	return mission->Save();
}

bool Load(bool misnSave)
{
	mission = new Misn17Mission();
	missionSave = misnSave;
	return mission->Load();
}

bool PostLoad(bool misnSave)
{
	missionSave = misnSave;
	return mission->PostLoad();
}

void AddObject(Handle h)
{
	mission->AddObject(h);
}

void Update(void)
{
	mission->Update();
}

void PostRun(void)
{
	delete mission;
}

static MisnExport misnExport;
MisnImport misnImport;

MisnExport * __cdecl GetMisnAPI(MisnImport *import)
{
	misnImport = *import;
	misnExport.misnImport = &misnImport;
	misnExport.Save = Save;
	misnExport.Load = Load;
	misnExport.PostLoad = PostLoad;
	misnExport.AddObject = AddObject;
	misnExport.Update = Update;
	misnExport.PostRun = PostRun;
	return &misnExport;
}

