using C1.Xaml;
using C1.Xaml.FlexGrid;
using C1.Xaml.InputPanel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Windows.Input;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace InputPanelSamples
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class IntegrationC1FlexGrid : Page
    {
        MyCellFactory _cellFactory;

        private ICommand viewDetailCommand;
        public ICommand ViewDetailCommand
        {
            get
            {
                return viewDetailCommand ?? (viewDetailCommand = new DelegateCommand(() => NavigateToDetails(), FlexGrid.SelectedItem!=null));
            }
        }

        public IntegrationC1FlexGrid()
        {
            InitializeComponent();
            if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
            {               
                IntegrationToC1FlexGrid();
                this.DataContext = this;
            }
            else
            {
                InitalizeFlexGrid();
            }
        }       

        void IntegrationToC1FlexGrid()
        {
            var list = Data.LoadEmployee();
            FlexGrid.ItemsSource = new Data().EmployeeObservable;
            FlexGrid.SelectionMode = C1.Xaml.FlexGrid.SelectionMode.Row;
            FlexGrid.SelectedIndex = 0;    
        }     

        void InitalizeFlexGrid()
        {
            var list = Data.Load();         
            FlexGrid.ItemsSource = new Data().CustomerObservable;
            FlexGrid.Loaded += FlexGrid_Loaded;
            FlexGrid.AllowMerging = AllowMerging.Cells;
            _cellFactory = new MyCellFactory();
            FlexGrid.CellFactory = _cellFactory;
            FlexGrid.SelectionChanging += FlexGrid_SelectionChanging;
            FlexGrid.SortedColumn += FlexGrid_SortedColumn;
            AddNewRowToFlexGrid(FlexGrid);
            FlexGrid.MergeManager = new MyMergeManager();
        }

        private void FlexGrid_Loaded(object sender, RoutedEventArgs e)
        {
            FlexGrid.AutoSizeColumns(1, FlexGrid.Columns.Count - 1, 10);          
        }

        private void NavigateToDetails()
        { 
            Employee employee = FlexGrid.SelectedItem as Employee;
            if (employee != null)
            {
                var frame = Window.Current.Content as Frame;
                if (frame != null)
                {
                    frame.Navigate(typeof(InputPanelCurrentItem), employee);
                }
                else
                {
                    this.Frame.Navigate(typeof(InputPanelCurrentItem), employee);
                }
            }
        }

        private void AddNewRowToFlexGrid(C1FlexGrid flexGrid)
        {
            for (int i = flexGrid.Rows.Count - 1; i >= 0; i = i - 1)
            {
                Row rw = new Row();
                rw.AllowMerging = true;
                flexGrid.Rows.Insert(i + 1, rw);
                rw.Height = 0.1;
            }
            _cellFactory.expandedList = new List<int>();
        }

        private void FlexGrid_SortedColumn(object sender, CellRangeEventArgs e)
        {
            C1FlexGrid flexGrid = sender as C1FlexGrid;
            AddNewRowToFlexGrid(flexGrid);
        }

        private void FlexGrid_SelectionChanging(object sender, CellRangeEventArgs e)
        {
            C1InputPanel inputPanel = null;
            GetInputPanelElement(e.Panel, ref inputPanel);
            if (inputPanel != null && e.CellRange.Row % 2 == 1)
            {
                e.Cancel = true;
            }
        }

        void GetInputPanelElement(DependencyObject obj, ref C1InputPanel element)
        {
            if (obj != null)
            {
                int count = VisualTreeHelper.GetChildrenCount(obj);
                for (int i = 0; i < count; i++)
                {
                    var child = VisualTreeHelper.GetChild(obj, i);
                    var inputPanel = child as C1InputPanel;
                    if (inputPanel != null)
                    {
                        element = inputPanel;
                        break;
                    }
                    else
                    {
                        GetInputPanelElement(child, ref element);
                    }
                }
            }
        }
    }

    public class MyMergeManager : IMergeManager
    {
        public CellRange GetMergedRange(C1FlexGrid grid, CellType cellType, CellRange range)
        {
            if (grid.Rows[range.Row].DataItem == null)
                if (cellType == CellType.Cell && range.Column >= 0 && range.Column < grid.Columns.Count)
                {
                    range.Column = 0;
                    range.Column2 = grid.Columns.Count - 1;
                }
            return range;
        }
    }

    public class MyCellFactory : CellFactory
    {
        Row _gr;
        C1FlexGrid _fg;
        static ImageSource _bmpExpanded, _bmpCollapsed;
        public List<int> expandedList = new List<int>();

        public MyCellFactory()
        {
            _bmpExpanded = ImageCell.GetImageSource("Expanded.png");
            _bmpCollapsed = ImageCell.GetImageSource("Collapsed.png");
        }

        public override void CreateCellContent(C1FlexGrid grid, Border bdr, CellRange rng)
        {
            base.CreateCellContent(grid, bdr, rng);
            if (_fg == null)
                _fg = grid;

            if (_fg.Rows[rng.Row].DataItem != null)
            {
                if (rng.Column == 0)
                {
                    Customer customer = (grid.Rows[rng.Row].DataItem as Customer);

                    if (customer != null)
                    {
                        bdr.Child = null;
                        Image _nodeImage;
                        _gr = grid.Rows[rng.Row];
                        _nodeImage = new Image();

                        if (expandedList.Contains(rng.Row))
                            _nodeImage.Source = _bmpExpanded;
                        else
                            _nodeImage.Source = _bmpCollapsed;

                        _nodeImage.Width = _nodeImage.Height = 9;
                        _nodeImage.VerticalAlignment = VerticalAlignment.Center;
                        _nodeImage.Stretch = Stretch.None;
                        bdr.Child = _nodeImage;
                        _nodeImage.PointerPressed += _nodeImage_PointerPressed;
                    }
                    else
                    {
                        expandedList.Remove(rng.Row);
                        _fg.Rows[rng.Row + 1].Height = 0.1;
                    }
                }
            }
            else if (rng.Column == 0 && rng.ColumnSpan > 1)
            {
                Customer customer = (grid.Rows[rng.Row - 1].DataItem as Customer);
                C1InputPanel panel = new C1InputPanel();
                panel.Tapped += (s, e) =>
                {
                    e.Handled = true;
                };
                panel.CurrentItem = customer;
                grid.Rows[rng.Row].Tag = grid.Rows[rng.Row - 1].ActualHeight * (grid.Columns.Count + 1) * 1.4;
                bdr.Child = panel;
                bdr.Padding = new Thickness(1);
                grid.Rows[rng.Row].IsReadOnly = true;
            }
        }

        #region Handle Mouse Down event for toggling the expand/Collapse icon and change the visibility of Child Row
        void _nodeImage_PointerPressed(object sender, PointerRoutedEventArgs e)
        {
            int _row = Grid.GetRow(((VisualTreeHelper.GetParent(e.OriginalSource as Image) as Border)));
            SetExpandCollapse(_row, sender);
        }

        public void SetExpandCollapse(int _row, object sender)
        {
            var image = sender as Image;
            if (expandedList.Contains(_row))
            {
                _fg.Rows[_row + 1].Height = 0.1;
                expandedList.Remove(_row);
                image.Source = _bmpCollapsed;
            }
            else
            {
                if (_fg.Rows[_row + 1].Tag != null)
                {
                    _fg.Rows[_row + 1].Height = double.Parse(_fg.Rows[_row + 1].Tag.ToString());
                }
                expandedList.Add(_row);
                image.Source = _bmpExpanded;
            }
        }

        #endregion
    }

    public abstract class ImageCell : StackPanel
    {
        ImageSource _imgSrc;

        public ImageCell(Row row)
        {
            if (_imgSrc == null)
            {
                _imgSrc = GetImageSource(GetImageResourceName());
            }
            Orientation = Orientation.Horizontal;
            var img = new Image();
            img.Source = _imgSrc;
            img.Width = 25;
            img.Height = 15;
            img.VerticalAlignment = VerticalAlignment.Center;
            img.Stretch = Stretch.None;
            Children.Add(img);
        }

        public abstract string GetImageResourceName();

        public static ImageSource GetImageSource(string imageName)
        {
            System.Uri _baseUri = new System.Uri("ms-appx:///InputPanelSamplesLib/");
            return new BitmapImage(new System.Uri(_baseUri, string.Format("Assets/{0}", imageName)));
        }
    }   
}
