#define HELPER_COMPILATION

#include "enbhelper.h"

bool	bInitialized = false;

#define GTASA_US_1_0				1
#define GTASA_STEAM_3_0				2
DWORD	game_ver=0;

DWORD	ADDR_HOURS=0;
DWORD	ADDR_MINUTES=0;
DWORD	ADDR_WEATHER_TRANSITION=0;
DWORD	ADDR_CURRENT_WEATHER=0;
DWORD	ADDR_UPCOMING_WEATHER=0;



bool HELPER_API getTime(float& time)
{
	if (!bInitialized) return false;
	if (!ADDR_HOURS) return false;
	if (!ADDR_MINUTES) return false;

	if (game_ver==GTASA_US_1_0)
	{
		BYTE	hours = *(BYTE*)ADDR_HOURS;
		BYTE	minutes = *(BYTE*)ADDR_MINUTES;
		time = ((float)hours) + (((float)minutes)/60.0f);
		return true;
	}

	if (game_ver==GTASA_STEAM_3_0)
	{
		BYTE	hours = *(BYTE*)ADDR_HOURS;
		BYTE	minutes = *(BYTE*)ADDR_MINUTES;
		time = ((float)hours) + (((float)minutes)/60.0f);
		return true;
	}

	return false;
}

bool HELPER_API getCustomShaderConstants1(float *vectors)
{
	if (!bInitialized) return false;
	if (!vectors) return false;
	//TODO: Add here whatever you want to get from game and then sent to shaders of ENBSeries
	//WARNING! vectors are 4 floats, 8 vectors total, which are 32 floats
	for (DWORD i=0; i<32; i++)
	{
		vectors[i] = 0.0f;
	}
	return false;
}

bool HELPER_API getWeatherTransition(float& t)
{
	if (!bInitialized) return false;
	//if (!ADDR_WEATHER_TRANSITION) return false;
	//Unused. When returned false, weather will be interpolated smoothly by time inside the mod
	t=0.0f;

	if (game_ver==GTASA_US_1_0)
	{
		if (!ADDR_WEATHER_TRANSITION) return false;
		DWORD	trans = ADDR_WEATHER_TRANSITION;
		trans = *(DWORD*)trans;
		t = *((float*)&trans);
		return true;
	}

	if (game_ver==GTASA_STEAM_3_0)
	{
		DWORD	trans=*(DWORD*)(((DWORD)GetModuleHandle(NULL)) + 0x00712680);
		if (trans)
		{
			trans+=44 - 16;
			trans = *(DWORD*)trans;
			t = *((float*)&trans);
			return true;
		}
	}

	return false;
}

bool HELPER_API getCurrentWeatherId(DWORD& id)
{
	if (!bInitialized) return false;

	if (game_ver==GTASA_US_1_0)
	{
		if (!ADDR_CURRENT_WEATHER) return false;
		WORD	weather = *(WORD*)ADDR_CURRENT_WEATHER;
		id=weather;
		return true;
	}

	if (game_ver==GTASA_STEAM_3_0)
	{
		ADDR_CURRENT_WEATHER=*(DWORD*)(((DWORD)GetModuleHandle(NULL)) + 0x00712680);
		if (ADDR_CURRENT_WEATHER)
		{
			ADDR_CURRENT_WEATHER+=48;
			DWORD	weather = *(DWORD*)ADDR_CURRENT_WEATHER;
			id=weather;
			return true;
		}
	}

	return false;
}

bool HELPER_API getUpcomingWeatherId(DWORD& id)
{
	if (!bInitialized) return false;

	if (game_ver==GTASA_US_1_0)
	{
		if (!ADDR_UPCOMING_WEATHER) return false;
		WORD	weather = *(WORD*)ADDR_UPCOMING_WEATHER;
		id=weather;
		return true;
	}

	if (game_ver==GTASA_STEAM_3_0)
	{
		ADDR_UPCOMING_WEATHER=*(DWORD*)(((DWORD)GetModuleHandle(NULL)) + 0x00712680);
		if (ADDR_UPCOMING_WEATHER)
		{
			ADDR_UPCOMING_WEATHER+=44;
			DWORD	weather = *(DWORD*)ADDR_UPCOMING_WEATHER;
			id=weather;
			return true;
		}
	}

	return false;
}

bool HELPER_API getFrameTimeMilliseconds(DWORD& ms)
{
	if (!bInitialized) return false;

	if (game_ver==GTASA_US_1_0)
	{
		/*static DWORD	offset=12;
		if (GetAsyncKeyState(VK_F10) & 0x8000) offset=4;
		if (GetAsyncKeyState(VK_F11) & 0x8000) offset=8;
		if (GetAsyncKeyState(VK_F12) & 0x8000) offset=12;
		if (GetAsyncKeyState(VK_F9) & 0x8000) offset=16;
		if (GetAsyncKeyState(VK_F8) & 0x8000) offset=0;
		if (GetAsyncKeyState(VK_F7) & 0x8000) offset=-4;*/
		//have no idea which is valid, just visually check it as less buggy
		DWORD	offset=4;
		ms = *(DWORD*)(0x00B7CB78 + offset);
		return true;
	}

	if (game_ver==GTASA_STEAM_3_0)
	{
		DWORD	timer=*(DWORD*)(((DWORD)GetModuleHandle(NULL)) + 0x007FC45C);
		if (timer)
		{
			//have no idea which is valid, just visually check it as less buggy
			DWORD	offset=16;
			ms = *(DWORD*)(timer + 77732 + offset);
			return true;
		}
	}

	return false;
}



bool HELPER_API helperInit(HelperFuncs& funcs)
{
	if (bInitialized) return false;

	bool	isvalid = false;
	DWORD	verify = *(DWORD*)(((DWORD)GetModuleHandle(NULL)) + 0x000CDE70);
	//GTASA 1.0 US
	if (verify == 0xC933C18B)
	{
		isvalid = true;
		game_ver=GTASA_US_1_0;

		ADDR_HOURS = 0x00B70153;
		ADDR_MINUTES = 0x00B70152;

		ADDR_WEATHER_TRANSITION=0x00C8131C - 16;
		ADDR_CURRENT_WEATHER=0x00C81320;
		ADDR_UPCOMING_WEATHER=0x00C8131C;
	}
	//GTASA Steam version 3.0 5/7/2017
	if (verify == 0x8BEC8B55)
	{
		isvalid = true;
		game_ver=GTASA_STEAM_3_0;

		ADDR_HOURS=*(DWORD*)(((DWORD)GetModuleHandle(NULL)) + 0x007FC45C);
		ADDR_MINUTES=*(DWORD*)(((DWORD)GetModuleHandle(NULL)) + 0x007FC45C);
		ADDR_HOURS+=1803;
		ADDR_MINUTES+=1802;

		//not valid till map loaded
	//	ADDR_WEATHER_TRANSITION=0;
	//	ADDR_CURRENT_WEATHER=*(DWORD*)(((DWORD)GetModuleHandle(NULL)) + 0x00712680);
	//	ADDR_UPCOMING_WEATHER=*(DWORD*)(((DWORD)GetModuleHandle(NULL)) + 0x00712680);
	//	ADDR_CURRENT_WEATHER+=48;
	//	ADDR_UPCOMING_WEATHER+=44;
	}

	funcs.version = HELPER_VER;
	funcs.getTime = getTime;
	funcs.getCustomShaderConstants1 = getCustomShaderConstants1;
	funcs.getWeatherTransition = getWeatherTransition;
	funcs.getCurrentWeatherId = getCurrentWeatherId;
	funcs.getUpcomingWeatherId = getUpcomingWeatherId;
	funcs.getFrameTimeMilliseconds = getFrameTimeMilliseconds;

	bInitialized = isvalid;
	return isvalid;
}



bool HELPER_API helperUninit()
{
	if (!bInitialized) return false;

	bInitialized = false;
	return true;
}



BOOL APIENTRY DllMain(HMODULE hModule, DWORD fdwReason, LPVOID lpReserved)
{
    return TRUE;
}