using ryCommon;
using ryCommon.Pram;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ryControls
{
    /// <summary>
    /// 设置管理类,快速添加设置。
    /// </summary>
    public class RySetting
    {
        /// <summary>
        /// 设置管理类,快速添加设置。
        /// </summary>
        public RySetting()
        {
        }
        /// <summary>
        /// 设置管理类,快速添加设置。
        /// </summary>
        /// <param name="_FilePath"></param>
        public RySetting(string _FilePath)
        {
            FilePath = _FilePath;
        }
        /// <summary>
        /// 存储类型
        /// </summary>
        public SettingType FileType = SettingType.XML;
        /// <summary>
        /// 配置存储路径
        /// </summary>
        public string FilePath = "";
        /// <summary>
        /// 设置XML内容
        /// </summary>
        public string SettingXML = "";
        private string Section = "Setting";
        private List<Control_Info> list = new List<Control_Info>();
        /// <summary>
        /// 添加控件
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="ctl"></param>
        /// <returns></returns>
        public int Add(string _id,Control ctl)
        {
            return Add(_id, ctl, CValueType.Default,"");
        }
       /// <summary>
       /// 设置值
       /// </summary>
       /// <param name="_id"></param>
       /// <param name="value"></param>
       /// <returns></returns>
        public int Add(string _id,string value)
        {
            return Add(_id, null, CValueType.Default,value);
        }
        /// <summary>
        /// 添加控件
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="ctl"></param>
        /// <param name="valuetype"></param>
        /// <param name="_defValue"></param>
        /// <returns></returns>
        public int Add(string _id, Control ctl,CValueType valuetype,object _defValue)
        {
            if(_id.ToLower()== Section.ToLower()) { return -1; }
            list.Add(new Control_Info() { id = _id, control = ctl, value_type= valuetype, defValue= _defValue });
            return 1;
        }
        /// <summary>
        /// 添加控件
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="ctl"></param>
        /// <param name="_defValue"></param>
        /// <returns></returns>
        public int Add(string _id, NumericUpDown ctl, decimal _defValue)
        {
            return Add(_id, ctl, CValueType.Default, _defValue);
        }
        /// <summary>
        /// 添加控件
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="ctl"></param>
        /// <param name="_defValue"></param>
        /// <returns></returns>
        public int Add(string _id, DateTimePicker ctl, DateTime _defValue)
        {
            return Add(_id, ctl, CValueType.Default, _defValue);
        }
        /// <summary>
        /// 添加控件
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="ctl"></param>
        /// <param name="_defValue"></param>
        /// <returns></returns>
        public int Add(string _id, CheckBox ctl, bool _defValue)
        {
            return Add(_id, ctl, CValueType.Default, _defValue);
        }
        /// <summary>
        /// 添加控件
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="ctl"></param>
        /// <param name="_defValue"></param>
        /// <returns></returns>
        public int Add(string _id, TextBoxEx2 ctl, string _defValue)
        {
            return Add(_id, ctl, CValueType.Default, _defValue);
        }
        /// <summary>
        /// 添加控件
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="ctl"></param>
        /// <param name="_defValue"></param>
        /// <returns></returns>
        public int Add(string _id, DoubleText ctl, string _defValue)
        {
            return Add(_id, ctl, CValueType.Default, _defValue);
        }
        /// <summary>
        /// 添加控件
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="ctl"></param>
        /// <param name="_defValue"></param>
        /// <returns></returns>
        public int Add(string _id, HotkeyTextBox ctl, string _defValue)
        {
            return Add(_id, ctl, CValueType.Default, _defValue);
        }
        /// <summary>
        /// 添加控件
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="ctl"></param>
        /// <param name="_defValue"></param>
        /// <returns></returns>
        public int Add(string _id, ComboBox ctl, int _defValue)
        {
            return Add(_id, ctl, CValueType.ItemIndex, _defValue);
        }
        /// <summary>
        /// 添加控件
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="ctl"></param>
        /// <param name="_defValue"></param>
        /// <returns></returns>
        public int Add(string _id, ComboBox ctl, string _defValue)
        {
            return Add(_id, ctl, CValueType.ItemText, _defValue);
        }
        /// <summary>
        /// 添加控件
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="ctl"></param>
        /// <param name="_defValue"></param>
        /// <returns></returns>
        public int Add(string _id, TextBox ctl, string _defValue)
        {
            return Add(_id, ctl, CValueType.Default, _defValue);
        }
        /// <summary>
        /// 读取配置
        /// </summary>
        public void Read()
        {
            string filepath = FilePath;
            if (FileType==SettingType.XML)
            {
                ryCommon.Storage myXML = new Storage();
                if (filepath == "")
                {
                    myXML.LoadFromXMLText(SettingXML);
                }
                else
                {
                    myXML.LoadFromFile(filepath);
                }
                myXML.SelectNode2("id", Section);
                for(int i=0;i<list.Count;i++)
                {
                    Control_Info item = list[i];
                    switch (item.control)
                    {
                        case CheckBox chk:
                            chk.Checked = myXML.GetAttrValue(item.id,item.defValue.ToBool());
                            break;
                        case TextBox txt:
                            txt.Text = myXML.GetAttrValue(item.id, item.defValue.ToString());
                            break;
                        case TextBoxEx2 txt:
                            txt.Text = myXML.GetAttrValue(item.id, item.defValue.ToString());
                            break;
                        case HotkeyTextBox txt:
                            txt.HotKey = myXML.GetAttrValue(item.id, item.defValue.ToString());
                            break;
                        case DoubleText txt:
                            txt.selectId = myXML.GetAttrValue(item.id, item.defValue.ToString());
                            break;
                        case NumericUpDown num:
                            num.Value = myXML.GetAttrValue(item.id, item.defValue.ToDecimal()).ToDecimal(num.Minimum, num.Maximum, (decimal)item.defValue);
                            break;
                        case DateTimePicker dt_picker:
                            try
                            {
                                dt_picker.Value = RyDate.UnixTimeToDateTime(myXML.GetAttrValue(item.id, RyDate.DateTimeToUnixTime((DateTime)item.defValue).ToString()));
                            }
                            catch
                            {
                                dt_picker.Value = (DateTime)item.defValue;
                            }
                            break;
                        case ComboBox cbb:
                            #region ComboBox
                            if (item.value_type == CValueType.ItemIndex || item.value_type == CValueType.Default)
                            {
                                int def_value = item.defValue.ToInt(0);
                                int value = myXML.GetAttrValue(item.id, item.defValue.ToInt(0));
                                if (cbb.Items.Count > value && value >= 0)
                                {
                                    cbb.SelectedIndex = value;
                                }
                                else
                                {
                                    if (cbb.Items.Count > def_value && def_value >= 0)
                                        cbb.SelectedIndex = def_value;
                                    else
                                        cbb.SelectedIndex = 0;
                                }
                            }
                            else if (item.value_type == CValueType.ItemText)
                            {
                                try
                                {
                                    cbb.Text = myXML.GetAttrValue(item.id, item.defValue.ToString());
                                }
                                catch { cbb.Text = item.defValue.ToString(); }
                            }
                            else if (item.value_type == CValueType.ObjectItem)
                            {
                                #region ObjectItem
                                string _id = myXML.GetAttrValue(item.id, item.defValue.ToString());
                                bool haveRecord = false;
                                for (int m = 0; m < cbb.Items.Count; m++)
                                {
                                    switch (cbb.Items[m])
                                    {
                                        case ObjectItem c_item:
                                            if (c_item.Id == _id)
                                            {
                                                cbb.SelectedIndex = m;
                                                haveRecord = true;
                                                break;
                                            }
                                            break;
                                    }
                                }
                                if (!haveRecord)
                                {
                                    cbb.SelectedIndex = 0;
                                } 
                                #endregion
                            }
                            break;
                        #endregion
                        default:
                            item.control.Text = myXML.GetAttrValue(item.id, item.defValue.ToString());
                            break;
                    }
                }
            }
            else if (FileType == SettingType.Ini)
            {
                ryCommon.Ini myIni = new ryCommon.Ini(filepath);
                for (int i = 0; i < list.Count; i++)
                {
                    Control_Info item = list[i];
                    switch (item.control)
                    {
                        case CheckBox chk:
                            chk.Checked = myIni.ReadIni(Section, item.id, item.defValue.ToBool());
                            break;
                        case TextBox txt:
                            txt.Text = myIni.ReadIni(Section, item.id, item.defValue.ToString());
                            break;
                        case TextBoxEx2 txt:
                            txt.Text = myIni.ReadIni(Section, item.id, item.defValue.ToString());
                            break;
                        case HotkeyTextBox txt:
                            txt.HotKey = myIni.ReadIni(Section, item.id, item.defValue.ToString());
                            break;
                        case DoubleText txt:
                            txt.selectId = myIni.ReadIni(Section, item.id, item.defValue.ToString());
                            break;
                        case NumericUpDown num:
                            num.Value = myIni.ReadIni(Section, item.id, item.defValue.ToString()).ToDecimal(num.Minimum,num.Maximum, (decimal)item.defValue);
                            break;
                        case DateTimePicker dt_picker:
                            try
                            {
                                dt_picker.Value = RyDate.UnixTimeToDateTime(myIni.ReadIni(Section, item.id, RyDate.DateTimeToUnixTime((DateTime)item.defValue).ToString()));
                            }
                            catch 
                            {
                                dt_picker.Value = (DateTime)item.defValue;
                            }
                            break;
                        case ComboBox cbb:
                            #region ComboBox
                            if (item.value_type == CValueType.ItemIndex || item.value_type == CValueType.Default)
                            {
                                int def_value = item.defValue.ToInt(0);
                                int value = myIni.ReadIni(Section, item.id, item.defValue.ToInt(0));
                                if (cbb.Items.Count > value && value >= 0)
                                {
                                    cbb.SelectedIndex = value;
                                }
                                else
                                {
                                    if (cbb.Items.Count > def_value && def_value >= 0)
                                        cbb.SelectedIndex = def_value;
                                    else
                                        cbb.SelectedIndex = 0;
                                }
                            }
                            else if (item.value_type == CValueType.ItemText)
                            {
                                try
                                {
                                    cbb.Text = myIni.ReadIni(Section, item.id, item.defValue.ToString());
                                }
                                catch { cbb.Text = item.defValue.ToString(); }
                            }
                            else if (item.value_type == CValueType.ObjectItem)
                            {
                                #region ObjectItem
                                string _id = myIni.ReadIni(Section, item.id, item.defValue.ToString());
                                bool haveRecord = false;
                                for (int m = 0; m < cbb.Items.Count; m++)
                                {
                                    switch (cbb.Items[m])
                                    {
                                        case ObjectItem c_item:
                                            if (c_item.Id == _id)
                                            {
                                                cbb.SelectedIndex = m;
                                                haveRecord = true;
                                                break;
                                            }
                                            break;
                                    }
                                }
                                if (!haveRecord)
                                {
                                    cbb.SelectedIndex = 0;
                                }
                                #endregion
                            }
                            break;
                        #endregion                       
                        default:
                            item.control.Text = myIni.ReadIni(Section, item.id, item.defValue.ToString());
                            break;
                    }
                }
            }
        }
        /// <summary>
        /// 保存配置
        /// </summary>
        public void Save()
        {
            string filepath = FilePath;
            if (FileType == SettingType.XML)
            {
                ryCommon.Storage myXML = new Storage();
                if (filepath == "")
                {
                    myXML.LoadFromXMLText(SettingXML);
                }
                else
                {
                    myXML.LoadFromFile(filepath);
                }
                myXML.SelectNode2("id", Section);
                for (int i = 0; i < list.Count; i++)
                {
                    Control_Info item = list[i];
                    switch (item.control)
                    {
                        case CheckBox chk:
                            myXML.SetAttrValue(item.id, chk.Checked);
                            break;
                        case TextBox txt:
                            myXML.SetAttrValue(item.id, txt.Text);
                            break;
                        case TextBoxEx2 txt:
                            myXML.SetAttrValue(item.id, txt.Text);
                            break;
                        case HotkeyTextBox txt:
                            myXML.SetAttrValue(item.id, txt.HotKey);
                            break;
                        case DoubleText txt:
                            myXML.SetAttrValue(item.id, txt.selectId);
                            break;
                        case NumericUpDown num:
                            myXML.SetAttrValue(item.id, num.Value);
                            break;
                        case DateTimePicker dt_picker:
                            myXML.SetAttrValue(item.id, RyDate.DateTimeToUnixTime(dt_picker.Value).ToString());
                            break;
                        case ComboBox cbb:
                            #region ComboBox
                            if (item.value_type == CValueType.ItemIndex || item.value_type == CValueType.Default)
                            {
                                myXML.SetAttrValue(item.id, cbb.SelectedIndex);
                            }
                            else if (item.value_type == CValueType.ItemText)
                            {
                                myXML.SetAttrValue(item.id, cbb.Text);
                            }
                            else if (item.value_type == CValueType.ObjectItem)
                            {
                                switch (cbb.SelectedItem)
                                {
                                    case ObjectItem c_item:
                                        myXML.SetAttrValue(item.id, c_item.Id);
                                        break;
                                }
                            }
                            break;
                        #endregion
                        case null:
                            myXML.SetAttrValue(item.id, item.defValue.ToString());
                            break;
                        default:
                            myXML.SetAttrValue(item.id, item.control.Text);
                            break;
                    }
                }
                if (filepath == "")
                {
                    SettingXML=myXML.XMLText;
                }
                else
                {
                    myXML.SaveToFile(filepath);
                }
            }
            else if (FileType == SettingType.Ini)
            {
                ryCommon.Ini myIni = new ryCommon.Ini(filepath);
                for (int i = 0; i < list.Count; i++)
                {
                    Control_Info item = list[i];
                    switch (item.control)
                    {
                        case CheckBox chk:
                            myIni.WriteIni(Section, item.id, chk.Checked);
                            break;
                        case TextBox txt:
                            myIni.WriteIni(Section, item.id, txt.Text);
                            break;
                        case TextBoxEx2 txt:
                            myIni.WriteIni(Section, item.id, txt.Text);
                            break;
                        case HotkeyTextBox txt:
                            myIni.WriteIni(Section, item.id, txt.HotKey);
                            break;
                        case DoubleText txt:
                            myIni.WriteIni(Section, item.id, txt.selectId);
                            break;
                        case NumericUpDown num:
                            myIni.WriteIni(Section, item.id, num.Value);
                            break;
                        case DateTimePicker dt_picker:
                            myIni.WriteIni(Section, item.id, RyDate.DateTimeToUnixTime(dt_picker.Value).ToString());
                            break;
                        case ComboBox cbb:
                            #region ComboBox
                            if (item.value_type == CValueType.ItemIndex || item.value_type == CValueType.Default)
                            {
                                myIni.WriteIni(Section, item.id, cbb.SelectedIndex);
                            }
                            else if (item.value_type == CValueType.ItemText)
                            {
                                myIni.WriteIni(Section, item.id, cbb.Text);
                            }
                            else if (item.value_type == CValueType.ObjectItem)
                            {
                                switch (cbb.SelectedItem)
                                {
                                    case ObjectItem c_item:
                                        myIni.WriteIni(Section, item.id, c_item.Id);
                                        break;
                                }
                            }
                            break;
                        #endregion
                        case null:
                            myIni.WriteIni(Section, item.id, item.defValue.ToString());
                            break;
                        default:
                            myIni.WriteIni(Section, item.id, item.control.Text);
                            break;
                    }
                }
            }
        }
    }
}
