using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace Aqua877.WinApp.IronLivetube.LSchedule
{
	public partial class MainWindow : Form
	{
		private object syncObj = new Object();
		private LiveDataBase LiveData;
		private global::Aqua877.WinApp.IronLivetube.SendersWiki WikiList;
		private MainWindowListViewSorter SortHelper = new MainWindowListViewSorter();

		public MainWindow()
		{
			this.InitializeComponent();

			this.LiveThumbnails.Images.Add(Settings.LoadingImage);
			this.LiveList.View = Settings.Setting.ViewMode;
			this.LiveList.ListViewItemSorter = this.SortHelper;
			this.LiveData = new LiveDataBase();
			this.LiveData.OnGetLiveDataFinished += this.OnGetLiveDataFinished;
			this.LiveData.OnStatusTextChanged += s => this.SetStatusText(s);
			this.LiveData.OnGetThumbnailFinished += data => {
				lock (syncObj)
				{
					if (data.Thumbnail != null)
					{
						this.LiveThumbnails.Images.Add(data.Thumbnail);
						var f = this.LiveList.Items.Cast<ListViewItem>().Where(xs => xs.SubItems[0].Text == data.Title && xs.SubItems[1].Text == data.Author);
						if (f.Count() > 0)
						{
							f.First().ImageIndex = this.LiveThumbnails.Images.Count - 1;
						}
					}
				}

				//Debug
				var x = this.LiveList.Items.Cast<ListViewItem>().ToArray();
				x.ToString();
			};
			this.LiveData.BeginGetLiveSchedule();

			this.WikiList = new SendersWiki();
		}

		public void OnGetLiveDataFinished(IEnumerable<LiveData> added, IEnumerable<LiveData> removed)
		{
			this.LiveList.ListViewItemSorter = null;
			this.LiveList.BeginUpdate();

			removed.Select(xs => {
				var o = this.LiveList.Items.Cast<ListViewItem>().SingleOrDefault(a => a.SubItems[1].Text == xs.Title || a.SubItems[2].Text == xs.Author);
				if (o == default(ListViewItem))
				{
					return -1;
				}
				else
				{
					return o.Index;
				}
			}).Where(xs => xs != -1)
			.ForEach(xs => this.LiveList.Items.RemoveAt(xs));

			added.Where(xs =>
				!Settings.Setting.FilteringList.Any(fs =>
				{
					switch (fs.Target)
					{
						case MatchTarget.Author:
						{
							if (xs.Author == fs.FilteringString)
							{
								return true;
							}
							break;
						}

						case MatchTarget.Title:
						{
							if (xs.Title == fs.FilteringString)
							{
								return true;
							}
							break;
						}
						case MatchTarget.Tags:
						{
							if (xs.Tags.Contains(fs.FilteringString))
							{
								return true;
							}
							break;
						}
					}
					return false;
				})).Select(xs => new {
					data = xs,
					item = new ListViewItem(new[] {
						new ListViewItem.ListViewSubItem { Text = xs.Title },
						new ListViewItem.ListViewSubItem { Text = xs.Author },
						new ListViewItem.ListViewSubItem { Text = xs.Listeners.ToString() },
						new ListViewItem.ListViewSubItem { Text = xs.Visitors.ToString() },
						new ListViewItem.ListViewSubItem { Text = xs.Comments.ToString() },
						new ListViewItem.ListViewSubItem { Text = xs.Start.ToString() },
						new ListViewItem.ListViewSubItem { Text = string.Join(" ", xs.Tags) }
				}, 0)}
				.Do(l =>
				{
					Settings.Setting.FavoriteList.ForEach(f =>
					{
						switch (f.Target)
						{
							case MatchTarget.Author:
							{
								if (xs.Author == f.FavoriteString)
								{
									l.item.ForeColor = f.TextColor;
									l.item.BackColor = f.BackgroundColor;
								}
								break;
							}

							case MatchTarget.Title:
							{
								if (xs.Title == f.FavoriteString)
								{
									l.item.ForeColor = f.TextColor;
									l.item.BackColor = f.BackgroundColor;
								}
								break;
							}

							case MatchTarget.Tags:
							{
								if (xs.Tags.Contains(f.FavoriteString))
								{
									l.item.ForeColor = f.TextColor;
									l.item.BackColor = f.BackgroundColor;
								}
								break;
							}
						}
					});
				})
			).ForEach(xs =>
			{
				xs.item.ImageIndex = 0;
				this.LiveList.Items.Add(xs.item);
			});
			
			this.LiveList.ListViewItemSorter = this.SortHelper;
			this.LiveList.Sort();
			this.LiveList.EndUpdate();

			if (Settings.Setting.IsNotifyOnPopUp && this.LiveData.LiveCollection.Count() != added.Count())
			{
				this.TaskTrayIcon.BalloonTipIcon = ToolTipIcon.Info;
				this.TaskTrayIcon.BalloonTipTitle = "お気に入り配信";
				this.TaskTrayIcon.BalloonTipText = added.Count() + " 件のお気に入り配信が見つかりました。";
				this.TaskTrayIcon.ShowBalloonTip(3000);
			}
		}

		private void LiveList_ColumnClick(object sender, ColumnClickEventArgs e)
		{
			if (!Settings.Setting.IsLockSort)
			{
				this.SortHelper.Column = e.Column;
				this.LiveList.Sort();
			}
		}

		private void LiveList_DoubleClick(object sender, EventArgs e)
		{
			try
			{
				Process.Start(this.LiveData.LiveCollection.Single(xs =>
					xs.Title == this.LiveList.SelectedItems[0].SubItems[0].Text &&
					xs.Author == this.LiveList.SelectedItems[0].SubItems[1].Text
				).Url.ToString());
			}
			catch(Win32Exception)
			{

			}
		}

		public void SetStatusText(string text)
		{
			this.StatusBarText.Text = text;

			Observable.Return(text)
				.Delay(TimeSpan.FromSeconds(3))
				.ObserveOnDispatcher()
				.Subscribe(s =>
					{
						if (this.StatusBarText.Text == s)
						{
							this.StatusBarText.Text = "";
						}
					}
				);
		}

		private void SettingsMenu_Click(object sender, EventArgs e)
		{
			using (var sw = new SettingsWindow())
			{
				sw.ShowDialog();
			}

			this.LiveList.Items.Cast<ListViewItem>().ForEach(xs =>
			{
				//除外
				Settings.Setting.FilteringList.ForEach(f => {
					switch (f.Target)
					{
						case MatchTarget.Author:
						{
							if (xs.SubItems[1].Text == f.FilteringString)
							{
								this.LiveList.Items.RemoveAt(xs.Index);
							}
							break;
						}

						case MatchTarget.Title:
						{
							if (xs.SubItems[0].Text == f.FilteringString)
							{
								this.LiveList.Items.RemoveAt(xs.Index);
							}
							break;
						}

						case MatchTarget.Tags:
						{
							if (xs.SubItems[6].Text.Split(' ').Contains(f.FilteringString))
							{
								this.LiveList.Items.RemoveAt(xs.Index);
							}
							break;
						}
					}
				});

				Settings.Setting.FavoriteList.ForEach(f =>
				{
					//色分け
					switch (f.Target)
					{
						case MatchTarget.Author:
						{
							if (xs.SubItems[1].Text == f.FavoriteString)
							{
								xs.ForeColor = f.TextColor;
								xs.BackColor = f.BackgroundColor;
							}
							break;
						}

						case MatchTarget.Title:
						{
							if (xs.SubItems[0].Text == f.FavoriteString)
							{
								xs.ForeColor = f.TextColor;
								xs.BackColor = f.BackgroundColor;
							}
							break;
						}

						case MatchTarget.Tags:
						{
							if (xs.SubItems[6].Text.Split(' ').Contains(f.FavoriteString))
							{
								xs.ForeColor = f.TextColor;
								xs.BackColor = f.BackgroundColor;
							}
							break;
						}
					}
				});
			});

			this.LiveList.View = Settings.Setting.ViewMode;
		}

		private void ExitMenu_Click(object sender, EventArgs e)
		{
			Application.Exit();
		}

		private void CopyMenu_Click(object sender, EventArgs e)
		{
			if(!this.LiveList.SelectedItems.Cast<ListViewItem>().Any())
			{
				return;
			}

			var livedata = this.LiveData.LiveCollection.First/*Single*/(xs => xs.Title == this.LiveList.SelectedItems[0].SubItems[0].Text);

			Clipboard.SetText(String.Format("[{0}]{1}({2}:{3}視:{4}コ) {5}", livedata.Author, livedata.Title, livedata.Listeners, livedata.Visitors, livedata.Comments, string.Join(" ", livedata.Tags)));
		}

		private void CopyLiveTitleMenu_Click(object sender, EventArgs e)
		{
			if (!this.LiveList.SelectedItems.Cast<ListViewItem>().Any())
			{
				return;
			}

			var livedata = this.LiveData.LiveCollection.First/*Single*/(xs => xs.Title == this.LiveList.SelectedItems[0].SubItems[0].Text);
		}

		private void CopyLiveAuthorMenu_Click(object sender, EventArgs e)
		{
			if (!this.LiveList.SelectedItems.Cast<ListViewItem>().Any())
			{
				return;
			}

			var livedata = this.LiveData.LiveCollection.First/*Single*/(xs => xs.Title == this.LiveList.SelectedItems[0].SubItems[0].Text);

			Clipboard.SetText(livedata.Author);
		}

		private void CopyUrlMenu_Click(object sender, EventArgs e)
		{
			if (!this.LiveList.SelectedItems.Cast<ListViewItem>().Any())
			{
				return;
			}

			var livedata = this.LiveData.LiveCollection.First/*Single*/(xs => xs.Title == this.LiveList.SelectedItems[0].SubItems[0].Text);

			Clipboard.SetText(livedata.Url.ToString());
		}

		private void SetFavoriteMenu_Click(object sender, EventArgs e)
		{
			if (!this.LiveList.SelectedItems.Cast<ListViewItem>().Any())
			{
				return;
			}

			if (Settings.Setting.FavoriteList.Any(xs => xs.FavoriteString == this.LiveList.SelectedItems[0].SubItems[1].Text && xs.Target == MatchTarget.Author))
			{
				return;
			}

			Settings.Setting.FavoriteList.Add(new Favorite(){
				FavoriteString = this.LiveList.SelectedItems[0].SubItems[1].Text,
				Target = MatchTarget.Author,
				BackgroundColor = Color.Orange,
				TextColor = Color.White
			});

			this.LiveList.SelectedItems[0].ForeColor = Color.White;
			this.LiveList.SelectedItems[0].BackColor = Color.Orange;
		}

		private void SetUnFavoriteMenu_Click(object sender, EventArgs e)
		{
			if (!this.LiveList.SelectedItems.Cast<ListViewItem>().Any())
			{
				return;
			}

			var f = Settings.Setting.FavoriteList.Find(xs => xs.FavoriteString == this.LiveList.SelectedItems[0].SubItems[1].Text && xs.Target == MatchTarget.Author);

			if (f == null)
			{
				return;
			}

			Settings.Setting.FavoriteList.Remove(f);

			this.LiveList.SelectedItems[0].ForeColor = this.LiveList.ForeColor;
			this.LiveList.SelectedItems[0].BackColor = this.LiveList.BackColor;
		}

		private void SetFilteringMenu_Click(object sender, EventArgs e)
		{
			if (!this.LiveList.SelectedItems.Cast<ListViewItem>().Any())
			{
				return;
			}

			if (Settings.Setting.FilteringList.Any(xs => xs.FilteringString == this.LiveList.SelectedItems[0].SubItems[1].Text && xs.Target == MatchTarget.Author))
			{
				return;
			}

			Settings.Setting.FilteringList.Add(new Filtering() {
				FilteringString = this.LiveList.SelectedItems[0].SubItems[1].Text,
				Target = MatchTarget.Author
			});

			this.LiveList.Items.RemoveAt(this.LiveList.SelectedItems[0].Index);
		}

		private void OpenLiveMenu_Click(object sender, EventArgs e)
		{
			Process.Start(this.LiveData.LiveCollection.Single(xs =>
				xs.Title == this.LiveList.SelectedItems[0].SubItems[0].Text &&
				xs.Author == this.LiveList.SelectedItems[0].SubItems[1].Text
			).Url.ToString());
		}

		private void OpenLivePageMenu_Click(object sender, EventArgs e)
		{
			Process.Start(this.LiveData.LiveCollection.Single(xs =>
				xs.Title == this.LiveList.SelectedItems[0].SubItems[0].Text &&
				xs.Author == this.LiveList.SelectedItems[0].SubItems[1].Text
			).Let(l => "http://livetube.cc/" + l.Author + "/" + l.Title));
		}

		private void OpenLiveWikiMenu_Click(object sender, EventArgs e)
		{
			if (this.LiveList.SelectedItems.Cast<ListViewItem>().Any())
			{
				if (this.WikiList.SendersWikiList.Keys.Contains(this.LiveList.SelectedItems[0].SubItems[1].Text))
				{
					Process.Start(this.WikiList.SendersWikiList[this.LiveList.SelectedItems[0].SubItems[1].Text].ToString());
				}
			}
		}

		private void InvokeIronLivetubeMenu_Click(object sender, EventArgs e)
		{
			if (Settings.Setting.IronLivetubePath != "")
			{
				Process.Start(Settings.Setting.IronLivetubePath, this.LiveData.LiveCollection.First/*Single*/(xs => xs.Title == this.LiveList.SelectedItems[0].SubItems[0].Text).Url.ToString());
			}
		}

		private void ShowVersionInfoMenu_Click(object sender, EventArgs e)
		{

		}

		private void CopyMenuStrip_Click(object sender, EventArgs e)
		{
			this.CopyMenu.PerformClick();
		}

		private void CopyLiveTitleMenuStrip_Click(object sender, EventArgs e)
		{
			this.CopyLiveTitleMenu.PerformClick();
		}

		private void CopyLiveAuthorMenuStrip_Click(object sender, EventArgs e)
		{
			this.CopyLiveAuthorMenu.PerformClick();
		}

		private void CopyLiveUrlMenuStrip_Click(object sender, EventArgs e)
		{
			this.CopyLiveUrlMenu.PerformClick();
		}

		private void SetFavoriteMenuStrip_Click(object sender, EventArgs e)
		{
			this.SetFavoriteMenu.PerformClick();
		}

		private void SetUnFavoriteMenuStrip_Click(object sender, EventArgs e)
		{
			this.SetUnFavoriteMenu.PerformClick();
		}

		private void SetFilteringMenuStrip_Click(object sender, EventArgs e)
		{
			this.SetFilteringMenu.PerformClick();
		}

		private void OpenLiveMenuStrip_Click(object sender, EventArgs e)
		{
			this.OpenLiveMenu.PerformClick();
		}

		private void OpenLivePageMenuStrip_Click(object sender, EventArgs e)
		{
			this.OpenLivePageMenu.PerformClick();
		}

		private void OpenLiveWikiMenuStrip_Click(object sender, EventArgs e)
		{
			this.OpenLiveWikiMenu.PerformClick();
		}

		private void InvokeIronLivetubeMenuStrip_Click(object sender, EventArgs e)
		{
			this.InvokeIronLivetubeMenu.PerformClick();
		}
	}
}
