/*
	$Id: TwitterStatusViewer.cs 68 2010-02-06 05:52:07Z catwalk $
*/
using System;
using System.Configuration;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Data;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Reflection;
using System.Web;
using System.Net;
using Hiyoko.Net;
using Hiyoko.Net.Twitter;
using Hiyoko.Utilities;

namespace Hiyoko.Forms{
	using WinForms = System.Windows.Forms;
	using Gdi = System.Drawing;
	
	public partial class TwitterStatusViewer : UserControl{
		public TwitterStatusViewer(){
			this.InitializeComponent();
			Program.ThemeManager.Attach(this.Resources);
			this.Unloaded += delegate{
				Program.ThemeManager.Detach(this.Resources);
			};
			this.inlineImagePanel.Children.Add(new Image());
		}
		
		public static readonly DependencyProperty StatusProperty =
			DependencyProperty.Register("Status", typeof(Status), typeof(TwitterStatusViewer), new PropertyMetadata(Status.Empty, StatusPropertyChanged));
		public Status Status{
			get{
				return (Status)this.GetValue(StatusProperty);
			}
			set{
				this.SetValue(StatusProperty, value);
			}
		}
		
		private static readonly Regex parseStatusTextRegex =
			new Regex(@"(?<url>[a-z]+:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)|@(?<user>[a-zA-Z0-9_]+)|(?<hash>#([a-zA-Z0-9_]+|[^ \t]+_))", RegexOptions.Compiled);
		private static void StatusPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){
			var self = (TwitterStatusViewer)d;
			self.inlineImagePanel.Children.Clear();
			var status = (Status)e.NewValue;
			
			// テキスト
			string text = status.Text;
			TextBlock textBlock = self.textBlock;
			textBlock.Inlines.Clear();
			if(!String.IsNullOrEmpty(text)){
				Match match = parseStatusTextRegex.Match(text);
				int right = 0;
				while(match.Success){
					textBlock.Inlines.Add(text.Substring(right, match.Index - right));
					Group group;
					if((group = match.Groups["url"]).Success){
						string url = group.Value;
						Hyperlink link = new Hyperlink();
						link.Tag = url;
						link.Click += Hyperlink_Click;
						link.Inlines.Add(url);
						link.TextDecorations = null;
						textBlock.Inlines.Add(link);
						if(Program.Settings.IsExpandUrlsInStatus){
							UrlShorter shorter = Program.UrlShorter;
							if((shorter != null) && shorter.CanExpand(url)){
								Program.NetworkJobServer.EnqueueJob(
									delegate{
										return shorter.RequireExpand(url);
									},
									null,
									delegate(NetworkJobData data){
										try{
											string longUrl = null;
											using(WebResponse res = data.WebRequestData.WebRequest.EndGetResponse(data.AsyncResult)){
												longUrl = shorter.Expand(res);
											}
											if(!String.IsNullOrEmpty(longUrl)){
												d.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(delegate{
													link.Inlines.Clear();
													link.Inlines.Add(longUrl);
												}));
											}
										}catch(WebException){
										}
									}
								);
							}
						}
					}else if((group = match.Groups["user"]).Success){
						Hyperlink link = new Hyperlink();
						link.Tag = "http://twitter.com/" + group.Value;
						link.Click += Hyperlink_Click;
						link.Inlines.Add(group.Value);
						link.TextDecorations = null;
						textBlock.Inlines.Add("@");
						textBlock.Inlines.Add(link);
					}else if((group = match.Groups["hash"]).Success){
						Hyperlink link = new Hyperlink();
						link.Tag = "http://search.twitter.com/search?q=" + HttpUtility.UrlEncode(group.Value, Encoding.UTF8);
						link.Click += Hyperlink_Click;
						link.Inlines.Add(group.Value);
						link.TextDecorations = null;
						textBlock.Inlines.Add(link);
					}
					
					right = match.Index + match.Length;
					match = match.NextMatch();
				}
				textBlock.Inlines.Add(text.Substring(right));
			}
			
			// 画像展開
			if(Program.Settings.IsExpandImagesInStatus){
				if(!String.IsNullOrEmpty(status.Text)){
					foreach(var url in status.Text.ExtractUrls()){
						BitmapImage bmp = null;
						var twitpic = Program.Twitpic ?? new Twitpic();
						bmp = twitpic.GetThumbnail(url, false);
						if(bmp == null){
							bmp = new BitmapImage(new Uri(url));
						}
						if(bmp != null){
							double scaleW = ((bmp.Width > 0) && (bmp.Width > 240)) ? (240 / bmp.Width) : 1.0;
							double scaleH = ((bmp.Height > 0) && (bmp.Height > 240)) ? (240 / bmp.Height) : 1.0;
							double scale = Math.Min(scaleW, scaleH);
							var image = new Image();
							image.Source = bmp;
							image.Width = bmp.Width * scale;
							image.Height = bmp.Height * scale;
							bmp.DownloadCompleted += delegate{
								scaleW = ((bmp.Width > 0) && (bmp.Width > 240)) ? (240 / bmp.Width) : 1.0;
								scaleH = ((bmp.Height > 0) && (bmp.Height > 240)) ? (240 / bmp.Height) : 1.0;
								scale = Math.Min(scaleW, scaleH);
								image.Width = bmp.Width * scale;
								image.Height = bmp.Height * scale;
							};
							bmp.DownloadFailed += delegate{
								self.inlineImagePanel.Children.Remove(image);
							};
							self.inlineImagePanel.Children.Add(image);
						}
					}
				}
			}
		}
		
		private static void Hyperlink_Click(object sender, RoutedEventArgs e){
			try{
				Hyperlink link = (Hyperlink)sender;
				Process.Start((string)link.Tag);
			}catch(Exception ex){
				MessageBox.Show("オープンに失敗しました。\n\n" + ex.Message, "Hiyoko", MessageBoxButton.OK, MessageBoxImage.Error);
			}
		}
	}
}