using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
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;

namespace DayTimePickControl
{
    /// <summary>
    /// Interaction logic for DayTimePick.xaml
    /// </summary>
    public partial class DayTimePick : UserControl
    {
        #region private
        private Thumb thumb1;
        private Thumb thumb2;

        private Border trackBackground1;
        private Border trackBackground2;

        private double timeBlockZeroOffset;//零点偏移位，通过自带的selection获得

        private Rectangle selectionBlock1;
        private Rectangle selectionBlock2;

        private Canvas timeBlockParentCanvas1;
        private Canvas timeBlockParentCanvas2;

        private List<Rectangle>[] recInSlider1 = new List<Rectangle>[24];
        private List<Rectangle> recInSlider2 = new List<Rectangle>();

        private List<TimeBlockArg> timeBlockList = new List<TimeBlockArg>();
        #endregion//private

        public event _DDayTimePickSDKEvents_OnTimeClickEventHandler OnTimeClick;

        private int currentTimeOfSecond = 0;
        public int CurrentTimeOfSecond
        {
            get { return currentTimeOfSecond; }
            set 
            {
                if (value == currentTimeOfSecond)
                {
                    return;
                }
                currentTimeOfSecond = value;
                if (!thumb1.IsDragging)
                {
                    slider1.Value = value % 3600 ;
                }
                if (!thumb2.IsDragging)
                {
                    slider2.Value = value / 60;
                }
                CurrentTimeOfHour = value / 3600;
            }
        }

        private int currentTimeOfHour;
        public int CurrentTimeOfHour
        {
            get { return currentTimeOfHour; }
            private set 
            {
                if (value==currentTimeOfHour)
                {
                    return;
                }
                currentTimeOfHour = value;

                //clear timeBlock
                timeBlockParentCanvas1.Children.Clear();

                if (recInSlider1[currentTimeOfHour] != null)
                {
                    foreach (var item in recInSlider1[currentTimeOfHour])
                    {
                        timeBlockParentCanvas1.Children.Add(item);
                    }
                }
               
            }
        }
       
        public DayTimePick()
        {
            InitializeComponent();
        }

        public int AddTimeBlock(int nStartSecondOfOneDay, int nEndSecondOfOneDay, int nRGBColor)
        {
            //UI
            for (int i = 0; i < 24; i++)
            {
                slider1_AddBlock( nStartSecondOfOneDay,  nEndSecondOfOneDay,  nRGBColor, i);
            }

            slider2_AddBlock(nStartSecondOfOneDay, nEndSecondOfOneDay, nRGBColor);

            timeBlockList.Add(new TimeBlockArg(nStartSecondOfOneDay,nEndSecondOfOneDay));
            return 0;
        }

        public void ClearTimeBlock()
        {
            for (int i = 0; i < 24; i++)
            {
                if (recInSlider1[i]!=null)
                {
                    recInSlider1[i].Clear();
                }
            }
            recInSlider2.Clear();

            timeBlockParentCanvas1.Children.Clear();
            timeBlockParentCanvas2.Children.Clear();

            timeBlockList.Clear();
        }

        public bool IsTimeExist(int nHour, int nMinute, int nSecond)
        {
            bool bRet = false;
            int nStartSecondOfOneDay = nHour * 3600 + nMinute * 60 + nSecond;
            var query = timeBlockList.Find(x => x.startSecond <= nStartSecondOfOneDay && x.endSecond >= nStartSecondOfOneDay);
            if (query!=null)
            {
                bRet = true;
            }

            return bRet;
        }
        private void InitSlider1()
        {
            UniformGrid TopTickNumGrid = this.slider1.Template.FindName("TopTickNumGrid", slider1) as UniformGrid;
            TopTickNumGrid.Columns = 12;
            Label label1 = TopTickNumGrid.Children[0] as Label;
            for (int i = 1; i < TopTickNumGrid.Columns; i++)
            {
                Label labeli=new Label();
                labeli.Style = label1.Style;
                labeli.Content = i * 5;
                TopTickNumGrid.Children.Add(labeli);
            }
            thumb1 = this.slider1.Template.FindName("Thumb", slider1) as Thumb;
            trackBackground1 = this.slider1.Template.FindName("TrackBackground",slider1) as Border;
            selectionBlock1 = this.slider1.Template.FindName("PART_SelectionRange", slider1) as Rectangle;
            timeBlockParentCanvas1 = selectionBlock1.Parent as Canvas;

            slider1.MouseLeftButtonUp += slider1_MouseLeftButtonUp;
            thumb1.DragDelta+=new DragDeltaEventHandler((a,b)=>
            {
                CurrentTimeOfSecond=(CurrentTimeOfSecond/3600*3600)+(int)slider1.Value;
            });
            thumb1.DragCompleted += new DragCompletedEventHandler((a, b) =>
            {
                CurrentTimeOfSecond = (CurrentTimeOfSecond / 3600 * 3600) + (int)slider1.Value;
                if (OnTimeClick != null)                    //通知事件
                {
                    OnTimeClick(slider1, new _DDayTimePickSDKEvents_OnTimeClickEvent(CurrentTimeOfSecond));
                }
            });
        }

        private void InitSlider2()
        {
            UniformGrid BottomTickNumGrid = slider1.Template.FindName("BottomTickNumGrid", slider2) as UniformGrid;
            BottomTickNumGrid.Columns = 24;
            Label label1 = BottomTickNumGrid.Children[0] as Label;
            for (int i = 1; i < BottomTickNumGrid.Columns; i++)
            {
                Label labeli = new Label();
                labeli.Style = label1.Style;
                labeli.Content = i ;
                BottomTickNumGrid.Children.Add(labeli);
            }
            thumb2 = this.slider2.Template.FindName("Thumb", slider2) as Thumb;
            trackBackground2 = this.slider2.Template.FindName("TrackBackground", slider2) as Border;
            selectionBlock2 = this.slider2.Template.FindName("PART_SelectionRange", slider2) as Rectangle;
            timeBlockParentCanvas2 = selectionBlock2.Parent as Canvas;

            slider2.MouseLeftButtonUp += new MouseButtonEventHandler(slider2_MouseLeftButtonUp);
            thumb2.DragDelta += new DragDeltaEventHandler((a, b) =>
            {
                CurrentTimeOfSecond = (int)(slider2.Value*60);//slider2的分钟*60
            });
            thumb2.DragCompleted += new DragCompletedEventHandler((a, b) =>//DragDelta得到的实时结果并不准，结束时需要校验一下
            {
                CurrentTimeOfSecond = (int)(slider2.Value * 60);//slider2的分钟*60
                if (OnTimeClick != null)                    //通知事件
                {
                    OnTimeClick(slider2, new _DDayTimePickSDKEvents_OnTimeClickEvent(CurrentTimeOfSecond));
                }
            });
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            InitSlider1();
            InitSlider2();
            
            Rectangle b = this.slider1.Template.FindName("PART_SelectionRange", slider1) as Rectangle;
            Canvas c = b.Parent as Canvas;
            timeBlockZeroOffset=Canvas.GetLeft(b);
        }

        private void slider1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Point p = e.GetPosition((IInputElement)sender);
            CurrentTimeOfSecond = (CurrentTimeOfSecond / 3600 * 3600) + (int)(p.X / trackBackground1.ActualWidth * slider1.Maximum);
            this.Dispatcher.BeginInvoke((Action)(() =>
                {
                    if (OnTimeClick != null)
                    {
                        OnTimeClick(slider1, new _DDayTimePickSDKEvents_OnTimeClickEvent(CurrentTimeOfSecond));
                    }
                }),System.Windows.Threading.DispatcherPriority.Background);
        }
        private void slider2_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Point p = e.GetPosition((IInputElement)sender);
            CurrentTimeOfSecond = (int)(p.X / trackBackground2.ActualWidth * slider2.Maximum * 60);
            this.Dispatcher.BeginInvoke((Action)(() =>
                {
                    if (OnTimeClick != null)
                    {
                        OnTimeClick(slider2, new _DDayTimePickSDKEvents_OnTimeClickEvent(CurrentTimeOfSecond));
                    }
                }), System.Windows.Threading.DispatcherPriority.Background);
            
        }

        private void slider1_AddBlock(int nStartSecondOfOneDay, int nEndSecondOfOneDay, int nRGBColor, int nSlider1Index)
        {
            if ((nStartSecondOfOneDay >= (nSlider1Index + 1) * 3600) || (nEndSecondOfOneDay < nSlider1Index * 3600))//不是目前小时块的，不要
            {
                return;
            }

            if (nStartSecondOfOneDay<nSlider1Index * 3600)
            {
                nStartSecondOfOneDay = nSlider1Index * 3600;
            }

            if (nEndSecondOfOneDay>=(nSlider1Index + 1) * 3600)
            {
                nEndSecondOfOneDay = (nSlider1Index + 1) * 3600 - 1;
            }

            Rectangle rec = new Rectangle();
            rec.SnapsToDevicePixels = false;//防止连续的时间块之间出现莫名其妙的空隙
            Color bgColor = Color.FromRgb((byte)(nRGBColor >> 16), (byte)(nRGBColor >> 8), (byte)nRGBColor);
            rec.Fill = new SolidColorBrush(bgColor);
            rec.Height = selectionBlock1.Height;
            
            rec.Width = (nEndSecondOfOneDay - nStartSecondOfOneDay) / slider1.Maximum * trackBackground1.ActualWidth;
            double leftOffset = (nStartSecondOfOneDay - nSlider1Index * 3600) / slider1.Maximum * trackBackground1.ActualWidth + timeBlockZeroOffset;
            Canvas.SetLeft(rec, leftOffset);

            if (null == recInSlider1[nSlider1Index])//没有list就new
            {
                recInSlider1[nSlider1Index] = new List<Rectangle>();
            }

            recInSlider1[nSlider1Index].Add(rec);

            //ADD IN UI 
            if (nSlider1Index == CurrentTimeOfHour)
            {
                timeBlockParentCanvas1.Children.Add(rec);
            }
            
        }
        private void slider2_AddBlock(int nStartSecondOfOneDay, int nEndSecondOfOneDay, int nRGBColor)
        {
            Rectangle rec = new Rectangle();
            rec.SnapsToDevicePixels = false;//防止连续的时间块之间出现莫名其妙的空隙
            Color bgColor = Color.FromRgb((byte)(nRGBColor >> 16), (byte)(nRGBColor >> 8), (byte)nRGBColor);
            rec.Fill = new SolidColorBrush(bgColor);
            rec.Height = selectionBlock1.Height;
            rec.Width = (nEndSecondOfOneDay - nStartSecondOfOneDay) / 60 / slider2.Maximum * trackBackground2.ActualWidth;
            double leftOffset = nStartSecondOfOneDay / 60 / slider2.Maximum * trackBackground2.ActualWidth + timeBlockZeroOffset;
            Canvas.SetLeft(rec, leftOffset);
            
            timeBlockParentCanvas2.Children.Add(rec);
        }
    }

    internal class TimeBlockArg
    {
        public int startSecond;
        public int endSecond;
        public TimeBlockArg(int nStartSecond, int nEndSecond)
        {
            startSecond = nStartSecond;
            endSecond = nEndSecond;
        }
    }

    public delegate void _DDayTimePickSDKEvents_OnTimeClickEventHandler(object sender, _DDayTimePickSDKEvents_OnTimeClickEvent e);

    public class _DDayTimePickSDKEvents_OnTimeClickEvent
    {
        public int nHour;
        public int nMinute;
        public int nSecond;

        public _DDayTimePickSDKEvents_OnTimeClickEvent(int nHour, int nMinute, int nSecond)
        {
            this.nHour = nHour;
            this.nMinute = nMinute;
            this.nSecond = nSecond;
        }
        public _DDayTimePickSDKEvents_OnTimeClickEvent(int nStartSecondOfDay)
        {
            this.nHour = nStartSecondOfDay / 3600;
            this.nMinute = nStartSecondOfDay % 3600 / 60;
            this.nSecond = nStartSecondOfDay % 60;
        }
    }
}
