#define _WIN32_WINNT 0x0502

#include "Windows.h"
#include "scripts.h"
#include "engine.h"
#include "stdio.h"
#include "YaRR.h"

HMODULE dlls[64];
static int scriptFunctions[86];
static bool YaRR_Loaded = 0;

void YaRR_Load()
{
	if(YaRR_Loaded)
	{
		return;
	}

	
	YaRR_Loaded = 1;

	memset((void *)dlls, 0, 64*4);

	char path[256];
	GetModulePath(0, path, 256);
	strcat(path, "\\YaRR");
	SetDllDirectory(path);

	Request_Load("YaRR.dll");
	scriptFunctions[0] = 0;	
}

void YaRR_Unload()
{
	for(int i = 0; i < 64; i++)
	{
		if(dlls[i])
		{
			FreeLibrary(dlls[i]);
			dlls[i] = 0;
		}
	}
}


extern "C" __declspec(dllexport) void Request_Load(const char *Module)
{
	if(scriptFunctions[0] == 0)
	{
		Load_Script_Commands(scriptFunctions);
	}

	for(int i = 0; i < 64; i++)
	{
		if(!dlls[i])
		{
			dlls[i] = LoadLibrary(Module);
			if(!dlls[i])
			{
				printf("[Error] Error loading %s\n[Error] %d\n", Module, GetLastError());
			}
			else
			{
				_Set_Script_Commands dll_Set_Script_Commands = (_Set_Script_Commands)GetProcAddress(dlls[i], "Set_Script_Commands");
				if(!dll_Set_Script_Commands)
				{
					printf("Loaded stand alone dll: %s \n", Module);
				}
				else
				{
					dll_Set_Script_Commands(scriptFunctions, Commands, Request_Load, Request_Unload, Request_Reload);
					printf("Loaded: %s\n", Module);
				}
			}
			break;
		}
	}
}

extern "C" __declspec(dllexport) void Request_Unload(HMODULE dll)
{
	for(int i = 0; i < 64; i++)
	{
		if(dlls[i] == dll)
		{
			FreeLibrary(dll);
			dlls[i] = 0;
		}
	}
}

extern "C" __declspec(dllexport) void Request_Reload(HMODULE dll)
{
	for(int i = 0; i < 64; i++)
	{
		if(dlls[i] == dll)
		{
			char path[256];
			GetModuleFileName(dll, path, 256);
			FreeLibrary(dll);

			Request_Load(path);

			break;
		}
	}
}

DWORD GetModulePath(HINSTANCE hInst, LPTSTR pszBuffer, DWORD dwSize ) //This function was created by microsoft
{
	DWORD dwLength = GetModuleFileName( hInst, pszBuffer, dwSize );
	if( dwLength )
	{
		while( dwLength && pszBuffer[ dwLength ] != '\\')
		{
			dwLength--;
		}

		if( dwLength )
			pszBuffer[ dwLength] = '\000';
	}
	return dwLength;
}

void Load_Script_Commands(int *x)
{
	x[0] = (int)Enable_Stealth_Player;
	x[1] = (int)Set_Fog_Enable_Player;
	x[2] = (int)Set_Fog_Range_Player;
	x[3] = (int)Set_Background_Music_Player;
	x[4] = (int)Fade_Background_Music_Player;
	x[5] = (int)Stop_Background_Music_Player;
	x[6] = (int)Enable_Radar_Player;
	x[7] = (int)Display_GDI_Player_Terminal_Player;
	x[8] = (int)Display_NOD_Player_Terminal_Player;
	x[9] = (int)Set_Screen_Fade_Color_Player;
	x[10] = (int)Set_Screen_Fade_Opacity_Player;
	x[11] = (int)Force_Camera_Look_Player;
	x[12] = (int)Enable_HUD_Player;
	x[13] = (int)Create_Sound_Player;
	x[14] = (int)Create_2D_Sound_Player;
	x[15] = (int)Create_2D_WAV_Sound_Player;
	x[16] = (int)Create_3D_WAV_Sound_At_Bone_Player;
	x[17] = (int)Create_3D_Sound_At_Bone_Player;
	x[18] = (int)Set_Display_Color_Player;
	x[19] = (int)Display_Text_Player;
	x[20] = (int)Display_Int_Player;
	x[21] = (int)Display_Float_Player;
	x[22] = (int)Set_Obj_Radar_Blip_Shape_Player;
	x[23] = (int)Set_Obj_Radar_Blip_Color_Player;
	x[24] = (int)AddObjectCreateHook;
	x[25] = (int)RemoveObjectCreateHook;
	x[26] = (int)AddKeyHook;
	x[27] = (int)RemoveKeyHook;
	x[28] = (int)Set_Scope;
	x[29] = (int)Set_HUD_Texture;
	x[30] = (int)AddChatHook;
	x[31] = (int)AddHostHook;
	x[32] = (int)AddLoadLevelHook;
	x[33] = (int)AddGameOverHook;
	x[34] = (int)AddPlayerJoinHook;
	x[35] = (int)GetCurrentMusicTrack;
	x[36] = (int)Set_Info_Texture;
	x[37] = (int)Clear_Info_Texture;
	x[38] = (int)Set_Vehicle_Limit;
	x[39] = (int)Get_Vehicle_Limit;
	x[40] = (int)Send_Message;
	x[41] = (int)Send_Message_Player;
	x[42] = (int)AddVersionHook;
	x[43] = (int)Set_Wireframe_Mode;
	x[44] = (int)Load_New_HUD_INI;
	x[45] = (int)Remove_Weapon;
	x[46] = (int)Update_PT_Data;
	x[47] = (int)Change_Radar_Map;
	x[48] = (int)AddPowerupPurchaseHook;
	x[49] = (int)AddVehiclePurchaseHook;
	x[50] = (int)AddCharacterPurchaseHook;
	x[51] = (int)AddPowerupPurchaseMonHook;
	x[52] = (int)AddVehiclePurchaseMonHook;
	x[53] = (int)AddCharacterPurchaseMonHook;
	x[54] = (int)RemovePowerupPurchaseHook;
	x[55] = (int)RemoveVehiclePurchaseHook;
	x[56] = (int)RemoveCharacterPurchaseHook;
	x[57] = (int)RemovePowerupPurchaseMonHook;
	x[58] = (int)RemoveVehiclePurchaseMonHook;
	x[59] = (int)RemoveCharacterPurchaseMonHook;
	x[60] = (int)Get_Build_Time_Multiplier;
	x[61] = (int)Set_Currently_Building;
	x[62] = (int)Is_Currently_Building;
	x[63] = (int)AddConsoleOutputHook;
	x[64] = (int)AddCRCHook;
	x[65] = (int)AddDataHook;
	x[66] = (int)Set_Reticle_Texture1;
	x[67] = (int)Set_Reticle_Texture2;
	x[68] = (int)Set_Fog_Color;
	x[69] = (int)Set_Fog_Color_Player;
	x[70] = (int)Set_Fog_Mode;
	x[71] = (int)Set_Fog_Mode_Player;
	x[72] = (int)Set_Shader_Number;
	x[73] = (int)Send_HUD_Number;
	x[74] = (int)Set_Fog_Density;
	x[75] = (int)Set_Fog_Density_Player;
	x[76] = (int)Change_Time_Remaining;
	x[77] = (int)Change_Time_Limit;
	x[78] = (int)Display_GDI_Sidebar;
	x[79] = (int)Display_NOD_Sidebar;
	x[80] = (int)Display_Security_Dialog;
	x[81] = (int)AddPlayerLeaveHook;
	x[82] = (int)GetExplosionObj;
	x[83] = (int)GetBHSVersion;
	x[84] = (int)Set_Shader_Number_Vector;
	x[85] = (int)AddShaderNotify;
	x[86] = (int)RemoveShaderNotify;
}
