#include <a_samp>
#include <core>
#include <float>

new globalik, whatislight = 5, lighttimer = -1, howmanyplayer;

new lightstartdelay = 5000;
new tl_green = 10400;
new tl_red = 20400;
new tl_yellow = 2000;

forward LightUpdate(lighttobe);
public LightUpdate(lighttobe)
{
	new sure, zamanzaman = GetTickCount();
	whatislight = lighttobe;
	switch(lighttobe)
	{
		case 1:
		{
		    sure = globalik + tl_red;
			#if defined DONT_CALL_TL_CB_IF_DELAYED
			if(zamanzaman <= (sure + 500))
			{
			#endif
				CallLocalFunction("OnTrafficLightStateChange","i",lighttobe);
			#if defined DONT_CALL_TL_CB_IF_DELAYED
			}
			#endif
		    sure = sure + tl_green - zamanzaman;
		    if(sure <= 0)
		    {
				LightUpdate(2);
				lighttimer = -1;
		        return 1;
		    }
		    else lighttimer = SetTimerEx("LightUpdate",sure,0,"i",2);
		    return 1;
		}
		case 2:
		{
		    sure = globalik + tl_red + tl_green;
			#if defined DONT_CALL_TL_CB_IF_DELAYED
			if(zamanzaman <= (sure + 500))
			{
			#endif
				CallLocalFunction("OnTrafficLightStateChange","i",lighttobe);
			#if defined DONT_CALL_TL_CB_IF_DELAYED
			}
			#endif
			sure = sure + tl_yellow - zamanzaman;
			if(sure <= 0)
		    {
				LightUpdate(3);
				lighttimer = -1;
		        return 1;
		    }
		    else lighttimer = SetTimerEx("LightUpdate",sure,0,"i",3);
		    return 1;
		}
		case 3:
		{
		    sure = globalik + tl_red + tl_green + tl_yellow;
			#if defined DONT_CALL_TL_CB_IF_DELAYED
			if(zamanzaman <= (sure + 500))
			{
			#endif
				CallLocalFunction("OnTrafficLightStateChange","i",lighttobe);
			#if defined DONT_CALL_TL_CB_IF_DELAYED
			}
			#endif
		    sure = sure + tl_green - zamanzaman;
		    if(sure <= 0)
		    {
				LightUpdate(4);
				lighttimer = -1;
		        return 1;
		    }
		    else lighttimer = SetTimerEx("LightUpdate",sure,0,"i",4);
		    return 1;
		}
		case 4:
		{
 			sure = globalik + tl_red + tl_green + tl_yellow + tl_green;
			#if defined DONT_CALL_TL_CB_IF_DELAYED
			if(zamanzaman <= (sure + 500))
			{
			#endif
				CallLocalFunction("OnTrafficLightStateChange","i",lighttobe);
			#if defined DONT_CALL_TL_CB_IF_DELAYED
			}
			#endif
		    sure = sure + tl_yellow - zamanzaman;
		    if(sure <= 0)
		    {
				LightUpdate(5);
				lighttimer = -1;
		        return 1;
		    }
		    else lighttimer = SetTimerEx("LightUpdate",sure,0,"i",5);
		    return 1;
		}
		case 5:
		{
 			sure = globalik + tl_red + tl_green + tl_yellow + tl_green + tl_yellow;
			#if defined DONT_CALL_TL_CB_IF_DELAYED
			if(zamanzaman <= (sure + 500))
			{
			#endif
				CallLocalFunction("OnTrafficLightStateChange","i",lighttobe);
			#if defined DONT_CALL_TL_CB_IF_DELAYED
			}
			#endif
		    sure = sure + tl_green - tl_yellow - zamanzaman;
			globalik = globalik + tl_green + tl_red + tl_yellow;
		    if(sure <= 0)
		    {
				LightUpdate(1);
				lighttimer = -1;
		        return 1;
		    }
		    else lighttimer = SetTimerEx("LightUpdate",sure,0,"i",1);
		    return 1;
		}
	}
	return 1;
}

stock GetTrafficLightState()
{
	return whatislight;
}

forward CalibrateTrafficLightCounter(lightstate);
public CalibrateTrafficLightCounter(lightstate)
{
	switch(lightstate)
	{
		case 1:
		{
			globalik = GetTickCount() - tl_red;
		}
		case 2:
		{
			globalik = GetTickCount() - tl_red - tl_green;
		}
		case 3:
		{
			globalik = GetTickCount() - tl_red - tl_green - tl_yellow;
		}
		case 4:
		{
			globalik = GetTickCount() - tl_red - tl_green - tl_yellow - tl_green;
		}
		case 5:
		{
			globalik = GetTickCount();
		}
	}
	if(lighttimer != -1)
	{
		KillTimer(lighttimer);
	}
	LightUpdate(lightstate);
	return 1;
}

forward OnTrafficLightStateChange(lightstate);

public OnPlayerConnect(playerid)
{
	if(!IsPlayerNPC(playerid))
	{
		if(!howmanyplayer)
		{
			lighttimer = SetTimerEx("CalibrateTrafficLightCounter",tl_red - lightstartdelay,0,"i",1);
		}
		howmanyplayer ++;
	}
	#if defined TRAFFIC_OnPlayerConnect
		return TRAFFIC_OnPlayerConnect(playerid);
	#else
		return 1;
	#endif
}

#if defined _ALS_OnPlayerConnect
	#undef OnPlayerConnect
#else
	#define _ALS_OnPlayerConnect
#endif
#define OnPlayerConnect TRAFFIC_OnPlayerConnect
#if defined TRAFFIC_OnPlayerConnect
	forward TRAFFIC_OnPlayerConnect(playerid);
#endif

public OnPlayerDisconnect(playerid, reason)
{
	if(!IsPlayerNPC(playerid))
	{
		howmanyplayer --;
		if(!howmanyplayer)
		{
			if(lighttimer != -1)
			{
				KillTimer(lighttimer);
			}
		}
	}
	#if defined TRAFFIC_OnPlayerDisconnect
		return TRAFFIC_OnPlayerDisconnect(playerid,reason);
	#else
		return 1;
	#endif
}

#if defined _ALS_OnPlayerDisconnect
	#undef OnPlayerDisconnect
#else
	#define _ALS_OnPlayerDisconnect
#endif
#define OnPlayerDisconnect TRAFFIC_OnPlayerDisconnect
#if defined TRAFFIC_OnPlayerDisconnect
	forward TRAFFIC_OnPlayerDisconnect(playerid,reason);
#endif