/*
*	Created:			12.03.09
*	Author:				009
*	Last Modifed:		29.12.09
*	Description:		Стриммер иконок, изменение любого параметра 
*	
*	29.12.09:
*	1.Добавлены параметры: mode interior & virtual world
*	2.Добавлена проверка аргументов на ошибки
*	3.Добавлен дебаг
*	4.Добавлены offset и counter
*
*	29.10.09:
*	1.Стриммер работает на OnPlayerUpdate
*	2.Лимит иконок для игроков - 100
*
*	05.09.09:
*	1.Сменены MAX_PLAYERS на GetMaxPlayer() в циклах
*	2.Заменён GetDistancePlayertoXYZ на IsPlayerInRangeOfPoint
*/

#if defined _mode_icons_included
	#endinput
#endif

#define _mode_icons_included
#pragma library mode_icons

// --------------------------------------------------
// includes
// --------------------------------------------------
#include "mode_debug"
#include "mode_core"

// --------------------------------------------------
// definess
// --------------------------------------------------
#define MAX_MODE_ICONS 1200
#define INVALID_MODE_ICON_ID -1
#define ICONS_DISTANCE 500.0
#if !defined MAX_ICONS 
	#define MAX_ICONS 100
#endif
#if !defined INVALID_ICON_ID
	#define INVALID_ICON_ID MAX_ICONS+1
#endif

// --------------------------------------------------
// enums
// --------------------------------------------------
enum ModeIconsIconInfo {
	iIconId,
	iColor
};
enum ModeIconsCoordInfo {
	Float:cPos[3],
	cModeInteriorId,
	cVirtualWorldId
};
enum ModeIconsInfo {
	bool:iActive,
	iIcon[ModeIconsIconInfo],
	iCoordinates[ModeIconsCoordInfo]
}
enum ModeIconsPlayerInfo {
	pOffset,
	bool:pState[MAX_ICONS],
	pGameId[MAX_MODE_ICONS]
};

// --------------------------------------------------
// news
// --------------------------------------------------
new ModeIcons[MAX_MODE_ICONS][ModeIconsInfo],
	ModeIcons_Player[MAX_PLAYERS][ModeIconsPlayerInfo],
	ModeIconsOffset,
	ModeIconsCount;

// --------------------------------------------------
// natives list (for pawno functions list)
// --------------------------------------------------
/*
native CreateModeIcon(Icon,Color,Float:X,Float:Y,Float:Z,ModeInterior,VirtualWorld);
native DestroyModeIcon(iconid);
native GetModeIconPos(iconid,&Float:X,&Float:Y,&Float:Z);
native SetModeIconPos(iconid,Float:X,Float:Y,Float:Z);
native GetModeIconModeInterior(iconid);
native SetModeIconModeInterior(iconid,modeinterior);
native GetModeIconVirtualWorld(iconid);
native SetModeIconVirtualWorld(iconid,virtualworld);
native GetModeIconIcon(iconid);
native SetModeIconIcon(iconid,icon);
native GetModeIconColor(iconid);
native SetModeIconColor(iconid,color);
native IsModeIconNeedToShow(playerid,iconid);
*/

// --------------------------------------------------
// stocks
// --------------------------------------------------
stock CreateModeIcon(Icon,Color,Float:X,Float:Y,Float:Z,ModeInterior,VirtualWorld)
{
	Debug(DEBUG_START,"CreateModeIcon(%d,%d,%f,%f,%f,%d,%d,)",Icon,Color,X,Y,Z,ModeInterior,VirtualWorld);
	for(new iconid = ModeIconsOffset;iconid < MAX_MODE_ICONS;iconid++)
	{
	    if(ModeIcons[iconid][iActive] == true) continue;
		Debug(DEBUG_ACTION,"Finded free slot,id = %d , set main data",iconid);
		ModeIcons[iconid][iActive] = true;
		Debug(DEBUG_ACTION,"Icon info set");
		ModeIcons[iconid][iIcon][iIconId] = Icon;
		ModeIcons[iconid][iIcon][iColor] = Color;
		Debug(DEBUG_ACTION,"Coordinates info set");
		ModeIcons[iconid][iCoordinates][cPos][0] = X;
		ModeIcons[iconid][iCoordinates][cPos][1] = Y;
		ModeIcons[iconid][iCoordinates][cPos][2] = Z;		
		ModeIcons[iconid][iCoordinates][cModeInteriorId] = ModeInterior;
		ModeIcons[iconid][iCoordinates][cVirtualWorldId] = VirtualWorld;
		Debug(DEBUG_ACTION,"Players info set");
		for(new playerid = 0;playerid < MAX_PLAYERS;playerid++) ModeIcons_Player[playerid][pGameId][iconid] = INVALID_ICON_ID;
		Debug(DEBUG_ACTION,"Set offset data(old: %d,%d)",ModeIconsOffset,ModeIconsCount);
		ModeIconsOffset = iconid;
		if(ModeIconsCount < iconid) ModeIconsCount = iconid;
		Debug(DEBUG_END,"CreateModeIcon(reason: complete)");
		return iconid;
	}
	Debug(DEBUG_END,"CreateModeIcon(reason: all slots used)");
	print("[WARNING] Mode icons -> CreateModeIcon (all slots used)");
	return 0;
}

stock DestroyModeIcon(iconid)
{
	Debug(DEBUG_START,"DestroyModeIcon(%d)",iconid);
	if(ModeIcons[iconid][iActive] == false)
	{
		Debug(DEBUG_END,"DestroyModeIcon(reason: error)");
		printf("[ERROR] Mode icons -> DestroyModeIcon (try destroy not created icon, iconid = %d)",iconid);
		return 0;
	}
	ModeIcons[iconid][iActive] = false;
	Debug(DEBUG_ACTION,"Icon info set");
	ModeIcons[iconid][iIcon][iIconId] = 0;
	ModeIcons[iconid][iIcon][iColor] = 0;
	Debug(DEBUG_ACTION,"Coordinates info reset");
	for(new i = 0;i < 3;i++) ModeIcons[iconid][iCoordinates][cPos][i] = 0.0;
	ModeIcons[iconid][iCoordinates][cModeInteriorId] = 0;
	ModeIcons[iconid][iCoordinates][cVirtualWorldId] = 0;
	Debug(DEBUG_ACTION,"Players info reset and destroy icon");
	for(new playerid = 0;playerid < MAX_PLAYERS;playerid++) 
	{
		if(ModeIcons_Player[playerid][pGameId][iconid] != INVALID_ICON_ID)
		{
			RemovePlayerMapIcon(playerid,ModeIcons_Player[playerid][pGameId][iconid]);
			ModeIcons_Player[playerid][pState][ ModeIcons_Player[playerid][pGameId][iconid] ] = false;
			ModeIcons_Player[playerid][pGameId][iconid] = INVALID_ICON_ID;
			if(ModeIcons_Player[playerid][pOffset] > iconid) ModeIcons_Player[playerid][pOffset] = iconid;
		}
	}
	Debug(DEBUG_ACTION,"Counter reset");
	if(ModeIconsOffset > iconid) ModeIconsOffset = iconid;
	if(ModeIconsCount == iconid) 
	{
		do ModeIconsCount--;
		while((ModeIcons[ ModeIconsCount ][iActive] == false) && (ModeIconsCount > 0));
	}
	Debug(DEBUG_END,"DestroyModeIcon(reason: complete)");
	return 1;
}

stock GetModeIconPos(iconid,&Float:X,&Float:Y,&Float:Z)
{
	Debug(DEBUG_START,"GetModeIconPos(%d)",iconid);
	if(ModeIcons[iconid][iActive] == false)
	{
		Debug(DEBUG_END,"GetModeIconPos(reason: error)");
		printf("[ERROR] Mode icons -> GetModeIconPos (try get pos not created icon's, iconid = %d)",iconid);
		return 0;
	}
	X = ModeIcons[iconid][iCoordinates][cPos][0];
	Y = ModeIcons[iconid][iCoordinates][cPos][1];
	Z = ModeIcons[iconid][iCoordinates][cPos][2];
	Debug(DEBUG_END,"GetModeIconPos(reason: complete)");
	return 1;
}

stock SetModeIconPos(iconid,Float:X,Float:Y,Float:Z)
{
	Debug(DEBUG_START,"SetModeIconPos(%d,%f,%f,%f)",iconid,X,Y,Z);
	if(ModeIcons[iconid][iActive] == false)
	{
		Debug(DEBUG_END,"SetModeIconPos(reason: error)");
		printf("[ERROR] Mode icons -> SetModeIconPos (try set pos not created icon's, iconid = %d)",iconid);
		return 0;
	}
	Debug(DEBUG_ACTION,"set new coords info");
	ModeIcons[iconid][iCoordinates][cPos][0] = X;
	ModeIcons[iconid][iCoordinates][cPos][1] = Y;
	ModeIcons[iconid][iCoordinates][cPos][2] = Z;
	Debug(DEBUG_ACTION,"destroy icon");
	for(new playerid = 0;playerid <= GetMaxPlayer();playerid++) 
	{
		if(ModeIcons_Player[playerid][pGameId][iconid] != INVALID_ICON_ID)
		{
			RemovePlayerMapIcon(playerid,ModeIcons_Player[playerid][pGameId][iconid]);
			ModeIcons_Player[playerid][pState][ ModeIcons_Player[playerid][pGameId][iconid] ] = false;
			ModeIcons_Player[playerid][pGameId][iconid] = INVALID_ICON_ID;
			if(ModeIcons_Player[playerid][pOffset] > iconid) ModeIcons_Player[playerid][pOffset] = iconid;
		}
	}
	Debug(DEBUG_END,"SetModeIconPos(reason: complete)");
	return 1;
}

stock GetModeIconModeInterior(iconid)
{
	Debug(DEBUG_START,"GetModeIconModeInterior(%d)",iconid);
	if(ModeIcons[iconid][iActive] == false)
	{
		Debug(DEBUG_END,"GetModeIconModeInterior(reason: error)");
		printf("[ERROR] Mode icons -> GetModeIconModeInterior (try get mode interior not created icon's, iconid = %d)",iconid);
		return 0;
	}
	Debug(DEBUG_END,"GetModeIconModeInterior(reason: complete)");
	return ModeIcons[iconid][iCoordinates][cModeInteriorId];
}

stock SetModeIconModeInterior(iconid,modeinterior)
{
	Debug(DEBUG_START,"SetModeIconModeInterior(%d,%d)",iconid,modeinterior);
	if(ModeIcons[iconid][iActive] == false)
	{
		Debug(DEBUG_END,"SetModeIconModeInterior(reason: error)");
		printf("[ERROR] Mode icons -> SetModeIconModeInterior (try set mode interior not created icon, iconid = %d)",iconid);
		return 0;
	}
	Debug(DEBUG_ACTION,"set new data and destroy icon");
	ModeIcons[iconid][iCoordinates][cModeInteriorId] = modeinterior;
	for(new playerid = 0;playerid <= GetMaxPlayer();playerid++) 
	{
		if(ModeIcons_Player[playerid][pGameId][iconid] != INVALID_ICON_ID)
		{
			RemovePlayerMapIcon(playerid,ModeIcons_Player[playerid][pGameId][iconid]);
			ModeIcons_Player[playerid][pState][ ModeIcons_Player[playerid][pGameId][iconid] ] = false;
			ModeIcons_Player[playerid][pGameId][iconid] = INVALID_ICON_ID;
			if(ModeIcons_Player[playerid][pOffset] > iconid) ModeIcons_Player[playerid][pOffset] = iconid;
		}
	}
	Debug(DEBUG_END,"SetModeIconModeInterior(reason: complete)");
	return 1;
}

stock GetModeIconVirtualWorld(iconid)
{
	Debug(DEBUG_START,"GetModeIconVirtualWorld(%d)",iconid);
	if(ModeIcons[iconid][iActive] == false)
	{
		Debug(DEBUG_END,"GetModeIconVirtualWorld(reason: error)");
		printf("[ERROR] Mode icons -> GetModeIconVirtualWorld (try get virtualworld not created icon's, iconid = %d)",iconid);
		return 0;
	}
	Debug(DEBUG_END,"GetModeIconVirtualWorld(reason: complete)");
	return ModeIcons[iconid][iCoordinates][cVirtualWorldId];
}

stock SetModeIconVirtualWorld(iconid,virtualworld)
{
	Debug(DEBUG_START,"SetModeIconVirtualWorld(%d,%d)",iconid,virtualworld);
	if(ModeIcons[iconid][iActive] == false)
	{
		Debug(DEBUG_END,"SetModeIconVirtualWorld(reason: error)");
		printf("[ERROR] Mode icons -> SetModeIconVirtualWorld (try set virtualworld not created icon, iconid = %d)",iconid);
		return 0;
	}
	Debug(DEBUG_ACTION,"set new data and destroy icon");
	ModeIcons[iconid][iCoordinates][cVirtualWorldId] = virtualworld;
	for(new playerid = 0;playerid <= GetMaxPlayer();playerid++) 
	{
		if(ModeIcons_Player[playerid][pGameId][iconid] != INVALID_ICON_ID)
		{
			RemovePlayerMapIcon(playerid,ModeIcons_Player[playerid][pGameId][iconid]);
			ModeIcons_Player[playerid][pState][ ModeIcons_Player[playerid][pGameId][iconid] ] = false;
			ModeIcons_Player[playerid][pGameId][iconid] = INVALID_ICON_ID;
			if(ModeIcons_Player[playerid][pOffset] > iconid) ModeIcons_Player[playerid][pOffset] = iconid;
		}
	}
	Debug(DEBUG_END,"SetModeIconVirtualWorld(reason: complete)");
	return 1;
}

stock GetModeIconIcon(iconid)
{
	Debug(DEBUG_START,"GetModeIconIcon(%d)",iconid);
	if(ModeIcons[iconid][iActive] == false)
	{
		Debug(DEBUG_END,"GetModeIconIcon(reason: error)");
		printf("[ERROR] Mode icons -> GetModeIconIcon (try get icon not created icon's, iconid = %d)",iconid);
		return 0;
	}
	Debug(DEBUG_END,"GetModeIconIcon(reason: complete)");
	return ModeIcons[iconid][iIcon][iIconId];
}

stock SetModeIconIcon(iconid,icon)
{
	Debug(DEBUG_START,"SetModeIconIcon(%d,%d)",iconid,icon);
	if(ModeIcons[iconid][iActive] == false)
	{
		Debug(DEBUG_END,"SetModeIconIcon(reason: error)");
		printf("[ERROR] Mode icons -> SetModeIconIcon (try set icon not created icon, iconid = %d)",iconid);
		return 0;
	}
	Debug(DEBUG_ACTION,"set new data and destroy icon");
	ModeIcons[iconid][iCoordinates][iIconId] = icon;
	for(new playerid = 0;playerid <= GetMaxPlayer();playerid++) 
	{
		if(ModeIcons_Player[playerid][pGameId][iconid] != INVALID_ICON_ID)
		{
			RemovePlayerMapIcon(playerid,ModeIcons_Player[playerid][pGameId][iconid]);
			ModeIcons_Player[playerid][pState][ ModeIcons_Player[playerid][pGameId][iconid] ] = false;
			ModeIcons_Player[playerid][pGameId][iconid] = INVALID_ICON_ID;
			if(ModeIcons_Player[playerid][pOffset] > iconid) ModeIcons_Player[playerid][pOffset] = iconid;
		}
	}
	Debug(DEBUG_END,"SetModeIconIcon(reason: complete)");
	return 1;
}

stock GetModeIconColor(iconid)
{
	Debug(DEBUG_START,"GetModeIconColor(%d)",iconid);
	if(ModeIcons[iconid][iActive] == false)
	{
		Debug(DEBUG_END,"GetModeIconColor(reason: error)");
		printf("[ERROR] Mode icons -> GetModeIconColor (try get color not created icon's, iconid = %d)",iconid);
		return 0;
	}
	Debug(DEBUG_END,"GetModeIconColor(reason: complete)");
	return ModeIcons[iconid][iIcon][iColor];
}

stock SetModeIconColor(iconid,color)
{
	Debug(DEBUG_START,"SetModeIconColor(%d,%d)",iconid,color);
	if(ModeIcons[iconid][iActive] == false)
	{
		Debug(DEBUG_END,"SetModeIconColor(reason: error)");
		printf("[ERROR] Mode icons -> SetModeIconColor (try set color not created icon, iconid = %d)",iconid);
		return 0;
	}
	Debug(DEBUG_ACTION,"set new data and destroy icon");
	ModeIcons[iconid][iIcon][iColor] = color;
	for(new playerid = 0;playerid <= GetMaxPlayer();playerid++) 
	{
		if(ModeIcons_Player[playerid][pGameId][iconid] != INVALID_ICON_ID)
		{
			RemovePlayerMapIcon(playerid,ModeIcons_Player[playerid][pGameId][iconid]);
			ModeIcons_Player[playerid][pState][ ModeIcons_Player[playerid][pGameId][iconid] ] = false;
			ModeIcons_Player[playerid][pGameId][iconid] = INVALID_ICON_ID;
			if(ModeIcons_Player[playerid][pOffset] > iconid) ModeIcons_Player[playerid][pOffset] = iconid;
		}
	}
	Debug(DEBUG_END,"SetModeIconColor(reason: complete)");
	return 1;
}

stock IsModeIconNeedToShow(playerid,iconid)
{
	Debug(DEBUG_START,"IsModeIconNeedToShow(%d,%d)",playerid,iconid);
	if(!IsPlayerConnected(playerid))
	{
		Debug(DEBUG_END,"IsModeIconNeedToShow(reason: error)");
		printf("[ERROR] Mode pickups -> IsModeIconNeedToShow (try check icon for offline player, playerid = %d)",playerid);
		return 0;
	}
	if(ModeIcons[iconid][iActive] == false)
	{
		Debug(DEBUG_END,"IsModeIconNeedToShow(reason: error)");
		printf("[ERROR] Mode pickups -> IsModeIconNeedToShow (try check not created icon, iconid = %d)",iconid);
		return 0;
	}
	Debug(DEBUG_END,"IsModeIconNeedToShow(reason: complete)");
	if(!IsPlayerInRangeOfPoint(playerid,ICONS_DISTANCE,ModeIcons[iconid][iCoordinates][cPos][0],ModeIcons[iconid][iCoordinates][cPos][1],ModeIcons[iconid][iCoordinates][cPos][2])) return 0;
	if((GetPlayerModeInterior(playerid) != ModeIcons[iconid][iCoordinates][cModeInteriorId]) && (ModeIcons[iconid][iCoordinates][cModeInteriorId] != -1)) return 0;
	if((GetPlayerVirtualWorld(playerid) != ModeIcons[iconid][iCoordinates][cVirtualWorldId]) && (ModeIcons[iconid][iCoordinates][cVirtualWorldId] != -1)) return 0;
	return 1;
}

// --------------------------------------------------
// Obligatory functions
// --------------------------------------------------
ModeIcons_OnGameModeInit()
{
	Debug(DEBUG_START,"ModeIcons_OnGameModeInit");
	print("Mode icons system loaded.");
	Debug(DEBUG_END,"ModeIcons_OnGameModeInit");	
}

ModeIcons_ResetStat(playerid)
{
	Debug(DEBUG_START,"ModeIcons_ResetStat(%d)",playerid);
	for(new iconid = 0;iconid < MAX_MODE_ICONS;iconid++) ModeIcons_Player[playerid][pGameId][iconid] = INVALID_ICON_ID;
	ModeIcons_Player[playerid][pOffset] = 0;
	Debug(DEBUG_END,"ModeIcons_ResetStat");
}

ModeIcons_OnPlayerUpdate(playerid)
{
	Debug(DEBUG_START,"ModeIcons_OnPlayerUpdate(%d)",playerid);
	for(new iconid = 0;iconid < ModeIconsCount;iconid++)
	{
		if(ModeIcons[iconid][iActive] == false) continue;
		
		if(ModeIcons_Player[playerid][pGameId][iconid] != INVALID_ICON_ID)
		{
			if(IsModeIconNeedToShow(playerid,iconid)) continue;
			RemovePlayerMapIcon(playerid,ModeIcons_Player[playerid][pGameId][iconid]);
			ModeIcons_Player[playerid][pState][ ModeIcons_Player[playerid][pGameId][iconid] ] = false;
			ModeIcons_Player[playerid][pGameId][iconid] = INVALID_ICON_ID;
			if(ModeIcons_Player[playerid][pOffset] > iconid) ModeIcons_Player[playerid][pOffset] = iconid;
		}
		else
		{
			if(!IsModeIconNeedToShow(playerid,iconid)) continue;
			for(new i = ModeIcons_Player[playerid][pOffset];i < MAX_ICONS;i++)
			{
				if(ModeIcons_Player[playerid][pState][i] == true) continue;
				ModeIcons_Player[playerid][pState][i] = true;
				ModeIcons_Player[playerid][pGameId][iconid] = i;
				SetPlayerMapIcon(playerid,i,ModeIcons[iconid][iCoordinates][cPos][0],ModeIcons[iconid][iCoordinates][cPos][1],ModeIcons[iconid][iCoordinates][cPos][2],ModeIcons[iconid][iIcon][iIcon],ModeIcons[iconid][iIcon][iColor]);
				ModeIcons_Player[playerid][pOffset] = i;
				break;
			}
		}
	}
	Debug(DEBUG_END,"ModeIcons_OnPlayerUpdate");
}