using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;

namespace skyscraper5.Skyscraper
{
    public class Ini : Dictionary<string,IniSection>
    {
        public Ini()
        {

        }

        public Ini (string filename)
        {
            string[] iniData = File.ReadAllLines (filename);
            IniSection currentSection = null;
            foreach (string line in iniData) {
                string s = line;
                s = s.Trim ();

                if (s.StartsWith (";"))
                    continue;

                if (s.Contains (";")) {
                    s = s.Split (';') [0];
                }

                if (s.StartsWith ("[") && s.EndsWith ("]")) {
                    string sectionName = s.Split ('[') [1].Split (']') [0];
                    currentSection = new IniSection ();
                    this [sectionName] = currentSection;
                    continue;
                }

                if (s.Contains ("=")) 
                {
                    string[] args = s.Split ('=');
                    args [0].Trim ();
                    args [1].Trim ();
                    currentSection [args [0]] = args [1];
                }
            }

        }

        public byte[] Export()
        {
            MemoryStream ms = new MemoryStream();
            StreamWriter sw = new StreamWriter(ms, Encoding.UTF8);
            foreach (KeyValuePair<string, IniSection> section in this)
            {
                sw.WriteLine("[{0}]", section.Key);
                foreach (KeyValuePair<string, string> entry in section.Value)
                {
                    sw.WriteLine("{0}={1}", entry.Key, entry.Value);
                }

                sw.WriteLine();
            }
            sw.Flush();
            return ms.ToArray();
        }

        public void Export(FileInfo fi)
        {
            byte[] export = Export();
            FileStream fs = new FileStream(fi.FullName, FileMode.Create);
            fs.Write(export, 0, export.Length);
            fs.Flush(true);
            fs.Close();
        }

        public bool ReadValue(string category, string key, bool defaultVaule)
        {
            if (!ContainsKey(category))
                return defaultVaule;

            IniSection section = this[category];
            if (!section.ContainsKey(key))
                return defaultVaule;

            string s = section[key];
            if (s.Equals("0"))
                return false;
            if (s.Equals("1"))
                return true;
            return Boolean.Parse(s);
        }
        
		public int ReadValue(string category, string key, int defaultVaule)
        {
            if (!ContainsKey(category))
                return defaultVaule;

            IniSection section = this[category];
            if (!section.ContainsKey(key))
                return defaultVaule;

            string s = section[key];
            return Int32.Parse(s);
        }

        public string ReadValue(string category, string key, string defaultVaule)
        {
            if (!ContainsKey(category))
                return defaultVaule;

            IniSection section = this[category];
            if (!section.ContainsKey(key))
                return defaultVaule;

            string s = section[key];
            return s;
        }

        public void WriteValue(string category, string key, int value)
        {
            if (!ContainsKey(category))
                Add(category, new IniSection());

            IniSection section = this[category];
            section[key] = value.ToString();
        }

        public void WriteValue(string category, string key, string value)
        {
            if (!ContainsKey(category))
                Add(category, new IniSection());

            IniSection section = this[category];
            section[key] = value;
        }

        public void WriteValue(string category, string key, bool value)
        {
            WriteValue(category, key, value ? 1 : 0);
        }

        public object ReadValue(string category, string key, float defaultVaule)
        {
			if (!ContainsKey(category))
				return defaultVaule;

			IniSection section = this[category];
			if (!section.ContainsKey(key))
				return defaultVaule;

			string s = section[key];
			return Single.Parse(s,CultureInfo.InvariantCulture);
        }

        public void WriteValue(string category, string key, long value)
        {
			if (!ContainsKey(category))
				Add(category, new IniSection());

			IniSection section = this[category];
			section[key] = value.ToString();
		}

        public void WriteValue(string category, string key, float value)
        {
			if (!ContainsKey(category))
				Add(category, new IniSection());

			IniSection section = this[category];
			section[key] = value.ToString(CultureInfo.InvariantCulture);
        }

        public static void WriteIniValue(FileInfo outputIni, string category, string key, string value)
        {
            Ini ini;
            if (outputIni.Exists)
                ini = new Ini(outputIni.FullName);
            else
                ini = new Ini();

            ini.WriteValue(category, key, value);
            ini.Export(outputIni);
        }
    }

    public class IniSection : Dictionary<string,string>
    {
    }
}