using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CaLib.User.PropertyGridUtil;
using ClipClop.Properties;
using System.ComponentModel;
using CaLib.User.DynamicProperty;

namespace ClipClop.Model.ImageHistory
{

	[TypeConverter(typeof(PropertyDisplayConverter))]
	[TypeDescriptionProvider(typeof(DynamicTypeDescriptionProvider))]
	public class ImageHistoryOptions : CaLib.User.PropertyGridUtil.IReversible
	{
		public ImageHistoryOptions()
		{
			bEnable_ = false;
			nMax_ = 10;
			nItemHeight_ = 100;
		}

		[DisplayNameLocalized(typeof(Resources), "PGDisplayNameCheckImage"),
		DescriptionLocalizedAttribute(typeof(Resources), "PGDescriptionCheckImage")]
		[RefreshProperties(RefreshProperties.All)]  // この値が変わると、他が変わるため。
		public bool bEnable_ { get; set; }

		/// <summary>
		/// 保持する画像履歴数
		/// </summary>
		[DisplayNameLocalized(typeof(Resources), "PGDisplayNameMaxImage"),
		DescriptionLocalizedAttribute(typeof(Resources), "PGDescriptionMaxImage")]
		public ushort MaxImage
		{
			get
			{
				return this.nMax_;
			}
			set
			{
				if (value < MAX_IMAGE_RANGE[0] || MAX_IMAGE_RANGE[1] < value)
				{
					throw new ArgumentOutOfRangeException();
				}
				this.nMax_ = value;
			}
		}
		ushort nMax_;

		/// <summary>
		/// 画像の高さ
		/// </summary>
		[DisplayNameLocalized(typeof(Resources), "PGDisplayNameImageHight"),
		DescriptionLocalizedAttribute(typeof(Resources), "PGDescriptionImageHight")]
		public ushort ItemHeight
		{
			get
			{
				return this.nItemHeight_;
			}
			set
			{
				if (value < MAX_HIGHT_RANGE[0] || MAX_HIGHT_RANGE[1] < value)
				{
					throw new ArgumentOutOfRangeException();
				}
				this.nItemHeight_ = value;
			}
		}
		ushort nItemHeight_;

		static readonly string[] strEnable = { Properties.Resources.PValueOn, Properties.Resources.PValueOff };
		static readonly char token_ = ',';
		static readonly ushort[] MAX_IMAGE_RANGE = { 1, 25 };// 上限に根拠なし
		static readonly ushort[] MAX_HIGHT_RANGE = { 1, 256 };// 上限に根拠なし



		public string Encode()
		{
			if (false == bEnable_)
			{
				return strEnable[1];
			}

			return string.Format("{1}{0}{2}{0}{3}", token_, strEnable[0], nMax_, nItemHeight_);
		}
		
		public void Decode(string value)
		{ 
			int tokenIdx = value.IndexOf(token_);

			if (tokenIdx != -1)
			{
				//offの場合
				bEnable_ = false;
				nMax_ = 10;
				nItemHeight_ = 100;
				return;
			}

			string[] part = value.Split(token_);
			if (part.Length != 3)
				throw new ArgumentException(string.Format(Properties.Resources.EF013, value));

			bEnable_ = true;

			try
			{
				nMax_ = ushort.Parse(part[1]);
				nItemHeight_ = ushort.Parse(part[2]);
			}
			catch (Exception exp)
			{
				StringBuilder sb = new StringBuilder(string.Format(Properties.Resources.EF013, value));
				sb.Append(Environment.NewLine);
				sb.Append(exp.Message);

				throw new ArgumentException(sb.ToString());
			}
		}

		public void ModifyDynamicProperties(PropertyDescriptorList pdl)
		{
			PropertyDescriptor pdMax = pdl.Find("MaxImage", false);
			if (pdMax != null)
			{
				//このあと追加するので取り除く
				pdl.Remove(pdMax);

				if (bEnable_ == true)
				{
					pdl.Add(TypeDescriptor.CreateProperty(this.GetType(), pdMax, new BrowsableAttribute(true), new ReadOnlyAttribute(false)));
				}
				else
				{
					pdl.Add(TypeDescriptor.CreateProperty(this.GetType(), pdMax, new BrowsableAttribute(false)));
				}
			}

			PropertyDescriptor pdHight = pdl.Find("ItemHeight", false);
			if (pdHight != null)
			{
				//このあと追加するので取り除く
				pdl.Remove(pdHight);

				if (bEnable_ == true)
				{
					pdl.Add(TypeDescriptor.CreateProperty(this.GetType(), pdHight, new BrowsableAttribute(true), new ReadOnlyAttribute(false)));
				}
				else
				{
					pdl.Add(TypeDescriptor.CreateProperty(this.GetType(), pdHight, new BrowsableAttribute(false)));
				}
			}
		}

	}
}
