using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using C1.Silverlight.DataGrid;
using C1.Silverlight.Data;
using System.Windows.Data;

namespace C1DataGrid_Demo2010
{
    public partial class AutoMerging : UserControl
    {
        public AutoMerging()
        {
            InitializeComponent();

            // handle merging when viewport changes
            grid.MergingCells += new EventHandler<DataGridMergingCellsEventArgs>(grid_MergingCells);

            cmbStrategy.Items.Add(MergeStrategy.None);
            cmbStrategy.Items.Add(MergeStrategy.Horizontal);
            cmbStrategy.Items.Add(MergeStrategy.HorizontalHierarchy);
            cmbStrategy.Items.Add(MergeStrategy.Vertical);
            cmbStrategy.Items.Add(MergeStrategy.VerticalHierarchy);
            //cmbStrategy.Items.Add(MergeStrategy.HorizontalExpandVertically);
            //cmbStrategy.Items.Add(MergeStrategy.VerticalExpandHorizontally);
            cmbStrategy.SelectedIndex = 1;

            cmbLines.Items.Add(DataGridGridLinesVisibility.All);
            cmbLines.Items.Add(DataGridGridLinesVisibility.Horizontal);
            cmbLines.Items.Add(DataGridGridLinesVisibility.Vertical);
            cmbLines.Items.Add(DataGridGridLinesVisibility.None);
            cmbLines.SetBinding(ComboBox.SelectedItemProperty, new Binding("GridLinesVisibility") { Mode = BindingMode.TwoWay, Source = grid });

            grid.CommittingEdit += (s, e) =>
            {
                var col = e.Column as DataGridBoundColumn;
                if (col == null) return;
                var row = e.Row;
                if (row.DataItem == null) return;

                FrameworkElement fe = new ContentControl();
                Binding b;
                b = new Binding(col.Binding.Path.Path);
                b.Converter = col.Binding.Converter;
                b.ConverterParameter = col.Binding.ConverterParameter;
                b.Source = row.DataItem;
                fe.SetBinding(FrameworkElement.TagProperty, b);
                var value = fe.Tag;

                var range = grid[row, col].Presenter.MergedRange;

                var rows = new List<DataGridRow>();
                foreach (var r in grid.Viewport.Rows)
                {
                    if (r.Index < range.TopLeftCell.Row.Index) continue;
                    if (range.BottomRightCell.Row.Index < r.Index) continue;
                    if (r.DataItem == null) continue;
                    rows.Add(r);
                }

                var cols = new List<DataGridBoundColumn>();
                foreach (var c in grid.Viewport.Columns)
                {
                    if (c.DisplayIndex < range.TopLeftCell.Column.DisplayIndex) continue;
                    if (range.BottomRightCell.Column.DisplayIndex < c.DisplayIndex) continue;
                    var bc = c as DataGridBoundColumn;
                    if (bc == null) continue;
                    cols.Add(bc);
                }

                foreach (var r in rows)
                {
                    foreach (var c in cols)
                    {
                        if (r == row && c == col) continue;

                        b = new Binding(c.Binding.Path.Path);
                        b.Mode = BindingMode.TwoWay;
                        b.Converter = c.Binding.Converter;
                        b.ConverterParameter = c.Binding.ConverterParameter;
                        b.Source = r.DataItem;

                        fe.SetBinding(FrameworkElement.TagProperty, b);
                        fe.Tag = value;
                    }
                }

                fe.ClearValue(FrameworkElement.TagProperty);
            };

            grid.ItemsSource = Data.GetData(false);
        }

        void grid_MergingCells(object sender, DataGridMergingCellsEventArgs e)
        {
            List<DataGridCellsRange> merges = new List<DataGridCellsRange>();
            switch (_mergeStrategy)
            {
                case MergeStrategy.Horizontal:
                    merges = MergingHelper.Merge(Orientation.Horizontal, grid.Viewport.Rows, grid.Viewport.Columns, false);
                    break;
                case MergeStrategy.HorizontalHierarchy:
                    merges = MergingHelper.Merge(Orientation.Horizontal, grid.Viewport.Rows, grid.Viewport.Columns, true);
                    break;
                //case MergeStrategy.HorizontalExpandVertically:
                //    merges = MergingHelper.Merge(Orientation.Horizontal, grid.Viewport.Rows, grid.Viewport.Columns, true, false);
                //    break;

                case MergeStrategy.Vertical:
                    merges = MergingHelper.Merge(Orientation.Vertical, grid.Viewport.Rows, grid.Viewport.Columns, false);
                    break;
                case MergeStrategy.VerticalHierarchy:
                    merges = MergingHelper.Merge(Orientation.Vertical, grid.Viewport.Rows, grid.Viewport.Columns, true);
                    break;
                //case MergeStrategy.VerticalExpandHorizontally:
                //    merges = MergingHelper.Merge(Orientation.Vertical, grid.Viewport.Rows, grid.Viewport.Columns, true, false);
                //    break;

                case MergeStrategy.None:
                default:
                    break;
            }

            // apply merges
            foreach (var range in merges)
            {
                e.Merge(range);
            }
        }

        MergeStrategy _mergeStrategy;
        public MergeStrategy MergeStrategy
        {
            get
            {
                return _mergeStrategy;
            }
            set
            {
                if (_mergeStrategy != value)
                {
                    _mergeStrategy = value;
                    grid.ReMerge();
                }
            }
        }

        private void cmbStrategy_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            MergeStrategy = (MergeStrategy)cmbStrategy.SelectedItem;
        }
    }

    public enum MergeStrategy
    {
        None,
        Horizontal,
        Vertical,
        HorizontalHierarchy,
        VerticalHierarchy,
        HorizontalExpandVertically,
        VerticalExpandHorizontally
    }

}
