using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows.Threading;
namespace SPC.Kiosk.Common
{

    /// <summary>
    /// MediaRoll.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MediaRoll : UserControl
    {
        #region [ Members ]
        /// <summary>
        /// Media Info List
        /// (ObservableCollection<MediaRollItem>)
        /// </summary>
        public static readonly DependencyProperty ListMediaProperty =
                 DependencyProperty.Register(nameof(ListMedia), typeof(ObservableCollection<M_MediaRollItem>), typeof(MediaRoll), new PropertyMetadata(null, new PropertyChangedCallback(OnListMediaProperty)));
        /// <summary>
        /// Command
        /// </summary>
        public static readonly DependencyProperty CommandProperty =
                 DependencyProperty.Register(nameof(Command), typeof(ICommand), typeof(MediaRoll), new UIPropertyMetadata(null));

        private DispatcherTimer RollTimer;

        private int CurrentDisplayItem = 0;
        /// <summary>
        /// Media Info List
        /// </summary>
        public ObservableCollection<M_MediaRollItem> ListMedia
        {
            get { return (ObservableCollection<M_MediaRollItem>)GetValue(ListMediaProperty); }
            set { SetValue(ListMediaProperty, value); }
        }
        /// <summary>
        /// Command
        /// </summary>
        public ICommand Command
        {
            get { return (ICommand)GetValue(CommandProperty); }
            set { SetValue(CommandProperty, value); }
        }
        #region [ RoutedEvent 'MouseClicked' ]

        /// <summary>
        /// MouseClicked Event
        /// </summary>
        public static readonly RoutedEvent MouseClickedEvent = EventManager.RegisterRoutedEvent(nameof(MouseClicked), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MediaRoll));
        /// <summary>
        /// MouseClicked Routed Event Handler
        /// </summary>
        public event RoutedEventHandler MouseClicked
        {
            add { AddHandler(MouseClickedEvent, value); }
            remove { RemoveHandler(MouseClickedEvent, value); }
        }
        #endregion RoutedEvent 'MouseClicked'

        #endregion Members

        #region [ Ctor ]
        /// <summary>
        /// MediaRoll Ctor
        /// </summary>
        public MediaRoll()
        {
            InitializeComponent();
            RollTimer = new DispatcherTimer
            {
                Interval = TimeSpan.FromSeconds(5)
            };
            RollTimer.Tick += RollTimer_Tick;
        }
        #endregion Ctor

        #region [ Methods ]
        /// <summary>
        /// Add Media Control to MediaRollStack
        /// </summary>
        /// <param name="_target"></param>
        /// <param name="_aMedia"></param>
        private  void AddMedia(MediaRoll _target, M_MediaRollItem _aMedia)
        {
            try
            {
                switch (_aMedia.Type)
                {
                    case MediaType.Image:
                        var imageGrid = new Grid();
                        var aImage = new AnimationButton
                        {
                            NormalBrush = _aMedia.MediaPath,
                            DownBrush = _aMedia.MediaPath,
                            Width = _target.Width,
                            VerticalAlignment = VerticalAlignment.Top,
                            BrushStretch = Stretch.Fill,
                            ClickAnimationType = ButtonAnimationType.None,
                            Tag = _aMedia,
                            Name = string.Format("RollItemContent{0}", _target.MediaRollStack.Children.Count)
                        };
                        aImage.MouseClicked += RollItemContent_MouseClick;
                        _target.ReregisterName(string.Format("RollItemContent{0}", _target.MediaRollStack.Children.Count), aImage);
                        imageGrid.Tag = _aMedia.RunnigSeconds;
                        imageGrid.IsEnabled = true;
                        imageGrid.Children.Add(aImage);
                        imageGrid.Name = string.Format("RollItem{0}", _target.MediaRollStack.Children.Count);
                        _target.ReregisterName(string.Format("RollItem{0}", _target.MediaRollStack.Children.Count), imageGrid);
                        _target.MediaRollStack.Children.Add(imageGrid);
                        break;
                    case MediaType.VOD:
                        var vodGrid = new Grid();
                        var aVod = new MediaPlayer
                        {
                            MediaFile = _aMedia.MediaPath,
                            RepeatMedia = _aMedia.RepeatMedia,
                            Width = _target.Width,
                            Tag = _aMedia,
                            Name = string.Format("RollItemContent{0}", _target.MediaRollStack.Children.Count)
                        };
                        aVod.MouseClicked += RollItemContent_MouseClick;
                        _target.ReregisterName(string.Format("RollItemContent{0}", _target.MediaRollStack.Children.Count), aVod);
                        vodGrid.Tag = _aMedia.RunnigSeconds;
                        vodGrid.IsEnabled = true;
                        vodGrid.Children.Add(aVod);
                        vodGrid.Name = string.Format("RollItem{0}", _target.MediaRollStack.Children.Count);
                        _target.ReregisterName(string.Format("RollItem{0}", _target.MediaRollStack.Children.Count), vodGrid);
                        _target.MediaRollStack.Children.Add(vodGrid);
                        break;
                }
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(_target, "AddMedia()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        /// <summary>
        /// Raise MouseClicked Event
        /// </summary>
        private void RaiseMouseClickedEvent(object _sender)
        {
            //Command Excute 
            if (Command != null && Command.CanExecute((_sender as FrameworkElement).Tag))
            {
                Command.Execute((_sender as FrameworkElement).Tag);
            }
            RoutedEventArgs newEventArgs = new RoutedEventArgs(MediaRoll.MouseClickedEvent, _sender);
            RaiseEvent(newEventArgs);
        }

        #endregion Methods

        #region [ Event Handlers ]
        private static void OnListMediaProperty(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var target = d as MediaRoll;
            if (e.NewValue is ObservableCollection<M_MediaRollItem> lstMedia)
            {
                target.MediaRollStack.Children.Clear();
                foreach (var aMedia in lstMedia)
                {
                    if (File.Exists(aMedia.MediaPath)) target.AddMedia(target, aMedia);
                }
                if (target.MediaRollStack.Children.Count > 0)
                {
                    var firstItem = target.FindName("RollItem0") as Grid;
                    var mediaObject = target.FindName(string.Format("RollItemContent{0}", 0));
                    var mediaObjectType = mediaObject.GetType();
                    if (mediaObject is MediaPlayer mediaPlayer)
                    {
                        mediaPlayer.Stop();
                        mediaPlayer.Play();
                    }
                    if (target.RollTimer != null)
                    {
                        target.RollTimer.Interval = TimeSpan.FromSeconds((double)firstItem.Tag);
                        target.RollTimer.Start();
                    }
                    
                }
            }
        }

        private void RollItemContent_MouseClick(object sender, RoutedEventArgs e)
        {
            RaiseMouseClickedEvent(e.OriginalSource);
        }

        private void RollTimer_Tick(object sender, EventArgs e)
        {

            try
            {
                RollTimer.Stop();
                if (this.MediaRollStack.Children.Count > 1)
                {
                    var currentObject = this.MediaRollStack.Children[CurrentDisplayItem] as FrameworkElement;
                    bool Selected = false;
                    var targetIndex = CurrentDisplayItem + 1;
                    var mediaSourceObject = this.FindName(string.Format("RollItemContent{0}", CurrentDisplayItem));
                    if (mediaSourceObject is MediaPlayer)
                    {
                        (mediaSourceObject as MediaPlayer).Stop();
                    }
                    FrameworkElement targetObject = null;
                    object mediaObject = null;
                    while (!Selected)
                    {
                        if (targetIndex.Equals(this.MediaRollStack.Children.Count)) targetIndex = 0;
                        targetObject = this.MediaRollStack.Children[targetIndex] as FrameworkElement;
                        mediaObject = this.FindName(string.Format("RollItemContent{0}", targetIndex));
                        var targetData = mediaObject is FrameworkElement selectObject ? selectObject.Tag : null;
                        if (targetData is M_MediaRollItem selectData)
                        {
                            var CurrentDateTime = DateTime.Now.TimeOfDay;
                            if (!(selectData.StartTime.Equals(default(TimeSpan)) || selectData.EndTime.Equals(default(TimeSpan))))
                            {
                                if (selectData.StartTime <= CurrentDateTime && selectData.EndTime >= CurrentDateTime)
                                {
                                    Selected = true;
                                    break;
                                }
                            }
                            else
                            {
                                Selected = true;
                                break;
                            }
                        }
                        else
                        {
                            Selected = true;
                            break;
                        }
                        targetIndex++;
                    }
                    if (mediaObject is MediaPlayer playObject)
                    {
                        playObject.Stop();
                        playObject.Play();
                    }
                    if (!currentObject.Equals(targetObject))
                    {
                        currentObject.IsEnabled = true;
                        targetObject.IsEnabled = false;
                        var targetAnimation = Animations.GetOpenAndCloseAnimation(currentObject, targetObject, OpenCloseAnimationType.GotoLeft, this.Width, 1, 0.3);
                        if (targetAnimation != null)
                        {
                            targetAnimation.Completed += TargetAnimation_Completed;
                            targetAnimation.Begin();
                        }
                    }
                    else
                    {
                        RollTimer.Start();
                    }
                }
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "RollTimer_Tick()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }

        private void TargetAnimation_Completed(object sender, EventArgs e)
        {
            CurrentDisplayItem += 1;
            if (CurrentDisplayItem.Equals(this.MediaRollStack.Children.Count))
            {
                //(this.MediaRollStack.Children[CurrentDisplayItem] as FrameworkElement).Width = 0;
                //(this.MediaRollStack.Children[0] as FrameworkElement).Width = this.Width;
                CurrentDisplayItem = 0;
            }
            if (this.MediaRollStack.Children[CurrentDisplayItem] is FrameworkElement viewMedia)
            {
                viewMedia.IsEnabled = true;
                if (this.RollTimer != null)
                {
                    this.RollTimer.Interval = TimeSpan.FromSeconds((double)viewMedia.Tag);
                    this.RollTimer.Start();
                }
            }
        }



        #endregion Event Handlers
    }
}
