using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Telerik.Web.UI;
using System.Collections;
using System.IO;


/// <summary>
/// Load and save grid settings just like PASS!!
/// </summary>

[Serializable]
public class GridSettings
{
    private GridTableView gridInstance;

    public GridSettings(GridTableView gridInstance)
    {
        this.gridInstance = gridInstance;
    }

    //this method should be called on Render 
    public string SaveSettings()
    {
        
        object[] gridSettings = new object[7];
        

        //Save groupBy
        GridGroupByExpressionCollection groupByExpressions = gridInstance.GroupByExpressions;
        object[] groupExpressions = new object[groupByExpressions.Count];
        

        int count = 0;
        foreach (GridGroupByExpression expression in groupByExpressions)
        {
            groupExpressions[count] = ((IStateManager)expression).SaveViewState();
            count++;
        }

        gridSettings[0] = groupExpressions;

        //Save sort expressions
        gridSettings[1] = ((IStateManager)gridInstance.SortExpressions).SaveViewState();

        //Save columns order
        int columnsLength = gridInstance.Columns.Count +
         gridInstance.AutoGeneratedColumns.Length;

        Pair[] columnOrder = new Pair[columnsLength];
        ArrayList visibleColumns = new ArrayList(columnsLength);

        ArrayList allColumns = new ArrayList(columnsLength);

        allColumns.AddRange(gridInstance.Columns);
        allColumns.AddRange(gridInstance.AutoGeneratedColumns);

        int i = 0;
        foreach (GridColumn column in allColumns)
        {
            Pair p = new Pair();
            p.First = column.OrderIndex;
            p.Second = column.HeaderStyle.Width;

            columnOrder[i] = p;
            visibleColumns.Add(column.Visible);

            i++;
        }

        gridSettings[2] = columnOrder;

        //Save filter expression
        gridSettings[3] = (object)gridInstance.FilterExpression;

        //Save visible columns
        gridSettings[4] = visibleColumns;

        //Save expanded state
        Hashtable _ordersExpandedState = new Hashtable();
        foreach(GridDataItem item in gridInstance.Items)
        {
            if (item.Expanded)
                _ordersExpandedState[item.ItemIndexHierarchical] = true;
            else
            {
                _ordersExpandedState.Remove(item.ItemIndexHierarchical);
                this.ClearExpandedChildren(item.ItemIndexHierarchical, _ordersExpandedState);
            }
        }

        gridSettings[5] = _ordersExpandedState;

     
        ////Save child tables settings

        string[] indexes = new string[_ordersExpandedState.Keys.Count];
        _ordersExpandedState.Keys.CopyTo(indexes, 0);

        ArrayList arr = new ArrayList(indexes);
        arr.Sort();
        GridTableView childTable;

        Hashtable childTableSettings = new Hashtable();

        foreach (string key in arr)
        {
            bool value = (bool)_ordersExpandedState[key];
            if (value)
            {
                childTable = this.gridInstance.Items[key].ChildItem.NestedTableViews[0] as GridTableView;
                GridSettings childSettings = new GridSettings(childTable);
                string setting = childSettings.SaveSettings();
                childTableSettings[key] = setting;
            }
            else
            {
                childTableSettings.Remove(key);
            }
        }

        gridSettings[6] = childTableSettings;

        
        LosFormatter formatter = new LosFormatter();
        StringWriter writer = new StringWriter();
        formatter.Serialize(writer, gridSettings);

        return writer.ToString();

    }

    //this method should be called on PageInit
    public void LoadSettings(string settings)
    {
        if ((settings == "") || (settings == null))
            return;
        LosFormatter formatter = new LosFormatter();
        StringReader reader = new StringReader(settings);

        object[] gridSettings = (object[])formatter.Deserialize(reader);

        //Load groupBy
        GridGroupByExpressionCollection groupByExpressions = this.gridInstance.GroupByExpressions;
        groupByExpressions.Clear();

        object[] groupExpressionsState = (object[])gridSettings[0];

        int count = 0;
        foreach (object obj in groupExpressionsState)
        {
            GridGroupByExpression expression = new GridGroupByExpression();
            ((IStateManager)expression).LoadViewState(obj);
            groupByExpressions.Add(expression);
            count++;
        }

        //Load sort expressions
        this.gridInstance.SortExpressions.Clear();
        ((IStateManager)this.gridInstance.SortExpressions).LoadViewState(gridSettings[1]);

        //Load columns order
        int columnsLength = this.gridInstance.Columns.Count +
         this.gridInstance.AutoGeneratedColumns.Length;

        Pair[] columnOrder = (Pair[])gridSettings[2];
        ArrayList visibleCols = (ArrayList)gridSettings[4];

        if (columnsLength == columnOrder.Length)
        {
            ArrayList allColumns = new ArrayList(columnsLength);

            allColumns.AddRange(this.gridInstance.Columns);
            allColumns.AddRange(this.gridInstance.AutoGeneratedColumns);

            int i = 0;
            foreach (GridColumn column in allColumns)
            {
                column.OrderIndex = (int)columnOrder[i].First;
                column.HeaderStyle.Width = (Unit)columnOrder[i].Second;

                column.Visible = (bool)visibleCols[i];

                i++;
            }
        }

        //Load filter expression
        this.gridInstance.FilterExpression = (string)gridSettings[3];



    }

    public void LoadExpandedStates(string settings)
    {
        if ((settings == "") || (settings == null))
            return;
        LosFormatter formatter = new LosFormatter();
        StringReader reader = new StringReader(settings);

        object[] gridSettings = (object[])formatter.Deserialize(reader);

        //retain expanded items
        Hashtable _expandedStates = gridSettings[5] as Hashtable;
        Hashtable childTableSettings = gridSettings[6] as Hashtable;

        if (childTableSettings != null)
        {

            string[] indexes = new string[_expandedStates.Keys.Count];
            _expandedStates.Keys.CopyTo(indexes, 0);

            ArrayList arr = new ArrayList(indexes);
            arr.Sort();

            foreach (string key in arr)
            {
                bool value = (bool)_expandedStates[key];

                if (value)
                {
                    this.gridInstance.Items[key].Expanded = true;
                    GridSettings childSetting = new GridSettings((GridTableView)this.gridInstance.Items[key].ChildItem.NestedTableViews[0]);
                    childSetting.LoadSettings(childTableSettings[key].ToString());
                    ((GridTableView)this.gridInstance.Items[key].ChildItem.NestedTableViews[0]).Rebind();

                }
            }
        }
    }
    //Clear the state for all expanded children if a parent item is collapsed
    private void ClearExpandedChildren(string parentHierarchicalIndex, Hashtable ExpandedStates)
    {
        string[] indexes = new string[ExpandedStates.Keys.Count];
        ExpandedStates.Keys.CopyTo(indexes, 0);
        foreach (string index in indexes)
        {
            //all indexes of child items
            if (index.StartsWith(parentHierarchicalIndex + "_") ||
                index.StartsWith(parentHierarchicalIndex + ":"))
            {
                ExpandedStates.Remove(index);
            }
        }
    }
}


[Serializable]
public class Pet
{
    public Pet()
    {
        // default ctor required for serializer
    }

    private Hashtable _names = new Hashtable();
    public Hashtable Names
    {
        get { return _names; }
        set { _names = value; }
    }

    public void SavePetNames(GridTableView Grid, string GridName)
    {
        GridSettings settings = new GridSettings(Grid);
        string settingvalue = settings.SaveSettings();
        _names.Add(GridName, settingvalue);
    }

    
}
