using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SamplesCommon;
using C1.Silverlight.RichTextBox.Documents;
using C1.Silverlight.RichTextBox;
using C1.Silverlight.SpellChecker;
using C1.Silverlight;

namespace Hyperlinks
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();

            _toolbar.RichTextBox = _rtb;
            var spellChecker = new C1SpellChecker();
            _toolbar.SpellChecker = spellChecker;
            spellChecker.MainDictionary.LoadAsync("C1Spell_en-US.dct");
            _rtb.Html = @"
                <html>
                    <body style=""font-family: Verdana; font-size: medium;"">
                	
                    <h1>
                    Welcome to C1RichTextBox for Silverlight.</h1>

                    <br/>

                    <p>
                    This demo shows the hyperlink feature in the <b>C1RichTextBox</b>.
                    Control-click <a href=""http://www.componentone.com"">this link</a> 
                    to visit the <i>ComponentOne</i> home page.</p>
                	
                    <br/>

                    <p>
                    Or use the navigation bar and browse the web.</p>

                    </body>
                </html>";
            _rtb.ElementMouseEnter += _rtb_ElementMouseEnter;
            _rtb.ElementMouseLeave += _rtb_ElementMouseLeave;
            _rtb.RequestNavigate += _rtb_RequestNavigate;

            _txtUrl.KeyDown += (s, e) =>
            {
                if (e.Key == Key.Enter)
                {
                    Go();
                }
            };
            _btnGo.Click += (s, e) => Go();
        }

        //--------------------------------------------------------------------------------
        #region ** hyperlink logic

        // update cursor and status message as user moves the mouse
        void _rtb_ElementMouseEnter(object sender, MouseEventArgs e)
        {
            var hyperlink = GetHyperlink(sender);
            if (hyperlink != null)
            {
                UpdateLinkStatus(hyperlink.NavigateUri.ToString());
            }
        }

        void _rtb_ElementMouseLeave(object sender, MouseEventArgs e)
        {
            var hyperlink = GetHyperlink(sender);
            _status.Text = hyperlink == null
                ? string.Empty
                : string.Format("You left the link '{0}'.", hyperlink.NavigateUri);
        }

        void UpdateLinkStatus(string linkText)
        {
            _status.Text = string.IsNullOrEmpty(linkText)
                ? string.Empty
                : string.Format("Control-click to follow the link to '{0}'...", linkText);
        }

        void UpdateStatus(string status)
        {
            _status.Text = status;
        }

        void _rtb_RequestNavigate(object sender, RequestNavigateEventArgs e)
        {
            System.Windows.Browser.HtmlPage.Window.Eval(string.Format("open('{0}')", e.Hyperlink.NavigateUri));
        }

        C1Hyperlink GetHyperlink(object sender)
        {
            var element = sender as C1TextElement;
            if (element == null)
            {
                return null;
            }
            return element.GetParents().Concat(new[] { element }).LastOrDefault(el => el is C1Hyperlink) as C1Hyperlink;            
        }

        #endregion

        //--------------------------------------------------------------------------------
        #region ** navigation

        private void Go()
        {
            try
            {
                var textUri = (_txtUrl.Text.StartsWith("http://") ? "" : "http://") + _txtUrl.Text;
                var uri = new Uri(textUri, UriKind.Absolute);

                WebClient c = new WebClient();
                c.DownloadStringCompleted += (s, e) =>
                {
                    if (e.Error == null)
                    {
                        _rtb.SetHtml(e.Result, uri);
                        UpdateStatus("");
                    }
                    else 
                    {
                        UpdateStatus(e.Error.ToString());
                    }
                };
                c.Headers["url"] = uri.ToString();
                c.DownloadStringAsync(Extensions.GetAbsoluteUri("browserService.ashx"));
                UpdateStatus("Loading...");
            }
            catch (UriFormatException)
            {
                UpdateStatus("Invalid URL: " + _txtUrl.Text);
            }
        }
        #endregion
    }
}
