using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using ClipClop.View;
using CaLib.User.PropertyGridUtil;
using System.Diagnostics;
using System.Drawing;

namespace ClipClop.Model
{
	/// <summary>
	/// User設定
	/// </summary>
	/// <see cref="http://www.atmarkit.co.jp/fdotnet/dotnettips/291pgridjapan/pgridjapan.html"/>
	[TypeConverter(typeof(PropertyDisplayConverter))]
	public class AplSetting
	{
		//TODO ○最小最大入力チェック

		#region ホットキー
		/// <summary>
		/// ホットキー種別
		/// </summary>
		public enum Hotkeys
		{
			Active,
			DeleteHistory,
			TemplatePopup,
		}

		/// <summary>
		/// EXEをアクティブにするホットキー
		/// </summary>
		[PropertyDisplayName("履歴を開く"), Category("ホットキー")]
		public System.Windows.Forms.Keys hkActive_ { get; set; }

		/// <summary>
		/// 履歴を一個削除するホットキー
		/// </summary>
		[PropertyDisplayName("最新履歴削除"), Category("ホットキー")]
		public System.Windows.Forms.Keys hkDeleteHistory_ { get; set; }

		/// <summary>
		/// 定型文メニューを表示するホットキー
		/// </summary>
		[PropertyDisplayName("定型文メニュー"), Category("ホットキー")]
		public System.Windows.Forms.Keys hkTemplatePopup_ { get; set; }
		#endregion

		#region 履歴
		[PropertyDisplayName("起動時最小化"), Description("起動時に最小化するかどうか"), Category("履歴")]
		public bool bMinimizeOnStart_ { get; set; }

		/// <summary>
		/// 保持する履歴の上限
		/// </summary>
		[PropertyDisplayName("履歴最大数"), Description("保持する履歴の上限"), Category("履歴")]
		public int maxHistory_ { get; set; }

		/// <summary>
		/// 前回の履歴を引き継ぐかどうか
		/// </summary>
		[PropertyDisplayName("履歴の保存"), Description("終了時に保存した履歴を起動時に復元するかどうか"), Category("履歴")]
		public bool bInheritHistory_ { get; set; }
	
		/// <summary>
		/// 最前面に表示
		/// </summary>
		[PropertyDisplayName("常に最前面"), Description("最前面に表示するかどうか"), Category("履歴")]
		public bool bAlwaysTop_ { get; set; }

		/// <summary>
		/// フォームの透明度
		/// </summary>
		[PropertyDisplayName("半透明"), Description("0.0(完全に透明)～1.0(完全に不透明)に設定します。"), Category("履歴")]
		public double Opacity_ { get; set; }

		#region フォント
		//[CategoryAttribute("ドキュメント設定")]
		[XmlIgnore] // XmlSerializer から隠す
		[PropertyDisplayName("フォント"), Description("フォントを指定します。"), Category("履歴")]
		public Font WindowFont_ { get; set; }

		[EditorBrowsable(EditorBrowsableState.Never)]
		[Browsable(false)]
		public string DisplayFontAsString
		{
			get { return ConvertToString(WindowFont_); }
			set { WindowFont_ = ConvertFromString<Font>(value); }
		}

		public static string ConvertToString<T>(T value)
		{
			return TypeDescriptor.GetConverter(typeof(T)).ConvertToString(value);
		}
		public static T ConvertFromString<T>(string value)
		{
			return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(value);
		}
		#endregion
		#endregion

		#region 定型文定義
		/// <summary>
		/// 定型文が定義されるファイルのパス
		/// </summary>
		/// <remarks>System.Designへの参照設定を追加した。</remarks>
		[PropertyDisplayName("ファイルパス"), Description("定型文を定義するファイルのパス"), Category("定型文定義")]
		[Editor(typeof(System.Windows.Forms.Design.FileNameEditor), typeof(System.Drawing.Design.UITypeEditor))]
		public string templateFilePath_ { get; set; }

		///// <summary>
		///// 定型文定義ファイルを暗号化するかどうか
		///// </summary>		
		//[PropertyDisplayName("暗号化指定"), Description("定型文定義ファイルの内容を暗号化するかどうか"), Category("定型文定義")]
		//public bool bEncryptTemplateFile_ { get; set; }

		[PropertyDisplayName("バックアップ"), Description("定型文を変更する前にバックアップを行うかどうか"), Category("定型文定義")]
		[Editor(typeof(System.Windows.Forms.Design.FileNameEditor), typeof(System.Drawing.Design.UITypeEditor))]
		public bool bBackup_ { get; set; }

		#endregion


        #region スクリプト
        /// <summary>
        /// 定型文が定義されるファイルのパス
        /// </summary>
        /// <remarks>System.Designへの参照設定を追加した。</remarks>
        [PropertyDisplayName("スクリプトファイルパス"), Description("クリップボードに文字列がコピーされた時に実行するPythonファイルのパス"), Category("スクリプト")]
        [Editor(typeof(System.Windows.Forms.Design.FileNameEditor), typeof(System.Drawing.Design.UITypeEditor))]
        public string sriptFilePath_ { get; set; }
        #endregion

		//public Version ApplicationVersion = Environment.Version;

		public static string APP_DATA_FOLDER_ = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),Application.ProductName);

		/// <summary>
		/// コンストラクタ
		/// </summary>
		public AplSetting()
		{
			Directory.CreateDirectory(APP_DATA_FOLDER_);
			Trace.WriteLine("Create " + APP_DATA_FOLDER_);

			//bEncryptTemplateFile_ = false;

			bMinimizeOnStart_ = false;
			maxHistory_ = 100;
			bInheritHistory_ = true;

			//templateFilePath_ = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), Properties.Settings.Default.DefaultTemplateFileName);
			templateFilePath_ = Path.Combine(APP_DATA_FOLDER_, Properties.Settings.Default.DefaultTemplateFileName);
			bBackup_ = true;

			hkActive_ = Keys.A | Keys.Shift | Keys.Control;
			hkDeleteHistory_ = Keys.D | Keys.Shift | Keys.Control;
			hkTemplatePopup_ = Keys.Q | Keys.Shift | Keys.Control;
			
			bAlwaysTop_ = false;

			Opacity_ = 1.0;

            sriptFilePath_ = string.Empty;

			WindowFont_ = global::ClipClop.Properties.Settings.Default.DefaultFont;
		}

		public static AplSetting Create(string setting)
		{
			if (string.IsNullOrEmpty(setting))
				return new AplSetting();

			try
			{
				XmlSerializer serializer = new XmlSerializer(typeof(AplSetting));

				AplSetting cls = null;
				using (StringReader sr = new StringReader(setting))
				{
					cls = (AplSetting)serializer.Deserialize(sr);
				}
				return cls;
			}
			catch
			{
				return new AplSetting();
			}
		}

		public override string ToString()
		{
			//XmlSerializerオブジェクトを作成
			//書き込むオブジェクトの型を指定する
			XmlSerializer serializer = new XmlSerializer(typeof(AplSetting));

			string ret = string.Empty;
			using (StringWriter sr = new StringWriter())
			{
				serializer.Serialize(sr, this);
				ret = sr.ToString();
			}
			return ret;
		}


		public int GetHotKeyCount()
		{
			return Enum.GetNames(typeof(Hotkeys)).Length;
		}

		public System.Windows.Forms.Keys GetHotKeyAt(int index)
		{
			switch ((Hotkeys)index)
			{
				case Hotkeys.Active:
					return this.hkActive_;
				case Hotkeys.DeleteHistory:
					return this.hkDeleteHistory_;
				case Hotkeys.TemplatePopup:
					return this.hkTemplatePopup_;
			}
			return System.Windows.Forms.Keys.None;
		}
	}
}
