#include <Control.h>

#define STR_MENU_EMPTY_ITEM_E	_LE("Empty")
#define STR_MENU_EMPTY_ITEM		_L("Empty")

class ListStoredMenu : public Menu
{
public:
	ListStoredMenu(HMENU hMenu, UINT nTagID, UINT nBeginID, UINT nEndID) : Menu(hMenu)
	{
		m_nTagID = nTagID;
		m_nBeginID = nBeginID;
		m_nEndID = nEndID;
		
		if ( nBeginID > nEndID )
		{
			m_nBeginID = nEndID;
			m_nEndID = nBeginID;
		}
	}
	
public:
	bool UpdateList(LPCSTR lpcszNew)
	{
		vector<string> vsList;
		GetList(vsList);
		if ( !AddToList(vsList, lpcszNew) )
			return false;
		///---Sim 06-17-2009 FIX_DUPLICATE_RECENT_ITEM
		SetList(vsList);
		///---END FIX_DUPLICATE_RECENT_ITEM
		SaveSettings(vsList);
		return true;
	}
	
	void Load()
	{
		vector<string> vsList;
		LoadSettings(vsList);
		SetList(vsList);
	}
	
	// Sim
	// move from private for dialog
	// should be friend to dialog only, but OC can't support
	void GetList(vector<string>& vsList)
	{
		vsList.SetSize(0);
		for(UINT nCmdID = m_nBeginID; nCmdID <= m_nEndID; nCmdID++)
		{
			string str;
			GetMenuString(nCmdID, str, MF_STRING);
			if(str.IsEmpty())
				break;
			vsList.Add(str);
		}
	
		// remove empty marker
		if ( vsList.GetSize() > 0 )
		{
			if ( compare_string_localization(vsList[0], STR_MENU_EMPTY_ITEM_E, true) )
				vsList.RemoveAt(0);			
		}
	}
	
protected:
	int GetMaxNumList()
	{
		return m_nEndID - m_nBeginID + 1;
	}
	
	virtual bool AddToList(vector<string>& vsList, LPCSTR lpcszNew)
	{
		if ( vsList.GetSize() >= GetMaxNumList() )
			return false;
		
		vsList.Add(lpcszNew);
		///---Sim 06-17-2009 FIX_DUPLICATE_RECENT_ITEM
		//SetList(vsList);
		///---END FIX_DUPLICATE_RECENT_ITEM
		
		return true;
	}
	
private:
	virtual void SaveSettings(const vector<string>& vsList) {ASSERT(FALSE);}
	virtual bool LoadSettings(vector<string>& vsList) {ASSERT(FALSE); return false;}
	virtual void ClearSettings() {ASSERT(FALSE);}
	
private:
	// Sim
	// move to public for dialog
	/*
	void GetList(vector<string>& vsList)
	{
		vsList.SetSize(0);
		for(UINT nCmdID = m_nBeginID; nCmdID <= m_nEndID; nCmdID++)
		{
			string str;
			GetMenuString(nCmdID, str, MF_STRING);
			if(str.IsEmpty())
				break;
			vsList.Add(str);
		}
	
		// remove empty marker
		if ( vsList.GetSize() > 0 )
		{
			if ( compare_string_localization(vsList[0], STR_MENU_EMPTY_ITEM_E, true) )
				vsList.RemoveAt(0);			
		}
	}
	*/
	void SetList(const vector<string>& vsList)
	{
		ClearList();
		
		int nSize = vsList.GetSize();
		if ( nSize > 0 )
		{
			for ( int ii = 0; ii < nSize; ii++ )
			{
				InsertMenu(m_nTagID, MF_STRING, m_nBeginID + ii, vsList[ii]);
			}
			RemoveMenu(m_nTagID, MF_STRING);
		}
	}
	void ClearList()
	{
		string str;
		GetMenuString(m_nBeginID, str, MF_STRING);
		if( !str.IsEmpty() ) // list is not empty
		{
			InsertMenu(m_nBeginID, MF_STRING, m_nTagID, STR_MENU_EMPTY_ITEM);
			for( UINT nCmdID = m_nBeginID; nCmdID <= m_nEndID; nCmdID++ )
				RemoveMenu(nCmdID, MF_STRING);
		}
	}
	
//protected:
	//vector<string> m_vsList;

private:
	UINT m_nTagID, m_nBeginID, m_nEndID;	
};

class MoreListMenu : public ListStoredMenu
{
public:
	MoreListMenu(HMENU hMenu, UINT nTagID, UINT nBeginID, UINT nEndID)
	: ListStoredMenu(hMenu, nTagID, nBeginID, nEndID)
	{
	}
	
public:
	virtual bool AddToList(vector<string>& vsList, LPCSTR lpcszNew)
	{
		if ( vsList.GetSize() >= GetMaxNumList() - 1 )
		{
			// Sim to do
			lpcszNew = _L("More...");
		}
		
		return ListStoredMenu::AddToList(vsList, lpcszNew);
	}
};

class RecentListMenu : public ListStoredMenu
{
public:
	RecentListMenu(HMENU hMenu, UINT nTagID, UINT nBeginID, UINT nEndID)
	: ListStoredMenu(hMenu, nTagID, nBeginID, nEndID)
	{
	}
	
public:
	virtual bool AddToList(vector<string>& vsList, LPCSTR lpcszNew)
	{
		int nRemove = vsList.Find(lpcszNew);
		if( nRemove < 0 && vsList.GetSize() >= GetMaxNumList() ) // full
			nRemove = vsList.GetSize()-1;
		
		if(nRemove >= 0)
			vsList.RemoveAt(nRemove);
		vsList.InsertAt(0, lpcszNew);
	
		///---Sim 06-17-2009 FIX_DUPLICATE_RECENT_ITEM
		//return ListStoredMenu::AddToList(vsList, lpcszNew);
		return true;
		///---END FIX_DUPLICATE_RECENT_ITEM
	}
};


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define MAX_CONDITION						10
#define IDC_RECENT_CONDITION_LIST_BEGIN		IDC_RECENT_FILE_LIST_BEGIN
#define IDC_RECENT_CONDITION_LIST_END  		IDC_RECENT_FILE_LIST_BEGIN + MAX_CONDITION - 1
#define IDC_LOAD_CONDITION_SAMPLE_BEGIN		1050
#define IDC_LOAD_CONDITION_SAMPLE_END		1059
#define IDC_LOAD_CONDITION_BEGIN			IDC_XFM_RECENT_FILE_LIST_BEGIN
#define IDC_LOAD_CONDITION_END				IDC_XFM_RECENT_FILE_LIST_END


#define STR_FAVORITE_CONDITION_FILE_SYS		okutil_get_origin_path(ORIGIN_PATH_SYSTEM)+"condition.txt"
#define STR_FAVORITE_CONDITION_FILE			okutil_get_origin_path(ORIGIN_PATH_USER)+"condition.txt"	
#define STR_FAVORITE_LIST_SETTING_FILE		okutil_get_origin_path(ORIGIN_PATH_USER) + STR_ORIGIN_INI_FILE_NAME

class ConditionListBase : public MoreListMenu
{
public:
	//ConditionListBase(HMENU hMenu, UINT nTagID, UINT nBeginID, UINT nEndID, LPCSTR lpcszConditionFile)
	ConditionListBase(HMENU hMenu, UINT nTagID, UINT nBeginID, UINT nEndID)
	: MoreListMenu(hMenu, nTagID, nBeginID, nEndID)
	{
		//m_strConditionFile = lpcszConditionFile;
	}
	
private:
	virtual void SaveSettings(const vector<string>& vsList)
	{
		//Sim, to do
		//nothing to do, dialog should handle this
	}
	virtual bool LoadSettings(vector<string>& vsList)
	{
		if ( m_strConditionFile.IsEmpty() )
			return false;
		
		INIFile	iniFile(m_strConditionFile);
		//if(iniFile)
		//{
		return iniFile.GetSectionNames(vsList);
			//return true;
		//}

		//return false;
	}
	virtual void ClearSettings()
	{
		//Sim, to do
		//nothing to do, dialog should handle this
	}

protected:
	string m_strConditionFile;
};

class ConditionSysSample : public ConditionListBase
{
public:
	ConditionSysSample(HMENU hMenu)
	//: ConditionListBase(hMenu, IDC_EXTRACT_EMPTY1, IDC_LOAD_CONDITION_SAMPLE_BEGIN, IDC_LOAD_CONDITION_SAMPLE_END, STR_FAVORITE_CONDITION_FILE_SYS)
	: ConditionListBase(hMenu, IDC_EXTRACT_EMPTY1, IDC_LOAD_CONDITION_SAMPLE_BEGIN, IDC_LOAD_CONDITION_SAMPLE_END)
	{
		m_strConditionFile = STR_FAVORITE_CONDITION_FILE_SYS;
	}
};

class ConditionUserDefined : public ConditionListBase
{
public:
	ConditionUserDefined(HMENU hMenu)
	//: ConditionListBase(hMenu, IDC_EXTRACT_EMPTY2, IDC_LOAD_CONDITION_BEGIN, IDC_LOAD_CONDITION_END, STR_FAVORITE_CONDITION_FILE)
	: ConditionListBase(hMenu, IDC_EXTRACT_EMPTY2, IDC_LOAD_CONDITION_BEGIN, IDC_LOAD_CONDITION_END)
	{
		m_strConditionFile = STR_FAVORITE_CONDITION_FILE;
	}
};


#define STR_CONDITION_RECENT_LIST_PREFIX			"condition"
#define STR_CONDITION_SECTION						"Condition"
#define CONDITION_RECENT_LIST_MAX_NUM			10

class ConditionRecentListMenu : public RecentListMenu
{
public:
	ConditionRecentListMenu(HMENU hMenu)
	: RecentListMenu(hMenu, IDC_EXTRACT_EMPTY, IDC_RECENT_CONDITION_LIST_BEGIN, IDC_RECENT_CONDITION_LIST_END)
	{
	}
	
private:
	virtual void SaveSettings(const vector<string>& vsList)
	{
		INIFile	iniFile(STR_FAVORITE_LIST_SETTING_FILE);
		
		//clear sections first
		ClearSettings();
	
		for(int ii=0; ii<vsList.GetSize(); ii++)
			iniFile.WriteString(STR_CONDITION_SECTION, STR_CONDITION_RECENT_LIST_PREFIX + (string)ii, vsList[ii]);
	}
	virtual bool LoadSettings(vector<string>& vsList)
	{
		vsList.SetSize(0);
		
		vector<string> vsKeyNames;
		INIFile	iniFile(STR_FAVORITE_LIST_SETTING_FILE);
	
		iniFile.GetKeyNames(vsKeyNames, STR_CONDITION_SECTION);
		for ( int ii = 0; ii < vsKeyNames.GetSize(); ii++ )
			vsList.Add(iniFile.ReadString(STR_CONDITION_SECTION, vsKeyNames[ii]));
		if(vsList.GetSize() > CONDITION_RECENT_LIST_MAX_NUM)
			vsList.SetSize(CONDITION_RECENT_LIST_MAX_NUM);
		return true;

	}
	virtual void ClearSettings()
	{
		INIFile	iniFile(STR_FAVORITE_LIST_SETTING_FILE);
		iniFile.WriteString(STR_CONDITION_SECTION, NULL, NULL); // clear
	}
};

//#include <..\OriginLab\FunctionsMenu.h>
//#define STR_FUNCTIONS_MENU_FAVORITES_SETTING_FILE				okutil_get_origin_path(ORIGIN_PATH_USER) + STR_ORIGIN_INI_FILE_NAME
//#define STR_FUNCTIONS_MENU_FAVORITES_SECTION					"Functions Menu Favorites"
//#define STR_FUNCTIONS_MENU_FAVORITES_FUNCTIONS_PREFIX			"Func"
//#define IDC_FUNCTIONS_MENU_FAVORITES_BEGIN						IDC_BASIC_FUNCTIONS_BEGIN + 0
//#define FUNCTIONS_MENU_FAVORITES_MAX_NUM						10

class FunctionsFavoriteMenu_ : public RecentListMenu
{
public:
	FunctionsFavoriteMenu_(HMENU hMenu, LPCSTR lpcszFavSection)
	: RecentListMenu(hMenu, IDC_FUNCTION_MENU_FAVORITE, IDC_FUNCTIONS_MENU_FAVORITES_BEGIN, IDC_FUNCTIONS_MENU_FAVORITES_BEGIN + FUNCTIONS_MENU_FAVORITES_MAX_NUM)
	{
		m_strFavSection = lpcszFavSection;
		if ( m_strFavSection.IsEmpty() )
			m_strFavSection = STR_FUNCTIONS_MENU_FAVORITES_SECTION;
	}
	
private:
	virtual void SaveSettings(const vector<string>& vsList)
	{
		INIFile	iniFile(STR_FUNCTIONS_MENU_FAVORITES_SETTING_FILE);
		
		//clear sections first
		ClearSettings();
	
		for(int ii=0; ii<vsList.GetSize(); ii++)
			update_ini_line(iniFile, m_strFavSection, STR_FUNCTIONS_MENU_FAVORITES_FUNCTIONS_PREFIX + (string)ii, vsList[ii]);
	}
	virtual bool LoadSettings(vector<string>& vsList)
	{
		vsList.SetSize(0);
		
		if ( m_strFavSection.IsEmpty() )
			return false;
	
		vector<string> vsKeyNames;
		INIFile	iniFile(STR_FUNCTIONS_MENU_FAVORITES_SETTING_FILE);
	
		iniFile.GetKeyNames(vsKeyNames, m_strFavSection);
		for ( int ii = 0; ii < vsKeyNames.GetSize(); ii++ )
			vsList.Add(iniFile.ReadString(m_strFavSection, vsKeyNames[ii]));
		if(vsList.GetSize() > FUNCTIONS_MENU_FAVORITES_MAX_NUM)
			vsList.SetSize(FUNCTIONS_MENU_FAVORITES_MAX_NUM);
		return true;
	}
	virtual void ClearSettings()
	{
		INIFile	iniFile(STR_FUNCTIONS_MENU_FAVORITES_SETTING_FILE);
		update_ini_line(iniFile, m_strFavSection, NULL, NULL );//clean functions
	}
	
protected:
	string 				m_strFavSection;
};
