using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using SPC.Kiosk.Base;
namespace SPC.Kiosk.Common
{
    /// <summary>
    /// AnimationButton.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class AnimationButton : UserControl
    {
        #region [ Private Members ]
        private bool MoseDown = false;
        private Point MoseDownPosition;
        private bool CircleMoseDown = false;
        private Point CircleMoseDownPosition;
        private Cursor DragCursor = null;
        private Storyboard BreathigStoryboard = null;
        #endregion Private Members

        #region [ Public Members ]

        #region [ DependencyProperty ]
        /// <summary>
        /// Noraml Bakcground 
        /// </summary>
        public static readonly DependencyProperty NormalBrushProperty =
                 DependencyProperty.Register(nameof(NormalBrush), typeof(string), typeof(AnimationButton), new PropertyMetadata("Transparent", new PropertyChangedCallback(OnNormalBrushPropertyChanged)));
        /// <summary>
        /// Image Brush Stretch Type
        /// </summary>
        public static readonly DependencyProperty BrushStretchProperty =
                 DependencyProperty.Register(nameof(BrushStretch), typeof(Stretch), typeof(AnimationButton), new PropertyMetadata(Stretch.None, new PropertyChangedCallback(OnBrushStretchPropertyChanged)));
        /// <summary>
        /// Touch Down Bakcground 
        /// </summary>
        public static readonly DependencyProperty DownBrushProperty =
                 DependencyProperty.Register(nameof(DownBrush), typeof(string), typeof(AnimationButton), new PropertyMetadata("Transparent"));
        /// <summary>
        /// Button Disable Background
        /// </summary>
        public static readonly DependencyProperty DisableBrushProperty =
                 DependencyProperty.Register(nameof(DisableBrush), typeof(string), typeof(AnimationButton), new PropertyMetadata("Transparent"));
        /// <summary>
        /// Drag Cursor Image Path
        /// </summary>
        public static readonly DependencyProperty DragCursorImageProperty =
                 DependencyProperty.Register(nameof(DragCursorImage), typeof(string), typeof(AnimationButton), new PropertyMetadata(string.Empty));
        /// <summary>
        /// Drag Cursor HotSpot Type
        /// </summary>
        public static readonly DependencyProperty DragCursorHotSpotProperty =
                 DependencyProperty.Register(nameof(DragCursorHotSpot), typeof(HotSpotType), typeof(AnimationButton), new PropertyMetadata(HotSpotType.LeftTop));
        /// <summary>
        /// Switch On Status Background
        /// </summary>
        public static readonly DependencyProperty SwitchOnBrushProperty =
                 DependencyProperty.Register(nameof(SwitchOnBrush), typeof(string), typeof(AnimationButton), new PropertyMetadata("Transparent"));
        /// <summary>
        /// Switch Status
        /// </summary>
        public static readonly DependencyProperty SwitchProperty =
                 DependencyProperty.Register(nameof(Switch), typeof(bool), typeof(AnimationButton), new PropertyMetadata(false, new PropertyChangedCallback(OnSwitchPropertyChanged)));
        /// <summary>
        /// Auto Switching Flag
        /// </summary>
        public static readonly DependencyProperty IsBreathingProperty =
                 DependencyProperty.Register(nameof(IsBreathing), typeof(bool), typeof(AnimationButton), new PropertyMetadata(false, new PropertyChangedCallback(IsBreathingPropertyChanged)));
        /// <summary>
        /// Auto Switching Flag
        /// </summary>
        public static readonly DependencyProperty AutoToggleProperty =
                 DependencyProperty.Register(nameof(AutoToggle), typeof(bool), typeof(AnimationButton), new PropertyMetadata(false));
        /// <summary>
        /// Click Send Flag
        /// </summary>
        public static readonly DependencyProperty ClickSendProperty =
                 DependencyProperty.Register(nameof(ClickSend), typeof(bool), typeof(AnimationButton), new PropertyMetadata(false));
        /// <summary>
        /// Button Enabled
        /// </summary>
        public static readonly DependencyProperty EnabledProperty =
                 DependencyProperty.Register(nameof(Enabled), typeof(bool), typeof(AnimationButton), new PropertyMetadata(true, new PropertyChangedCallback(OnEnabledPropertyChanged)));
        /// <summary>
        /// Base Grid Name
        /// </summary>
        public static readonly DependencyProperty BaseGridProperty =
                 DependencyProperty.Register(nameof(BaseGrid), typeof(string), typeof(AnimationButton), new PropertyMetadata(string.Empty));
        /// <summary>
        /// Recive Element Name (AnimationButton)
        /// </summary>
        public static readonly DependencyProperty ReciveElementProperty =
                 DependencyProperty.Register(nameof(ReciveElement), typeof(string), typeof(AnimationButton), new PropertyMetadata(string.Empty));
        /// <summary>
        /// Click Animation Type
        /// </summary>
        public static readonly DependencyProperty ClickAnimationTypeProperty =
                 DependencyProperty.Register(nameof(ClickAnimationType), typeof(ButtonAnimationType), typeof(AnimationButton), new PropertyMetadata(ButtonAnimationType.None));
        /// <summary>
        /// Drop Animation Type
        /// </summary>
        public static readonly DependencyProperty DropAnimationTypeProperty =
                 DependencyProperty.Register(nameof(DropAnimationType), typeof(ButtonAnimationType), typeof(AnimationButton), new PropertyMetadata(ButtonAnimationType.None));
        /// <summary>
        /// Button MultiLanguage Text
        /// </summary>
        public static readonly DependencyProperty LanguageTextProperty =
                 DependencyProperty.Register(nameof(LanguageText), typeof(List<M_Language>), typeof(AnimationButton), new PropertyMetadata(default(List<M_Language>)));
        /// <summary>
        /// Button Text
        /// </summary>
        public static readonly DependencyProperty TextProperty =
                 DependencyProperty.Register(nameof(Text), typeof(string), typeof(AnimationButton), new PropertyMetadata(default(List<M_Language>)));
        /// <summary>
        /// Button Text Visibility
        /// </summary>
        public static readonly DependencyProperty TextVisibleProperty =
                 DependencyProperty.Register(nameof(TextVisible), typeof(Visibility), typeof(AnimationButton), new PropertyMetadata(Visibility.Collapsed, new PropertyChangedCallback(OnTextVisiblePropertyChanged)));
        /// <summary>
        /// Button Text Foreground
        /// </summary>
        public static readonly DependencyProperty TextForegroundProperty =
                 DependencyProperty.Register(nameof(TextForeground), typeof(string), typeof(AnimationButton), new PropertyMetadata("Transparent", new PropertyChangedCallback(OnTextForegroundPropertyChanged)));
        /// <summary>
        /// Button Switch On Foreground
        /// </summary>
        public static readonly DependencyProperty SwitchOnForegroundProperty =
                 DependencyProperty.Register(nameof(SwitchOnForeground), typeof(string), typeof(AnimationButton), new PropertyMetadata("Transparent", new PropertyChangedCallback(OnSwitchOnForegroundPropertyChanged)));
        /// <summary>
        /// Button Disable Foreground
        /// </summary>
        public static readonly DependencyProperty DisableForegroundProperty =
                 DependencyProperty.Register(nameof(DisableForeground), typeof(string), typeof(AnimationButton), new PropertyMetadata("Transparent", new PropertyChangedCallback(OnDisableForegroundPropertyChanged)));
        /// <summary>
        /// Button Text VerticalAlignment
        /// </summary>
        public static readonly DependencyProperty TextVerticalAlignmentProperty =
                 DependencyProperty.Register(nameof(TextVerticalAlignment), typeof(VerticalAlignment), typeof(AnimationButton), new PropertyMetadata(VerticalAlignment.Center, new PropertyChangedCallback(OnTextVerticalAlignmentPropertyChanged)));
        /// <summary>
        /// Button Text HorizontalAlignment
        /// </summary>
        public static readonly DependencyProperty TextHorizontalAlignmentProperty =
                 DependencyProperty.Register(nameof(TextHorizontalAlignment), typeof(HorizontalAlignment), typeof(AnimationButton), new PropertyMetadata(HorizontalAlignment.Center, new PropertyChangedCallback(OnTextHorizontalAlignmentPropertyChanged)));
        /// <summary>
        /// Button Text FontFamily
        /// </summary>
        public static readonly DependencyProperty TextFontFamilyProperty =
                 DependencyProperty.Register(nameof(TextFontFamily), typeof(string), typeof(AnimationButton), new PropertyMetadata(Fonts.SystemFontFamilies.First().Source, new PropertyChangedCallback(OnTextFontFamilyPropertyChanged)));
        /// <summary>
        /// Button Text FontSize
        /// </summary>
        public static readonly DependencyProperty TextFontSizeProperty =
                 DependencyProperty.Register(nameof(TextFontSize), typeof(double), typeof(AnimationButton), new PropertyMetadata((double)10, new PropertyChangedCallback(OnTextFontSizePropertyChanged)));
        /// <summary>
        /// SwitchOn FontSize
        /// </summary>
        public static readonly DependencyProperty SwitchOnFontSizeProperty =
                 DependencyProperty.Register(nameof(SwitchOnFontSize), typeof(double), typeof(AnimationButton), new PropertyMetadata((double)0, new PropertyChangedCallback(OnSwitchOnFontSizePropertyChanged)));
        /// <summary>
        /// Disable FontSize
        /// </summary>
        public static readonly DependencyProperty DisableFontSizeProperty =
                 DependencyProperty.Register(nameof(DisableFontSize), typeof(double), typeof(AnimationButton), new PropertyMetadata((double)0, new PropertyChangedCallback(OnDisableFontSizePropertyChanged)));



        /// <summary>
        /// Button Text Weight
        /// </summary>
        public static readonly DependencyProperty TextFontWeightProperty =
                 DependencyProperty.Register(nameof(TextFontWeight), typeof(FontWeight), typeof(AnimationButton), new PropertyMetadata(FontWeights.Normal, new PropertyChangedCallback(OnTextFontWeightPropertyChanged)));
        /// <summary>
        /// SwitchOn FontWeight
        /// </summary>
        public static readonly DependencyProperty SwitchOnFontWeightProperty =
                 DependencyProperty.Register(nameof(SwitchOnFontWeight), typeof(FontWeight), typeof(AnimationButton), new PropertyMetadata(FontWeights.Normal, new PropertyChangedCallback(OnSwitchOnFontWeightPropertyChanged)));
        /// <summary>
        /// Disable FontWeight
        /// </summary>
        public static readonly DependencyProperty DisableWeightProperty =
                 DependencyProperty.Register(nameof(DisableWeight), typeof(FontWeight), typeof(AnimationButton), new PropertyMetadata(FontWeights.Normal, new PropertyChangedCallback(OnDisableWeightPropertyChanged)));


        /// <summary>
        /// Button Text Wrapping
        /// </summary>
        public static readonly DependencyProperty TextWrappingProperty =
                 DependencyProperty.Register(nameof(TextWrapping), typeof(TextWrapping), typeof(AnimationButton), new PropertyMetadata(TextWrapping.NoWrap, new PropertyChangedCallback(OnTextWrappingPropertyChanged)));
        /// <summary>
        /// Button Text Alignment
        /// </summary>
        public static readonly DependencyProperty TextAlignmentProperty =
                 DependencyProperty.Register(nameof(TextAlignment), typeof(TextAlignment), typeof(AnimationButton), new PropertyMetadata(TextAlignment.Center, new PropertyChangedCallback(OnTextAlignmentPropertyChanged)));
        /// <summary>
        /// Button Text Margin
        /// </summary>
        public static readonly DependencyProperty TextMarginProperty =
                 DependencyProperty.Register(nameof(TextMargin), typeof(Thickness), typeof(AnimationButton), new PropertyMetadata(new Thickness(0, 0, 0, 0), new PropertyChangedCallback(OnTextMarginPropertyChanged)));
        /// <summary>
        /// Command
        /// </summary>
        public static readonly DependencyProperty CommandProperty =
                 DependencyProperty.Register(nameof(Command), typeof(ICommand), typeof(AnimationButton), new UIPropertyMetadata(null));

        /// <summary>
        /// Circle Clicked Command
        /// </summary>
        public static readonly DependencyProperty CircleCommandProperty =
                 DependencyProperty.Register(nameof(CircleCommand), typeof(ICommand), typeof(AnimationButton), new UIPropertyMetadata(null));
        /// <summary>
        /// Drop Command
        /// </summary>
        public static readonly DependencyProperty DropCommandProperty =
                 DependencyProperty.Register(nameof(DropCommand), typeof(ICommand), typeof(AnimationButton), new UIPropertyMetadata(null));
        /// <summary>
        /// Drag Enable
        /// </summary>
        public static readonly DependencyProperty DragEnableProperty =
                 DependencyProperty.Register(nameof(DragEnable), typeof(bool), typeof(AnimationButton), new PropertyMetadata(false));
        /// <summary>
        /// DataParameter
        /// </summary>
        public static readonly DependencyProperty DataParameterProperty =
                 DependencyProperty.Register(nameof(DataParameter), typeof(object), typeof(AnimationButton), new PropertyMetadata(null, new PropertyChangedCallback(OnDataParameterPropertyChanged)));
        /// <summary>
        /// Circle Size
        /// </summary>
        public static readonly DependencyProperty CircleSizeProperty =
                 DependencyProperty.Register(nameof(CircleSize), typeof(double), typeof(AnimationButton), new PropertyMetadata((double)12, new PropertyChangedCallback(OnCircleSizePropertyChanged)));
        /// <summary>
        /// Circle Back Brush
        /// </summary>
        public static readonly DependencyProperty CircleBackBrushProperty =
                 DependencyProperty.Register(nameof(CircleBackBrush), typeof(string), typeof(AnimationButton), new PropertyMetadata("Transparent", new PropertyChangedCallback(OnCircleBackBrushPropertyChanged)));
        /// <summary>
        /// Circle Over Text Bruch Forground Brush
        /// </summary>
        public static readonly DependencyProperty CircleTextBruchProperty =
                 DependencyProperty.Register(nameof(CircleTextBruch), typeof(string), typeof(AnimationButton), new PropertyMetadata("Transparent", new PropertyChangedCallback(OnCircleTextBruchPropertyChanged)));
        /// <summary>
        /// Circle Over Text
        /// </summary>
        public static readonly DependencyProperty CircleTextProperty =
                 DependencyProperty.Register(nameof(CircleText), typeof(string), typeof(AnimationButton), new PropertyMetadata(string.Empty, new PropertyChangedCallback(OnCircleTextPropertyChanged)));
        /// <summary>
        /// Circle Outer Option Flag
        /// </summary>
        public static readonly DependencyProperty CircleOuterProperty =
                 DependencyProperty.Register(nameof(CircleOuter), typeof(bool), typeof(AnimationButton), new PropertyMetadata(false, new PropertyChangedCallback(OnCircleOuterPropertyChanged)));
        /// <summary>
        /// Display Language Type
        /// </summary>
        public static readonly DependencyProperty DisplayLanguagePropery =
                 DependencyProperty.Register(nameof(DisplayLanguage), typeof(SupportLanguageType), typeof(AnimationButton), new PropertyMetadata(SupportLanguageType.ko));

        #endregion DependencyProperty 
        #region [ SendItem Properties ]
        /// <summary>
        /// Send Button
        /// </summary>
        public AnimationButton SendSource { get; set; } = null;
        /// <summary>
        /// Revice Button
        /// </summary>
        public UIElement ReciveTarget { get; set; } = null;
        /// <summary>
        /// Targer Grid
        /// </summary>
        public Grid TargetGrid { get; set; } = null;
        #endregion SendItem Properties

        #region [ Propertis For DependencyProperty ]

        #region Base Propertis

        /// <summary>
        /// Noraml Bakcground 
        /// </summary>
        public string NormalBrush
        {
            get { return (string)GetValue(NormalBrushProperty); }
            set { SetValue(NormalBrushProperty, value); }
        }
        /// <summary>
        /// Image Brush Stretch Type
        /// </summary>
        public Stretch BrushStretch
        {
            get { return (Stretch)GetValue(BrushStretchProperty); }
            set { SetValue(BrushStretchProperty, value); }

        }
        /// <summary>
        /// Mouse/Touch Down Bakcground 
        /// </summary>
        public string DownBrush
        {
            get { return (string)GetValue(DownBrushProperty); }
            set { SetValue(DownBrushProperty, value); }
        }
        /// <summary>
        /// Button Disable Background
        /// </summary>
        public string DisableBrush
        {
            get { return (string)GetValue(DisableBrushProperty); }
            set { SetValue(DisableBrushProperty, value); }
        }
        /// <summary>
        /// Switch On Status Background
        /// </summary>
        public string SwitchOnBrush
        {
            get { return (string)GetValue(SwitchOnBrushProperty); }
            set { SetValue(SwitchOnBrushProperty, value); }
        }
        /// <summary>
        /// Switch Status
        /// </summary>
        public bool Switch
        {
            get { return (bool)GetValue(SwitchProperty); }
            set { SetValue(SwitchProperty, value); }
        }
        /// <summary>
        /// Breathing Status
        /// </summary>
        public bool IsBreathing
        {
            get { return (bool)GetValue(IsBreathingProperty); }
            set { SetValue(IsBreathingProperty, value); }
        }
        /// <summary>
        /// Auto Switching Flag
        /// </summary>
        public bool AutoToggle
        {
            get { return (bool)GetValue(AutoToggleProperty); }
            set { SetValue(AutoToggleProperty, 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>
        /// 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>
        /// Drop Command
        /// </summary>
        public ICommand DropCommand
        {
            get { return (ICommand)GetValue(DropCommandProperty); }
            set { SetValue(DropCommandProperty, value); }
        }
        /// <summary>
        /// Data Parameter
        /// </summary>
        public object DataParameter
        {
            get { return (object)GetValue(DataParameterProperty); }
            set { SetValue(DataParameterProperty, value); }
        }
        /// <summary>
        /// Click Animation Type
        /// </summary>
        public ButtonAnimationType ClickAnimationType
        {
            get { return (ButtonAnimationType)GetValue(ClickAnimationTypeProperty); }
            set { SetValue(ClickAnimationTypeProperty, value); }
        }
        /// <summary>
        /// Drop Animation Type
        /// </summary>
        public ButtonAnimationType DropAnimationType
        {
            get { return (ButtonAnimationType)GetValue(DropAnimationTypeProperty); }
            set { SetValue(DropAnimationTypeProperty, value); }
        }
        /// <summary>
        /// Drag Enable
        /// </summary>
        public bool DragEnable
        {
            get { return (bool)GetValue(DragEnableProperty); }
            set { SetValue(DragEnableProperty, value); }
        }
        /// <summary>
        /// Enabled
        /// </summary>
        public bool Enabled
        {
            get { return (bool)GetValue(EnabledProperty); }
            set { SetValue(EnabledProperty, value); }
        }
        /// <summary>
        /// Drag Cursor Image Path
        /// </summary>
        public string DragCursorImage
        {
            get { return (string)GetValue(DragCursorImageProperty); }
            set { SetValue(DragCursorImageProperty, value); }
        }
        /// <summary>
        /// Drag Cursor Hot Spot Type
        /// </summary>
        public HotSpotType DragCursorHotSpot
        {
            get { return (HotSpotType)GetValue(DragCursorHotSpotProperty); }
            set { SetValue(DragCursorHotSpotProperty, value); }
        }


        #endregion Base Propertis

        #region ButtonText Properties
        /// <summary>
        /// Display Language Type
        /// </summary>
        public SupportLanguageType DisplayLanguage
        {
            get { return (SupportLanguageType)GetValue(DisplayLanguagePropery); }
            set { SetValue(DisplayLanguagePropery, value); }
        }
        /// <summary>
        /// Button Text
        /// </summary>
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }
        /// <summary>
        /// Button Text Multi Language Text 
        /// </summary>
        public List<M_Language> LanguageText
        {
            get { return (List<M_Language>)GetValue(LanguageTextProperty); }
            set { SetValue(LanguageTextProperty, value); }
        }
        /// <summary>
        /// Button Text Visibility
        /// </summary>
        public Visibility TextVisible
        {
            get { return (Visibility)GetValue(TextVisibleProperty); }
            set { SetValue(TextVisibleProperty, value); }
        }
        /// <summary>
        /// Button Text Foreground
        /// </summary>
        public string TextForeground
        {
            get { return (string)GetValue(TextForegroundProperty); }
            set { SetValue(TextForegroundProperty, value); }
        }
        /// <summary>
        /// Button Switch On Foreground
        /// </summary>
        public string SwitchOnForeground
        {
            get { return (string)GetValue(SwitchOnForegroundProperty); }
            set { SetValue(SwitchOnForegroundProperty, value); }
        }
        /// <summary>
        /// Button Disable Foreground
        /// </summary>
        public string DisableForeground
        {
            get { return (string)GetValue(DisableForegroundProperty); }
            set { SetValue(DisableForegroundProperty, value); }
        }

        /// <summary>
        /// Button Text VerticalAlignment
        /// </summary>
        public VerticalAlignment TextVerticalAlignment
        {
            get { return (VerticalAlignment)GetValue(TextVerticalAlignmentProperty); }
            set { SetValue(TextVerticalAlignmentProperty, value); }
        }
        /// <summary>
        /// Button Text HorizontalAlignment
        /// </summary>
        public HorizontalAlignment TextHorizontalAlignment
        {
            get { return (HorizontalAlignment)GetValue(TextHorizontalAlignmentProperty); }
            set { SetValue(TextHorizontalAlignmentProperty, value); }
        }
        /// <summary>
        /// Button Text FontFamily 
        /// </summary>
        public string TextFontFamily
        {
            get { return (string)GetValue(TextFontFamilyProperty); }
            set { SetValue(TextFontFamilyProperty, value); }
        }
        /// <summary>
        /// Button Text FontSize
        /// </summary>
        public double TextFontSize
        {
            get { return (double)GetValue(TextFontSizeProperty); }
            set { SetValue(TextFontSizeProperty, value); }
        }
        /// <summary>
        /// Switch On FontSize
        /// </summary>
        public double SwitchOnFontSize
        {
            get { return (double)GetValue(SwitchOnFontSizeProperty); }
            set { SetValue(SwitchOnFontSizeProperty, value); }
        }
        /// <summary>
        /// Disable FontSize
        /// </summary>
        public double DisableFontSize
        {
            get { return (double)GetValue(DisableFontSizeProperty); }
            set { SetValue(DisableFontSizeProperty, value); }
        }
        /// <summary>
        /// Button Text FontWeight
        /// </summary>
        public FontWeight TextFontWeight
        {
            get { return (FontWeight)GetValue(TextFontWeightProperty); }
            set { SetValue(TextFontWeightProperty, value); }
        }
        /// <summary>
        /// SwitchOn FontWeight
        /// </summary>
        public FontWeight SwitchOnFontWeight
        {
            get { return (FontWeight)GetValue(SwitchOnFontWeightProperty); }
            set { SetValue(SwitchOnFontWeightProperty, value); }
        }
        /// <summary>
        /// Disable Font Weight
        /// </summary>
        public FontWeight DisableWeight
        {
            get { return (FontWeight)GetValue(DisableWeightProperty); }
            set { SetValue(DisableWeightProperty, value); }
        }
        /// <summary>
        /// Button Text Wrapping 
        /// </summary>
        public TextWrapping TextWrapping
        {
            get { return (TextWrapping)GetValue(TextWrappingProperty); }
            set { SetValue(TextWrappingProperty, value); }
        }
        /// <summary>
        /// Button Text Alignment
        /// </summary>
        public TextAlignment TextAlignment
        {
            get { return (TextAlignment)GetValue(TextAlignmentProperty); }
            set { SetValue(TextAlignmentProperty, value); }
        }
        /// <summary>
        /// Button Text Margin
        /// </summary>
        public Thickness TextMargin
        {
            get { return (Thickness)GetValue(TextMarginProperty); }
            set { SetValue(TextMarginProperty, value); }
        }

        #endregion

        #region Circle Options Properties
        /// <summary>
        /// Circle BAck Brush
        /// </summary>
        public string CircleBackBrush
        {
            get { return (string)GetValue(CircleBackBrushProperty); }
            set { SetValue(CircleBackBrushProperty, value); }

        }
        /// <summary>
        /// Circle Over Text
        /// </summary>
        public string CircleText
        {
            get { return (string)GetValue(CircleTextProperty); }
            set { SetValue(CircleTextProperty, value); }
        }
        /// <summary>
        /// Circle Over Text Foregraund Brush
        /// </summary>
        public string CircleTextBruch
        {
            get { return (string)GetValue(CircleTextBruchProperty); }
            set { SetValue(CircleTextBruchProperty, value); }
        }
        /// <summary>
        /// Circle Size
        /// </summary>
        public double CircleSize
        {
            get { return (double)GetValue(CircleSizeProperty); }
            set { SetValue(CircleSizeProperty, value); }
        }
        /// <summary>
        /// Circle Outer Option Flag
        /// </summary>
        public bool CircleOuter
        {
            get { return (bool)GetValue(CircleOuterProperty); }
            set { SetValue(CircleOuterProperty, value); }

        }
        #endregion Circle Options Properties

        #endregion Propertis For DependencyProperty

        #region [ RoutedEvent 'MouseClicked' ]

        /// <summary>
        /// MouseClicked Event
        /// </summary>
        public static readonly RoutedEvent MouseClickedEvent = EventManager.RegisterRoutedEvent(nameof(MouseClicked), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(AnimationButton));
        /// <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(AnimationButton));
        /// <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(AnimationButton));
        /// <summary>
        /// MouseClicked Routed Event Handler
        /// </summary>
        public event RoutedEventHandler ItemDrop
        {
            add { AddHandler(ItemDropEvent, value); }
            remove { RemoveHandler(ItemDropEvent, value); }
        }
        #endregion RoutedEvent 'ItemDrop'


        #region [ RoutedEvent 'SendStart' ]

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

        #region [ RoutedEvent 'SendEnd' ]

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

        #endregion Public Members

        #region [  Ctor ]
        /// <summary>
        /// Ctor
        /// </summary>
        public AnimationButton()
        {
            try
            {
                InitializeComponent();
                this.ButtonText.Visibility = Visibility.Collapsed;
                this.CountCircle.Visibility = Visibility.Collapsed;
                this.CountText.Visibility = Visibility.Collapsed;
                this.AllowDrop = true;
                this.Drop += AnimationButton_Drop;
                this.MouseLeave += AnimationButton_MouseLeave;
                this.MouseDown += AnimationButton_MouseDown;
                this.MouseUp += AnimationButton_MouseUp;
                this.CountText.MouseLeave += Circle_MouseLeave;
                this.CountText.MouseDown += Circle_MouseDown;
                this.CountText.MouseUp += Circle_MouseUp;
                this.GiveFeedback += AnimationButton_GiveFeedback;
            }
            catch(Exception ex) 
            {
                CommonLog.ErrorLogWrite(this, "Ctor", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        ~AnimationButton()
        {
            this.Drop -= AnimationButton_Drop;
            this.MouseLeave -= AnimationButton_MouseLeave;
            this.MouseDown -= AnimationButton_MouseDown;
            this.MouseUp -= AnimationButton_MouseUp;
            this.CountText.MouseLeave -= Circle_MouseLeave;
            this.CountText.MouseDown -= Circle_MouseDown;
            this.CountText.MouseUp -= Circle_MouseUp;
            this.GiveFeedback -= AnimationButton_GiveFeedback;
        }
        #endregion Ctor

        #region [ Methods ]

        protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
        {
            try
            {
                var targetText = this.ButtonText;
                if (this.Enabled)
                {
                    if (this.Switch)
                    {
                        ResourceManager.SetBrush(this.ButtonGrid, "Background", this.SwitchOnBrush, this.BrushStretch, sizeInfo.NewSize);
                        ResourceManager.SetBrush(targetText, "Foreground", this.SwitchOnForeground);
                        targetText.FontSize = this.SwitchOnFontSize > 0 ? this.SwitchOnFontSize : this.TextFontSize > 0 ? this.TextFontSize : 12;
                        targetText.FontWeight = this.SwitchOnFontWeight;

                    }
                    else
                    {
                        ResourceManager.SetBrush(this.ButtonGrid, "Background", this.NormalBrush, this.BrushStretch, sizeInfo.NewSize);
                        ResourceManager.SetBrush(targetText, "Foreground", this.TextForeground);
                        targetText.FontSize = this.TextFontSize > 0 ? this.TextFontSize : 12;
                        targetText.FontWeight = this.TextFontWeight;
                    }
                }
                else
                {
                    ResourceManager.SetBrush(this.ButtonGrid, "Background", this.DisableBrush, this.BrushStretch, sizeInfo.NewSize);
                    ResourceManager.SetBrush(targetText, "Foreground", this.DisableForeground);
                    targetText.FontSize = this.DisableFontSize > 0 ? this.DisableFontSize : this.TextFontSize > 0 ? this.TextFontSize : 12;
                    targetText.FontWeight = this.DisableWeight;
                }
                base.OnRenderSizeChanged(sizeInfo);
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "OnRenderSizeChanged()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        private void RaiseSendStartEvent()
        {
            if (ClickSend)
            {
                RoutedEventArgs newEventArgs = new RoutedEventArgs(AnimationButton.SendStartEvent);
                RaiseEvent(newEventArgs);
            }
        }
        private void RaiseSendEndEvent()
        {
            if (ClickSend)
            {
                RoutedEventArgs newEventArgs = new RoutedEventArgs(AnimationButton.SendEndEvent);
                RaiseEvent(newEventArgs);
            }
        }
        /// <summary>
        /// Raise MouseClicked Event
        /// </summary>
        private void RaiseMouseClickedEvent()
        {
            //Auto Toggle Process
            if (AutoToggle) Switch = !Switch;
            //Command Excute 
            if (Command != null && Command.CanExecute(DataParameter))
            {
                Command.Execute(DataParameter);
            }
            // Click SendObject
            if (ClickSend)
            {
                SendItem(this);
            }
            //Raise MouseClicked Event
            RoutedEventArgs newEventArgs = new RoutedEventArgs(AnimationButton.MouseClickedEvent);
            RaiseEvent(newEventArgs);
        }

        /// <summary>
        /// Raise CircleClicked Event
        /// </summary>
        private void RaiseCircleClickedEvent()
        {
            if (CircleCommand != null && CircleCommand.CanExecute(DataParameter))
            {
                CircleCommand.Execute(DataParameter);
            }
            RoutedEventArgs newEventArgs = new RoutedEventArgs(AnimationButton.CircleClickedEvent);
            RaiseEvent(newEventArgs);
        }
        /// <summary>
        /// Raise ItemDrop Event
        /// </summary>
        /// <param name="sender"></param>
        private void RaiseItemDropEvent(object sender)
        {

            if (DropCommand != null && DropCommand.CanExecute(sender))
            {
                DropCommand.Execute(sender);
            }
            RoutedEventArgs newEventArgs = new RoutedEventArgs(AnimationButton.ItemDropEvent, sender);
            RaiseEvent(newEventArgs);
        }

        /// <summary>
        /// Get Target By ButtonAnimationType
        /// </summary>
        /// <param name="_buttonAnimationType"></param>
        /// <returns></returns>
        private FrameworkElement GetAnimationTarget(ButtonAnimationType _buttonAnimationType)
        {
            FrameworkElement AnimationTarget = null;
            switch (_buttonAnimationType)
            {
                case ButtonAnimationType.TextBounceUp:
                case ButtonAnimationType.TextBounceDown:
                case ButtonAnimationType.TextSizeDown:
                case ButtonAnimationType.TextSizeUp:
                case ButtonAnimationType.TextTwist:
                    AnimationTarget = this.ButtonText;
                    break;
                case ButtonAnimationType.BounceUp:
                case ButtonAnimationType.BounceDown:
                case ButtonAnimationType.SizeDown:
                case ButtonAnimationType.SizeUp:
                case ButtonAnimationType.Twist:
                case ButtonAnimationType.OpacityDown:
                case ButtonAnimationType.OpacityUp:
                    AnimationTarget = this.ButtonGrid;
                    break;
            }
            return AnimationTarget;
        }
        /// <summary>
        /// Click Animation Run
        /// </summary>
        private void ClickAnimationRun()
        {
            
            var target = GetAnimationTarget(ClickAnimationType);
            if (target != null) Animations.GetClickAnimation(target, ClickAnimationType).Begin();
        }
        /// <summary>
        /// Drop Animation Run
        /// </summary>
        private void DropAnimationRun()
        {
            var target = GetAnimationTarget(DropAnimationType);
            if (target != null) Animations.GetClickAnimation(target, DropAnimationType).Begin();
        }
        /// <summary>
        /// Item Image Send
        /// </summary>
        /// <param name="source"></param>
        private void SendItem(AnimationButton source)
        {
            try
            {
                RaiseSendStartEvent();
                SendSource = source;
                var _targetGrid = source.FindParent(source.BaseGrid);
                if (_targetGrid is Grid)
                {
                    TargetGrid = _targetGrid as Grid;
                    var _reviceTarget = TargetGrid.FindName(source.ReciveElement);
                    switch (_reviceTarget.GetType().Name)
                    {
                        case "AnimationButton":
                            ReciveTarget = _reviceTarget as AnimationButton;
                            break;
                        case "ButtonList":
                            var listTarget = _reviceTarget as ButtonList;
                            if (listTarget.DefaultIndex > -1)
                            {
                                ReciveTarget = listTarget.DefaultItem;
                            }
                            else
                            {
                                ReciveTarget = null;
                            }
                            break;
                    }
                }
                if (TargetGrid != null && SendSource != null && ReciveTarget != null)
                {
                    SendSource.IsEnabled = false;
                    ReciveTarget.IsEnabled = false;
                    var targetCanvas = new Canvas() { Name = "SendItemCanvas" };
                    var sendImage = new Image
                    {
                        Width = SendSource.RenderSize.Width,
                        Height = SendSource.RenderSize.Height,
                        Name = "SendImage"
                    };
                    var sourcePosition = SendSource.TranslatePoint(new Point(0, 0), TargetGrid);
                    var targetPosition = ReciveTarget.TranslatePoint(new Point(0, 0), TargetGrid);
                    sendImage.Source = ResourceManager.GetBitmapImage(SendSource.NormalBrush);
                    targetCanvas.Children.Add(sendImage);
                    targetCanvas.Background = new SolidColorBrush(Colors.Transparent);
                    TargetGrid.Children.Add(targetCanvas);
                    TargetGrid.ReregisterName("SendImage", sendImage);
                    TargetGrid.ReregisterName("SendItemCanvas", targetCanvas);
                    Canvas.SetLeft(sendImage, sourcePosition.X);
                    Canvas.SetTop(sendImage, sourcePosition.Y);
                    Canvas.SetZIndex(sendImage, int.MaxValue);
                    var moveX = targetPosition.X + (ReciveTarget.RenderSize.Width / 2);//- sourcePosition.X + (SendSource.RenderSize.Width / 2);
                    var moveY = targetPosition.Y - (ReciveTarget.RenderSize.Height / 2);// - sourcePosition.Y - (SendSource.RenderSize.Height / 2);
                    var SendAnimations = Animations.GetSendAnimation(sendImage, ButtonSendAnimationType.Normal, targetPosition.X - sourcePosition.X, targetPosition.Y - sourcePosition.Y);
                    if (SendAnimations != null)
                    {
                        SendAnimations.Completed += SendAnimations_Completed;
                        SendAnimations.Begin();
                    }
                }
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "SendItem()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        private static void SetButton(AnimationButton _thisButton, M_AnimationButton _m_ButtonData)
        {
            try
            {
                _thisButton.Width = _m_ButtonData.Width;
                _thisButton.Height = _m_ButtonData.Height;
                _thisButton.Margin = _m_ButtonData.Margin;
                _thisButton.NormalBrush = _m_ButtonData.NormalBrush;
                _thisButton.DownBrush = _m_ButtonData.DownBrush;
                _thisButton.DisableBrush = _m_ButtonData.DisableBrush;
                _thisButton.SwitchOnBrush = _m_ButtonData.SwitchOnBrush;
                _thisButton.DragCursorImage = _m_ButtonData.DragCursorImage;
                _thisButton.DragCursorHotSpot = _m_ButtonData.DragCursorHotSpot;
                _thisButton.BrushStretch = _m_ButtonData.BrushStretch;
                _thisButton.Enabled = _m_ButtonData.Enabled;
                _thisButton.Switch = _m_ButtonData.Switch;
                _thisButton.IsBreathing = _m_ButtonData.IsBreathing;
                _thisButton.AutoToggle = _m_ButtonData.AutoToggle;
                _thisButton.ClickSend = _m_ButtonData.ClickSend;
                _thisButton.BaseGrid = _m_ButtonData.BaseGrid;
                _thisButton.ReciveElement = _m_ButtonData.ReciveElement;
                _thisButton.ClickAnimationType = _m_ButtonData.ClickAnimationType;
                _thisButton.DropAnimationType = _m_ButtonData.DropAnimationType;
                _thisButton.Text = _m_ButtonData.Text;
                _thisButton.LanguageText = _m_ButtonData.LanguageText;
                _thisButton.TextVisible = _m_ButtonData.TextVisible;
                _thisButton.TextForeground = _m_ButtonData.TextForeground;
                _thisButton.SwitchOnForeground = _m_ButtonData.SwitchOnForeground;
                _thisButton.DisableForeground = _m_ButtonData.DisableForeground;
                _thisButton.TextVerticalAlignment = _m_ButtonData.TextVerticalAlignment;
                _thisButton.TextHorizontalAlignment = _m_ButtonData.TextHorizontalAlignment;
                _thisButton.TextFontFamily = _m_ButtonData.TextFontFamily;
                _thisButton.TextFontSize = _m_ButtonData.TextFontSize;
                _thisButton.SwitchOnFontSize = _m_ButtonData.SwitchOnFontSize;
                _thisButton.DisableFontSize = _m_ButtonData.DisableFontSize;
                _thisButton.TextFontWeight = _m_ButtonData.TextFontWeight;
                _thisButton.SwitchOnFontWeight = _m_ButtonData.SwitchOnFontWeight;
                _thisButton.DisableWeight = _m_ButtonData.DisableWeight;
                _thisButton.TextWrapping = _m_ButtonData.TextWrapping;
                _thisButton.TextAlignment = _m_ButtonData.TextAlignment;
                _thisButton.TextMargin = _m_ButtonData.TextMargin;
                _thisButton.DragEnable = _m_ButtonData.DragEnable;
                _thisButton.CircleSize = _m_ButtonData.CircleSize;
                _thisButton.CircleBackBrush = _m_ButtonData.CircleBackBrush;
                _thisButton.CircleTextBruch = _m_ButtonData.CircleTextBruch;
                _thisButton.CircleText = _m_ButtonData.CircleText;
                _thisButton.CircleOuter = _m_ButtonData.CircleOuter;
                _thisButton.DisplayLanguage = _m_ButtonData.DisplayLanguage;
                SetNormalBrush(_thisButton);

            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(_thisButton, "SetButton()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        private static void SetNormalBrush(AnimationButton _thisButton)
        {
            try
            {
                var targetText = _thisButton.ButtonText;
                if (_thisButton.Enabled)
                {
                    if (_thisButton.Switch)
                    {
                        ResourceManager.SetBrush(_thisButton.ButtonGrid, "Background", _thisButton.SwitchOnBrush, _thisButton.BrushStretch, new Size(_thisButton.Width, _thisButton.Height));
                        ResourceManager.SetBrush(targetText, "Foreground", _thisButton.SwitchOnForeground);
                        if (_thisButton.TextVisible.Equals(Visibility.Visible))
                        {
                            targetText.FontSize = _thisButton.SwitchOnFontSize > 0 ? _thisButton.SwitchOnFontSize : _thisButton.TextFontSize > 0 ? _thisButton.TextFontSize : 12;
                            targetText.FontWeight = _thisButton.SwitchOnFontWeight;
                        }
                    }
                    else
                    {
                        ResourceManager.SetBrush(_thisButton.ButtonGrid, "Background", _thisButton.NormalBrush, _thisButton.BrushStretch, new Size(_thisButton.Width, _thisButton.Height));
                        ResourceManager.SetBrush(targetText, "Foreground", _thisButton.TextForeground);
                        if (_thisButton.TextVisible.Equals(Visibility.Visible))
                        {
                            targetText.FontSize = _thisButton.TextFontSize > 0 ? _thisButton.TextFontSize : 12;
                            targetText.FontWeight = _thisButton.TextFontWeight;
                        }
                    }
                }
                else
                {
                    ResourceManager.SetBrush(_thisButton.ButtonGrid, "Background", _thisButton.DisableBrush, _thisButton.BrushStretch, new Size(_thisButton.Width, _thisButton.Height));
                    ResourceManager.SetBrush(targetText, "Foreground", _thisButton.DisableForeground);
                    if (_thisButton.TextVisible.Equals(Visibility.Visible))
                    {
                        targetText.FontSize = _thisButton.DisableFontSize > 0 ? _thisButton.DisableFontSize : _thisButton.TextFontSize > 0 ? _thisButton.TextFontSize : 12;
                        targetText.FontWeight = _thisButton.DisableWeight;
                    }
                }
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(_thisButton, "SetButton()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        #endregion Methods

        #region [ Event Handlers ]

        #region [ SendItem Animation Completed ]
        private void SendAnimations_Completed(object sender, EventArgs e)
        {

            try
            {
                if (TargetGrid.FindName("SendItemCanvas") is Canvas sendItemCanvas)
                {
                    sendItemCanvas.Children.Clear();
                    TargetGrid.Children.Remove(sendItemCanvas);
                    sendItemCanvas = null;
                    TargetGrid.UnregisterName("SendImage");
                    TargetGrid.UnregisterName("SendItemCanvas");
                    var eventArgs = new M_ItemDropEventArgs
                    {
                        SourceObject = SendSource,
                        TargetObject = ReciveTarget
                    };
                    if (ReciveTarget is AnimationButton animationButton)
                    {
                        animationButton.DropAnimationRun();
                        animationButton.RaiseItemDropEvent(eventArgs);

                    }
                    SendSource.IsEnabled = true;
                    ReciveTarget.IsEnabled = true;
                }
                RaiseSendEndEvent();
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "SetButton()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        #endregion SendItem Animation Completed

        #region [ DependencyProperty OnChanged Event Handler  ]

        private static void IsBreathingPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var target = d as AnimationButton;
            if ((bool)e.NewValue)
            {
                if (target.BreathigStoryboard is Storyboard storyboard)
                {
                    storyboard.Resume();
                }
                else
                {
                    target.BreathigStoryboard = Animations.GetClickAnimation(target.ButtonGrid, ButtonAnimationType.OpacityDown, 0.5);
                    target.BreathigStoryboard.RepeatBehavior = RepeatBehavior.Forever;
                    target.BreathigStoryboard.Begin();
                }
            }
            else
            {
                if (target.BreathigStoryboard is Storyboard storyboard)
                {
                    storyboard.Pause();
                }
            }
        }


        private static void OnDataParameterPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null && !e.NewValue.Equals(e.OldValue))
            {
                var target = d as AnimationButton;
                var getType = e.NewValue.GetType();
                if (e.NewValue is M_ItemData m_ItemData)
                {
                    if (m_ItemData.DataParameter is M_AnimationButton m_ButtonData)
                    {
                        SetButton(target, m_ButtonData);
                    }
                }
                else if (e.NewValue is M_AnimationButton m_ButtonData)
                {
                    SetButton(target, m_ButtonData);
                }
            }
        }
        private static void OnNormalBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue !=null)
            {
                var target = d as AnimationButton;
                ResourceManager.SetBrush(target.ButtonGrid, "Background", target.SwitchOnBrush, target.BrushStretch, new Size(target.Width, target.Height));
                SetNormalBrush(target);
            }
        }
        private static void OnBrushStretchPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                var target = d as AnimationButton;
                SetNormalBrush(target);
            }
        }
        private static void OnSwitchPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                var target = d as AnimationButton;
                SetNormalBrush(target);
            }
        }
        private static void OnEnabledPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue is bool enabled)
            {
                var target = d as AnimationButton;
                SetNormalBrush(target);
                target.IsEnabled = enabled;
            }
        }
        private static void OnTextVisiblePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var targetText = (d as AnimationButton).ButtonText;
            targetText.Visibility = (Visibility)e.NewValue;
        }
        private static void OnTextForegroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                var target = d as AnimationButton;
                if (string.IsNullOrEmpty(target.SwitchOnForeground)
                    || target.SwitchOnForeground.Equals("Transparent")) target.SwitchOnForeground = (string)e.NewValue;
                if (string.IsNullOrEmpty(target.DisableForeground)
                    || target.DisableForeground.Equals("Transparent")) target.DisableForeground = (string)e.NewValue;
                SetNormalBrush(target);
            }

        }
        private static void OnSwitchOnForegroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                var target = d as AnimationButton;
                SetNormalBrush(target);
            }
        }
        private static void OnDisableForegroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                var target = d as AnimationButton;
                SetNormalBrush(target);
            }
        }

        private static void OnTextVerticalAlignmentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var targetText = (d as AnimationButton).ButtonText;
            targetText.VerticalAlignment = (VerticalAlignment)e.NewValue;
        }
        private static void OnTextHorizontalAlignmentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var targetText = (d as AnimationButton).ButtonText;
            targetText.HorizontalAlignment = (HorizontalAlignment)e.NewValue;
        }
        private static void OnTextFontFamilyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var targetText = (d as AnimationButton).ButtonText;
            try
            {
                targetText.FontFamily = new FontFamily((string)e.NewValue);
            }
            catch
            {
                targetText.FontFamily = Fonts.SystemFontFamilies.First();
            }
        }
        private static void OnTextFontSizePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var targetText = (d as AnimationButton).ButtonText;
            try
            {
                targetText.FontSize = (double)e.NewValue;
            }
            catch
            {
                targetText.FontSize = 10;
            }
        }
        private static void OnSwitchOnFontSizePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                var target = d as AnimationButton;
                SetNormalBrush(target);
            }
        }
        private static void OnDisableFontSizePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                var target = d as AnimationButton;
                SetNormalBrush(target);
            }
        }

        private static void OnTextFontWeightPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var targetText = (d as AnimationButton).ButtonText;
            targetText.FontWeight = (FontWeight)e.NewValue;
        }
        private static void OnSwitchOnFontWeightPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                var target = d as AnimationButton;
                SetNormalBrush(target);
            }
        }
        private static void OnDisableWeightPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                var target = d as AnimationButton;
                SetNormalBrush(target);
            }
        }

        private static void OnTextWrappingPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var targetText = (d as AnimationButton).ButtonText;
            targetText.TextWrapping = (TextWrapping)e.NewValue;
        }
        private static void OnTextAlignmentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var targetText = (d as AnimationButton).ButtonText;
            targetText.TextAlignment = (TextAlignment)e.NewValue;
        }
        private static void OnTextMarginPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var targetText = (d as AnimationButton).ButtonText;
            targetText.Margin = (Thickness)e.NewValue;
        }
        private static void OnCircleSizePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if ((double)e.NewValue > 12)
            {
                var target = d as AnimationButton;
                target.CountCircle.Width = (double)e.NewValue;
                target.CountCircle.Height = (double)e.NewValue;
                target.CountCircle.StrokeThickness = (double)e.NewValue * 0.07;
                target.CountText.Width = (double)e.NewValue;
                target.CountText.Height = (double)e.NewValue;
                target.CountText.FontSize = (double)e.NewValue * 0.7;
            }
        }
        private static void OnCircleTextBruchPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var target = d as AnimationButton;
            ResourceManager.SetBrush(target.CountText, "Foreground", (string)e.NewValue);
            ResourceManager.SetBrush(target.CountCircle, "Stroke", (string)e.NewValue);
        }
        private static void OnCircleTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var target = d as AnimationButton;
            if (e.NewValue.Equals(string.Empty))
            {
                target.CountText.Visibility = Visibility.Collapsed;
            }
            else
            {
                target.CountText.Visibility = Visibility.Visible;
                target.CountText.Text = (string)e.NewValue;
            }

        }
        private static void OnCircleBackBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var target = d as AnimationButton;
            if (e.NewValue.Equals("Transparent"))
            {
                target.CountCircle.Visibility = Visibility.Collapsed;
            }
            else
            {
                target.CountCircle.Visibility = Visibility.Visible;
                ResourceManager.SetBrush(target.CountCircle, "Fill", (string)e.NewValue);
            }
        }
        private static void OnCircleOuterPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if ((bool)e.NewValue)
            {
                var target = d as AnimationButton;
                target.CountCircle.RenderTransform = new TranslateTransform();
                var _circleTranslateTransform = target.CountCircle.RenderTransform as TranslateTransform;
                _circleTranslateTransform.X = target.CountCircle.Width / 2;
                _circleTranslateTransform.Y = target.CountCircle.Height / 2 * -1;
                target.CountText.RenderTransform = new TranslateTransform();
                var _textTranslateTransform = target.CountText.RenderTransform as TranslateTransform;
                _textTranslateTransform.X = target.CountText.Width / 2;
                _textTranslateTransform.Y = target.CountText.Height / 2 * -1;

            }
        }
        private static void OnBadgeImagesProperyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
                if (e.NewValue is List<string> badgeImages)
                {
                    var target = d as AnimationButton;
                    target.BadgeStack.Children.Clear();
                    foreach (var aBadge in badgeImages)
                    {
                        var sourceImage = ResourceManager.GetBitmapImage(aBadge);
                        if (sourceImage is BitmapImage)
                        {
                            var aBadgeImage = new Image()
                            {
                                Width = sourceImage.Width,
                                Height = sourceImage.Height,
                                Source = sourceImage
                            };
                            target.BadgeStack.Children.Add(aBadgeImage);
                        }
                    }

                }
        }
        #endregion DependencyProperty OnChanged Event Handler

        #region Drag & Drap Event Handler
        private void AnimationButton_GiveFeedback(object sender, GiveFeedbackEventArgs e)
        {
            var dropSource = e.Source as AnimationButton;
            if (e.Effects.Equals(DragDropEffects.Link) && !string.IsNullOrEmpty(dropSource.DragCursorImage) && DragEnable)
            {
                if (DragCursor == null) DragCursor = ResourceManager.GetCursorByImage(dropSource.DragCursorImage, dropSource.DragCursorHotSpot, dropSource.Width);
                if (DragCursor != null)
                {
                    e.UseDefaultCursors = false;
                    Mouse.SetCursor(DragCursor);
                }
                else
                {
                    e.UseDefaultCursors = true;
                }
            }
            else
            {
                e.UseDefaultCursors = true;
            }
            e.Handled = DragEnable;
        }
        private void AnimationButton_Drop(object sender, DragEventArgs e)
        {
            var source = (sender as AnimationButton);
            if (e.Data.GetData(sender.GetType()) is AnimationButton dropSource && !source.Equals(dropSource) && e.AllowedEffects.Equals(DragDropEffects.Link))
            {
                var eventArgs = new M_ItemDropEventArgs
                {
                    SourceObject = dropSource,
                    TargetObject = source
                };
                DropAnimationRun();
                RaiseItemDropEvent(eventArgs);
            }
            MoseDown = false;
        }
        #endregion Drag & Drap Event Handler

        #region Mouse Events Handler
        private void AnimationButton_MouseLeave(object sender, MouseEventArgs e)
        {

            if ( MoseDown && DragEnable)
            {
                DragDrop.DoDragDrop(sender as DependencyObject, sender, DragDropEffects.Link);
            }
            if (!Switch )
            {
                SetNormalBrush(this);
                MoseDown = false;
            }
        }

        private void AnimationButton_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (!MoseDown && !(CountCircle.IsMouseOver || CountText.IsMouseOver))
            {
                if (!string.IsNullOrEmpty(DownBrush) 
                 && !DownBrush.Equals("Transparent")) ResourceManager.SetBrush(ButtonGrid, "Background", DownBrush, BrushStretch, RenderSize);
                if (this.IsEnabled)
                {
                    ClickAnimationRun();
                    MoseDown = true;
                }
                MoseDownPosition = e.GetPosition(this); 
            }
        }
        
        private void AnimationButton_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (MoseDown && !(CountCircle.IsMouseOver || CountText.IsMouseOver))
            {
                if (Math.Abs(e.GetPosition(this).X - MoseDownPosition.X) > 50) MoseDown = false;
                if (Math.Abs(e.GetPosition(this).Y - MoseDownPosition.Y) > 50) MoseDown = false;
                if (MoseDown )
                {
                    RaiseMouseClickedEvent();
                }
                SetNormalBrush(this);
                MoseDown = false;
            }
        }
        #endregion Mouse Events

        #region CircleMouse Events Handler
        private void Circle_MouseLeave(object sender, MouseEventArgs e)
        {
            CircleMoseDown = false;
        }

        private void Circle_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (!CircleMoseDown )
            {
                if (this.IsEnabled)
                {
                    Animations.GetClickAnimation(this.CountCircle, ButtonAnimationType.SizeDown).Begin();
                    CircleMoseDown = true;
                }
                CircleMoseDownPosition = e.GetPosition(this);
            }
        }

        private void Circle_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (CircleMoseDown)
            {
                if (Math.Abs(e.GetPosition(this).X - CircleMoseDownPosition.X) > this.CountText.Width) MoseDown = false;
                if (Math.Abs(e.GetPosition(this).Y - CircleMoseDownPosition.Y) > this.CountText.Height) MoseDown = false;
                RaiseCircleClickedEvent();
                CircleMoseDown = false;
            }
        }
        #endregion CircleMouse Events Handler

        #endregion Event Handlers


    }


}
