using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using Telerik.Web.UI.Skins;
using Telerik.Web.UI;


public class GridSettingsPersister
{
    /// <summary>
    /// Initializes an instance of GridSettingsPersister from a RadGrid instance
    /// </summary>
    /// <param name="grid">The RadGrid instance to import and exports settings</param>
    public GridSettingsPersister(Telerik.Web.UI.RadGrid grid)
        : this(grid, GridSettingsType.All)
    {

    }

    /// <summary>
    /// Initializes an instance of GridSettingsPersister from a RadGrid instance
    /// and a collection GridSettingsType values
    /// </summary>
    /// <param name="grid">The RadGrid instance to import and exports settings</param>
    /// <param name="persistedSettings">
    /// A collection of GridSettingType values specifying the type of grid settings
    /// to import or export
    /// </param>
    public GridSettingsPersister(Telerik.Web.UI.RadGrid grid, GridSettingsType persistedSettingFlags)
    {
        _grid = grid;
        _persistedSettingTypes = persistedSettingFlags;
        _settings = new GridSettingsCollection();
        _settings.ColumnSettings = new List<ColumnSettings>();
        _settings.AutoGeneratedColumnSettings = new List<ColumnSettings>();
    }

    private Telerik.Web.UI.RadGrid _grid;
    private GridSettingsType _persistedSettingTypes;
    private GridSettingsCollection _settings;

    /// <summary>
    /// The underlyiong RadGrid instance to import or export settings from
    /// </summary>
    public Telerik.Web.UI.RadGrid Grid
    {
        get { return _grid; }
    }

    /// <summary>
    /// Gets or sets the GridSettingType flags that specify the grid settings to 
    /// export or import
    /// </summary>
    public virtual GridSettingsType PersistedSettingTypes
    {
        get { return _persistedSettingTypes; }
        set { _persistedSettingTypes = value; }
    }

    protected virtual GridSettingsCollection Settings
    {
        get { return _settings; }
        set { _settings = value; }
    }

    /// <summary>
    /// Saves the current grid settings and returns the settings serilized to string
    /// </summary>
    public virtual string SaveSettings()
    {
        return GetSavedSettings().ToString();
    }

    /// <summary>
    /// Saves the current grid settings and retrieves the underlying
    /// GridSettingsCollection instance that contains the grid settings
    /// </summary>
    public virtual GridSettingsCollection GetSavedSettings()
    {
        if (Grid == null)
        {
            throw new NullReferenceException();
        }

        if (IsSettingSpecified(GridSettingsType.Paging)) SavePagingSettings();
        if (IsSettingSpecified(GridSettingsType.Grouping)) SaveGroupByExpressions();
        if (IsSettingSpecified(GridSettingsType.Sorting)) SaveSortExpressions();
        if (IsSettingSpecified(GridSettingsType.Filtering)) SaveFilterExpression();
        if (IsSettingSpecified(GridSettingsType.ColumnSettings)) SaveColumnSettings();

        return Settings;
    }

    protected bool IsSettingSpecified(GridSettingsType settingType)
    {
        return (PersistedSettingTypes & GridSettingsType.All) == GridSettingsType.All ||
               (PersistedSettingTypes & settingType) == settingType;
    }

    protected virtual void SavePagingSettings()
    {
        Settings.PageSize = Grid.MasterTableView.PageSize;
    }

    protected virtual void SaveGroupByExpressions()
    {
        Settings.GroupByExpressionsStates = new object[Grid.MasterTableView.GroupByExpressions.Count];
        for (int i = 0; i < Settings.GroupByExpressionsStates.Length; i++)
        {
            Settings.GroupByExpressionsStates[i] = ((IStateManager)Grid.MasterTableView.GroupByExpressions[i]).SaveViewState();
        }
    }

    protected virtual void SaveSortExpressions()
    {
        Settings.SortExpressionsState = ((IStateManager)Grid.MasterTableView.SortExpressions).SaveViewState();
    }

    protected virtual void SaveFilterExpression()
    {
        Settings.FilterExpression = Grid.MasterTableView.FilterExpression;
    }

    protected virtual void SaveColumnSettings()
    {
        Settings.ColumnSettings.Clear();
        foreach (GridColumn column in Grid.MasterTableView.Columns)
        {
            Settings.ColumnSettings.Add(GetColumnSettings(column));
        }

        Settings.AutoGeneratedColumnSettings.Clear();
        foreach (GridColumn column in Grid.MasterTableView.AutoGeneratedColumns)
        {
            Settings.AutoGeneratedColumnSettings.Add(GetColumnSettings(column));
        }
    }

    private ColumnSettings GetColumnSettings(GridColumn column)
    {
        ColumnSettings colSettings = new ColumnSettings();
        colSettings.UniqueName = column.UniqueName;
       //
        colSettings.Visible = column.Visible;
        colSettings.Display = column.Display;
        colSettings.OrderIndex = column.OrderIndex;
        colSettings.CurrentFilterFunction = column.CurrentFilterFunction;
        colSettings.CurrentFilterValue = column.CurrentFilterValue;

        return colSettings;
    }

    private void SetColumnSettings(ref GridColumn column, ColumnSettings setting)
    {
        column.Display = setting.Display;
        column.Visible = setting.Visible;
        //
        column.OrderIndex = setting.OrderIndex;
        column.CurrentFilterFunction = setting.CurrentFilterFunction;
        column.CurrentFilterValue = setting.CurrentFilterValue;
    }

    /// <summary>
    /// Loads grids settings from a serialized string
    /// </summary>
    /// <param name="value">The string that contains the serialized settings</param>
    public virtual void LoadSettings(string value)
    {
        LoadSettings(GridSettingsCollection.LoadFromSerializedData(value));
    }

    /// <summary>
    /// Loads grids settings from a byte array
    /// </summary>
    /// <param name="data">The byte array that contains the serialized grid settings</param>
    public virtual void LoadSettings(byte[] data)
    {
        LoadSettings(GridSettingsCollection.LoadFromSerializedData(data));
    }

    /// <summary>
    /// Loads grid settings from a GridSettingsCollection instance
    /// </summary>
    /// <param name="settings">The GridSettingsCollection instance to load settings from</param>
    public virtual void LoadSettings(GridSettingsCollection settings)
    {
        if (Grid == null || settings == null)
        {
            throw new NullReferenceException();
        }

        Settings = settings;

        if (IsSettingSpecified(GridSettingsType.Paging)) LoadPagingSettings();
        if (IsSettingSpecified(GridSettingsType.Grouping)) LoadGroupByExpressions();
        if (IsSettingSpecified(GridSettingsType.Sorting)) LoadSortExpressions();
        if (IsSettingSpecified(GridSettingsType.Filtering)) LoadFilterExpression();
        if (IsSettingSpecified(GridSettingsType.ColumnSettings)) LoadColumnSettings();
    }

    protected virtual void LoadPagingSettings()
    {
        if (Grid.MasterTableView.AllowPaging && Settings.PageSize > 0)
        {
            Grid.MasterTableView.PageSize = Settings.PageSize;
        }
    }

    protected virtual void LoadGroupByExpressions()
    {
        if (Settings.GroupByExpressionsStates == null) return;

        Grid.MasterTableView.GroupByExpressions.Clear();
        foreach (object expressionState in Settings.GroupByExpressionsStates)
        {
            GridGroupByExpression expression = new GridGroupByExpression();
            ((IStateManager)expression).LoadViewState(expressionState);
            Grid.MasterTableView.GroupByExpressions.Add(expression);
        }
    }

    protected virtual void LoadSortExpressions()
    {
        if (Settings.SortExpressionsState == null) return;

        ((IStateManager)Grid.MasterTableView.SortExpressions).LoadViewState(Settings.SortExpressionsState);
    }

    protected virtual void LoadFilterExpression()
    {
        Grid.MasterTableView.FilterExpression = Settings.FilterExpression;
    }

    protected virtual void LoadColumnSettings()
    {
        if (Settings.AutoGeneratedColumnSettings.Count > 0)
        {
            Grid.ColumnCreated += new GridColumnCreatedEventHandler(Grid_ColumnCreated);
        }

        foreach (ColumnSettings colSetting in Settings.ColumnSettings)
        {
            GridColumn column = Grid.MasterTableView.GetColumnSafe(colSetting.UniqueName);

            if (column != null)
            {
                SetColumnSettings(ref column, colSetting);
            }
        }
    }

    private void Grid_ColumnCreated(object sender, GridColumnCreatedEventArgs e)
    {
        ColumnSettings settings = Settings.AutoGeneratedColumnSettings.Find(delegate(ColumnSettings set)
        {
            return set.UniqueName == e.Column.UniqueName;
        });
        GridColumn column = e.Column;

        if (settings != null)
        {
            SetColumnSettings(ref column, settings);
        }
    }
}
