/*
	THIS FILE IS A PART OF GTA V SCRIPT HOOK SDK
				http://dev-c.com			
			(C) Alexander Blade 2015
*/

#include "script.h"
#include "keyboard.h"
#include "ClosestVehicleHelpers.h"
#include "OutputHelpers.h"
#include "TruckList.h"
#include "WorldHelpers.h"
#include "MathHelpers.h"

#include<stdio.h>
#include <tchar.h>
#include <iostream>

#include <Windows.h>
#include <string>

//Main List Variables
std::list<TruckListEntry> myTruckList;
int entrysLeft = 0;

//Mod mode
bool active = false;

// Function Prototypes 
void ScriptMain();
void update();
void showTrucks();

void refreshTruckList(std::list<TruckListEntry>* truckList, Ped ped = 0, int maxDistance = 100, int maxHeight = 5, bool canReturnVehicleInside = false);
TruckListEntry toTruckListEntry(Vehicle truck, Vector3 playerPos, int playerHeading, int distance);

//***** MAIN *****//
void ScriptMain()
{
	AllocConsole();
	FILE* f;
	freopen_s(&f, "CONOUT$", "w", stdout);
	printf("Hello\n");
	std::cout.clear();

	//The following things did not work
	//testFile();
	//testUart();
	//testSharedMemory();

	while (true)
	{
		update();
		WAIT(0);
	}
}

void update()
{
	//testScreenDrawing();
	if (IsKeyJustUp(VK_F5)) {
		active = !active;
		if (active) {
			setupPixelSize();
			setupPlayer();
			setupEnvironment();
		}

	}

	if (IsKeyJustUp(VK_F6)) {
		spawnBike();
	}
	else if (IsKeyJustUp(VK_F7)) {
		teleport(4);
		spawnBike();

	}
	else if (IsKeyJustUp(VK_F8)) {
		teleport(16);
		spawnBike();
	}

	if (active) {
		updatePlayerFeatures();
		showTrucks();
	}
}

void showTrucks() {
	if (entrysLeft == 0) {
		refreshTruckList(&myTruckList);
		entrysLeft = myTruckList.size();
		drawStartSignal(); //id field is white, null
		debugPrintTruckList(myTruckList);
	}
	else {
		if (myTruckList.size() > 0) {
			encodeString(listEntryToCsv(myTruckList.front()));
			myTruckList.pop_front();
		}
		entrysLeft--;
	}
}

void refreshTruckList(std::list<TruckListEntry> *truckList, Ped ped, int maxDistance, int maxHeight, bool canReturnVehicleInside) {
	if (ped == 0) {
		ped = PLAYER::GET_PLAYER_PED(-1);
	}

	Vehicle veh = NULL;
	const int ARR_SIZE = 1024;
	Vehicle vehs[ARR_SIZE];
	int count = worldGetAllVehicles(vehs, ARR_SIZE);

	truckList->clear();
	int playerHeading = toClockwiseAngle(ENTITY::GET_ENTITY_HEADING(PLAYER::PLAYER_PED_ID()));
	std::cout << "player heading: " << playerHeading << std::endl;
	Vector3 playerPos = ENTITY::GET_ENTITY_COORDS(PLAYER::PLAYER_PED_ID(), true);
	if (vehs != NULL)
	{
		for (int i = 0; i < count; i++)
		{
			if (doesEntityExistsAndIsNotNull(vehs[i]) && (canReturnVehicleInside || PED::IS_PED_IN_VEHICLE(ped, vehs[i], false) == false))
			{
				float distance = getDistanceBetweenEntities(ped, vehs[i]);
				float height = getDistanceToGround(vehs[i]);
				if (distance <= maxDistance && height <= maxHeight && height >= 0 && isVehicleDrivable(vehs[i]))
				{
					if (isTruck(vehs[i])) {
						TruckListEntry newTruck = toTruckListEntry(vehs[i], playerPos, playerHeading,distance);
						truckList->push_back(newTruck);
					}
				}
			}
		}
	}
}

TruckListEntry toTruckListEntry(Vehicle truck, Vector3 playerPos, int playerHeading, int distance) {
	TruckListEntry newTruck;

	Vector3 truckPos = ENTITY::GET_ENTITY_COORDS(truck, false);
	int truckRotation = toClockwiseAngle(ENTITY::GET_ENTITY_HEADING(truck));
	Vector3 velocity = ENTITY::GET_ENTITY_VELOCITY(truck);
	newTruck.id = truck;
	newTruck.distanceToPlayer = distance;
	newTruck.angleToPlayer = toAngleToPlayer(playerHeading, playerPos, truckPos);
	newTruck.heading = toRelativeHeading(playerHeading, truckRotation);
	newTruck.velocity = toSpeed(velocity);
	return newTruck;
}