//////////////////////////////////////////////////////////////////////////
//ModIconDLL
// 
//Copyright (C)2006-2007 WiZaRd ( thewizardofdos@gmail.com / http://kademlia-net.de )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//This is a dll which wraps the annoying task of managing modicons for the modder
//Feel free to use it as you like, however you HAVE to mention me as the author
//and make your program OpenSource if you use this code or parts of it in 
//your own program!
//////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <atlstr.h>
#include "ModIconDLL.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

enum eModIcon 
{
//Read this carefully!
//this will be/should be hardcoded in future versions, just kept for compatibility
	eMOD_BADGUY = 0,
	eMOD_ACKRONIC,
	eMOD_EMULEFUTURE,
	eMOD_TOMBSTONE,
	eMOD_CYREX,
	eMOD_EASTSHARE,
	eMOD_IONIX,
	eMOD_MAXMOD,
	eMOD_MORPH,
	eMOD_NEOMULE,
	eMOD_NEXTEMF,
	eMOD_SCARANGEL,
	eMOD_STULLE,
	eMOD_WEBCACHE,
	eMOD_XTREME,
	eMOD_EF_MOD,
	eMOD_FRTK_EVOSTAR,
	eMOD_EWOMBAT,
	eMOD_HEARTBREAKER,
	eMOD_LSD,
	eMOD_KILLERBEAN,
	eMOD_NETF,
	eMOD_EMULESPANA,
	eMOD_PHOENIX,
	eMOD_ZZUL,
	eMOD_LAMA,
	eMOD_SPIKE2,
	eMOD_FLOWERPOWER,
	eMOD_HARDSTYLE,
	eMOD_SMARTMULI,
	eMOD_BASTARD,
	eMOD_BOWLFISH,
	eMOD_MAGICANGEL,
	eMOD_REDSMURF,
	eMOD_TK4,
	eMOD_SIVKA,
	eMOD_HEBMULE,
	eMOD_VIPER,
	eMOD_SNAKE,
	eMOD_NETFWARP,
	eMOD_ANTARES,
	eMOD_EXORZIST,
	eMOD_NEXTEVO,
	eMOD_SILVERSURFER,
	eMOD_SION,
	eMOD_ECHANBLARD,
	eMOD_XRAY,
	eMOD_RAPCOM,
	eMOD_RMOD,
	eMOD_DREAMULE,
	eMOD_SHARKX,
	eMOD_BEBA,
	eMOD_MEPHISTO,
	eMOD_ICONCOUNT
};

const CString arrIconStrings[] = {
//Read this carefully!
//this will be/should be hardcoded in future versions, just kept for compatibility
	L"COMPAT_BADGUY",
	L"MOD_ACKRONIC",
	L"MOD_EMULEFUTURE",
	L"MOD_TOMBSTONE",
	L"MOD_CYREX",
	L"MOD_EASTSHARE",
	L"MOD_IONIX",
	L"MOD_MAXMOD",
	L"MOD_MORPH",
	L"MOD_NEOMULE",
	L"MOD_NEXTEMF",
	L"MOD_SCARANGEL",
	L"MOD_STULLE",
	L"MOD_WEBCACHE",
	L"MOD_XTREME",
	L"MOD_EF_MOD",
	L"MOD_FRTK_EVOSTAR",
	L"MOD_EWOMBAT",
	L"MOD_HEARTBREAKER",
	L"MOD_LSD",
	L"MOD_KILLERBEAN",
	L"MOD_NETF",
	L"MOD_EMULESPANA",
	L"MOD_PHOENIX",
	L"MOD_ZZUL",
	L"MOD_LAMA",
	L"MOD_SPIKE2",
	L"MOD_FLOWERPOWER",
	L"MOD_HARDSTYLE",
	L"MOD_SMARTMULI",
	L"MOD_BASTARD",
	L"MOD_BOWLFISH",
	L"MOD_MAGICANGEL",
	L"MOD_REDSMURF",
	L"MOD_TK4",
	L"MOD_SIVKA",
	L"MOD_HEBMULE",
	L"MOD_VIPER",
	L"MOD_SNAKE",
	L"MOD_NETFWARP",
	L"MOD_ANTARES",
	L"MOD_EXORZIST",
	L"MOD_NEXTEVO",
	L"MOD_SILVERSURFER",
	L"MOD_SION",
	L"MOD_ECHANBLARD",
	L"MOD_XRAY",
	L"MOD_RAPCOM",
	L"MOD_RMOD",
	L"MOD_DREAMULE",
	L"MOD_SHARKX",
	L"MOD_BEBA",
	L"MOD_MEPHISTO"
};

struct siIaS //intIconAndString :)
{
	siIaS(const CString& modstring, const int& iconIndex)
	{
		strMod = modstring;
		iIconIndex = iconIndex;
	}
	~siIaS()	{}
	CString strMod;
	int		iIconIndex;
};

const siIaS m_arrIcoList[] = {
	siIaS(L"eMuleFuture v",	eMOD_EMULEFUTURE),
	siIaS(L"Tombstone v",	eMOD_TOMBSTONE),
	siIaS(L"Cyrex2001 ",	eMOD_CYREX), //just to be sure, removed the v
	siIaS(L"EastShare ",	eMOD_EASTSHARE),
	siIaS(L"iONiX v",		eMOD_IONIX),
	siIaS(L"MAXmod",		eMOD_MAXMOD),
	siIaS(L"MorphXT ",		eMOD_MORPH),
	siIaS(L"Neo Mule v",	eMOD_NEOMULE),
	siIaS(L"NextEMF ",		eMOD_NEXTEMF), //v is mandatory
	siIaS(L"ScarAngel",		eMOD_SCARANGEL),
	siIaS(L"StulleMule ",	eMOD_STULLE),
	siIaS(L"WebCache ",		eMOD_WEBCACHE),
	siIaS(L"Xtreme",		eMOD_XTREME),
	siIaS(L"AcKroNiC v",	eMOD_ACKRONIC),
	siIaS(L"eF-Mod ",		eMOD_EF_MOD), //Spike2 - for old versions
	siIaS(L"eF-MOD ",		eMOD_EF_MOD),
	siIaS(L"FRTK EvoStar v",eMOD_FRTK_EVOSTAR),
	siIaS(L"eWombat ",		eMOD_EWOMBAT),
	siIaS(L"LSD-",			eMOD_LSD),
	siIaS(L"LSD.",			eMOD_LSD), //Spike2
	siIaS(L"The Killer Bean", eMOD_KILLERBEAN),
	siIaS(L"NetF WARP v",	eMOD_NETFWARP),	
	siIaS(L"NetF ",			eMOD_NETF),
	siIaS(L"ESE ",			eMOD_NETF),
	siIaS(L"emulEspaņa v",	eMOD_EMULESPANA),
	siIaS(L"pHoeniX ",		eMOD_PHOENIX),
	siIaS(L"ZZUL ",			eMOD_ZZUL),
	siIaS(L"ReSuRReCTioN ",	eMOD_LAMA),
	siIaS(L"Diclonius v",	eMOD_LAMA),
	siIaS(L"Spike2 v",		eMOD_SPIKE2),
	siIaS(L"FlowerPower v",	eMOD_FLOWERPOWER),
	siIaS(L"Hardstyle ",	eMOD_HARDSTYLE),
	siIaS(L"SmartMuli ",	eMOD_SMARTMULI),
	siIaS(L"BastarD ",		eMOD_BASTARD),
	siIaS(L"Bowlfish.",		eMOD_BOWLFISH),
	siIaS(L"Magic Angel",	eMOD_MAGICANGEL),
	siIaS(L"RedSmurf v",	eMOD_REDSMURF),
	siIaS(L"TK4 V",			eMOD_TK4),
	siIaS(L"sivka v",		eMOD_SIVKA),
	siIaS(L"hebMule v",		eMOD_HEBMULE),
	siIaS(L"hebMule-Onyx v",eMOD_HEBMULE),
	siIaS(L"VipeR V",		eMOD_VIPER),
	siIaS(L"Antares ",		eMOD_ANTARES),
	siIaS(L"NextEvolution ",	eMOD_NEXTEVO),
	siIaS(L"Silversurfer v",	eMOD_SILVERSURFER),
	siIaS(L"Silver Surfer v",	eMOD_SILVERSURFER),	//new Silver Surfer [shadow2004]
	siIaS(L"Sion ",			eMOD_SION),
	siIaS(L"eChanblardv", eMOD_ECHANBLARD),		//ancient versions
	siIaS(L"eChanblardNext ", eMOD_ECHANBLARD),
	siIaS(L"X-Ray v",		eMOD_XRAY),
	siIaS(L"RapCom ",		eMOD_RAPCOM),
	siIaS(L"R-Mod v",		eMOD_RMOD),
	siIaS(L"DreaMule ",		eMOD_DREAMULE),
	siIaS(L"SharkX v",		eMOD_SHARKX),
	siIaS(L"beba v",		eMOD_BEBA),
	siIaS(L"Mephisto v",	eMOD_MEPHISTO)
};

const siIaS m_arrIcoFindList[] = {
	siIaS(L"Heartbreaker",	eMOD_HEARTBREAKER),
};

CArray<int> m_arrIcons;

int DLL_EXPORT		FillModIconList(CImageList* pImageList)
{
	//////////////////////////////////////////////////////////////////////////
	// Cleanup - has to be done *every* time!
	m_arrIcons.RemoveAll();
	if(pImageList == NULL)
		return 0; //done ;)

	//////////////////////////////////////////////////////////////////////////
	// Fill image list and map the icon indexes
	m_arrIcons.SetSize(eMOD_ICONCOUNT);
	HICON hIcon = NULL; 
	for(int i = 0; i < ARRSIZE(arrIconStrings); i++)
	{
		hIcon = (HICON)::LoadImage(AfxGetResourceHandle(), arrIconStrings[i], IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
		if(hIcon)
		{
			m_arrIcons[i] = pImageList->Add(hIcon);
			::DestroyIcon(hIcon); //>>> FiX for IP2Country and other custom lists
		}
		else
		{
			TRACE(L"Failed to load %s", arrIconStrings[i]);
			ASSERT(0);
			m_arrIcons[i] = -1;
		}
	}

	//returns the number of MAPPINGS not the number of icons!
	return ARRSIZE(m_arrIcoList)+ARRSIZE(m_arrIcoFindList);
}

int	DLL_EXPORT GetIconIndexForModstring(const CString& strMod)
{
	if(!strMod.IsEmpty())
	{
		//Those are "loose guesses" for parts of a modstring
		for(int i = 0; i < ARRSIZE(m_arrIcoFindList); i++)
		{
			const siIaS* cur = &m_arrIcoFindList[i];
			if(StrStrI(strMod, cur->strMod))
				return m_arrIcons[cur->iIconIndex];
		}
		//These however are "real checks" for the equality of the mod strings
		for(int i = 0; i < ARRSIZE(m_arrIcoList); i++)
		{
			const siIaS* cur = &m_arrIcoList[i];
			if(_tcsncmp(strMod, cur->strMod, cur->strMod.GetLength()) == 0)
				return m_arrIcons[cur->iIconIndex];
		}
		//Here's place for additional (more complex) checks, e.g.:
		if(_tcsncmp(strMod, L"ZX v", 4) == 0)
		{
			//actually we could assign this icon to all ZX versions...
			//first of all the modder seems to be the same and second the 
			//older versions have nearly vanished... but it's a good example :P
			if(_tstoi(strMod.Mid(4, 1)) > 3
				|| (_tstoi(strMod.Mid(4, 1)) == 3 && _tstoi(strMod.Mid(6, 1)) != 0))
				return m_arrIcons[eMOD_SNAKE];
		}
//These must be checked for validity:
		if(strMod.GetLength() > 7)
		{
			CString tmp(strMod);
			tmp.MakeLower();
			if(strMod.GetAt(1) == L'x'
				&& strMod.GetAt(3) == L'r'
				&& strMod.GetAt(4) == L'z'
				&& strMod.GetAt(7) == L't')
				return m_arrIcons[eMOD_EXORZIST];
		}
	}
	return -1;
}