using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace HistoryDLL
{
    public partial class CyclicScroller : UserControl
    {
        private List<ExtraUnitGrid> ExtraUnitGridList = new List<ExtraUnitGrid>();
    }

    public class ExtraUnitGrid : Grid
    {
        //外掛 Delegate event for communicate with CyclicScroller (通知用)
        public delegate void ExtraUnitGridBubbleToCyclicScroller(string ProcessCode, int index);
        public event ExtraUnitGridBubbleToCyclicScroller ExtraUnitGridBubbleToCyclicScrollerEvent;

        //原始物件寬度
        private int OriginalObjectWidth = 0;
        //放大後原始寬度必須增加的值
        private int ExtendValue = 400;
        //縮小一次的值
        public int ShrinkValueOne = 200;
        //展開縮小棟話時間
        private int MyStoryBoardTimeL = 200;
        private int MyStoryBoardTimeS = 100;
        //Storyboard delay time
        private int delayTime = 100;
        //紀錄方向
        private string Direction = "";

        private double detailviewerPos = -36;
        private double thumbnailPos = -7;
        //當前物件可被控制的狀態
        public enum ControlMode
        {
            //可展開 (正常狀態)
            CanExtend = 0x00001,
            //已經展開
            Extend = 0x00010,
            //不可展開 (處在最兩邊的無用地帶)
            UnUse = 0x00100,
            //縮小一次
            Clip = 0x01000,
            //縮小第二次 (最小寬度)
            MinStatus = 0x00000
        };

        public enum ObjectSize
        {
            OriginalSize = 0x0001,
            ShrinkNoneMarginSize = 0x0010,
            ShrinkMarginSize = 0x0100,
            ShrinkWholeSize = 0x1000
        }

        private int MonitorIndex;
        private ControlMode BlockControlMode;
        private ControlMode RecodeOriMode;
        public Border BorderUp = new Border();
        public Border BorderDown = new Border();
        //是否已經被加到畫面中
        public int IsUsing = 0;
        public TextBlock textblock = new TextBlock();
        public int curDataIndex = -1;
        //紀錄回到原位置的Margin值 ~以確保可以正確回到該位置
        public double RecodeMarginLeft = 0;
        private double borderupheight = 0;
        private double borderdownheight = 0;
        private double NonoUseSize = 0;

        private ObjectSize objSize = ObjectSize.OriginalSize;
        private double ThisMarginLeft = 0.0;

        public bool ExtendStoryboardRun = false;
        public bool ShrinkStoryboardRun = false;

        //下方方塊顏色
        private SolidColorBrush borderDownColor = new SolidColorBrush(ConfigSettingClass.TimelineExtentCollect.BackgroundColor);
        private SolidColorBrush TextBlockExtendColor = new SolidColorBrush(ConfigSettingClass.TimelineExtentCollect.TextColor);
        private SolidColorBrush TextBlockShrinkColor = new SolidColorBrush(ConfigSettingClass.TimelineCollect.TextColor);

        public int Get_Set_MonitorIndex
        {
            get { return MonitorIndex; }
            set
            {
                MonitorIndex = value;
                if (MonitorIndex >= 2)
                {
                    ThisMarginLeft = (MonitorIndex - 2) * OriginalObjectWidth + (OriginalObjectWidth - NonoUseSize);
                }
                else
                {
                    ThisMarginLeft = -NonoUseSize;
                }
            }
        }

        public ControlMode Get_Set_BlockControlMode
        {
            get { return BlockControlMode; }
            set { BlockControlMode = value; }
        }

        public ExtraUnitGrid(int Width, int Height, int DownHeight, int NoneUse)
        {
            int borderMargin = 5;
            if (GlobalFunction.isSolutionUsing4K)
            {
                ExtendValue *= 2;
                ShrinkValueOne *= 2;
                borderMargin *= 2;
            }

            this.Width = this.OriginalObjectWidth = Width;
            this.Height = Height + DownHeight;
            this.NonoUseSize = NoneUse;
            CutTheGrid();

            borderupheight = Height;
            borderdownheight = DownHeight;

            this.BorderUp.Height = Height;
            this.BorderUp.Height = 0;
            //this.BorderUp.Background = Brushes.Red;
            this.BorderUp.BorderBrush = Brushes.Transparent;
            this.BorderUp.BorderThickness = new Thickness(borderMargin);

            this.BorderDown.Height = DownHeight;
            this.BorderDown.Background = borderDownColor;
            //this.BorderDown.Background = Brushes.Green;
            this.BorderDown.BorderBrush = Brushes.Transparent;
            this.BorderDown.BorderThickness = new Thickness(borderMargin, borderMargin, borderMargin, GlobalFunction.isSolutionUsing4K ? 0 : borderMargin);

            //字體設定
            textblock.FontSize = GlobalFunction.isSolutionUsing4K ? 40 * 1.5 : 40;
            textblock.TextTrimming = TextTrimming.CharacterEllipsis;
            textblock.VerticalAlignment = System.Windows.VerticalAlignment.Center;
            textblock.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
            BorderDown.Child = textblock;

            this.Children.Add(BorderUp);
            this.Children.Add(BorderDown);
            Grid.SetRow(BorderUp, 0);
            Grid.SetRow(BorderDown, 1);

            this.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
            this.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
            Get_Set_MonitorIndex = 0;
            IsUsing = 0;
            this.BorderDown.TouchUp += new EventHandler<System.Windows.Input.TouchEventArgs>(BorderDown_TouchUp);
        }

        public void SetOriControlMode(ControlMode Set)
        {
            RecodeOriMode = Set;
        }

        public void BorderDown_TouchUp(object sender, System.Windows.Input.TouchEventArgs e)
        {
            if (ExtendStoryboardRun)
                return;

            if (this.BlockControlMode == ControlMode.Extend)
            {
                this.Dispatcher.BeginInvoke(ExtraUnitGridBubbleToCyclicScrollerEvent, "Change", Get_Set_MonitorIndex);
            }
        }

        //回復原始大小動畫完成
        void Mystoryboard_Completed(object sender, EventArgs e)
        {
            this.Dispatcher.BeginInvoke(ExtraUnitGridBubbleToCyclicScrollerEvent, "Remove", Get_Set_MonitorIndex - 1);
        }

        private void CutTheGrid()
        {
            //切成上下兩塊
            RowDefinition rowDefinitionUp = new RowDefinition();
            RowDefinition rowDefinitionDown = new RowDefinition();

            rowDefinitionUp.Height = new GridLength(6, GridUnitType.Star);
            rowDefinitionDown.Height = new GridLength(1, GridUnitType.Star);
            //rowDefinitionDown.Height = new GridLength(GlobalFunction.isSolutionUsing4K ? 184 : 92, GridUnitType.Pixel);

            this.RowDefinitions.Add(rowDefinitionUp);
            this.RowDefinitions.Add(rowDefinitionDown);
        }

        #region 展開動畫 :
        /// <summary>
        /// 1.下方區塊先展開(0.2) 
        /// 2.上方區塊由下往上升起(0.2)
        /// 3.call Detailviewer opacity changed(0.1)
        /// </summary>
        public void ExtendFunction()
        {
            this.BlockControlMode = ControlMode.Extend;
            this.textblock.Foreground = TextBlockExtendColor;
            //下方區塊的變化
            Storyboard Mystoryboard = new Storyboard();

            this.textblock.Opacity = 1;
            this.BorderUp.Opacity = 1;
            ExtendStoryboardRun = true;
            Mystoryboard = SetExtendChangeAnimation(MyStoryBoardTimeL, OriginalObjectWidth + ExtendValue);
            Mystoryboard.Completed += new EventHandler(EventContainerExtend_Complete);
            Mystoryboard.Begin();
        }

        //中間放大
        private Storyboard SetExtendChangeAnimation(int time, int ToValue)
        {
            Storyboard ResultStoryboard = new Storyboard();

            DoubleAnimation dbOffset = new DoubleAnimation()
            {
                Duration = TimeSpan.FromMilliseconds(time),
                EasingFunction = new CircleEase()
                {
                    EasingMode = EasingMode.EaseOut,
                },
                From = this.Width,
                To = ToValue
            };

            ThicknessAnimation dbMargin = new ThicknessAnimation()
            {
                Duration = TimeSpan.FromMilliseconds(time),
                EasingFunction = new CircleEase()
                {
                    EasingMode = EasingMode.EaseOut,
                },
                From = this.Margin,
                To = new Thickness(this.Margin.Left - Math.Abs(this.Width - ToValue) / 2, 0, 0, this.Margin.Bottom)
            };
            this.RenderTransformOrigin = new Point(0.5, 0.5);
            Storyboard.SetTarget(dbOffset, (DependencyObject)this);
            Storyboard.SetTarget(dbMargin, (DependencyObject)this);
            Storyboard.SetTargetProperty(dbOffset, new PropertyPath(Grid.WidthProperty));
            Storyboard.SetTargetProperty(dbMargin, new PropertyPath(Grid.MarginProperty));
            ResultStoryboard.Children.Add(dbOffset);
            ResultStoryboard.Children.Add(dbMargin);
            ResultStoryboard.FillBehavior = FillBehavior.HoldEnd;

            return ResultStoryboard;
        }

        private void EventContainerExtend_Complete(object sender, EventArgs e)
        {
            //上方區塊的變化
            Storyboard MystoryboardUp = new Storyboard();

            MystoryboardUp = ObjectAnimationToShow(MyStoryBoardTimeL, this.BorderUp.Height, borderupheight, detailviewerPos);
            MystoryboardUp.Completed += new EventHandler(DetailViewerControlShow);
            MystoryboardUp.Begin();
        }

        //Object is fade in
        internal void DetailViewerControlShow(object sender, EventArgs e)
        {
            //call detailviewer to show
            Grid gd = new Grid();

            gd = this.BorderUp.Child as Grid;

            if (gd != null && gd.Children.Count > 0)
            {
                if (gd.Children[0].ToString() == GlobalFunction.projectname + ".DetailViewer")
                {
                    //sdlu
                    //((DetailViewer)gd.Children[0]).StartOpacityAnimation();
                }
            }
            else if (this.BorderUp.Child.ToString() == GlobalFunction.projectname + ".ThumbnailContainer")
            {
                ((ThumbnailContainer)this.BorderUp.Child).StartOpacityAnimation();
            }

            ExtendStoryboardRun = false;
        }

        //Object is fade out
        internal void DetailViewerControlHide()
        {
            //call detailviewer to show
            Grid gd = new Grid();

            gd = this.BorderUp.Child as Grid;

            if (gd != null)
            {
                if (gd.Children[0].ToString() == "nLightenHistoryWall.DetailViewer")
                {
                    //sdlu
                    //((DetailViewer)gd.Children[0]).StopOpacityAnimation();
                }
            }
            else if (this.BorderUp.Child.ToString() == "nLightenHistoryWall.ThumbnailContainer")
            {
                ((ThumbnailContainer)this.BorderUp.Child).StopOpacityAnimation();
            }
        }

        //上方物件由下往上飛入
        private Storyboard ObjectAnimationToShow(int time, double fromValue, double toValue, double marginvalue)
        {
            Storyboard ResultStoryboard = new Storyboard();

            DoubleAnimation dbOffset = new DoubleAnimation()
            {
                Duration = TimeSpan.FromMilliseconds(time),
                EasingFunction = new CircleEase()
                {
                    EasingMode = EasingMode.EaseOut,
                },
                From = fromValue,
                To = toValue
            };

            ThicknessAnimation dbMargin = new ThicknessAnimation()
            {
                Duration = TimeSpan.FromMilliseconds(time),
                EasingFunction = new ExponentialEase()
                {
                    EasingMode = EasingMode.EaseOut,
                },
                From = new Thickness(this.BorderDown.Margin.Left, 0, 0, -borderdownheight),
                To = new Thickness(this.BorderDown.Margin.Left, 0, 0, marginvalue)
            };

            Storyboard.SetTarget(dbOffset, this.BorderUp);
            Storyboard.SetTarget(dbMargin, this.BorderUp);
            Storyboard.SetTargetProperty(dbOffset, new PropertyPath(Grid.HeightProperty));
            Storyboard.SetTargetProperty(dbMargin, new PropertyPath(Grid.MarginProperty));
            ResultStoryboard.Children.Add(dbOffset);
            ResultStoryboard.Children.Add(dbMargin);
            ResultStoryboard.FillBehavior = FillBehavior.HoldEnd;

            return ResultStoryboard;
        }
        #endregion

        private void SetCurrentObjSizeShrink(string Direction)
        {
            if (objSize == ObjectSize.OriginalSize)
            {
                if (Direction == "Left")
                {
                    objSize = ObjectSize.ShrinkNoneMarginSize;
                }
                else if (Direction == "Right")
                {
                    objSize = ObjectSize.ShrinkMarginSize;
                }
            }
            else if (objSize == ObjectSize.ShrinkNoneMarginSize)
            {
                if (Direction == "Right")
                {
                    objSize = ObjectSize.ShrinkWholeSize;
                }
            }
            else if (objSize == ObjectSize.ShrinkMarginSize)
            {
                if (Direction == "Left")
                {
                    objSize = ObjectSize.ShrinkWholeSize;
                }
            }
            else
            {
                objSize = ObjectSize.OriginalSize;
            }
        }

        private void SetCurrentObjSizeExtend(string Driection)
        {
            if (objSize == ObjectSize.ShrinkWholeSize)
            {
                if (Direction == "Left")
                {
                    objSize = ObjectSize.ShrinkMarginSize;
                }
                else if (Direction == "Right")
                {
                    objSize = ObjectSize.ShrinkNoneMarginSize;
                }
            }
            else if (objSize == ObjectSize.ShrinkNoneMarginSize || objSize == ObjectSize.ShrinkMarginSize)
            {
                objSize = ObjectSize.OriginalSize;
            }
        }

        private void GetTargetSizeAndPos(ObjectSize objectsize, ref double size, ref double pos)
        {
            int oriSize = 460;
            int shrSize = 260;
            int shrWholeSize = 60;
            int marginValue = 200;

            if (GlobalFunction.isSolutionUsing4K)
            {
                oriSize *= 2;
                shrSize *= 2;
                shrWholeSize *= 2;
                marginValue *= 2;
            }

            if (objectsize == ObjectSize.OriginalSize)
            {
                size = oriSize;
                pos = ThisMarginLeft;
            }
            else if (objectsize == ObjectSize.ShrinkNoneMarginSize)
            {
                size = shrSize;
                pos = ThisMarginLeft;
            }
            else if (objectsize == ObjectSize.ShrinkMarginSize)
            {
                size = shrSize;
                pos = ThisMarginLeft + marginValue;
            }
            else if (objectsize == ObjectSize.ShrinkWholeSize)
            {
                size = shrWholeSize;
                pos = ThisMarginLeft + marginValue;
            }
        }
        #region 兩旁縮小動畫
        /// <summary>
        /// 1.下方區塊先縮小(0.2) 
        /// 2.上方區塊由下往上升起(0.1)
        /// 3.如果今天是縮小一次的狀態則call Detailviewer to changed opacity(0.1)
        /// </summary>
        /// <param name="Direction">相對於被點擊物件的位置方向</param>
        public void ShrinkFunction(string Direction)
        {
            Storyboard Mystoryboard = new Storyboard();
            this.textblock.Foreground = TextBlockShrinkColor;

            SetCurrentObjSizeShrink(Direction);
            if (this.BlockControlMode != ControlMode.Clip)
            {
                this.BlockControlMode = ControlMode.Clip;

                //縮第一次
                Mystoryboard = SetShrinkChangeAnimation(MyStoryBoardTimeL, objSize, Direction);
                Mystoryboard.Completed += new EventHandler(EventContainerShrink_Complete);
                this.textblock.Opacity = 1;
                this.BorderUp.Opacity = 1;
                Mystoryboard.Begin();
            }
            else if (this.BlockControlMode == ControlMode.Clip)
            {
                //縮第二次
                this.BlockControlMode = ControlMode.MinStatus;

                Mystoryboard = SetShrinkChangeAnimation(MyStoryBoardTimeS, objSize, Direction);
                this.textblock.Opacity = 0;
                this.BorderUp.Opacity = 0;

                Mystoryboard.Begin();
            }
        }

        private void EventContainerShrink_Complete(object sender, EventArgs e)
        {
            Storyboard MystoryboardUp = new Storyboard();

            MystoryboardUp = ObjectAnimationToShow(MyStoryBoardTimeL, this.BorderUp.Height, borderupheight, thumbnailPos);
            MystoryboardUp.Completed += new EventHandler(DetailViewerControlShow);
            MystoryboardUp.Begin();
        }

        private Storyboard SetShrinkChangeAnimation(int time, ObjectSize objectsize, string Direction)
        {
            Storyboard ResultStoryboard = new Storyboard();
            double size = 0;
            double pos = 0;

            GetTargetSizeAndPos(objectsize, ref size, ref pos);
            DoubleAnimation dbOffset = new DoubleAnimation()
            {
                Duration = TimeSpan.FromMilliseconds(time),
                EasingFunction = new ExponentialEase()
                {
                    EasingMode = EasingMode.EaseIn,
                    Exponent = 0.3
                },
                From = this.Width,
                To = size
            };

            ThicknessAnimation dbMargin = new ThicknessAnimation()
            {
                Duration = TimeSpan.FromMilliseconds(time),
                EasingFunction = new ExponentialEase()
                {
                    EasingMode = EasingMode.EaseIn,
                    Exponent = 0.3
                },
                From = this.Margin,
                To = new Thickness(pos, 0, 0, this.Margin.Bottom)
            };

            this.RenderTransformOrigin = new Point(0.5, 0.5);

            Storyboard.SetTarget(dbOffset, (DependencyObject)this);
            Storyboard.SetTargetProperty(dbOffset, new PropertyPath(Grid.WidthProperty));
            ResultStoryboard.Children.Add(dbOffset);

            Storyboard.SetTarget(dbMargin, (DependencyObject)this);
            Storyboard.SetTargetProperty(dbMargin, new PropertyPath(Grid.MarginProperty));
            ResultStoryboard.Children.Add(dbMargin);

            ResultStoryboard.FillBehavior = FillBehavior.HoldEnd;

            return ResultStoryboard;
        }

        #endregion

        private void EventContainerShrinkOneTime_Complete(object sender, EventArgs e)
        {
            this.textblock.Opacity = 1;
            this.BorderUp.Opacity = 1;
            DetailViewerControlShow(sender, e);
        }

        #region 回原始大小動畫
        public void ReturnToOriginalSize()
        {
            this.BlockControlMode = this.RecodeOriMode;
            //上方區塊變化
            Storyboard Mystoryboard = new Storyboard();

            this.IsUsing--;
            SetCurrentObjSizeShrink("");
            Mystoryboard = ObjectAnimationToHide(MyStoryBoardTimeL, this.BorderUp.Height, 0);
            Mystoryboard.Completed += new EventHandler(ReturnToOriginal_Complete);
            Mystoryboard.Begin();
        }

        private void ClearBorderUpChild()
        {
            Grid gd = BorderUp.Child as Grid;
            if (gd != null)
            {
                gd.Children.Clear();
            }
        }

        private void ReturnToOriginal_Complete(object sender, EventArgs e)
        {
            Storyboard Mystoryboard = new Storyboard();

            ClearBorderUpChild();
            Mystoryboard = SetOriginalChangeAnimation(MyStoryBoardTimeL, OriginalObjectWidth);
            Mystoryboard.Completed += new EventHandler(Mystoryboard_Completed);
            Mystoryboard.Begin();
        }
        #endregion

        #region 返回上一級大小
        /// <summary>
        /// 1.call Detailviewer to change opacity (0.1) 
        /// 2.上方區塊由上往下縮到消失~
        /// 3.時間軸縮回(0.1)
        /// </summary>
        /// <param name="Direction"></param>
        public void BackSize(string Direction)
        {
            Storyboard Mystoryboard = new Storyboard();
            this.Direction = Direction;

            SetCurrentObjSizeExtend(Direction);
            DetailViewerControlHide();

            if (this.BlockControlMode == ControlMode.MinStatus)
            {
                this.IsUsing--;
                //縮回第一次
                this.BlockControlMode = ControlMode.Clip;
                Mystoryboard = SetBackSizeChangeAnimation(MyStoryBoardTimeL, objSize, Direction, 420);
                Mystoryboard.Completed += new EventHandler(EventContainerShrinkOneTime_Complete);

                Mystoryboard.Begin();
            }
            else if (this.BlockControlMode == ControlMode.Clip)
            {
                this.IsUsing--;
                //縮回原始大小
                this.BlockControlMode = this.RecodeOriMode;

                ClearBorderUpChild();
                Mystoryboard = ObjectAnimationToHide(MyStoryBoardTimeL, this.BorderUp.Height, 0);
                Mystoryboard.Completed += new EventHandler(BorderUpHide_Complete);

                Mystoryboard.Begin();
            }
        }

        private void BorderUpHide_Complete(object sender, EventArgs e)
        {
            Storyboard Mystoryboard = new Storyboard();

            Mystoryboard = SetBackSizeChangeAnimation(MyStoryBoardTimeL, objSize, Direction, 100);
            Mystoryboard.Completed += new EventHandler(Mystoryboard_Completed);
            Mystoryboard.Begin();
        }

        private Storyboard ObjectAnimationToHide(int time, double from, double to)
        {
            Storyboard ResultStoryboard = new Storyboard();

            DoubleAnimation dbOffset = new DoubleAnimation()
            {
                Duration = TimeSpan.FromMilliseconds(time),
                EasingFunction = new CircleEase()
                {
                    EasingMode = EasingMode.EaseOut,
                },
                From = this.Width,
                To = to
            };

            ThicknessAnimation dbMargin = new ThicknessAnimation()
            {
                Duration = TimeSpan.FromMilliseconds(time),
                EasingFunction = new ExponentialEase()
                {
                    EasingMode = EasingMode.EaseOut,
                },
                From = new Thickness(this.BorderDown.Margin.Left, 0, 0, 0),
                To = new Thickness(this.BorderDown.Margin.Left, 0, 0, -borderdownheight)
            };

            Storyboard.SetTarget(dbOffset, this.BorderUp);
            Storyboard.SetTarget(dbMargin, this.BorderUp);
            Storyboard.SetTargetProperty(dbOffset, new PropertyPath(Grid.HeightProperty));
            Storyboard.SetTargetProperty(dbMargin, new PropertyPath(Grid.MarginProperty));
            ResultStoryboard.BeginTime = TimeSpan.FromMilliseconds(delayTime);
            ResultStoryboard.Children.Add(dbOffset);
            ResultStoryboard.Children.Add(dbMargin);
            ResultStoryboard.FillBehavior = FillBehavior.HoldEnd;

            return ResultStoryboard;
        }
        #endregion

        private Storyboard SetBackSizeChangeAnimation(int time, ObjectSize objectsize, string Direction, int delaytime)
        {
            Storyboard ResultStoryboard = new Storyboard();
            double size = 0.0;
            double pos = 0.0;

            GetTargetSizeAndPos(objectsize, ref size, ref pos);
            DoubleAnimation dbOffset = new DoubleAnimation()
            {
                Duration = TimeSpan.FromMilliseconds(time),
                EasingFunction = new ExponentialEase()
                {
                    EasingMode = EasingMode.EaseIn,
                    Exponent = 0.3
                },
                From = this.Width,
                To = size
            };

            ThicknessAnimation dbMargin = new ThicknessAnimation()
            {
                Duration = TimeSpan.FromMilliseconds(time),
                EasingFunction = new ExponentialEase()
                {
                    EasingMode = EasingMode.EaseIn,
                    Exponent = 0.3
                },
                From = this.Margin,
                To = new Thickness(pos, 0, 0, this.Margin.Bottom)
            };

            Storyboard.SetTarget(dbOffset, (DependencyObject)this);
            Storyboard.SetTargetProperty(dbOffset, new PropertyPath(Grid.WidthProperty));
            ResultStoryboard.Children.Add(dbOffset);

            Storyboard.SetTarget(dbMargin, (DependencyObject)this);
            Storyboard.SetTargetProperty(dbMargin, new PropertyPath(Grid.MarginProperty));
            ResultStoryboard.Children.Add(dbMargin);

            ResultStoryboard.BeginTime = TimeSpan.FromMilliseconds(delaytime);
            ResultStoryboard.FillBehavior = FillBehavior.HoldEnd;

            return ResultStoryboard;
        }

        private Storyboard SetOriginalChangeAnimation(int time, int ToValue)
        {
            Storyboard ResultStoryboard = new Storyboard();

            DoubleAnimation dbOffset = new DoubleAnimation()
            {
                Duration = TimeSpan.FromMilliseconds(time),
                EasingFunction = new ExponentialEase()
                {
                    EasingMode = EasingMode.EaseIn,
                    Exponent = 0.3
                },
                From = this.Width,
                To = ToValue
            };

            ThicknessAnimation dbMargin = new ThicknessAnimation()
            {
                Duration = TimeSpan.FromMilliseconds(time),
                EasingFunction = new ExponentialEase()
                {
                    EasingMode = EasingMode.EaseIn,
                    Exponent = 0.3
                },
                From = this.Margin,
                To = new Thickness(this.Margin.Left + Math.Abs(this.Width - ToValue) / 2, 0, 0, this.Margin.Bottom)
            };

            Storyboard.SetTarget(dbOffset, (DependencyObject)this);
            Storyboard.SetTarget(dbMargin, (DependencyObject)this);
            Storyboard.SetTargetProperty(dbOffset, new PropertyPath(Grid.WidthProperty));
            Storyboard.SetTargetProperty(dbMargin, new PropertyPath(Grid.MarginProperty));
            ResultStoryboard.Children.Add(dbOffset);
            ResultStoryboard.Children.Add(dbMargin);
            ResultStoryboard.BeginTime = TimeSpan.FromMilliseconds(delayTime);
            ResultStoryboard.FillBehavior = FillBehavior.HoldEnd;

            return ResultStoryboard;
        }
    }
}
