using System;
using System.ComponentModel;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using C1.Silverlight.FlexGrid;

namespace C1.Silverlight.FlexGridExcel
{
    /// <summary>
    /// Undo/Redo stack for the C1FlexGrid.
    /// </summary>
    public class FlexUndoStack : UndoStack
    {
        //-------------------------------------------------------------------------
        #region ** fields

        C1FlexGrid _flex;
        bool _resizing = false;
        string _oldColumnLayout;
        object _oldValue;
        SortDescription[] _oldSortDescriptions;

        #endregion

        //-------------------------------------------------------------------------
        #region ** ctor

        /// <summary>
        /// Initializes a new instance of a <see cref="FlexUndoStack"/>.
        /// </summary>
        /// <param name="flex"><see cref="C1FlexGrid"/> that owns this undo stack.</param>
        public FlexUndoStack(C1FlexGrid flex)
        {
            _flex = flex;
            flex.PrepareCellForEdit += flex_PrepareCellForEdit;
            flex.CellEditEnded += _flex_CellEditEnded;
            flex.ResizingColumn += flex_ResizingColumn;
            flex.ResizedColumn += flex_ResizedColumn;
            flex.SortingColumn += flex_SortingColumn;
            flex.SortedColumn += flex_SortedColumn;
            flex.DraggingColumn += flex_DraggingColumn;
            flex.DraggedColumn += flex_DraggedColumn;
        }

        #endregion

        //-------------------------------------------------------------------------
        #region ** event handlers

        // record original column size
        void flex_ResizingColumn(object sender, CellRangeEventArgs e)
        {
            if (!_resizing)
            {
                _resizing = true;
                _oldColumnLayout = _flex.ColumnLayout;
            }
        }

        // add undoable column resized action
        void flex_ResizedColumn(object sender, CellRangeEventArgs e)
        {
            _resizing = false;
            try
            {
                var action = new ColumnAction(_flex, _oldColumnLayout);
                AddAction(action);
            }
            catch { }
        }

        // record original cell value
        void flex_PrepareCellForEdit(object sender, CellEditEventArgs e)
        {
            _oldValue = _flex[e.Row, e.Column];
        }

        // add undoable bound edit action
        void _flex_CellEditEnded(object sender, CellEditEventArgs e)
        {
            try
            {
                var action = new EditAction(sender, e, _oldValue);
                AddAction(action);
            }
            catch { }
        }

        // record original sort values
        void flex_SortingColumn(object sender, CellRangeEventArgs e)
        {
            if (_flex.CollectionView != null)
            {
                _oldSortDescriptions = new SortDescription[_flex.CollectionView.SortDescriptions.Count];
                _flex.CollectionView.SortDescriptions.CopyTo(_oldSortDescriptions, 0);
            }
        }

        //  add undoable sort column action
        void flex_SortedColumn(object sender, CellRangeEventArgs e)
        {
            try
            {
                var action = new SortAction(sender, _oldSortDescriptions);
                AddAction(action);
            }
            catch { }
        }

        // record original column positions
        void flex_DraggingColumn(object sender, CellRangeEventArgs e)
        {
            _oldColumnLayout = _flex.ColumnLayout;
        }

        // add undoable column drag
        void flex_DraggedColumn(object sender, CellRangeEventArgs e)
        {
            try
            {
                var action = new ColumnAction(_flex, _oldColumnLayout);
                AddAction(action);
            }
            catch { }
        }

        #endregion
    }
}
