using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Windows.ApplicationModel.Resources.Core;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Controls;
using BasicLibrarySamples.View;
using Windows.UI.Xaml;

// The data model defined by this file serves as a representative example of a strongly-typed
// model that supports notification when members are added, removed, or modified.  The property
// names chosen coincide with data bindings in the standard item templates.
//
// Applications may use this model as a starting point and build on it, or discard it entirely and
// replace it with something appropriate to their needs.

namespace BasicLibrarySamples.Data
{
    /// <summary>
    /// Base class for <see cref="SampleDataItem"/> and <see cref="SampleDataGroup"/> that
    /// defines properties common to both.
    /// </summary>
    [Windows.Foundation.Metadata.WebHostHidden]
    public abstract class SampleDataCommon : BasicLibrarySamples.Common.BindableBase
    {
        private static Uri _baseUri = new Uri("ms-appx:///");

        public SampleDataCommon(String uniqueId, String title, String subtitle, String imagePath, String description)
        {
            this._uniqueId = uniqueId;
            this._title = title;
            this._subtitle = subtitle;
            this._description = description;
            this._imagePath = imagePath;
            this.Name = title;
        }

        private string _uniqueId = string.Empty;
        public string UniqueId
        {
            get { return this._uniqueId; }
            set { this.SetProperty(ref this._uniqueId, value); }
        }

        private string _title = string.Empty;
        public string Title
        {
            get { return this._title; }
            set { this.SetProperty(ref this._title, value); }
        }

        private string _subtitle = string.Empty;
        public string Subtitle
        {
            get { return this._subtitle; }
            set { this.SetProperty(ref this._subtitle, value); }
        }

        public string Name { get; set; }

        public DataTemplate Icon
        {
            get
            {
                object res;
                if (App.Current.Resources.TryGetValue("IconC1" + Name.Replace(" ", ""), out res))
                    return (DataTemplate)res;
                else
                {
                    res = App.Current.Resources["IconC1Gray"];
                    return (DataTemplate)res;
            }
                return App.Current.Resources.TryGetValue("IconC1" + Name.Replace(" ", ""), out res) ? (DataTemplate)res :
                    (DataTemplate)App.Current.Resources["IconC1Gray"];

                //return (DataTemplate)App.Current.Resources["IconC1" + Name.Replace(" ", "")] ?? (DataTemplate)App.Current.Resources["IconC1Gray"];
        }
        }

        private string _description = string.Empty;
        public string Description
        {
            get { return this._description; }
            set { this.SetProperty(ref this._description, value); }
        }

        private ImageSource _image = null;
        private String _imagePath = null;
        public ImageSource Image
        {
            get
            {
                if (this._image == null && this._imagePath != null)
                {
                    this._image = new BitmapImage(new Uri(SampleDataCommon._baseUri, this._imagePath));
                }
                return this._image;
            }

            set
            {
                this._imagePath = null;
                this.SetProperty(ref this._image, value);
            }
        }

        public void SetImage(String path)
        {
            this._image = null;
            this._imagePath = path;
            this.OnPropertyChanged("Image");
        }
    }

    /// <summary>
    /// Generic item data model.
    /// </summary>
    public class SampleDataItem : SampleDataCommon
    {
        public SampleDataItem(String uniqueId, String title, String subtitle, String imagePath, String description, UserControl sample, SampleDataGroup group)
            : base(uniqueId, title, subtitle, imagePath, description)
        {
            this._group = group;
            this._sample = sample;
        }

        UserControl _sample = null;
        public UserControl Sample
        {
            get { return this._sample; }
            set { this.SetProperty(ref this._sample, value); }
        }

        private SampleDataGroup _group;
        public SampleDataGroup Group
        {
            get { return this._group; }
            set { this.SetProperty(ref this._group, value); }
        }
    }

    /// <summary>
    /// Generic group data model.
    /// </summary>
    public class SampleDataGroup : SampleDataCommon
    {
        public SampleDataGroup(String uniqueId, String title, String subtitle, String imagePath, String description)
            : base(uniqueId, title, subtitle, imagePath, description)
        {
        }

        private ObservableCollection<SampleDataItem> _items = new ObservableCollection<SampleDataItem>();
        public ObservableCollection<SampleDataItem> Items
        {
            get { return this._items; }
        }
        
        public IEnumerable<SampleDataItem> TopItems
        {
            // Provides a subset of the full items collection to bind to from a GroupedItemsPage
            // for two reasons: GridView will not virtualize large items collections, and it
            // improves the user experience when browsing through groups with large numbers of
            // items.
            //
            // A maximum of 12 items are displayed because it results in filled grid columns
            // whether there are 1, 2, 3, 4, or 6 rows displayed
            get { return this._items.Take(12); }
        }
    }

    /// <summary>
    /// Creates a collection of groups and items with hard-coded content.
    /// </summary>
    public sealed class SampleDataSource
    {
        private static SampleDataSource _sampleDataSource = new SampleDataSource();

        private ObservableCollection<SampleDataGroup> _allGroups = new ObservableCollection<SampleDataGroup>();
        public ObservableCollection<SampleDataGroup> AllGroups
        {
            get { return this._allGroups; }
        }

        public static IEnumerable<SampleDataGroup> GetGroups(string uniqueId)
        {
            if (!uniqueId.Equals("AllGroups")) throw new ArgumentException("Only 'AllGroups' is supported as a collection of groups");
            
            return _sampleDataSource.AllGroups;
        }

        public static SampleDataGroup GetGroup(string uniqueId)
        {
            // Simple linear search is acceptable for small data sets
            var matches = _sampleDataSource.AllGroups.Where((group) => group.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }

        public static SampleDataItem GetItem(string uniqueId)
        {
            // Simple linear search is acceptable for small data sets
            var matches = _sampleDataSource.AllGroups.SelectMany(group => group.Items).Where((item) => item.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }

        public SampleDataSource()
        {
            var group_input = new SampleDataGroup("Input",
                    "Input Controls",
                    "Simple Input Made Easy",
                    "Assets/DarkGray.png",
                    "Provide smarter input for phone numbers, zip codes, percentages and more.");
            group_input.Items.Add(new SampleDataItem("MaskedTextBox",
                    "MaskedTextBox",
                    "Conform text to a given mask",
                    "Assets/LightGray.png",
                    "The C1MaskedTextBox control allows users to type text that conforms to a given mask.",
                    new MaskedTextBoxSample(),
                    group_input));
            group_input.Items.Add(new SampleDataItem("NumericBox",
                    "NumericBox",
                    "Format numeric values",
                    "Assets/DarkGray.png",
                    "The C1NumericBox control allows users to type formatted numeric values (use the UP/DOWN buttons to skip by an increment).",
                    new NumericBoxSample(),
                    group_input));
            group_input.Items.Add(new SampleDataItem("DropDown",
                    "DropDown",
                    "Custom drop-down controls.",
                    "Assets/LightGray.png",
                    "Host any UIElement in a drop-down with the C1DropDown control.",
                    new DropDownDemo(),
                    group_input));
            group_input.Items.Add(new SampleDataItem("HierarchicalDropDown",
                    "Hierarchical Tree",
                    "Displays a hierarchical drop-down.",
                    "Assets/LightGray.png",
                    "Create a hierarchical drop-down combobox by putting a C1TreeView control inside C1DropDown.",
                    new HierarchicalDropDown(),
                    group_input));
            group_input.Items.Add(new SampleDataItem("AutoComplete",
                    "AutoComplete",
                    "Create an auto-complete box with C1DropDown.",
                    "Assets/LightGray.png",
                    "Create an auto-complete textbox with the C1DropDown control.",
                    new AutoCompleteDropDown(),
                    group_input));
            
            var group_panels = new SampleDataGroup("Panels",
                    "Layout Panels",
                    "Easy-to-use Panels for Arranging Content",
                    "Assets/DarkGray.png",
                    "Control the flow and positioning of the content in your Windows Store apps.");
            group_panels.Items.Add(new SampleDataItem("DockPanel",
                    "DockPanel",
                    "Dock content along the edges",
                    "Assets/LightGray.png",
                    "Dock content along the edges of your page using the C1DockPanel control.",
                    new DockPanelSample(),
                    group_panels));
            group_panels.Items.Add(new SampleDataItem("UniformGrid",
                    "UniformGrid",
                    "Display content neatly in a grid",
                    "Assets/LightGray.png",
                    "Display content neatly in a grid using the C1UniformGrid control.",
                    new UniformGridSample(),
                    group_panels));
            group_panels.Items.Add(new SampleDataItem("WrapPanel",
                    "WrapPanel",
                    "Wrap content vertically or horizontally",
                    "Assets/DarkGray.png",
                    "Wrap content vertically or horizontally using the C1WrapPanel control.",
                    new WrapPanelSample(),
                    group_panels));
            group_panels.Items.Add(new SampleDataItem("RadialPanel",
                   "RadialPanel",
                   "Display content in a circle",
                   "Assets/LightGray.png",
                   "Display content in a circle.",
                   new RadialPanelSample(),
                   group_panels));

            var group_tabs = new SampleDataGroup("Tabs",
                    "Tabs",
                    "High Performance ListBoxes for Every Scenario",
                    "Assets/DarkGray.png",
                    "Get two high performance controls for displaying lists of bound data.");
            group_tabs.Items.Add(new SampleDataItem("EntranceTab",
                   "TabControl",
                   "Switch between different pages of content.",
                   "Assets/LightGray.png",
                   "This demo shows how you can easily switch among multiple pages of content using a C1TabControl.",
                   new EntranceTab(),
                   group_tabs));
            group_tabs.Items.Add(new SampleDataItem("ClearStyleTabControl",
                   "Tab Placement",
                   "Switch between different pages of content.",
                   "Assets/LightGray.png",
                   "Align the tabs along any edge of the control.",
                   new ClearStyleTabControl(),
                   group_tabs));
            group_tabs.Items.Add(new SampleDataItem("TabControlSample",
                   "Close and Pin",
                   "Switch between different pages of content.",
                   "Assets/LightGray.png",
                   "This demo shows a classic looking tab control complete with close and pin buttons.",
                   new TabControlSample(),
                   group_tabs));

            var group_collectionview = new SampleDataGroup("C1CollectionView",
                    "C1CollectionView",
                    "ICollectionView implementation with a capability to sort, filter and group data",
                    "Assets/DarkGray.png",
                    "ICollectionView implementation with a capability to sort, filter and group data.");
            group_collectionview.Items.Add(new SampleDataItem("CollectionViewConditions",
                    "Conditions",
                    "Binding to C1CollectionView",
                    "Assets/LightGray.png",
                    "C1CollectionView implements the ICollectionView interface and provides live sorting, filtering and grouping for any list control.",
                    new CollectionViewConditions(),
                    group_collectionview));
            group_collectionview.Items.Add(new SampleDataItem("BindingToC1CollectionView",
                    "Grouping",
                    "Grouping with C1CollectionView",
                    "Assets/LightGray.png",
                    "This sample shows how to setup ListBox and GridView controls to work with C1CollectionView in the group mode.",
                    new BindingToC1CollectionView(),
                    group_collectionview));
            
            var group_listbox = new SampleDataGroup("ItemsControl",
                    "ItemsControl",
                    "Present a collection of items",
                    "Assets/DarkGray.png",
                    "Present a collection of items like a tree structure.");
            group_listbox.Items.Add(new SampleDataItem("ListBox",
                    "ListBox",
                    "High performance list box",
                    "Assets/LightGray.png",
                    "The C1ListBox control is a high performance list box that has zoom functionality built-in. Users can scale the list of items by intuitively pinching.",
                    new ListBoxSample(),
                    group_listbox));
            //group_listbox.Items.Add(new SampleDataItem("TileListBox",
            //        "TileListBox",
            //        "Display lists of items as tiles",
            //        "Assets/DarkGray.png",
            //        "The C1TileListBox control is a high performance list box that can arrange its items in both rows and columns to create tile displays. Both ComponentOne ListBox controls support incremental loading so you can infinitely load more items on demand as the user scrolls to the end of the list.",
            //        new TileListBoxSample(),
            //        group_listbox));
            

            var group_treeview = new SampleDataGroup("C1TreeView",
                    "TreeView",
                    "Show hierarchical lists of items.",
                    "Assets/DarkGray.png",
                    "Get a hierarchical view of your data items with C1TreeView.");
            group_treeview.Items.Add(new SampleDataItem("TreeView",
                     "TreeView",
                     "Easy-to-use for hierarchical data",
                     "Assets/LightGray.png",
                     "The familiar TreeView UI is now available for Windows Store apps with the C1TreeView control.",
                     new TreeViewSample(),
                     group_treeview));

            var group_menus = new SampleDataGroup("Menu",
                    "Menus",
                    "Present different menu types",
                    "Assets/DarkGray.png",
                    "Present different menu types.");
            group_menus.Items.Add(new SampleDataItem("Menu",
                    "Menu",
                    "Easy-to-use for hierarchical data",
                    "Assets/LightGray.png",
                    "Represents a control that displays hierarchical data in a menu structure.",
                    new MenuSample(),
                    group_menus));
            group_menus.Items.Add(new SampleDataItem("ContextMenu",
                    "ContextMenu",
                    "Easy-to-use for hierarchical data",
                    "Assets/LightGray.png",
                    "Represents a control that displays hierarchical context menu.",
                    new ContextMenu(),
                    group_menus));
            group_menus.Items.Add(new SampleDataItem("RadialMenu",
                    "RadialMenu",
                    "Touch-friendly radial menu",
                    "Assets/LightGray.png",
                    "Represents a control that displays hierarchical data in a touch-friendly menu.",
                    new RadialMenu(),
                    group_menus));

            var group_inputhandling = new SampleDataGroup("Other",
                    "Other",
                    "Handle mouse and touch gestures",
                    "Assets/DarkGray.png",
                    "Other controls that fit no category.");
            group_inputhandling.Items.Add(new SampleDataItem("ProgressIndicator",
                    "Progress Indicator",
                    "Indicates a busy UI.",
                    "Assets/DarkGray.png",
                    "Indicate to the user that your app is busy with the C1ProgressIndicator control.",
                    new ProgressIndicatorDemo(),
                    group_inputhandling));
            group_inputhandling.Items.Add(new SampleDataItem("InputHandling",
                    "Input Handling",
                    "Handle mouse and touch gestures",
                    "Assets/DarkGray.png",
                    "Show how to handle drag and zoom gestures using cross-platform helpers.",
                    new InputHandling(),
                    group_inputhandling));
            group_inputhandling.Items.Add(new SampleDataItem("RangeSlider",
                    "RangeSlider",
                    "Indicates a RangeSlider",
                    "Assets/DarkGray.png",
                    "Represent a RangeSlider",
                    new RangeSlider(),
                    group_inputhandling));
            group_inputhandling.Items.Add(new SampleDataItem("GridSplitter",
                    "GridSplitter",
                    "Grid splitter",
                    "Assets/LightGray.png",
                    "Use grid splitter to redestribute the space between grid rows and columns.",
                    new GridSplitterSample(),
                    group_inputhandling));


            this.AllGroups.Add(group_collectionview);
            this.AllGroups.Add(group_input);
            this.AllGroups.Add(group_menus);
            this.AllGroups.Add(group_tabs);
            this.AllGroups.Add(group_treeview);
            this.AllGroups.Add(group_listbox);
            this.AllGroups.Add(group_panels);
            this.AllGroups.Add(group_inputhandling);
        }
    }
}
