#pragma once

#include <fstream>
#include <string>
#include <vector>
#include <map>

#include "json/jsonOps.hpp"

struct aimConfig {
	bool state;
	bool rcs;
	bool trigger;

	bool alaimlock = false;
	bool checkSpotted = true;
	float smoothing = 3.2f;
	int trigger_reaction = 200;

	float fov = 2.5;
	bool fovCircle;

	int bone;
	int boneSelect = 1;
	std::vector<std::string> bones = { "Head", "Neck","Chest", "Crotch" };
	std::map <std::string, int> boneMap = { {"Head",6},{"Neck",5},{"Chest",4},{"Crotch",0} };

	int aimMode = 2;
	std::vector<std::string> aimModes = { "Closest to Player", "Closest to Crosshair", "Furthest from crosshair", "No preference" };
	std::map <std::string, int> aimModeMap = { {"Closest to Player",0},{"Closest to Crosshair",1},{"Furthest from crosshair",2},{"No preference",3} };

	int hotSelectAim = 0;
	int hotAim;

	//float sens = 2.25f;

	bool isHotTrigger;
	int hotSelectTrigger = 0;
	int hotTrigger;

	bool triggerON = false;

	int sensitivityCheck;

	bool playerLock;
	bool predictionTest;

	std::vector<std::string> hotKey = { "SHIFT","ALT","CTRL","Left mouse","Right mouse" };
	std::map <std::string, int> hotKeyMap = { {"SHIFT",VK_SHIFT}, {"ALT",VK_MENU},{"CTRL",VK_CONTROL},{"Left mouse",VK_LBUTTON},{"Right mouse",VK_RBUTTON} };

	inline nlohmann::json to_json();
	inline bool from_json(nlohmann::json json);
};
inline aimConfig aimConf;



//settings for configs
const int MAX_CONFIGS = 32;
inline std::vector<std::wstring> CONFIG_NAMES;
inline namespace config {
	inline nlohmann::json configFiles[MAX_CONFIGS]; // to store multiple configs
	inline int currentConfigIndex = 0; // current config

	nlohmann::json to_json();
	void load(int index);
	void save(int index);
	void refresh();
	void create(std::wstring name);
	bool exists(int index);
}

enum bones : int {
	head            = 6,
	neck            = 5,
	chest           = 4,
	chest_1         = 2,
	shoulderRight   = 8,
	shoulderLeft    = 13,
	elbowRight      = 9,
	elbowLeft       = 14,
	handRight       = 11,
	handLeft        = 16,
	crotch          = 0,
	leftCrotch      = 22,
	rightCrotch     = 25,
	kneeRight       = 26,
	kneeLeft        = 23,
	ankleRight      = 27,
	ankleLeft       = 24,
};

struct BoneConnection {
	int bone1;
	int bone2;

	BoneConnection(int b1, int b2) : bone1(b1), bone2(b2) {}
};

inline BoneConnection boneConnections[] = {
	BoneConnection(bones::head, bones::neck),
	BoneConnection(bones::neck, bones::chest),
	BoneConnection(bones::chest,bones::crotch),
	BoneConnection(bones::chest, bones::shoulderRight),
	BoneConnection(bones::shoulderRight, bones::elbowRight),
	BoneConnection(bones::elbowRight, bones::handRight),
	BoneConnection(bones::chest, bones::shoulderLeft),
	BoneConnection(bones::shoulderLeft, bones::elbowLeft),
	BoneConnection(bones::elbowLeft, bones::handLeft),
	BoneConnection(bones::chest, bones::chest_1),
	BoneConnection(bones::crotch, bones::leftCrotch),
	BoneConnection(bones::crotch, bones::rightCrotch),
	BoneConnection(bones::leftCrotch, bones::kneeLeft),
	BoneConnection(bones::kneeLeft,bones::ankleLeft),
	BoneConnection(bones::rightCrotch, bones::kneeRight),
	BoneConnection(bones::kneeRight, bones::ankleRight)
};