using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
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;
using SPC.Kiosk.Base;
using SPC.Kiosk.Common;
namespace SPC.Kiosk.Common
{
    /// <summary>
    /// ButtonList.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class ButtonList : UserControl
    {
        #region [ Members ]
        /// <summary>
        /// ListItems
        /// </summary>
        public static readonly DependencyProperty ListItemsProperty =
                 DependencyProperty.Register(nameof(ListItems), typeof(ObservableCollection<M_ItemData>), typeof(ButtonList), new PropertyMetadata(null, new PropertyChangedCallback(OnListItemsPropertyChanged)));
        /// <summary>
        /// Command
        /// </summary>
        public static readonly DependencyProperty CommandProperty =
                 DependencyProperty.Register(nameof(Command), typeof(ICommand), typeof(ButtonList), new UIPropertyMetadata(null));
        /// <summary>
        /// DropCommand
        /// </summary>
        public static readonly DependencyProperty CircleCommandProperty =
                 DependencyProperty.Register(nameof(CircleCommand), typeof(ICommand), typeof(ButtonList), new UIPropertyMetadata(null));
        /// <summary>
        /// DropCommand
        /// </summary>
        public static readonly DependencyProperty DropCommandProperty =
                 DependencyProperty.Register(nameof(DropCommand), typeof(ICommand), typeof(ButtonList), new UIPropertyMetadata(null));
        /// <summary>
        /// Columns Count
        /// </summary>
        public static readonly DependencyProperty ColumnCountProperty =
                 DependencyProperty.Register(nameof(ColumnCount), typeof(int), typeof(ButtonList), new PropertyMetadata(3));
        /// <summary>
        /// Page Stack Orientation
        /// </summary>
        public static readonly DependencyProperty StackOrientationProperty =
                 DependencyProperty.Register(nameof(StackOrientation), typeof(Orientation), typeof(ButtonList), new PropertyMetadata(Orientation.Vertical, new PropertyChangedCallback(OnStackOrientationPropertyChanged)));
        /// <summary>
        /// Vertical Scroll Offset
        /// </summary>
        public static readonly DependencyProperty VerticalOffsetProperty =
                 DependencyProperty.Register(nameof(VerticalOffset), typeof(double), typeof(ButtonList), new PropertyMetadata(0d, new PropertyChangedCallback(OnVerticalOffsetPropertyChanged)));
        /// <summary>
        /// Horizontal Scroll Offset
        /// </summary>
        public static readonly DependencyProperty HorizontalOffsetProperty =
                 DependencyProperty.Register(nameof(HorizontalOffset), typeof(double), typeof(ButtonList), new PropertyMetadata(0d, new PropertyChangedCallback(OnHorizontalOffsetPropertyChanged)));
        /// <summary>
        /// Rows Count
        /// </summary>
        public static readonly DependencyProperty RowCountProperty =
                 DependencyProperty.Register(nameof(RowCount), typeof(int), typeof(ButtonList), new PropertyMetadata(1));
        /// <summary>
        /// ItemWidth
        /// </summary>
        public static readonly DependencyProperty ItemWidthProperty =
                 DependencyProperty.Register(nameof(ItemWidth), typeof(double), typeof(ButtonList), new PropertyMetadata(double.NaN));
        /// <summary>
        /// ItemHeight
        /// </summary>
        public static readonly DependencyProperty ItemHeightProperty =
                 DependencyProperty.Register(nameof(ItemHeight), typeof(double), typeof(ButtonList), new PropertyMetadata(double.NaN));
        /// <summary>
        /// Default PageNo
        /// </summary>
        public static readonly DependencyProperty DefaultPageNoProperty =
                 DependencyProperty.Register(nameof(DefaultPageNo), typeof(int), typeof(ButtonList), new PropertyMetadata(0, new PropertyChangedCallback(OnDefaultPageNoPropertyChanged)));
        /// <summary>
        /// TextPosition
        /// </summary>
        public static readonly DependencyProperty TextPositionProperty =
                 DependencyProperty.Register(nameof(TextPosition), typeof(TextPosition), typeof(ButtonList), new PropertyMetadata(TextPosition.InnerButton));
        /// <summary>
        /// ClickSend
        /// </summary>
        public static readonly DependencyProperty ClickSendProperty =
                 DependencyProperty.Register(nameof(ClickSend), typeof(bool), typeof(ButtonList), new PropertyMetadata(false, new PropertyChangedCallback(OnClickSendPropertyChanged)));


        /// <summary>
        /// BaseGrid
        /// </summary>
        public static readonly DependencyProperty BaseGridProperty =
                 DependencyProperty.Register(nameof(BaseGrid), typeof(string), typeof(ButtonList), new PropertyMetadata(string.Empty));
        /// <summary>
        /// ReciveElement
        /// </summary>
        public static readonly DependencyProperty ReciveElementProperty =
                 DependencyProperty.Register(nameof(ReciveElement), typeof(string), typeof(ButtonList), new PropertyMetadata(string.Empty));
        /// <summary>
        /// DefaultItem
        /// </summary>
        public static readonly DependencyProperty DefaultItemProperty =
                 DependencyProperty.Register(nameof(DefaultItem), typeof(AnimationButton), typeof(ButtonList), new PropertyMetadata(null));
        /// <summary>
        /// DefaultIndex
        /// </summary>
        public static readonly DependencyProperty DefaultIndexProperty =
                 DependencyProperty.Register(nameof(DefaultIndex), typeof(int), typeof(ButtonList), new PropertyMetadata(0, new PropertyChangedCallback(OnDefaultIndexPropertyChanged)));
        /// <summary>
        /// Display Language
        /// </summary>
        public static readonly DependencyProperty DisplayLanguagePropery =
                 DependencyProperty.Register(nameof(DisplayLanguage), typeof(SupportLanguageType), typeof(ButtonList), new PropertyMetadata(SupportLanguageType.ko, new PropertyChangedCallback(OnDisplayLanguageProperyChanged)));
        /// <summary>
        /// Drag Enable Flag
        /// </summary>
        public static readonly DependencyProperty DragEnablePropery =
                 DependencyProperty.Register(nameof(DragEnable), typeof(bool), typeof(ButtonList), new PropertyMetadata(false, new PropertyChangedCallback(OnDragEnableProperyChanged)));
        /// <summary>
        /// AutoToggle Flag
        /// </summary>
        public static readonly DependencyProperty AutoTogglePropery =
                 DependencyProperty.Register(nameof(AutoToggle), typeof(bool), typeof(ButtonList), new PropertyMetadata(false, new PropertyChangedCallback(OnAutoToggleProperyChanged)));
        /// <summary>
        /// Selected Item Switch On Flag
        /// </summary>
        public static readonly DependencyProperty SelectOnPropery =
                 DependencyProperty.Register(nameof(SelectOn), typeof(bool), typeof(ButtonList), new PropertyMetadata(false, new PropertyChangedCallback(OnSelectOnProperyChanged)));


        private int TargetPageNo = 0;
        private double mouseDownYposition = -1;
        private double mouseDownXposition = -1;
        private bool MoseDown = false;
        /// <summary>
        /// Drag Enable Flag
        /// </summary>
        public bool DragEnable
        {
            get { return (bool)GetValue(DragEnablePropery); }
            set { SetValue(DragEnablePropery, value); }
        }
        /// <summary>
        /// AutoToggle Flag
        /// </summary>
        public bool AutoToggle
        {
            get { return (bool)GetValue(AutoTogglePropery); }
            set { SetValue(AutoTogglePropery, value); }
        }
        /// <summary>
        /// Selected Item Switch On Flag
        /// </summary>
        public bool SelectOn
        {
            get { return (bool)GetValue(SelectOnPropery); }
            set { SetValue(SelectOnPropery, value); }
        }

        /// <summary>
        /// ListItems
        /// </summary>
        public ObservableCollection<M_ItemData> ListItems
        {
            get { return (ObservableCollection<M_ItemData>)GetValue(ListItemsProperty); }
            set { SetValue(ListItemsProperty, value); }
        }
        /// <summary>
        /// Command
        /// </summary>
        public ICommand Command
        {
            get { return (ICommand)GetValue(CommandProperty); }
            set { SetValue(CommandProperty, value); }
        }
        /// <summary>
        /// Circle Clicked Command
        /// </summary>
        public ICommand CircleCommand
        {
            get { return (ICommand)GetValue(CircleCommandProperty); }
            set { SetValue(CircleCommandProperty, value); }
        }
        /// <summary>
        /// DropCommand
        /// </summary>
        public ICommand DropCommand
        {
            get { return (ICommand)GetValue(DropCommandProperty); }
            set { SetValue(DropCommandProperty, value); }
        }
        /// <summary>
        /// StackOrientation
        /// </summary>
        public Orientation StackOrientation
        {
            get { return (Orientation)GetValue(StackOrientationProperty); }
            set { SetValue(StackOrientationProperty, value); }
        }
        /// <summary>
        /// ColumnCount
        /// </summary>
        public int ColumnCount
        {
            get { return (int)GetValue(ColumnCountProperty); }
            set { SetValue(ColumnCountProperty, value); }
        }
        /// <summary>
        /// RowCount
        /// </summary>
        public int RowCount
        {
            get { return (int)GetValue(RowCountProperty); }
            set { SetValue(RowCountProperty, value); }
        }
        /// <summary>
        /// ItemWidth
        /// </summary>
        public double ItemWidth
        {
            get { return (double)GetValue(ItemWidthProperty); }
            set { SetValue(ItemWidthProperty, value); }
        }
        /// <summary>
        /// ItemHeight
        /// </summary>
        public double ItemHeight
        {
            get { return (double)GetValue(ItemHeightProperty); }
            set { SetValue(ItemHeightProperty, value); }
        }

        /// <summary>
        /// DefaultPageNo
        /// </summary>
        public int DefaultPageNo
        {
            get { return (int)GetValue(DefaultPageNoProperty); }
            set { SetValue(DefaultPageNoProperty, value); }
        }
        /// <summary>
        /// TextPosition
        /// </summary>
        public TextPosition TextPosition
        {
            get { return (TextPosition)GetValue(TextPositionProperty); }
            set { SetValue(TextPositionProperty, value); }
        }
        /// <summary>
        /// DefaultItem
        /// </summary>
        public AnimationButton DefaultItem
        {
            get { return (AnimationButton)GetValue(DefaultItemProperty); }
            set { SetValue(DefaultItemProperty, value); }
        } 
        /// <summary>
        /// DefaultIndex
        /// </summary>
        public int DefaultIndex
        {
            get { return (int)GetValue(DefaultIndexProperty); }
            set { SetValue(DefaultIndexProperty, value); }
        }
        /// <summary>
        /// ClickSend
        /// </summary>
        public bool ClickSend
        {
            get { return (bool)GetValue(ClickSendProperty); }
            set { SetValue(ClickSendProperty, value); }
        }
        /// <summary>
        /// ReciveElement
        /// </summary>
        public string ReciveElement
        {
            get { return (string)GetValue(ReciveElementProperty); }
            set { SetValue(ReciveElementProperty, value); }
        }
        /// <summary>
        /// BaseGrid
        /// </summary>
        public string BaseGrid
        {
            get { return (string)GetValue(BaseGridProperty); }
            set { SetValue(BaseGridProperty, value); }
        }
        /// <summary>
        /// VerticalOffset
        /// </summary>
        public double VerticalOffset
        {
            get { return (double)GetValue(VerticalOffsetProperty); }
            set { SetValue(VerticalOffsetProperty, value); }
        }
        /// <summary>
        /// HorizontalOffset
        /// </summary>
        public double HorizontalOffset
        {
            get { return (double)GetValue(HorizontalOffsetProperty); }
            set { SetValue(HorizontalOffsetProperty, value); }
        }
        /// <summary>
        /// Display Language
        /// </summary>
        public SupportLanguageType DisplayLanguage
        {
            get { return (SupportLanguageType)GetValue(DisplayLanguagePropery); }
            set { SetValue(DisplayLanguagePropery, value); }
        }

        #region [ RoutedEvent 'MouseClicked' ]

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

        #region [ RoutedEvent 'CircleClicked' ]

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

        #region [ RoutedEvent 'ItemDrop' ]

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

        #endregion Members

        #region [ Ctor & Etc ]
        /// <summary>
        /// Ctor
        /// </summary>
        public ButtonList()
        {
            InitializeComponent();
            this.Unloaded += ButtonList_Unloaded;
        }

        #endregion Ctor & Etc

        #region [ Methods ]
        /// <summary>
        /// Default Item Set By Index
        /// </summary>
        /// <param name="_itemIndex"></param>
        public void SetDefaultItem(int _itemIndex)
        {
            if (this.FindName(string.Format("ButtonListItem{0}", _itemIndex)) is AnimationButton findItem)
            {
                DefaultItem = findItem;
                findItem.Switch = SelectOn;
            }
        }
        /// <summary>
        /// Reset Default Item
        /// </summary>
        /// <param name="_itemIndex"></param>
        public void ResetDefaultItem(int _itemIndex)
        {
            if (this.FindName(string.Format("ButtonListItem{0}", _itemIndex)) is AnimationButton findItem)
            {
                findItem.Switch = false;
            }
        }

        /// <summary>
        /// Raise MouseClicked Event
        /// </summary>
        private void RaiseMouseClickedEvent(object _sender)
        {
            //Command Excute 
            if (Command != null && Command.CanExecute(_sender))
            {
                Command.Execute(_sender);
            }
            RoutedEventArgs newEventArgs = new RoutedEventArgs(ButtonList.MouseClickedEvent, _sender);
            RaiseEvent(newEventArgs);
        }
        /// <summary>
        /// Raise CircleClicked Event
        /// </summary>
        private void RaiseCircleClickedEvent(object _sender)
        {
            if (CircleCommand != null && CircleCommand.CanExecute(_sender))
            {
                CircleCommand.Execute(_sender);
            }
            RoutedEventArgs newEventArgs = new RoutedEventArgs(ButtonList.CircleClickedEvent, _sender);
            RaiseEvent(newEventArgs);
        }
        private void RaiseItemDropEvent(object sender)
        {

            if (DropCommand != null && DropCommand.CanExecute(sender))
            {
                DropCommand.Execute(sender);
            }
            RoutedEventArgs newEventArgs = new RoutedEventArgs(ButtonList.ItemDropEvent, sender);
            RaiseEvent(newEventArgs);
        }
        private static void ItemsButtonCreate(ButtonList _target, object _listItems)
        {
            try
            {
                if (_listItems is ObservableCollection<M_ItemData> lstItems && lstItems.Count > 0)
                {
                    int itemCnt = 0;
                    int PageCount = 0;
                    int RowsCount = 0;
                    Grid PageGrid = null;
                    StackPanel PageStak = null;
                    Grid RowGrid = null;
                    StackPanel RowStack = null;
                    foreach (var aItem in lstItems)
                    {
                        if (itemCnt % (_target.ColumnCount * _target.RowCount) == 0)
                        {
                            PageGrid = new Grid
                            {
                                Background = new SolidColorBrush(Colors.Transparent),
                                Width = _target.Width,
                                Height = _target.Height,
                                HorizontalAlignment = HorizontalAlignment.Right,
                                Name = string.Format("PageGrid{0}", PageCount),
                            };
                            PageGrid.IsEnabled = PageCount.Equals(_target.DefaultPageNo);
                            PageGrid.Width = _target.Width;
                            PageGrid.Height = _target.RowCount * _target.ItemHeight;
                           _target.ReregisterName(string.Format("PageGrid{0}", PageCount), PageGrid);
                            

                            PageStak = new StackPanel
                            {
                                Background = new SolidColorBrush(Colors.Transparent),
                                HorizontalAlignment = HorizontalAlignment.Left,
                                VerticalAlignment = VerticalAlignment.Top,
                                Orientation = Orientation.Vertical,
                                Name = string.Format("PageStak{0}", PageCount)
                            };
                            _target.ReregisterName(string.Format("PageStak{0}", PageCount), PageStak);

                        }
                        if (itemCnt % _target.ColumnCount == 0)
                        {
                            RowGrid = new Grid
                            {
                                Background = new SolidColorBrush(Colors.Transparent),
                                Width = _target.Width
                            };
                            RowStack = new StackPanel
                            {
                                Background = new SolidColorBrush(Colors.Transparent),
                                HorizontalAlignment = HorizontalAlignment.Center,
                                Orientation = Orientation.Horizontal
                            };
                            if (!_target.ItemHeight.Equals(double.NaN)) RowStack.Height = _target.ItemHeight;
                            RowStack.Name = string.Format("RowStack{0}", RowsCount);
                            _target.ReregisterName(string.Format("RowStack{0}", RowsCount), RowStack);
                            RowGrid.Children.Add(RowStack);
                        }
                        var ItemStack = new StackPanel
                        {
                            Background = new SolidColorBrush(Colors.Transparent),
                            Width = _target.ItemWidth,
                            Height = _target.ItemHeight
                        };
                        if (aItem.BadgeHeight > 0)
                        {
                            var bageGrid = new Grid
                            {
                                Width = _target.ItemWidth,
                                Height = aItem.BadgeHeight,
                            };
                            var bageStack = new StackPanel
                            {
                                Background = new SolidColorBrush(Colors.Transparent),
                                Orientation = aItem.BadgeOrientation,
                                HorizontalAlignment = aItem.BadgeHorizontalAlignment,
                                VerticalAlignment = aItem.BadgeVerticalAlignment,
                            };
                            if (aItem.BadgeImages is List<string>)
                            {
                                foreach (var bageImage in aItem.BadgeImages)
                                {
                                    var sourceImage = ResourceManager.GetBitmapImage(bageImage);
                                    if (sourceImage !=null)
                                    {
                                        var aBadgeImage = new Image()
                                        {
                                            Width = sourceImage.Width,
                                            Height = sourceImage.Height,
                                            Source = sourceImage,
                                            HorizontalAlignment = aItem.BadgeHorizontalAlignment,
                                        };
                                        bageStack.Children.Add(aBadgeImage); 
                                    }
                                }
                            }
                            bageStack.Name = string.Format("BageStack{0}", itemCnt);
                            _target.ReregisterName(string.Format("BageStack{0}", itemCnt), bageStack);
                            bageGrid.Children.Add(bageStack);
                            ItemStack.Children.Add(bageGrid);

                        }
                        var aItemButton = new AnimationButton();
                        if (aItem.DataParameter.Width.Equals(double.NaN) || aItem.DataParameter.Width.Equals(0d))
                        {
                            aItem.DataParameter.Width = _target.ItemWidth;
                        }
                        Grid baseTextGrid = null;
                        StackPanel textStack = null;
                        MutiLanguageTextBlock baseText = null;
                        MutiLanguageTextBlock additionText = null;
                        if (!_target.TextPosition.Equals(TextPosition.InnerButton))
                        {
                            baseTextGrid = new Grid
                            {
                                Background = new SolidColorBrush(Colors.Transparent)
                            };
                            textStack = new StackPanel
                            {
                                Background = new SolidColorBrush(Colors.Transparent)
                            };
                            baseText = new MutiLanguageTextBlock
                            {
                                FontSize = aItem.BaseTextBlock.TextSize,
                                Background = new SolidColorBrush(Colors.Transparent)
                            };
                            ResourceManager.SetBrush(baseText, "Foreground", aItem.BaseTextBlock.TextBrush);
                            baseText.Width = aItem.BaseTextBlock.Width;
                            baseText.Height = aItem.BaseTextBlock.Height;
                            baseText.HorizontalAlignment = aItem.BaseTextBlock.TextHorizontalAlignment;
                            baseText.VerticalAlignment = aItem.BaseTextBlock.TextVerticalAlignment;
                            baseText.TextAlignment = aItem.BaseTextBlock.TextAlignment;
                            baseText.Margin = aItem.BaseTextBlock.TextMargin;
                            baseText.AutoTextTrim = aItem.BaseTextBlock.AutoTextTrim;
                            baseText.TextWrapping = aItem.BaseTextBlock.TextWrapping;
                            baseText.FontWeight = aItem.BaseTextBlock.TextWeight;
                            baseText.FontFamily = new FontFamily(aItem.BaseTextBlock.TextFontFamily);
                            baseText.TextWrapping = TextWrapping.Wrap;
                            baseText.MultiLanguage = aItem.BaseTextBlock.LanguageData;
                            baseText.DisplayLanguage = _target.DisplayLanguage;
                            additionText = new MutiLanguageTextBlock
                            {
                                FontSize = aItem.AdditionTextBlock.TextSize,
                                Background = new SolidColorBrush(Colors.Transparent)
                            };
                            ResourceManager.SetBrush(additionText, "Foreground", aItem.AdditionTextBlock.TextBrush);
                            additionText.Width = aItem.AdditionTextBlock.Width;
                            additionText.Height = aItem.AdditionTextBlock.Height;
                            additionText.HorizontalAlignment = aItem.AdditionTextBlock.TextHorizontalAlignment;
                            additionText.VerticalAlignment = aItem.AdditionTextBlock.TextVerticalAlignment;
                            additionText.TextAlignment = aItem.AdditionTextBlock.TextAlignment;
                            additionText.TextWrapping = aItem.AdditionTextBlock.TextWrapping;
                            additionText.Margin = aItem.AdditionTextBlock.TextMargin;
                            additionText.AutoTextTrim = aItem.AdditionTextBlock.AutoTextTrim;
                            additionText.FontWeight = aItem.AdditionTextBlock.TextWeight;
                            additionText.FontFamily = new FontFamily(aItem.AdditionTextBlock.TextFontFamily);
                            additionText.TextWrapping = TextWrapping.Wrap;
                            additionText.MultiLanguage = aItem.AdditionTextBlock.LanguageData;
                            additionText.DisplayLanguage = _target.DisplayLanguage;
                        }
                        switch (_target.TextPosition)
                        {
                            case TextPosition.Left:
                                baseTextGrid.Width = (_target.ItemWidth - aItem.DataParameter.Width) < 0 ? 0 : _target.ItemWidth - aItem.DataParameter.Width;
                                baseTextGrid.Height = _target.ItemHeight;
                                ItemStack.Orientation = Orientation.Horizontal;
                                textStack.HorizontalAlignment = HorizontalAlignment.Left;
                                textStack.VerticalAlignment = VerticalAlignment.Center;
                                break;
                            case TextPosition.Right:
                                baseTextGrid.Width = (_target.ItemWidth - aItem.DataParameter.Width) < 0 ? 0 : _target.ItemWidth - aItem.DataParameter.Width;
                                baseTextGrid.Height = _target.ItemHeight;
                                ItemStack.Orientation = Orientation.Horizontal;
                                textStack.HorizontalAlignment = HorizontalAlignment.Right;
                                textStack.VerticalAlignment = VerticalAlignment.Center;
                                break;
                            case TextPosition.Top:
                                baseTextGrid.Width = _target.ItemWidth;
                                baseTextGrid.Height = (_target.ItemHeight - aItem.DataParameter.Height) < 0 ? 0 : _target.ItemHeight - aItem.DataParameter.Height;
                                ItemStack.Orientation = Orientation.Vertical;
                                textStack.HorizontalAlignment = HorizontalAlignment.Center;
                                textStack.VerticalAlignment = VerticalAlignment.Bottom;
                                break;
                            case TextPosition.Bottom:
                                baseTextGrid.Width = _target.ItemWidth;
                                baseTextGrid.Height = (_target.ItemHeight - aItem.DataParameter.Height) < 0 ? 0 : _target.ItemHeight - aItem.DataParameter.Height;
                                ItemStack.Orientation = Orientation.Vertical;
                                textStack.HorizontalAlignment = HorizontalAlignment.Center;
                                textStack.VerticalAlignment = VerticalAlignment.Top;
                                break;
                        }
                        aItemButton.VerticalAlignment = VerticalAlignment.Center;
                        aItemButton.HorizontalAlignment = HorizontalAlignment.Center;
                        aItemButton.DataParameter = aItem;
                        aItemButton.DisplayLanguage = _target.DisplayLanguage;
                        aItemButton.BaseGrid = _target.BaseGrid;
                        aItemButton.ReciveElement = _target.ReciveElement;
                        aItemButton.ClickSend = !string.IsNullOrEmpty(_target.BaseGrid) 
                                                && !string.IsNullOrEmpty(_target.ReciveElement);
                        aItemButton.Name = string.Format("ButtonListItem{0}", itemCnt);
                        _target.ReregisterName(string.Format("ButtonListItem{0}", itemCnt), aItemButton);
                        ItemStack.Name = string.Format("ItemStack{0}", itemCnt);
                        _target.ReregisterName(string.Format("ItemStack{0}", itemCnt), ItemStack);
                        switch (_target.TextPosition)
                        {
                            case TextPosition.Left:
                            case TextPosition.Top:
                                textStack.Children.Add(baseText);
                                textStack.Children.Add(additionText);
                                baseTextGrid.Children.Add(textStack);
                                ItemStack.Children.Add(baseTextGrid);
                                ItemStack.Children.Add(aItemButton);
                                break;
                            case TextPosition.Right:
                            case TextPosition.Bottom:
                                ItemStack.Children.Add(aItemButton);
                                textStack.Children.Add(baseText);
                                textStack.Children.Add(additionText);
                                baseTextGrid.Children.Add(textStack);
                                ItemStack.Children.Add(baseTextGrid);
                                break;
                            default:
                                ItemStack.Children.Add(aItemButton);
                                break;
                        }

                        RowStack.Children.Add(ItemStack);

                        itemCnt++;
                        if (itemCnt % _target.ColumnCount == 0)
                        {
                            PageStak.Children.Add(RowGrid);
                            RowsCount++;
                        }
                        if (itemCnt % (_target.ColumnCount * _target.RowCount) == 0)
                        {
                            PageGrid.Children.Add(PageStak);
                            _target.MainStack.Children.Add(PageGrid);
                            PageCount++;
                        }
                    }
                    if (itemCnt % _target.ColumnCount != 0)
                    {
                        for (int i = 0; i < _target.ColumnCount - (itemCnt % _target.ColumnCount); i++)
                        {
                            var ItemStack = new StackPanel
                            {
                                Background = new SolidColorBrush(Colors.Transparent),
                                Width = _target.ItemWidth,
                                Height = _target.ItemHeight
                            };
                            RowStack.Children.Add(ItemStack);
                        }
                        PageStak.Children.Add(RowGrid);
                    }
                    if (itemCnt % (_target.ColumnCount * _target.RowCount) != 0)
                    {
                        PageGrid.Children.Add(PageStak);
                        _target.MainStack.Children.Add(PageGrid);
                    }
                }
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(_target, "ItemsButtonCreate()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        /// <summary>
        /// Events Set
        /// </summary>
        public void GridEventsSet()
        {
            try
            {
                MainGrid.PreviewMouseDown += Grid_PreviewMouseDown;
                MainGrid.PreviewMouseUp += Grid_PreviewMouseUp;
                foreach (Grid pageGrid in this.MainStack.Children)
                {

                    foreach (StackPanel aPageStack in pageGrid.Children)
                    {
                        foreach (Grid aRowGrid in aPageStack.Children)
                        {
                            foreach (StackPanel sRowStack in aRowGrid.Children)
                            {
                                foreach (StackPanel ItemStack in sRowStack.Children)
                                {
                                    foreach (var aItem in ItemStack.Children)
                                    {
                                        if (aItem is AnimationButton ItemContent)
                                        {
                                            ItemContent.MouseClicked += ItemContent_MouseClicked;
                                            ItemContent.CircleClicked += ItemContent_CircleClicked;
                                            ItemContent.ItemDrop += ItemContent_ItemDrop;
                                            ItemContent.SendStart += ItemContent_SendStart;
                                            ItemContent.SendEnd += ItemContent_SendEnd;
                                        }
                                    }
                                }

                            }

                        }
                    }
                    
                }
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "GridEventsSet()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }


        /// <summary>
        /// Events Remove
        /// </summary>
        public void GridEventsRemove()
        {
            try
            {
                MainGrid.PreviewMouseDown -= Grid_PreviewMouseDown;
                MainGrid.PreviewMouseUp -= Grid_PreviewMouseUp;
                foreach (Grid pageGrid in this.MainStack.Children)
                {
                    foreach (StackPanel aPageStack in pageGrid.Children)
                    {
                        foreach (Grid aRowGrid in aPageStack.Children)
                        {
                            foreach (StackPanel sRowStack in aRowGrid.Children)
                            {
                                foreach (StackPanel ItemStack in sRowStack.Children)
                                {
                                    foreach (var aItem in ItemStack.Children)
                                    {
                                        if (aItem is AnimationButton ItemContent)
                                        {
                                            ItemContent.MouseClicked -= ItemContent_MouseClicked;
                                            ItemContent.CircleClicked -= ItemContent_CircleClicked;
                                            ItemContent.ItemDrop -= ItemContent_ItemDrop;
                                            ItemContent.SendStart -= ItemContent_SendStart;
                                            ItemContent.SendEnd -= ItemContent_SendEnd;

                                        }
                                    }
                                    ItemStack.Children.Clear();
                                }
                                sRowStack.Children.Clear();
                            }
                            aRowGrid.Children.Clear();
                        }
                        aPageStack.Children.Clear();
                    }
                    pageGrid.Children.Clear();

                }
                this.MainStack.Children.Clear();
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "GridEventsRemove()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        /// <summary>
        /// Set Button Parameter
        /// </summary>
        public void SetButtonParameter()
        {
            try
            {
                foreach (Grid pageGrid in this.MainStack.Children)
                {

                    foreach (StackPanel aPageStack in pageGrid.Children)
                    {
                        foreach (Grid aRowGrid in aPageStack.Children)
                        {
                            foreach (StackPanel sRowStack in aRowGrid.Children)
                            {
                                foreach (StackPanel ItemStack in sRowStack.Children)
                                {
                                    foreach (var aItem in ItemStack.Children)
                                    {
                                        if (aItem is AnimationButton ItemContent)
                                        {
                                            ItemContent.ClickSend = this.ClickSend;
                                            ItemContent.AutoToggle = this.AutoToggle;
                                            ItemContent.DragEnable = this.DragEnable;
                                        }
                                    }
                                }

                            }

                        }
                    }

                }
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "SetButtonParameter()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }

        /// <summary>
        /// PageChange 
        /// </summary>
        /// <param name="_fromPageNo"></param>
        /// <param name="_toPageNo"></param>
        public void ChangePageTo( int _toPageNo)
        {
            try
            {
                var fromOffset = 0d;
                var toOffset = 0d;
                var totalTime = 0.3;
                if (this.MainStack.Orientation.Equals(Orientation.Horizontal))
                {
                    fromOffset = this.MainScroll.HorizontalOffset;
                    toOffset = this.Width * _toPageNo;
                    totalTime = Math.Abs(toOffset - fromOffset) / (this.Width) * totalTime;

                }
                else
                {
                    fromOffset = this.MainScroll.VerticalOffset;
                    toOffset = this.ItemHeight * this.RowCount * _toPageNo;
                    totalTime = Math.Abs(toOffset - fromOffset) / (this.ItemHeight * this.RowCount) * totalTime;
                }
                var scrollAnimation = Animations.GetScrollAnimation(this, this.MainStack.Orientation, fromOffset, toOffset, totalTime);
                if (scrollAnimation != null)
                {
                    scrollAnimation.Completed += ScrollAnimation_Completed;
                    scrollAnimation.Begin();
                }
                TargetPageNo = _toPageNo;
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "ChangePageTo()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }

        private void ScrollAnimation_Completed(object sender, EventArgs e)
        {
            var targetGrid = this.FindName(string.Format("PageGrid{0}", TargetPageNo)) ;
            if (targetGrid is Grid selectGrid)
            {
                DefaultPageNo = TargetPageNo;
                selectGrid.IsEnabled = true;
            }
        }

        #endregion Methods

        #region [ Event Handlers ]
        private void ButtonList_Unloaded(object sender, RoutedEventArgs e)
        {
            this.MainStack.Children.Clear();
            this.ListItems = null;
        }
        private static void OnDisplayLanguageProperyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            try
            {
                if (e.NewValue != null && !e.NewValue.Equals(e.OldValue))
                {
                    var target = d as ButtonList;
                    foreach (Grid pageGrid in target.MainStack.Children)
                    {
                        foreach (StackPanel aPageStack in pageGrid.Children)
                        {
                            foreach (Grid aRowGrid in aPageStack.Children)
                            {
                                foreach (StackPanel sRowStack in aRowGrid.Children)
                                {
                                    foreach (StackPanel ItemStack in sRowStack.Children)
                                    {
                                        foreach (var aItem in ItemStack.Children)
                                        {
                                            if (aItem is AnimationButton ItemContent)
                                            {
                                                ItemContent.DisplayLanguage = (SupportLanguageType)e.NewValue;
                                            }
                                            else if (aItem is Grid textGrid)
                                            {
                                                foreach (StackPanel textStack in textGrid.Children)
                                                {
                                                    foreach (var aTextItem in textStack.Children)
                                                    {
                                                        if (aTextItem is MutiLanguageTextBlock textItem)
                                                        {
                                                            textItem.DisplayLanguage = (SupportLanguageType)e.NewValue;

                                                        }
                                                    }

                                                }
                                            }
                                        }
                                    }

                                }

                            }
                        }
                    } 
                }
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(d, "OnDisplayLanguageProperyChanged()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }

        private static void OnDefaultPageNoPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {

                var target = d as ButtonList;
                target.ChangePageTo((int)e.NewValue);
            }
        }

        private static void OnStackOrientationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != e.OldValue)
            {
                var target = d as ButtonList;
                target.MainStack.Orientation = (Orientation)e.NewValue;
                switch ((Orientation)e.NewValue)
                {
                    case Orientation.Horizontal:
                        target.MainScroll.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled;
                        target.MainScroll.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
                        break;
                    case Orientation.Vertical:
                        target.MainScroll.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
                        target.MainScroll.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
                        break;
                }
            }
        }

        private static void OnHorizontalOffsetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != e.OldValue)
            {
                var target = d as ButtonList;
                target.MainScroll.ScrollToHorizontalOffset((double)e.NewValue);
            }
        }

        private static void OnVerticalOffsetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != e.OldValue)
            {
                var target = d as ButtonList;
                target.MainScroll.ScrollToVerticalOffset((double)e.NewValue);
            }
        }

        private static void OnListItemsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue!=null && !e.NewValue.Equals(e.OldValue))
            {
                var target = d as ButtonList;
                target.GridEventsRemove();
                ItemsButtonCreate(target, e.NewValue);
                target.UpdateLayout();
                CommonFunction.ReregisterName(target.Parent as FrameworkElement, target.Name, target);
                target.GridEventsSet();
                target.SetDefaultItem(target.DefaultIndex);

            }
        }
        private static void OnDefaultIndexPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var target = d as ButtonList;
            if (!e.NewValue.Equals(e.OldValue))
            {
                if (e.OldValue != null)
                {
                    target.ResetDefaultItem((int)e.OldValue);
                }
                if (target.ListItems != null && target.ListItems.Count > 0 && (int)e.NewValue > -1)
                {
                    target.SetDefaultItem((int)e.NewValue);
                    target.DefaultPageNo = (int)e.NewValue / (target.ColumnCount * target.RowCount);
                }
            }
        }
        private static void OnClickSendPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!e.NewValue.Equals(e.OldValue))
            {
                var target = d as ButtonList;
                target.SetButtonParameter();
            }
        }
        private static void OnDragEnableProperyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!e.NewValue.Equals(e.OldValue))
            {
                var target = d as ButtonList;
                target.SetButtonParameter();
            }
        }
        private static void OnAutoToggleProperyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!e.NewValue.Equals(e.OldValue))
            {
                var target = d as ButtonList;
                target.SetButtonParameter();
            }
        }
        private static void OnSelectOnProperyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue !=null)
            {
                var target = d as ButtonList;
                if (target.FindName(string.Format("ButtonListItem{0}", target.DefaultIndex)) is AnimationButton findItem)
                {
                    findItem.Switch=(bool)e.NewValue;
                }

            }
        }

        private void Grid_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            var requstGrid = sender as Grid;
            mouseDownXposition = e.GetPosition(sender as Grid).X;
            mouseDownYposition = e.GetPosition(sender as Grid).Y;
            MoseDown = true;
        }
        private void Grid_PreviewMouseUp(object sender, MouseButtonEventArgs e)
        {
            if (!MoseDown) return;
            var requstGrid = sender as Grid;
            var curMouseXposition = e.GetPosition(requstGrid).X;
            var curMouseYposition = e.GetPosition(requstGrid).Y;
            if (this.StackOrientation.Equals(Orientation.Horizontal))
            {
                if (!mouseDownXposition.Equals(-1) && (mouseDownXposition - curMouseXposition) > 50)
                {
                    if (this.DefaultPageNo < this.MainStack.Children.Count - 1) this.DefaultPageNo++;
                }
                else if (!mouseDownXposition.Equals(-1) && (mouseDownXposition - curMouseXposition) < -50)
                {
                    if (this.DefaultPageNo > 0) this.DefaultPageNo--;
                }
            }
            else
            {
                if (!mouseDownYposition.Equals(-1) && (mouseDownYposition - curMouseYposition) > 50)
                {
                    if (this.DefaultPageNo < this.MainStack.Children.Count - 1) this.DefaultPageNo++;
                }
                else if (!mouseDownYposition.Equals(-1) && (mouseDownYposition - curMouseYposition) < -50)
                {
                    if (this.DefaultPageNo > 0) this.DefaultPageNo--;
                }
            }
            mouseDownXposition = curMouseXposition;
            mouseDownYposition = curMouseYposition;
            MoseDown = false;
        }

        private void ItemContent_MouseClicked(object sender, RoutedEventArgs e)
        {
            RaiseMouseClickedEvent(e.OriginalSource);
        }
        private void ItemContent_CircleClicked(object sender, RoutedEventArgs e)
        {
            RaiseCircleClickedEvent(e.OriginalSource);
        }
        private void ItemContent_ItemDrop(object sender, RoutedEventArgs e)
        {
            RaiseItemDropEvent(e.OriginalSource);
        }
        private void ItemContent_SendEnd(object sender, RoutedEventArgs e)
        {
            this.IsEnabled = true;
        }

        private void ItemContent_SendStart(object sender, RoutedEventArgs e)
        {
            this.IsEnabled = false;
        }

        #endregion Event Handlers
    }
}
