using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace pcd_g1
{
	class SaveData
	{
		Dictionary<string, string> strDat = new Dictionary<string,string>();
		Dictionary<string, int> intDat = new Dictionary<string,int>();

		const int IntDefault = 0;
		const string StrDefault = "";

		public int GetInt(string key)
		{
			if (intDat.ContainsKey(key))
			{
				return intDat[key];
			}
			else
			{
				return IntDefault;
			}
		}

		public string GetString(string key)
		{
			if (strDat.ContainsKey(key))
			{
				return strDat[key];
			}
			else
			{
				return StrDefault;
			}
		}

		public string Get(string key)
		{
			if (IsStr(key))
			{
				return GetString(key);
			}
			else if (IsInt(key))
			{
				return GetInt(key).ToString();
			}
			else
			{
				return StrDefault;
			}
		}

		public bool IsInt(string key)
		{
			return intDat.ContainsKey(key);
		}

		public bool IsStr(string key)
		{
			return strDat.ContainsKey(key);
		}

		public bool Contains(string key)
		{
			return IsInt(key) || IsStr(key);
		}

		public void Set(string key, int dat)
		{
			strDat.Remove(key);
			if (intDat.ContainsKey(key))
			{
				intDat[key] = dat;
			}
			else
			{
				intDat.Add(key, dat);
			}
		}

		public void Set(string key, string dat)
		{
			intDat.Remove(key);
			if (strDat.ContainsKey(key))
			{
				strDat[key] = dat;
			}
			else
			{
				strDat.Add(key, dat);
			}
		}

		public void Clean()
		{
			int i = 0;
			while (i < intDat.Count)
			{
				if (intDat.Keys.ToList()[i].StartsWith("@"))
				{
					intDat.Remove(intDat.Keys.ToList()[i]);
				}
				else
				{
					i++;
				}
			}
			i = 0;
			while (i < strDat.Count)
			{
				if (strDat.Keys.ToList()[i].StartsWith("@"))
				{
					strDat.Remove(strDat.Keys.ToList()[i]);
				}
				else
				{
					i++;
				}
			}
		}

		public string GetTypeName(string key)
		{
			if (IsInt(key)) return "int";
			if (IsStr(key)) return "string";
			return "other";
		}

		public void Clear()
		{
			intDat.Clear();
			strDat.Clear();
		}

		public void Debug()
		{
			intDat.Keys.ToList<string>().ForEach(p => DebugKey(p));
			strDat.Keys.ToList<string>().ForEach(p => DebugKey(p));
		}

		public void DebugKey(string key)
		{
			pcd_g1.Debug.WriteLine(string.Format("{0}\t : ({1})\t {2}", key, GetTypeName(key), Get(key)));
		}

		public XElement Serialize()
		{
			Clean();
			var ret = new XElement("savedata");
			int i;
			for (i = 0; i < intDat.Count; i++)
			{
				ret.Add(new XElement("data" + i.ToString(),
					new XElement("key", intDat.Keys.ElementAt<string>(i)),
					new XElement("value", intDat.Values.ElementAt<int>(i).ToString()),
					new XElement("type", "int")));
			}
			i++;
			for (int j = 0; j < strDat.Count; j++)
			{
				ret.Add(new XElement("data" + (i + j).ToString(),
					new XElement("key", strDat.Keys.ElementAt<string>(i)),
					new XElement("value", strDat.Values.ElementAt<string>(i)),
					new XElement("type", "str")));
			}

			return ret;
		}

		public void Deserialize(XContainer doc)
		{
			intDat.Clear();
			strDat.Clear();
			foreach (XElement item in doc.Nodes())
			{
				string datTyp = item.Element("type").Value;
				if (datTyp == "int")
				{
					intDat.Add(item.Element("key").Value,
						int.Parse(item.Element("value").Value));
				}
				else if (datTyp == "str")
				{
					strDat.Add(item.Element("key").Value,
						item.Element("value").Value);
				}
			}
		}
	}
}
