using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Xml.Serialization;
using System.IO;
using System.Diagnostics;

namespace ClipClop.View
{
	public class ClipboardListBox : ListBox
	{
		int maxItemCount_ = 100;

		public ClipboardListBox()
		{
			this.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.OnMouseDoubleClick);
		}

		private void OnMouseDoubleClick(object sender, MouseEventArgs e)
		{
			MoveHead(false);
		}

		/// <summary>
		/// 選択項目を先頭に移動する。
		/// </summary>
		public void MoveHead(bool bRemoveNewLine )
		{
			string text = this.SelectedItem.ToString();

			if (string.IsNullOrEmpty(text))
				return;

			if (bRemoveNewLine)
			{
				text = text.Replace(Environment.NewLine,string.Empty);
			}

			DataObject data = new DataObject();
			data.SetData(text);

			DeleteSelectedItem();

			try
			{
				Clipboard.SetDataObject(data, true);
			}
			catch (ExternalException)
			{
				//何もしない。
			}
		}


		/// <summary>
		/// 選択項目を削除する
		/// </summary>
		public void DeleteSelectedItem()
		{
			int index = this.SelectedIndex;
			if (index < 0)
				return;
			this.Items.RemoveAt(index);
		}

		public void Clear()
		{
			this.Items.Clear();
		}

		public void RemoveLast()
		{
			if( this.Items.Count > 0 )
				this.Items.RemoveAt(0);
		}

		public void RemoveOld(int count)
		{
			Trace.WriteLine(string.Format("remove old {0} imtes.", count));

			for (int i = 0; i < count; i++)
			{
				Items.RemoveAt(Items.Count-1);
			}
		}


		public void InsertHead(string s)
		{
			//先頭と同じ文字列は挿入しない
			if (this.Items.Count > 0)
			{
				string head = this.Items[0].ToString();
				if (!string.IsNullOrEmpty(head) && head.Equals(s) )
				{
					Trace.WriteLine(string.Format("input={0} AND head={1} are same.",s,head));
					return;
				}
			}

			this.Items.Insert(0, s);

			Trace.WriteLine(string.Format("inset input={0}.", s));

			if (this.Items.Count > maxItemCount_)
			{
				RemoveOld(this.Items.Count - maxItemCount_);
			}
		}

		public void SetMax(int max)
		{
			maxItemCount_ = max;

			if (this.Items.Count > maxItemCount_)
			{
				RemoveOld(this.Items.Count - maxItemCount_);
			}
		}

		public void Read(string filepath)
		{
			if (!File.Exists(filepath))
			{
				return;
			}
			XmlSerializer serializer = new XmlSerializer(typeof(string[]));

			string[] array = null;

			using (FileStream fs = new FileStream(filepath, FileMode.Open))
			{
				object o = serializer.Deserialize(fs);

				array = (string[])o;

				fs.Close();
			}

			this.Items.Clear();

			for( int idx = array.Length; idx > 0; idx--)
			{
				this.InsertHead(array[idx-1]);
			}

		}

		public void Save(string filepath)
		{
			XmlSerializer serializer = new XmlSerializer(typeof(string[]));

			string[] array = new string[this.Items.Count];

			this.Items.CopyTo(array, 0);

			using (FileStream fs = new FileStream(filepath, FileMode.Create, FileAccess.Write))
			{
				serializer.Serialize(fs, array);

				fs.Close();
			}
		}

	}
}
