using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;

namespace HistoryDLL
{
    /// <summary>
    /// LiveContainer.xaml 的互動邏輯
    /// </summary>
    public partial class LiveContainer : UserControl
    {
        //uxUpSide 被點擊紀錄為第幾個事件
        private int TriggerEvent = 0;
        private int TriggerPicture = 0;

        public enum ShowMethod
        {
            ShowForTwo = 0x01,
            ShowForSix = 0x10,
        };

        //創造 LiveContainer 物件
        private delegate void CreateLiveContainerDelegate();
        //事件個數
        public XmlData xmlData = new XmlData();
        private int eventCount = 2;
        private ShowMethod showMethod = ShowMethod.ShowForTwo;
        //PlaneRotate 暫存區
        private List<PlaneRotateMap> PlaneRotateMapList = new List<PlaneRotateMap>();
        private Grid MainUpSideGrid = new Grid();
        //當前 LiveConainer 在 CyclisScroller中的索引位置
        private int ContainerIndex = -1;
        //Gird 經過切割後每個小區塊的寬高設定
        //兩塊
        private int BitmapBWidth = 290;
        private int BitmapBHeight = 225;
        //六塊
        private int BitmapSWidth = 210;
        private int BitmapSHeight = 158;
        // 區塊切割倍數
        private int cutMultiple = 1;

        //亂數產生
        private Random rnd = new Random(Guid.NewGuid().GetHashCode());
        //顯示該區塊是否可點擊的顏色設定
        private SolidColorBrush CanControlColor = new SolidColorBrush(ConfigSettingClass.TimelineCollect.BackgroundColor);
        private SolidColorBrush CantControlColor = new SolidColorBrush(ConfigSettingClass.TimelineExtentCollect.BackgroundColor);
        private SolidColorBrush TextBlockControlColor = new SolidColorBrush(ConfigSettingClass.TimelineCollect.TextColor);
        //原始物件寬度
        private int OriginalObjectWidth = 0;
        private bool canControl = true;

        public int Set_Get_ContainerIndex
        {
            set { ContainerIndex = value; }
            get { return ContainerIndex; }
        }

        public LiveContainer(XmlData Data, int objectWidth, int objectHeight)
        {
            InitializeComponent();
            if (GlobalFunction.isSolutionUsing4K)
            {
                BitmapBWidth *= 2;
                BitmapBHeight *= 2;

                BitmapSWidth *= 2;
                BitmapSHeight *= 2;

                uxDownSide.Height *= 2;
                cutMultiple *= 2;

                uxYearStr.FontSize *= 1.5;
            }

            xmlData = Data;
            uxUpSide.Width = uxLiveContainerMainGrid.Width = OriginalObjectWidth = objectWidth;
            uxUpSide.Height = uxLiveContainerMainGrid.Height = objectHeight;
            //該年份有幾個事件~?
            eventCount = xmlData.monthclassList.Count;
            //上方 Border 處理
            //判斷該年份事件各數是兩個以下(包括兩個)或者以上
            if (eventCount > 2)
            {
                showMethod = ShowMethod.ShowForSix;
                //切割成六塊
                CutTheGridToSixBlock();
                //縮小每個區塊可容納圖片大小
                BitmapBWidth = BitmapSWidth;
                BitmapBHeight = BitmapSHeight;
            }
            else
            {
                showMethod = ShowMethod.ShowForTwo;
                //切割成兩塊
                CutTheGridToTwoBlock();
            }
            uxUpSide.Child = MainUpSideGrid;
            //下方 Border 處理
            WriteYearBarStr();
            uxYearStr.Foreground = TextBlockControlColor;
            uxDownSide.PreviewTouchDown += new EventHandler<TouchEventArgs>(uxDownSide_PreviewTouchDown);
        }

        internal void WriteYearBarStr()
        {
            string langStr = xmlData.yearlan1;

            if (ConfigSettingClass.MainBackCollect.DefaultLangIndex == 1)
            {
                langStr = xmlData.yearlan2;
            }
            else if (ConfigSettingClass.MainBackCollect.DefaultLangIndex == 2)
            {
                langStr = xmlData.yearlan3;
            }
            else if (ConfigSettingClass.MainBackCollect.DefaultLangIndex == 3)
            {
                langStr = xmlData.yearlan4;
            }

            if (ConfigSettingClass.MainBackCollect.DefaultLangIndex < ConfigSettingClass.MainBackCollect.LangFlowDir.Length)
            {
                uxYearStr.FlowDirection = ConfigSettingClass.MainBackCollect.LangFlowDir[ConfigSettingClass.MainBackCollect.DefaultLangIndex];
            }

            uxYearStr.Text = langStr;
        }

        internal void ChangeCurPlaneRotateLan()
        {
            for (int i = 0; i < MainUpSideGrid.Children.Count; i++)
            {
                PlaneRotateMap prm = MainUpSideGrid.Children[i] as PlaneRotateMap;

                prm.ChangeLanByDynamic();
            }
        }

        internal void ChangePlaneRotateLan()
        {
            for (int i = 0; i < PlaneRotateMapList.Count; i++)
            {
                PlaneRotateMap prm = PlaneRotateMapList[i] as PlaneRotateMap;

                prm.ChangeLanByDynamic();
            }
        }

        internal void CreateLiveContainer()
        {
            //將這個年份的所有事件創出來並建立出 PlaneRotate
            System.Windows.Application.Current.Dispatcher.Invoke(new CreateLiveContainerDelegate(CreateLiveContainerBkWork));
        }

        private void CreateLiveContainerBkWork()
        {
            CreateEventRotate();
            //開始將創建出來的PlaneRotate放入
            ShowThePlaneRotate();
        }

        //被通知當前區塊應該要處理的動作
        public void ListenFromCyclicTouchStatus(CyclicScroller cs)
        {
            cs.CyclicScrollerBubbleToLiveContainerEvent += new CyclicScroller.CyclicScrollerBubbleToLiveContainer(ReceiveFromCyclicScroller);
        }

        #region 當上或者下區塊被點擊~這兩個其中一個Key會被啟動並通知CyclicScroller
        //下方年份
        void uxDownSide_PreviewTouchDown(object sender, TouchEventArgs e)
        {
            TriggerEvent = 0;
            TriggerPicture = 0;
            SendInfoToCyclicScroller("TouchDown");
        }

        //上方 PlaneRotate 有物件被點擊
        void RecevieFromPlaneRotateMapForCheckTouch(int indexofevent, int indexofpicture)
        {
            TriggerEvent = indexofevent;
            TriggerPicture = indexofpicture;
            SendInfoToCyclicScroller("TouchDown");
        }
        #endregion

        /// <summary>
        /// 將創建出來的PlaneRotate放入
        /// (放入的方式由做下層開始由左至右)
        /// </summary>
        private void ShowThePlaneRotate()
        {
            //兩個事件處理
            if (showMethod == ShowMethod.ShowForTwo)
            {
                int j = 3;
                int rndIndex = 0;
                MainUpSideGrid.Children.Clear();

                for (int i = 0; i < eventCount; i++, j -= 2)
                {
                    PlaneRotateMap newprm = new PlaneRotateMap();
                    //亂數取得要放入的 PlaneRotateMap (不重複)
                    rndIndex = rnd.Next(0, PlaneRotateMapList.Count);

                    //抽出該PlaneRotateMap 並做設定~完後指到 newprm
                    newprm = SelectprmToShow(rndIndex, i);

                    //加到Gird中 
                    MainUpSideGrid.Children.Add(newprm);

                    //放入指定的位置
                    Grid.SetRow(newprm, j);
                    //移除該prm在亂數選擇的Buffer當中 (該 Buffer 只存在沒有顯示的事件)
                    PlaneRotateMapList.RemoveAt(rndIndex);
                }
            }
            else if (showMethod == ShowMethod.ShowForSix)
            {
                int j = 5, k = 1;
                int rndIndex = 0;
                MainUpSideGrid.Children.Clear();

                for (int i = 0; i < eventCount; i++)
                {
                    PlaneRotateMap newprm = new PlaneRotateMap();
                    //亂數取得要放入的 PlaneRotateMap (不重複)
                    rndIndex = rnd.Next(0, PlaneRotateMapList.Count);
                    //抽出該PlaneRotateMap 並做設定~完後指到 newprm

                    newprm = SelectprmToShow(rndIndex, i);
                    //加到Gird中 
                    MainUpSideGrid.Children.Add(newprm);

                    //放入指定的位置
                    Grid.SetRow(PlaneRotateMapList[rndIndex], j);
                    Grid.SetColumn(PlaneRotateMapList[rndIndex], k);

                    //移除該prm在亂數選擇的Buffer當中 (該 Buffer 只存在沒有顯示的事件)
                    PlaneRotateMapList.RemoveAt(rndIndex);

                    //如果是基數次則
                    if (k == 3)
                    {
                        j -= 2;
                        k = 1;
                    }
                    else
                    {
                        k += 2;
                    }
                    if (j <= 0)
                        break;
                }
            }
        }

        /// <summary>
        /// 抽出該PlaneRotateMap 並做設定~完後指到 newprm
        /// </summary>
        /// <param name="rndIndex">選擇的PlaneRotateMap的索引值</param>
        /// <param name="blockIndex">在該區塊中顯示的位置</param>
        /// <returns></returns>
        private PlaneRotateMap SelectprmToShow(int rndIndex, int blockIndex)
        {
            //顯示
            PlaneRotateMapList[rndIndex].startShow();
            //將該區塊位置索引指給 PlaneRotateMap的BlockIndex
            PlaneRotateMapList[rndIndex].BlockIndex = blockIndex;

            return PlaneRotateMapList[rndIndex];
        }

        /// <summary>
        ///依照事件數量創造出相應的PlaneRotate
        /// </summary>
        private void CreateEventRotate()
        {
            for (int eventcount = 0; eventcount < eventCount; eventcount++)
            {
                PlaneRotateMap prm = new PlaneRotateMap(xmlData.monthclassList[eventcount], BitmapBWidth, BitmapBHeight);

                prm.indexOfEvent = eventcount;
                //通知 LiveContainer 通道
                prm.ListenFromLiveContainerCode(this);
                //接收來自 PlaneRotateMap 通知的通道(確認是否為點擊?)
                prm.PlaneRotateMapBubbleToLiveContainerEvent += new PlaneRotateMap.PlaneRotateMapBubbleToLiveContainer(RecevieFromPlaneRotateMapForCheckTouch);
                //接收來自 PlaneRotateMap 通知的通道(確認可顯示的資料是否已經到底)
                prm.PlaneRotateFileIsBlankEvent += new PlaneRotateMap.PlaneRotateFileIsBlank(ReceiveFromPlaneRotateFileBlankInfo);
                prm.CreatePlaneRotateMap();
                //之後在換事件的時候可以透過SetRow or SetCol去選擇Grid要顯示哪一個或者哪一個需要改變
                PlaneRotateMapList.Add(prm);
            }
        }

        //控制該年份的時間軸顏色
        public void ChangeControlColor(bool CanControl)
        {
            if (CanControl)
            {
                uxDownSide.Background = CanControlColor;
            }
            else
            {
                uxDownSide.Background = CantControlColor;
            }
            canControl = CanControl;
        }

        //將 MainUpSideGrid 切成兩塊
        private void CutTheGridToTwoBlock()
        {
            //切成上下兩塊
            RowDefinition NoneUseUp = new RowDefinition();
            RowDefinition rdBk1 = new RowDefinition();
            RowDefinition rdMid = new RowDefinition();
            RowDefinition rdBk2 = new RowDefinition();

            NoneUseUp.Height = new GridLength(48 * cutMultiple);
            rdBk1.Height = new GridLength(225 * cutMultiple);
            rdMid.Height = new GridLength(10 * cutMultiple);
            rdBk2.Height = new GridLength(225 * cutMultiple);

            MainUpSideGrid.RowDefinitions.Add(NoneUseUp);
            MainUpSideGrid.RowDefinitions.Add(rdBk1);
            MainUpSideGrid.RowDefinitions.Add(rdMid);
            MainUpSideGrid.RowDefinitions.Add(rdBk2);
        }

        //將 MainUpSideGrid 切成六塊
        private void CutTheGridToSixBlock()
        {
            //切成上中下三塊
            RowDefinition rdUp = new RowDefinition();
            RowDefinition rdBk1 = new RowDefinition();
            RowDefinition rdRow1 = new RowDefinition();
            RowDefinition rdBk2 = new RowDefinition();
            RowDefinition rdRow2 = new RowDefinition();
            RowDefinition rdBk3 = new RowDefinition();

            rdUp.Height = new GridLength(15 * cutMultiple);
            rdBk1.Height = new GridLength(158 * cutMultiple);
            rdRow1.Height = new GridLength(10 * cutMultiple);
            rdBk2.Height = new GridLength(158 * cutMultiple);
            rdRow2.Height = new GridLength(10 * cutMultiple);
            rdBk3.Height = new GridLength(158 * cutMultiple);

            MainUpSideGrid.RowDefinitions.Add(rdUp);
            MainUpSideGrid.RowDefinitions.Add(rdBk1);
            MainUpSideGrid.RowDefinitions.Add(rdRow1);
            MainUpSideGrid.RowDefinitions.Add(rdBk2);
            MainUpSideGrid.RowDefinitions.Add(rdRow2);
            MainUpSideGrid.RowDefinitions.Add(rdBk3);
            //切成左右兩個區塊
            ColumnDefinition colLeft = new ColumnDefinition();
            ColumnDefinition colLeftLeft = new ColumnDefinition();
            ColumnDefinition colRight = new ColumnDefinition();
            ColumnDefinition colRightRight = new ColumnDefinition();
            ColumnDefinition colMid = new ColumnDefinition();

            colLeftLeft.Width = new GridLength(10 * cutMultiple);
            colLeft.Width = new GridLength(210 * cutMultiple);
            colMid.Width = new GridLength(10 * cutMultiple);
            colRight.Width = new GridLength(210 * cutMultiple);
            colRightRight.Width = new GridLength(10 * cutMultiple);

            MainUpSideGrid.ColumnDefinitions.Add(colLeftLeft);
            MainUpSideGrid.ColumnDefinitions.Add(colLeft);
            MainUpSideGrid.ColumnDefinitions.Add(colMid);
            MainUpSideGrid.ColumnDefinitions.Add(colRight);
            MainUpSideGrid.ColumnDefinitions.Add(colRightRight);
        }
    }
}
