using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using C1.Silverlight;
using SilverTunes.MediaLibrary;
using C1.Silverlight.Theming;
using System.Windows.Threading;
using System.Net;
using System.Xml.Linq;
using C1.Silverlight.MediaPlayer;
using System.Text.RegularExpressions;
using System.Collections.Generic;

namespace SilverTunes
{
    public partial class Page : UserControl
    {
        public class Video
        {
            public string Title { get; set; }
            public string Description { get; set; }
            public Uri Source { get; set; }
        }

        List<Album> _albums = new List<Album>();
        List<Video> _videos = new List<Video>();

        Button lastPlayButton = null;

        public Page()
        {
            InitializeComponent();

            browseButton.Visibility = Application.Current.Host.Source.Host == "localhost" ? 
                Visibility.Visible 
                : Visibility.Collapsed;

            sectionList.ItemsSource = new[] { "Music", "TEDTalks" };
            sectionList.SelectedIndex = 0;
            sectionList.SelectionChanged += (s, e) =>
            {
                if ("Music".Equals(sectionList.SelectedItem))
                {
                    musicCoverFlow.Visibility = Visibility.Visible;
                    musicInfo.Visibility = Visibility.Visible;
                    tedCoverFlow.Visibility = Visibility.Collapsed;
                    tedInfo.Visibility = Visibility.Collapsed;
                    lblSummary.Visibility = Visibility.Visible;

                    OnMusicIndexChanged(null, null);
                }
                else if ("TEDTalks".Equals(sectionList.SelectedItem))
                {
                    musicCoverFlow.Visibility = Visibility.Collapsed;
                    musicInfo.Visibility = Visibility.Collapsed;
                    tedCoverFlow.Visibility = Visibility.Visible;
                    tedInfo.Visibility = Visibility.Visible;
                    lblSummary.Visibility = Visibility.Collapsed;

                    OnTedIndexChanged(null, null);
                }
            };

            LoadMusic(null);
            LoadTED();
        }

        void LoadMusic(string path)
        {
            lblAlbumArtist.Text = "Loading Music...";
            lblSummary.Text = "";
            lbSongs.ItemsSource = null;
            musicCoverFlow.ItemsSource = null;

            // start spinner while we load
            spinner.Visibility = Visibility.Visible;
            sbSpinner.Begin();

            // go load the data
            var media = App.CreateMediaLibraryClient();
            media.GetLibraryCompleted += GetLibraryCompleted;
            media.GetLibraryAsync(path);
        }

        void LoadTED()
        {
            var client = new WebClient();
            client.DownloadStringAsync(new Uri("http://feeds.feedburner.com/tedtalks_video"));
            client.DownloadStringCompleted += (s, e) =>
            {
                if (string.IsNullOrEmpty(e.Result))
                {
                    return;
                }
                _videos.Clear();
                tedCoverFlow.Items.Clear();
                var doc = XDocument.Parse(e.Result);
                foreach (var item in doc.Descendants("item").Take(5))
                {
                    var title = item.Element("title");
                    var description = item.Element("description");
                    var enclosure = item.Element("enclosure");
                    if (title != null && description != null && enclosure != null)
                    {
                        var video = new Video
                        {
                            Title = title.Value,
                            Description = Regex.Replace(description.Value, "<img .*?/>", ""),
                            Source = new Uri(enclosure.Attribute("url").Value),
                        };
                        _videos.Add(video);
                        tedCoverFlow.Items.Add(
                            new C1MediaPlayer
                            {
                                AutoPlay = false,
                                IsChapterListButtonVisible = false,
                                IsItemListButtonVisible = false,
                                Items = 
                                { 
                                    new C1MediaItem 
                                    { 
                                        MediaSource = video.Source 
                                    } 
                                }
                            });
                    }
                }
                OnTedIndexChanged(null, null);
            };
        }

        void GetLibraryCompleted(object sender, GetLibraryCompletedEventArgs e)
        {
            // done with spinner
            sbSpinner.Stop();
            spinner.Visibility = Visibility.Collapsed;
            lblAlbumArtist.Text = "";

            if (e.Result != null)
            {
                _albums = e.Result.OrderBy(a => a.Artist + a.Title).ToList();

                musicCoverFlow.ItemsSource = _albums.Select(r =>
                    string.IsNullOrEmpty(r.Cover)? 
                        null 
                        : new BitmapImage(C1.Silverlight.Extensions.GetAbsoluteUri("GetCover.ashx?path=" + HttpUtility.UrlEncode(r.Cover))));

                OnMusicIndexChanged(null, null);
            }
        }

        void ToggleFullScreen(object sender, RoutedEventArgs e)
        {
            System.Windows.Interop.Content content = Application.Current.Host.Content;
            content.IsFullScreen = !content.IsFullScreen;
        }

        void PlayStop(object sender, RoutedEventArgs e)
        {
            if (lastPlayButton != null)
            {
                (lastPlayButton.FindName("pathPlay") as FrameworkElement).Visibility = Visibility.Visible;
                (lastPlayButton.FindName("pathStop") as FrameworkElement).Visibility = Visibility.Collapsed;
            }
            // if playing, stop
            if (mp3Player.CurrentState == MediaElementState.Playing && lastPlayButton == sender)
            {
                mp3Player.Stop();
            }
            else // play
            {
                var button = sender as Button;
                var song = button.DataContext as Song;
                if (song != null)
                {
                    mp3Player.Source = C1.Silverlight.Extensions.GetAbsoluteUri("GetSong.ashx?path=" + HttpUtility.UrlEncode(song.Path));
                    mp3Player.Play();
                    (button.FindName("pathPlay") as FrameworkElement).Visibility = Visibility.Collapsed;
                    (button.FindName("pathStop") as FrameworkElement).Visibility = Visibility.Visible;
                    lastPlayButton = button;
                }
            }
        }

        // restart search timer when search text changes
        void txtSearch_TextChanged(object sender, EventArgs e)
        {
            if (txtSearch.Text.Length == 0)
            {
                return;
            }

            for(int i=0; i<_albums.Count; ++i)
            {
                var album = _albums[i];
                if (album.Artist.IndexOf(txtSearch.Text, 0, StringComparison.OrdinalIgnoreCase) > -1
                    || album.Title.IndexOf(txtSearch.Text, 0, StringComparison.OrdinalIgnoreCase) > -1)
                {
                    musicCoverFlow.SelectedIndex = i;
                    return;
                }
            }
        }

        void OnMusicIndexChanged(object sender, PropertyChangedEventArgs<int> e)
        {
            if (musicCoverFlow.Visibility != Visibility.Visible)
            {
                return;
            }
            if (musicCoverFlow.SelectedIndex >= 0 && musicCoverFlow.SelectedIndex < musicCoverFlow.Items.Count)
            {
                var album = _albums[musicCoverFlow.SelectedIndex];
                lblAlbumArtist.Text = album.Artist + ": " + album.Title;
                UpdateSongs();
            }
            else
            {
                lbSongs.ItemsSource = new string[] { };
                lblSummary.Text = "";
            }
        }

        void OnTedIndexChanged(object sender, PropertyChangedEventArgs<int> e)
        {
            if (tedCoverFlow.Visibility != Visibility.Visible)
            {
                return;
            }
            if (tedCoverFlow.SelectedIndex >= 0 && tedCoverFlow.SelectedIndex < tedCoverFlow.Items.Count)
            {
                var item = _videos[tedCoverFlow.SelectedIndex];
                lblAlbumArtist.Text = item.Title;
                tedDescription.Text = item.Description;
            }
        }

        // update list of songs for the currently selected album
        private void UpdateSongs()
        {
            // show summary
            lblSummary.Text = string.Format(CultureInfo.CurrentCulture, "Album {0:N0} of {1:N0} :: {2:N0} Artists :: {3:N0} Songs",
                musicCoverFlow.SelectedIndex + 1,
                _albums.Count,
                _albums.Select(a => a.Artist).GroupBy(s => s).Count(),
                _albums.Sum(a => a.Songs.Count));

            // populate song panel
            var album = _albums[musicCoverFlow.SelectedIndex];
            lbSongs.ItemsSource = album.Songs;
        }

        private void coverFlow_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Right) 
            {
                if (musicCoverFlow.SelectedIndex < musicCoverFlow.Items.Count - 1)
                {
                    musicCoverFlow.SelectedIndex += 1;
                }
            }
            if (e.Key == Key.Left)
            {
                if (musicCoverFlow.SelectedIndex > 0)
                {
                    musicCoverFlow.SelectedIndex -= 1;
                }
            }
        }

        void Browse(object sender, RoutedEventArgs e)
        {
            var browser = new FolderBrowser();
            var win = new C1Window
            {
                Width = 300,
                Height = 400,
                Content = browser,
                Header="Import music from:",
            };
            browser.Done += path =>
            {
                win.Close();
                if (!string.IsNullOrEmpty(path))
                {
                    LoadMusic(path);
                }
            };
            win.CenterOnScreen();
            win.ShowModal();
        }
    }
}
