/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Portions created by the Initial Developer are
 * Copyright (C) 2012 the Initial Developer.
 * All Rights Reserved.
 *
 * The Original Code is "http://semi-frame.googlecode.com/svn/trunk/".
 *
 * The Initial Developer of the Original Code is the author below.
 */

/**
 * @file ConfigUtil.cs
 * @brief auto generated.
 * @author mornongcloud
 * @date 2011/07/21
 */


using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;

namespace masterframe.util
{
    /// <summary>
    /// config file data
    /// </summary>
    public class ConfigUtil : Dictionary<string, string>
    {
        private const string SETTING_FILE_EXT = ".config";
        private string location;
        private Configuration config;

        /// <summary>
        /// </summary>
        /// <param name="fileName">file name except extension</param>
        public ConfigUtil(string fileName)
        {
            init(fileName);
        }

        /// <summary>
        /// initialize
        /// </summary>
        /// <param name="fileName">file name except extension</param>
        private void init(string fileName)
        {
            Type t = typeof(ConfigUtil);
            string loc = t.Assembly.Location;
            location = Path.GetDirectoryName(loc) + @"\" + fileName;
            //location = AppUtil.GetCurrentDirectory() + fileName;
        }

        /// <summary>
        /// Fit order to config(able to change the name)
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        protected Object Translate(Object obj)
        {
            Type t = obj.GetType();
            FieldInfo[] infs = t.GetFields();
            if (0 == infs.Length) return obj;

            Configuration conf = this.GetMyConfig(location);
            if (null == conf) return obj;
            string[] keys = conf.AppSettings.Settings.AllKeys;

            for (int idx = 0; idx < infs.Length; idx++)
            {
                if (idx < keys.Length)
                {
                    var val = conf.AppSettings.Settings[keys[idx]].Value;
                    if (null != val)
                        infs[idx].SetValue(obj, TranslateValue(val, infs[idx].FieldType.Name));
                }
                else
                {
                    infs[idx].SetValue(obj, TranslateValue("", infs[idx].FieldType.Name));
                }
            }
            return obj;
        }

        /// <summary>
        /// コレクションで保持する場合
        /// </summary>
        /// <returns></returns>
        //protected Dictionary<string, string> Translate()
        protected void Translate()
        {
            Configuration conf = this.GetMyConfig(location);
            if (null == conf) return;
            string[] keys = conf.AppSettings.Settings.AllKeys;

            //var ret = new Dictionary<string, string>();
            for (int idx = 0; idx < keys.Length; idx++)
            {
                if (null != conf.AppSettings.Settings[keys[idx]])
                    base.Add(keys[idx], conf.AppSettings.Settings[keys[idx]].Value);
            }
            //return ret;
        }

        /// <summary>
        /// save all.
        /// </summary>
        public bool Save()
        {
            bool ret = Save(this);

            // TODO テスト
            try
            {
                Configuration conf = this.GetMyConfig(location);
                string[] keys1 = conf.AppSettings.Settings.AllKeys;
                KeyCollection keys2 = base.Keys;
                foreach (string k in keys2)
                {
                    var setting = config.AppSettings.Settings[k];
                    if (setting == null)
                    {
                        // create
                        config.AppSettings.Settings.Add(k, base[k].ToString());
                    }
                    // rewrite
                    setting.Value = base[k].ToString();
                }
                config.Save();
                ret = true;
            }
            catch (Exception)
            {
                ret = false;
            }
            return ret;
        }

        /// <summary>
        /// save all.
        /// </summary>
        private bool Save(Object obj)
        {
            // if (null == config) return false;

            Type t = obj.GetType();
            FieldInfo[] infs = t.GetFields();
            if (0 == infs.Length) return false;

            try
            {
                Configuration conf = this.GetMyConfig(location);
                if (null == conf) return false;
                string[] keys = conf.AppSettings.Settings.AllKeys;
                for (int idx = 0; idx < infs.Length; idx++)
                {
                    if (keys.Length <= idx) break;
                    var setting = config.AppSettings.Settings[keys[idx]];
                    //if (setting == null)
                    //{
                    //    // 新規追加・・・はできない
                    //    config.AppSettings.Settings.Add(keys[idx], infs[idx].GetValue(obj).ToString());
                    //}
                    // 上書き
                    if (null != infs[idx] && null != infs[idx].GetValue(obj))
                        setting.Value = infs[idx].GetValue(obj).ToString();
                }
                config.Save();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 設定キー(key)からデータを取得する
        /// </summary>
        /// <param name="key">設定キー</param>
        /// <returns>設定値</returns>
        public string StringSetting(string key)
        {
            var setting = GetSetting(location, key);
            if (setting == null)
            {
                return "";
            }
            return setting.Value.ToString();
        }

        /// <summary>
        /// 設定キー(key)からデータを取得する
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public int IntSetting(string key)
        {
            var setting = GetSetting(location, key);
            if (setting != null) return int.Parse(setting.ToString());
            return 0;
        }

        /// <summary>
        /// 設定キー(key)のデータを書き換える。
        /// </summary>
        /// <param name="key">キー</param>
        /// <param name="value">設定値</param>
        /// <returns></returns>
        public bool SetStringSetting(string key, string value)
        {
            try
            {
                var config = GetMyConfig(location);

                var setting = config.AppSettings.Settings[key];
                if (setting == null)
                {
                    // 新規追加
                    config.AppSettings.Settings.Add(key, value);
                    config.Save();
                    return false;
                }

                // 上書き
                setting.Value = value;
                config.Save();
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// GetAllSetting
        /// </summary>
        /// <Author>Dung-VT</Author>
        /// <returns></returns>
        public Dictionary<string, string> GetAllSettings()
        {
            Dictionary<string, string> rsDict = new Dictionary<string, string>();
            var config = this.GetMyConfig(location);

            if (config == null)
                return rsDict;

            foreach (KeyValueConfigurationElement setting in config.AppSettings.Settings)
            {
                rsDict.Add(setting.Key, setting.Value);
            }
            return rsDict;
        }

        /// <summary>
        /// RemoveSettings
        /// </summary>
        public void RemoveSettings()
        {
            var config = this.GetMyConfig(location);
            if (config == null)
                return;

            string[] keys = config.AppSettings.Settings.AllKeys;
            if (keys != null)
            {
                foreach (string key in keys)
                {
                    config.AppSettings.Settings.Remove(key);
                }
            }
            config.Save();
        }

        /// <summary>
        /// RemoveSetting
        /// </summary>
        /// <param name="key">キー</param>
        public void RemoveSetting(string key)
        {
            var config = this.GetMyConfig(location);
            if (config == null)
                return;
            config.AppSettings.Settings.Remove(key);
            config.Save();
        }

        /// <summary>
        /// AddSettings
        /// </summary>
        /// <param name="settingValues"></param>
        public void AddSettings(List<string> settingValues)
        {
            var config = this.GetMyConfig(location);
            if (settingValues != null && config != null)
            {
                RemoveSettings();

                for (int i = 0; i < settingValues.Count; i++)
                {
                    config.AppSettings.Settings.Add(Convert.ToString(i + 1), settingValues[i]);
                }
                config.Save();
            }
        }

        /// <summary>
        /// IsFileExist
        /// </summary>
        /// <param name="fileName">拡張子のないファイル名</param>
        /// <returns></returns>
        public static bool IsFileExists(string fileName)
        {
            try
            {
                Type t = typeof(ConfigUtil);
                string location = t.Assembly.Location;
                string loc = Path.GetDirectoryName(location) + @"\" + fileName + SETTING_FILE_EXT;
                FileInfo fileInfo = new FileInfo(loc);
                return fileInfo.Exists;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// GetAllKeys
        /// </summary>
        /// <Author>Dung-VT</Author>
        /// <returns></returns>
        public List<string> GetAllKeys()
        {
            List<string> result = new List<string>();
            var config = this.GetMyConfig(location);
            if (config == null)
                return result;
            return config.AppSettings.Settings.AllKeys.ToList<string>();
        }

        /// <summary>
        /// IsKeyExisted
        /// </summary>
        /// <Author>Dung-VT</Author>
        /// <param name="key">キー</param>
        /// <returns>true/false</returns>
        public bool IsKeyExisted(string key)
        {
            List<string> keys = GetAllKeys();
            if (keys.Contains(key))
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="loc"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static KeyValueConfigurationElement GetSetting(string loc, string key)
        {
            var config = GetConfig(loc);

            if (config == null)
            {
                return null;
            }

            return config.AppSettings.Settings[key];
        }

        //private Configuration GetConfig(string loca)
        //{
        //    string dll_config_path = loca + SETTING_FILE_EXT;

        //    if (!File.Exists(dll_config_path))
        //    {
        //        return null;
        //    }
        //    var file_map = new ExeConfigurationFileMap();
        //    file_map.ExeConfigFilename = dll_config_path;
        //    System.Configuration.Configuration config =
        //           ConfigurationManager.OpenMappedExeConfiguration(file_map, ConfigurationUserLevel.None);
        //    return config;
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="loca"></param>
        /// <returns></returns>
        private Configuration GetMyConfig(string loca)
        {
            if (!this.location.Equals(loca)) config = ConfigUtil.GetConfig(loca);
            if (null == this.config) config = ConfigUtil.GetConfig(loca);
            return this.config;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="loca"></param>
        /// <returns></returns>
        public static Configuration GetConfig(string loca)
        {
            string dll_config_path = loca + SETTING_FILE_EXT;

            //if (!File.Exists(dll_config_path))
            //    using (FileStream str = File.Create(dll_config_path))
            //        str.Close();
            if (!File.Exists(dll_config_path)) return null;

            var file_map = new ExeConfigurationFileMap();
            file_map.ExeConfigFilename = dll_config_path;
            System.Configuration.Configuration config = ConfigurationManager.OpenMappedExeConfiguration(file_map, ConfigurationUserLevel.None);

            return config;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <param name="typename"></param>
        /// <returns></returns>
        private static Object TranslateValue(string item, string typename)
        {
            typename = typename.ToLower();

            try
            {
                if (typename.Contains("string")) return item;
                if (null == item || 0 == item.Length) item = "0";

                if (typename.Contains("int16")) return short.Parse(item);
                else if (typename.Contains("int")) return int.Parse(item);
                else if (typename.Contains("short")) return short.Parse(item);
                else if (typename.Contains("double")) return double.Parse(item);
            }
            catch (Exception)
            {
                return null;
            }
            return null;
        }

        /// <summary>
        /// 羅列型のconfig の場合、以下を利用する。
        /// 使い方:
        /// List&lt;Object&gt; lst1 = ConfigUtil.GetSettingsList("FILE_NAME", new Sample1());
        /// List&lt;Sample1&gt; lst = lst1.ConvertAll&lt;Sample1&gt;(o =&gt; (Sample1)o);
        /// </summary>
        /// <param name="loca">Config名</param>
        /// <param name="obj">格納用オブジェクト</param>
        /// <returns></returns>
        public static Dictionary<string, Object> GetSettings(string loca, Object obj)
        {
            ConfigItemCollection settings1 = ConfigUtil.GetConfigItemCollection(loca);
            return ConfigUtil.Translate(settings1, obj);
        }

        /// <summary>
        /// List&lt;Sample1&gt; lst = lst1.ConvertAll&lt;Sample1&gt;(o =&gt; (Sample1)o);
        /// </summary>
        /// <param name="loca"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static List<Object> GetSettingsList(string loca, Object obj)
        {
            var dic = ConfigUtil.GetSettings(loca, obj);
            return dic.Values.ToList<Object>();
        }

        /// <summary>
        /// 羅列型のconfig の場合、以下を利用する。
        /// 使い方:
        /// List&lt;Object&gt; lst1 = ConfigUtil.GetSettingsList("FILE_NAME", new Sample1());
        /// List&lt;Sample1&gt; lst = lst1.ConvertAll&lt;Sample1&gt;(o =&gt; (Sample1)o);
        /// </summary>
        /// <param name="loca">Config名</param>
        /// <returns>Dictionary</returns>
        public static Dictionary<string, List<string>> GetSettings(string loca)
        {
            ConfigItemCollection settings1 = ConfigUtil.GetConfigItemCollection(loca);
            return ConfigUtil.Translate(settings1);
        }

        /// <summary>
        /// 羅列型のconfig の場合、以下を利用する。
        /// 使い方:
        /// ConfigItemCollection settings1 = ConfigUtil.GetConfigItemCollection("FILE_NAME");
        /// List&lt;Sample1&gt; lst = (ConfigUtil.Translate(settings1, new Sample1())).ConvertAll\&lt;Sample1&gt;(o => (Sample1)o);
        /// 
        /// </summary>
        /// <param name="loca">Config名</param>
        /// <returns>ConfigSettingsSection</returns>
        private static ConfigItemCollection GetConfigItemCollection(string loca)
        {
            //string dll_config_path = loca + SETTING_FILE_EXT;
            Configuration conf = GetConfig(loca);
            if (conf == null) return new ConfigItemCollection();
            ConfigurationSection sec = conf.GetSection("SettingsSection");
            if (sec == null) return new ConfigItemCollection();
            try
            {
                return ((ConfigSettingsSection)sec).settings;
            }
            catch (Exception)
            {
                return new ConfigItemCollection();
            }
        }

        /// <summary>
        /// 羅列型のconfigを翻訳する
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        private static Dictionary<string, List<string>> Translate(ConfigItemCollection items)
        {
            var ret = new Dictionary<string, List<string>>();
            items.ResetIndex();
            for (int i = 0; items.HasNext(); i++)
            {
                ConfigItem cnf = items.Next();
                var add = new List<string>();

                if (null != cnf.value && 0 < cnf.value.Length)
                {
                    add.Add(cnf.value.ToString());
                }
                else // valueならvalue1～は無い
                {
                    if (null != cnf.value1 && 0 < cnf.value1.Length)
                    {
                        add.Add(cnf.value1.ToString());
                        if (null != cnf.value2 && 0 < cnf.value2.Length)
                        {
                            add.Add(cnf.value2.ToString());
                            if (null != cnf.value3 && 0 < cnf.value3.Length)
                            {
                                add.Add(cnf.value3.ToString());
                                if (null != cnf.value4 && 0 < cnf.value4.Length)
                                {
                                    add.Add(cnf.value4.ToString());
                                    if (null != cnf.value5 && 0 < cnf.value5.Length)
                                    {
                                        add.Add(cnf.value5.ToString());
                                        if (null != cnf.value6 && 0 < cnf.value6.Length)
                                        {
                                            add.Add(cnf.value6.ToString());
                                            if (null != cnf.value7 && 0 < cnf.value7.Length)
                                            {
                                                add.Add(cnf.value7.ToString());
                                                if (null != cnf.value8 && 0 < cnf.value8.Length)
                                                {
                                                    add.Add(cnf.value8.ToString());
                                                    if (null != cnf.value9 && 0 < cnf.value9.Length)
                                                    {
                                                        add.Add(cnf.value9.ToString());
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else // value無し
                    {
                        add.Add("");
                    }
                }

                if (null != cnf.key && 0 < cnf.key.Length)
                    ret.Add(cnf.key, add);
                else
                    ret.Add(i.ToString("000"), add);
            }
            return ret;
        }

        /// <summary>
        /// 羅列型のconfigを翻訳する
        /// </summary>
        /// <param name="items">ConfigSettingsSectionオブジェクト</param>
        /// <param name="obj">格納用オブジェクト</param>
        /// <returns>オブジェクトリスト</returns>
        private static Dictionary<string, Object> Translate(ConfigItemCollection items, Object obj)
        {
            var ret = new Dictionary<string, Object>();

            Type t = obj.GetType();
            FieldInfo[] infs = t.GetFields();
            if (0 == infs.Length) return ret;

            items.ResetIndex();

            //while (items.HasNext())
            for (int i = 0; items.HasNext(); i++)
            {
                ConfigItem cnf = items.Next();

                object o1 = Activator.CreateInstance(t);

                int idx = 0;
                string dbg = "";
                string ky = "";
                if (idx < infs.Length && null != cnf.key && 0 < cnf.key.Length)
                {
                    object v = TranslateValue(cnf.key, infs[idx].FieldType.Name);
                    ky = v.ToString();
                    dbg += " " + v.ToString();
                    infs[idx].SetValue(o1, v);
                    idx = idx + 1;
                }
                if (idx < infs.Length && null != cnf.value && 0 < cnf.value.Length)
                {
                    object v = TranslateValue(cnf.value, infs[idx].FieldType.Name);
                    infs[idx].SetValue(o1, v);
                    dbg += " " + v.ToString();

                    if (0 == ky.Length) ky = i.ToString("0000");
                }
                else // valueならvalue1～は無い
                {
                    if (idx < infs.Length && null != cnf.value1 && 0 < cnf.value1.Length)
                    {
                        object v1 = TranslateValue(cnf.value1, infs[idx].FieldType.Name);
                        infs[idx].SetValue(o1, v1);
                        dbg += " " + v1.ToString();
                    }
                    idx = idx + 1;
                    if (idx < infs.Length && null != cnf.value2 && 0 < cnf.value2.Length)
                    {
                        object v2 = TranslateValue(cnf.value2, infs[idx].FieldType.Name);
                        infs[idx].SetValue(o1, v2);
                        dbg += " " + v2.ToString();
                    }
                    idx = idx + 1;
                    if (idx < infs.Length && null != cnf.value3 && 0 < cnf.value3.Length)
                    {
                        object v3 = TranslateValue(cnf.value3, infs[idx].FieldType.Name);
                        infs[idx].SetValue(o1, v3);
                        dbg += " " + v3.ToString();
                    }
                    idx = idx + 1;
                    if (idx < infs.Length && null != cnf.value4 && 0 < cnf.value4.Length)
                    {
                        object v4 = TranslateValue(cnf.value4, infs[idx].FieldType.Name);
                        infs[idx].SetValue(o1, v4);
                        dbg += " " + v4.ToString();
                    }
                    idx = idx + 1;
                    if (idx < infs.Length && null != cnf.value5 && 0 < cnf.value5.Length)
                    {
                        object v5 = TranslateValue(cnf.value5, infs[idx].FieldType.Name);
                        infs[idx].SetValue(o1, v5);
                        dbg += " " + v5.ToString();
                    }
                    idx = idx + 1;
                    if (idx < infs.Length && null != cnf.value6 && 0 < cnf.value6.Length)
                    {
                        object v6 = TranslateValue(cnf.value6, infs[idx].FieldType.Name);
                        infs[idx].SetValue(o1, v6);
                        dbg += " " + v6.ToString();
                    }
                    idx = idx + 1;
                    if (idx < infs.Length && null != cnf.value7 && 0 < cnf.value7.Length)
                    {
                        object v7 = TranslateValue(cnf.value7, infs[idx].FieldType.Name);
                        infs[idx].SetValue(o1, v7);
                        dbg += " " + v7.ToString();
                    }
                    idx = idx + 1;
                    if (idx < infs.Length && null != cnf.value8 && 0 < cnf.value8.Length)
                    {
                        object v8 = TranslateValue(cnf.value8, infs[idx].FieldType.Name);
                        infs[idx].SetValue(o1, v8);
                        dbg += " " + v8.ToString();
                    }
                    idx = idx + 1;
                    if (idx < infs.Length && null != cnf.value9 && 0 < cnf.value9.Length)
                    {
                        object v9 = TranslateValue(cnf.value9, infs[idx].FieldType.Name);
                        infs[idx].SetValue(o1, v9);
                        dbg += " " + v9.ToString();
                    }
                }
                if (NLog.LogManager.GetCurrentClassLogger().IsDebugEnabled)
                    NLog.LogManager.GetCurrentClassLogger().Debug("ConfigUtil.Translate>>" + t.Name + ":" + dbg);
                ret.Add(ky, o1);
            }
            return ret;
        }

        /// <summary>
        /// 羅列型のconfigを保存
        /// </summary>
        /// <returns></returns>
        public static bool SaveSettingsList(string loca, IList lst)
        {
            Configuration conf = ConfigUtil.GetConfig(loca);
            if (conf == null) return false;
            ConfigSettingsSection sec = (ConfigSettingsSection)conf.GetSection("SettingsSection");
            if (sec == null) return false;

            if (null == lst || 0 == lst.Count) return false;

            try
            {
                // 項目設定状況を確認
                bool hKey = false;
                bool hVal = false;
                bool hVl1 = false;
                bool hVl2 = false;
                bool hVl3 = false;
                bool hVl4 = false;
                bool hVl5 = false;
                bool hVl6 = false;
                bool hVl7 = false;
                bool hVl8 = false;
                bool hVl9 = false;
                ConfigItemCollection items = ((ConfigSettingsSection)sec).settings;
                items.ResetIndex();
                while (items.HasNext())
                {
                    ConfigItem cnf = items.Next();
                    if (0 < cnf.key.Length) hKey = true;
                    if (0 < cnf.value.Length) hVal = true;
                    if (hVal) break; // valueならvalue1～は無い
                    if (0 < cnf.value1.Length) hVl1 = true;
                    if (0 < cnf.value2.Length) hVl2 = true;
                    if (0 < cnf.value3.Length) hVl3 = true;
                    if (0 < cnf.value4.Length) hVl4 = true;
                    if (0 < cnf.value5.Length) hVl5 = true;
                    if (0 < cnf.value6.Length) hVl6 = true;
                    if (0 < cnf.value7.Length) hVl7 = true;
                    if (0 < cnf.value8.Length) hVl8 = true;
                    if (0 < cnf.value9.Length) hVl9 = true;
                    break;
                }

                // 全削除
                //sec.settings.Clear();
                sec.ClearSettings();

                // 引数解析
                Object obj = lst[0];
                Type t = obj.GetType();
                FieldInfo[] infs = t.GetFields();
                if (0 == infs.Length) return false;

                // 保存開始
                for (int i = 0; i < lst.Count; i++)
                {
                    ConfigItem itm = new ConfigItem();
                    obj = lst[i];
                    int idx = 0;
                    if (hKey && idx < infs.Length)
                    {
                        itm.key = infs[idx].GetValue(obj).ToString();
                        idx += 1;
                    }
                    if (hVal && idx < infs.Length)
                    {
                        itm.value = infs[idx].GetValue(obj).ToString();
                        // valueならvalue1～は無い
                        continue;
                    }
                    if (hVl1 && idx < infs.Length)
                    {
                        itm.value1 = infs[idx].GetValue(obj).ToString();
                    }
                    idx += 1;
                    if (hVl2 && idx < infs.Length)
                    {
                        itm.value2 = infs[idx].GetValue(obj).ToString();
                    }
                    idx += 1;
                    if (hVl3 && idx < infs.Length)
                    {
                        itm.value3 = infs[idx].GetValue(obj).ToString();
                    }
                    idx += 1;
                    if (hVl4 && idx < infs.Length)
                    {
                        itm.value4 = infs[idx].GetValue(obj).ToString();
                    }
                    idx += 1;
                    if (hVl5 && idx < infs.Length)
                    {
                        itm.value5 = infs[idx].GetValue(obj).ToString();
                    }
                    idx += 1;
                    if (hVl6 && idx < infs.Length)
                    {
                        itm.value6 = infs[idx].GetValue(obj).ToString();
                    }
                    idx += 1;
                    if (hVl7 && idx < infs.Length)
                    {
                        itm.value7 = infs[idx].GetValue(obj).ToString();
                    }
                    idx += 1;
                    if (hVl8 && idx < infs.Length)
                    {
                        itm.value8 = infs[idx].GetValue(obj).ToString();
                    }
                    idx += 1;
                    if (hVl9 && idx < infs.Length)
                    {
                        itm.value9 = infs[idx].GetValue(obj).ToString();
                    }
                    sec.settings.Add(itm);
                }

                conf.Save();
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }


    }
    /// <summary>
    /// 独自に定義するセクション
    /// </summary>
    public class ConfigSettingsSection : ConfigurationSection
    {
        ///// <summary>
        ///// key属性
        ///// </summary>
        //[ConfigurationProperty("key", IsRequired = false)]
        //public string key
        //{
        //    get
        //    {
        //        return (string)this["key"];
        //    }
        //    set
        //    {
        //        this["key"] = value;
        //    }
        //}

        ///// <summary>
        ///// defaultSettings要素
        ///// </summary>
        //[ConfigurationProperty("defaultSettings", IsRequired = true)]
        //public ConfigItem DefaultSettings
        //{
        //    get
        //    {
        //        return (FooNetConfigItem)this["defaultSettings"];
        //    }
        //}

        /// <summary>
        /// settings要素下にhost要素のリストを設定する
        /// </summary>
        [ConfigurationProperty("settings", IsDefaultCollection = true)]
        public ConfigItemCollection settings
        {
            get
            {
                return (ConfigItemCollection)this["settings"];
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void ClearSettings()
        {
            settings.Clear();
            this["settings"] = new ConfigItemCollection();
        }

        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="lst"></param>
        //public void Add(ConfigItem itm)
        //{
        //    settings.Add(itm);
        //}

        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="lst"></param>
        //public void AddSettings(ConfigItemCollection lst)
        //{
        //    for (int i = 0; i < lst.Count; i++)
        //    {
        //        settings.Add(lst[i]);
        //    }
        //}
    }

    /// <summary>
    /// host要素のコレクションをまとめるservers要素の定義
    /// </summary>
    public class ConfigItemCollection : ConfigurationElementCollection
    {
        ///// <summary>
        ///// すべてのキー名のコレクション
        ///// </summary>
        //public string[] AllKeys
        //{
        //    get
        //    {
        //        return (from o in BaseGetAllKeys() select o.ToString()).ToArray();
        //    }
        //}

        /// <summary>
        /// 指定されたキーに対応する要素の情報
        /// </summary>
        /// <param key="key">キー名</param>
        /// <returns>要素</returns>
        public new ConfigItem this[string key]
        {
            get
            {
                return (ConfigItem)BaseGet(key);
            }
        }

        /// <summary>
        /// 指定されたインデックスに対応する要素の情報
        /// </summary>
        /// <param key="key">index</param>
        /// <returns>要素</returns>
        public ConfigItem this[int index]
        {
            get
            {
                return (ConfigItem)BaseGet(index);
            }
        }

        /// <summary>
        /// 要素ポインタ
        /// </summary>
        int myindex = -1;

        /// <summary>
        /// 指定されたキーに対応する要素の情報
        /// </summary>
        /// <returns>要素</returns>
        public void ResetIndex()
        {
            myindex = -1;
        }

        /// <summary>
        /// 指定されたキーに対応する要素の情報
        /// </summary>
        /// <returns>要素</returns>
        public ConfigItem First()
        {
            ResetIndex();
            return Next();
        }

        /// <summary>
        /// 指定されたキーに対応する要素の情報
        /// </summary>
        /// <returns>要素</returns>
        public ConfigItem Next()
        {
            myindex = myindex + 1;
            return (ConfigItem)BaseGet(myindex);
        }

        /// <summary>
        /// exists next element.
        /// </summary>
        /// <returns>要素</returns>
        public bool HasNext()
        {
            if (base.Count <= myindex + 1) return false;
            return null != (ConfigItem)BaseGet(myindex + 1);
        }

        /// <summary>
        /// create new ConfigurationElement
        /// </summary>
        /// <returns></returns>
        protected override ConfigurationElement CreateNewElement()
        {
            return new ConfigItem();
        }

        /// <summary>
        /// get item key.
        /// </summary>
        /// <param key="element"></param>
        /// <returns></returns>
        protected override object GetElementKey(ConfigurationElement element)
        {
            ConfigItem item = element as ConfigItem;
            //return item.key;
            if (null != item.key && 0 < item.key.Length) return item.key;
            return Guid.NewGuid().ToString();
        }

        /// <summary>
        /// 
        /// </summary>
        public void Clear()
        {
            BaseClear();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        public void Add(ConfigItem item)
        {
            BaseAdd((ConfigurationElement)item);
        }
    }

    /// <summary>
    /// host
    /// </summary>
    public class ConfigItem : ConfigurationElement
    {
        /// <summary>
        /// key
        /// </summary>
        //[ConfigurationProperty("key", IsRequired = true, IsKey = true)]
        [ConfigurationProperty("key", IsRequired = false, IsKey = false)]
        public string key
        {
            get
            {
                return (string)this["key"];
            }
            set
            {
                this["key"] = value;
            }
        }

        /// <summary>
        /// value
        /// </summary>
        [ConfigurationProperty("value", IsRequired = false)]
        public string value
        {
            get
            {
                return (string)this["value"];
            }
            set
            {
                this["value"] = value;
            }
        }

        /// <summary>
        /// value1
        /// </summary>
        [ConfigurationProperty("value1", IsRequired = false)]
        public string value1
        {
            get
            {
                return (string)this["value1"];
            }
            set
            {
                this["value1"] = value;
            }
        }

        /// <summary>
        /// value2
        /// </summary>
        [ConfigurationProperty("value2", IsRequired = false)]
        public string value2
        {
            get
            {
                return (string)this["value2"];
            }
            set
            {
                this["value2"] = value;
            }
        }

        /// <summary>
        /// value3
        /// </summary>
        [ConfigurationProperty("value3", IsRequired = false)]
        public string value3
        {
            get
            {
                return (string)this["value3"];
            }
            set
            {
                this["value3"] = value;
            }
        }

        /// <summary>
        /// value4
        /// </summary>
        [ConfigurationProperty("value4", IsRequired = false)]
        public string value4
        {
            get
            {
                return (string)this["value4"];
            }
            set
            {
                this["value4"] = value;
            }
        }

        /// <summary>
        /// value5
        /// </summary>
        [ConfigurationProperty("value5", IsRequired = false)]
        public string value5
        {
            get
            {
                return (string)this["value5"];
            }
            set
            {
                this["value5"] = value;
            }
        }

        /// <summary>
        /// value6
        /// </summary>
        [ConfigurationProperty("value6", IsRequired = false)]
        public string value6
        {
            get
            {
                return (string)this["value6"];
            }
            set
            {
                this["value6"] = value;
            }
        }

        /// <summary>
        /// value7
        /// </summary>
        [ConfigurationProperty("value7", IsRequired = false)]
        public string value7
        {
            get
            {
                return (string)this["value7"];
            }
            set
            {
                this["value7"] = value;
            }
        }

        /// <summary>
        /// value8
        /// </summary>
        [ConfigurationProperty("value8", IsRequired = false)]
        public string value8
        {
            get
            {
                return (string)this["value8"];
            }
            set
            {
                this["value8"] = value;
            }
        }

        /// <summary>
        /// value9
        /// </summary>
        [ConfigurationProperty("value9", IsRequired = false)]
        public string value9
        {
            get
            {
                return (string)this["value9"];
            }
            set
            {
                this["value9"] = value;
            }
        }

        /// <summary>
        /// return log.
        /// </summary>
        /// <returns>log string</returns>
        public override string ToString()
        {
            var buf = new System.Text.StringBuilder();
            buf.Append("key:").Append(key);
            buf.Append(", value:").Append(value);
            buf.Append(", value1:").Append(value1);
            buf.Append(", value2:").Append(value2);
            buf.Append(", value3:").Append(value3);
            buf.Append(", value4:").Append(value4);
            buf.Append(", value5:").Append(value5);
            buf.Append(", value6:").Append(value6);
            buf.Append(", value7:").Append(value7);
            buf.Append(", value8:").Append(value8);
            buf.Append(", value9:").Append(value9);
            return buf.ToString();
        }

    }
}
