using C1.Xaml;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using Windows.UI.Xaml;

namespace ControlExplorer
{
    public class ViewModel : INotifyPropertyChanged
    {
        #region Singleton implementation

        public static ViewModel Instance { get; private set; }

        static ViewModel()
        {
            Instance = new ViewModel();
        }

        #endregion

        public List<ControlViewModel> Controls { get; set; }
        public ObservableCollection<CategoryViewModel> Categories { get; set; }


        public ViewModel()
        {
            Categories = new ObservableCollection<CategoryViewModel>();
            Controls = new List<ControlViewModel>();
            ControlsVersion = typeof(C1.Xaml.C1TextBoxBase).AssemblyQualifiedName.Split(',')[2].Replace(" Version=", "");

            // fill controls data
            #region Data

            Controls.Add(new ControlViewModel("BarCode")
            {
                Samples =
                {
                    new SampleViewModel { Title = "", CreateDemo = ()=> new ControlExplorer.Controls.BarCode.Generator(), Description = "" },
                },
                Categories = { ControlCat.all, ControlCat.data }
            });

            Controls.Add(new ControlViewModel("Calendar")
            {
                Samples =
                {
                    new SampleViewModel 
                    { 
                        Title = "default view",
                        CreateDemo = ()=> new ControlExplorer.Controls.Calendar.CalendarDemo(),
                        SampleIconKey = "calendarDefaultView",
                        Description = "Shows the C1Calendar control with default appearance options and some bolded dates.",
                    },
                    new SampleViewModel 
                    { 
                        Title = "bolded days",
                        CreateDemo = ()=> new ControlExplorer.Controls.Calendar.BoldedDayTemplate(),
                        SampleIconKey = "calendarBoldedDays",
                        Description = "The C1Calendar control allows to set custom DataTemplate to represent bolded days. Use C1Calendar.BoldedDaySlotTemplate property to alter appearance of all bolded days.",
                    },
                    //new SampleViewModel 
                    //{ 
                    //    Title = "custom days",
                    //    Demo = ()=> new ControlExplorer.Controls.Calendar.DaySlotTemplateSelector(),
                    //    Thumbnail = "calendarCustomDays",
                    //    Description = "Use DataTemplate selectors to customize calendar days. Supply custom appearance for weekends, today date, holidays or any other days.",
                    //},
                    new SampleViewModel 
                    { 
                        Title = "custom data",
                        CreateDemo = ()=> new ControlExplorer.Controls.Calendar.CustomData(),
                        SampleIconKey = "calendarCustomData",
                        Description = "Bind calendar to custom data and use custom BoldedDaySlotTemplate to show information about events. Double tap on day to review detailed information about events.",
                    },
              },
                Categories = { ControlCat.all, ControlCat.favorites }
            });
            Controls.Add(new ControlViewModel("Chart")
            {
                Samples =
                {
                    new SampleViewModel { Title = "gallery", CreateDemo = ()=> new ControlExplorer.Controls.Chart.Gallery(), SampleIconKey = "chartGallery", Description = "See all supported chart types including bar, column, pie, area, line and scatter." },
                    new SampleViewModel { Title = "labels", CreateDemo = ()=> new ControlExplorer.Controls.Chart.Labels(),  SampleIconKey = "chartLabels", Description = "See static values displayed as labels on each plot element." },
                    new SampleViewModel { Title = "markers", CreateDemo = ()=> new ControlExplorer.Controls.Chart.Markers(),  SampleIconKey = "chartMarkers", Description = "Interactive bound markers using the layers collection." },
                    new SampleViewModel { Title = "popup labels", CreateDemo = ()=> new ControlExplorer.Controls.Chart.PopupLabels(), SampleIconKey = "chartPopup", Description = "See values displayed as pop-ups when you tap a plot element." },
                    new SampleViewModel { Title = "pie spin", CreateDemo = ()=> new ControlExplorer.Controls.Chart.PieSpin(), SampleIconKey = "chartPieSpin", Description = "Shows a pie chart that spins around its center like a wheel." },
                    new SampleViewModel { Title = "selection", CreateDemo = ()=> new ControlExplorer.Controls.Chart.Selection(), SampleIconKey = "chartSelection", Description = "Selection support for data sources with ICollectionView." },
                    new SampleViewModel { Title = "interaction", CreateDemo = ()=> new ControlExplorer.Controls.Chart.InteractiveChart(), SampleIconKey = "chartInteraction", Description = "Zoom, scale and pan a large chart by touch." },
                    new SampleViewModel { Title = "financial", CreateDemo = ()=> new ControlExplorer.Controls.Chart.FinancialChart(), SampleIconKey = "chartFinancial", Description = "Shows a candle chart with High-Low -Open-Close data series." },
                    new SampleViewModel { Title = "dynamic", CreateDemo = ()=> new ControlExplorer.Controls.Chart.Dynamic(), SampleIconKey = "chartDynamic", Description = "Shows live data as it happens." },
                    //new SampleViewModel { Title = "legend checkbox", CreateDemo = ()=> new ControlExplorer.Controls.Chart.LegendCheckBox(), ThumbnailKey = "chartLegendCheckBox", Description = "Custom legend template with check box that controls series visibility." },
                    //new SampleViewModel { Title = "multiple axes", CreateDemo = ()=> new ControlExplorer.Controls.Chart.DependentAxes(), ThumbnailKey = "chartMultipleAxes", Description = "Display multiple, dependent Y-axes with different units of measure." },
                    new SampleViewModel { Title = "animation", CreateDemo = ()=> new ControlExplorer.Controls.Chart.Animation(), SampleIconKey = "chartAnimation", Description = "See plot elements animate on load." },
                    new SampleViewModel { Title = "aggregates", CreateDemo = ()=> new ControlExplorer.Controls.Chart.AggregateChart(), SampleIconKey = "chartAggregates", Description = "Built-in aggregation features allow you to quickly summarize data points." },
                },
                Categories = { ControlCat.all, ControlCat.favorites }
            });
            //Controls.Add(new ControlViewModel("ContextMenu")
            //{
            //    Samples =
            //    {
            //        new SampleViewModel { Title = "", CreateDemo = ()=> new ControlExplorer.Controls.ContextMenu.ContextMenuDemo(), Description = "" }
            //    },
            //    Categories = { ControlCat.all }
            //});
            //Controls.Add(new ControlViewModel("DateTimePicker")
            //{
            //    Samples =
            //    {
            //        new SampleViewModel { Title = "", CreateDemo = ()=> new ControlExplorer.Controls.DateTimePicker.DateTimePickerDemo(), Description = "" }
            //    },
            //    Categories = { ControlCat.all, ControlCat.input }
            //});
            Controls.Add(new ControlViewModel("Excel")
            {
                Samples =
                {
                    new SampleViewModel { Title = "", CreateDemo = ()=> new ControlExplorer.DemoExcel(), Description = "" },
                },
                Categories = { ControlCat.all, ControlCat.libraries }
            });
            Controls.Add(new ControlViewModel("FlexGrid")
            {
                Samples =
                {
                    new SampleViewModel { Title = "in action", CreateDemo = ()=> new ControlExplorer.Controls.FlexGrid.FlexGridDemo(), SampleIconKey = "flexgrid", Description = "See how to interact and select cells with FlexGrid." },
                    new SampleViewModel { Title = "editing", CreateDemo = ()=> new ControlExplorer.Controls.FlexGrid.Editing(), SampleIconKey = "flexgridEditing", Description = "See how to edit cells of mapped columns." },
                    new SampleViewModel { Title = "sorting & filtering", CreateDemo = ()=> new ControlExplorer.Controls.FlexGrid.SortingFiltering(), SampleIconKey = "flexgridSort", Description = "See how to implement filtering, sorting and even multiple column sorting using our API." },
                    new SampleViewModel { Title = "media library", CreateDemo = ()=> new ControlExplorer.Controls.FlexGrid.MediaLibrary(), SampleIconKey = "flexgridMedialibrary", Description = "See how to create custom cells using a Cell Factory." },
                },
                Categories = { ControlCat.all, ControlCat.favorites, ControlCat.data }
            });
            Controls.Add(new ControlViewModel("Gauges")
            {
                Samples =
                {
                    new SampleViewModel { Title = "radial", CreateDemo = ()=> new ControlExplorer.Controls.Gauge.RadialGauge(), SampleIconKey = "gaugeRadialGauge", Description = "See a basic radial gauge with ranges." },
                    new SampleViewModel { Title = "linear", CreateDemo = ()=> new ControlExplorer.Controls.Gauge.LinearGauge(), SampleIconKey = "gaugeLinearGauge", Description = "See a vertical linear gauge with ranges" },
                    new SampleViewModel { Title = "knob", CreateDemo = ()=> new ControlExplorer.Controls.Gauge.Knob(), SampleIconKey = "gaugeKnob", Description = "See an interactive knob gauge." },
                    new SampleViewModel { Title = "region knob", CreateDemo = ()=> new ControlExplorer.Controls.Gauge.RegionKnob(), SampleIconKey = "gaugeRegionKnob", Description = "See an interactive knob gauge with a customized appearance." },
                    new SampleViewModel { Title = "ruler", CreateDemo = ()=> new ControlExplorer.Controls.Gauge.RulerGauge(), SampleIconKey = "gaugeRulerGauge", Description = "See a simple linear gauge styled to look like a ruler." },
                    new SampleViewModel { Title = "speedometer", CreateDemo = ()=> new ControlExplorer.Controls.Gauge.SpeedometerGauge(), SampleIconKey = "gaugeSpeedometerGauge", Description = "See a styled speedometer gauge with animation." },
                    new SampleViewModel { Title = "volume", CreateDemo = ()=> new ControlExplorer.Controls.Gauge.VolumeGauge(), SampleIconKey = "gaugeVolumeGauge", Description = "See a rectangular fuel gauge with animation." }
                },
                Categories = { ControlCat.all, ControlCat.favorites, ControlCat.data }
            });
            Controls.Add(new ControlViewModel("Imaging")
            {
                Samples =
                {
                    new SampleViewModel { Title = "gif", CreateDemo = ()=> new ControlExplorer.Controls.Imaging.GifImages(), SampleIconKey = "imagingGif", Description = "Render animated GIF files using the C1GifImage class." },
                    new SampleViewModel { Title = "manipulation", CreateDemo = ()=> new ControlExplorer.Controls.Imaging.ImageManipulation(), SampleIconKey = "imagingManipulation", Description = "Crop and manipulate pictures using the C1Bitmap class." },
                },
                Categories = { ControlCat.all, ControlCat.libraries }
            });
            Controls.Add(new ControlViewModel("Input")
            {
                Samples =
                {
                    new SampleViewModel { Title = "masked", CreateDemo = ()=> new ControlExplorer.Controls.MaskedTextBox.MaskedTextBoxDemo(), SampleIconKey="inputMaskedTextBox", Description = "The C1MaskedTextBox control prevents users from entering invalid characters with masking." },
                    new SampleViewModel { Title = "numeric", CreateDemo = ()=> new ControlExplorer.Controls.NumericBox.NumericBoxDemo(), SampleIconKey="inputNumericBox", Description = "The C1NumericBox control displays and edits formatted values such as currencies and percentages." }
                },
                Categories = { ControlCat.all, ControlCat.input }
            });
            Controls.Add(new ControlViewModel("LayoutPanels")
            {
                Samples =
                {
                    new SampleViewModel { Title = "dock", CreateDemo = ()=> new ControlExplorer.Controls.LayoutPanels.DemoDockPanel(), SampleIconKey="layoutpanelsDock", Description = "Dock content along the top, left, right and bottom edges of the screen with the C1DockPanel control." },
                    new SampleViewModel { Title = "uniform", CreateDemo = ()=> new ControlExplorer.Controls.LayoutPanels.DemoUniformGrid(), SampleIconKey="layoutpanelsUniform", Description = "Neatly display child elements in columns and rows with the C1UniformGrid control." },
                    new SampleViewModel { Title = "wrap", CreateDemo = ()=> new ControlExplorer.Controls.LayoutPanels.DemoWrapPanel(), SampleIconKey="layoutpanelsWrap", Description = "Create flow type layouts that wrap content vertically or horizontally using the C1WrapPanel control." }
                },
                Categories = { ControlCat.all }
            });
            Controls.Add(new ControlViewModel("ListBox")
            {
                Samples =
                {
                    new SampleViewModel 
                    { 
                        Title = "flickr photo viewer",
                        CreateDemo = ()=> new ControlExplorer.Controls.ListBox.ListBoxSample(),
                        SampleIconKey = "listbox",
                        Description = "Displays a list of photos from flickr, which can be zoomed by pinching",
                    },
                    //new SampleViewModel 
                    //{ 
                    //    Title = "youtube video viewer",
                    //    CreateDemo = ()=> new ControlExplorer.TileListBoxSample(),
                    //    SampleIconKey = "tilelistbox",
                    //    Description = "Displays a list of videos from youtube in three columns",
                    //},
                },
                Categories = { ControlCat.all, ControlCat.data }
            });

            Controls.Add(new ControlViewModel("Maps")
            {
                Samples =
                {
                    new SampleViewModel { Title = "bing", CreateDemo = ()=> new ControlExplorer.Controls.Maps.DemoMaps(), SampleIconKey = "mapBing", Description = "Get smooth zooming, panning and mapping between screen and geographical coordinates." },
                    new SampleViewModel { Title = "layers", CreateDemo = ()=> new ControlExplorer.Controls.Maps.Layers(), SampleIconKey = "mapLayers", Description = "Superimpose your own custom elements to the maps." },
                    new SampleViewModel { Title = "custom tiles", CreateDemo = ()=> new ControlExplorer.Controls.Maps.CustomTiles(), SampleIconKey = "mapCustomTiles", Description = "Display map tiles from OpenStreetMap+." },
                    new SampleViewModel { Title = "kml", CreateDemo = ()=> new ControlExplorer.Controls.Maps.VectorMap(), SampleIconKey = "mapKml", Description = "Import common geographic files in KML and KMZ formats." },
                    new SampleViewModel { Title = "factories", CreateDemo = () => new ControlExplorer.Controls.Maps.Factories(), SampleIconKey = "mapFactories", Description = "Show how you can use VirtualLayer to display elements on the map control." },
                    new SampleViewModel { Title = "shape file", CreateDemo = () => new ControlExplorer.Controls.Maps.MapShape(), SampleIconKey = "mapShape", Description = "Import common geographic files in ShapeFile format." },
                },
                Categories = { ControlCat.all, ControlCat.favorites, ControlCat.data }
            });
            Controls.Add(new ControlViewModel("OrgChart")
            {
                Samples =
                {
                    new SampleViewModel { Title = "See it in action", CreateDemo = ()=> new ControlExplorer.Controls.OrgChart.OrgChartSample(), SampleIconKey="orgChartOverview", Description = "Create hierarchical diagrams that show relationships of your data." },
                    new SampleViewModel { Title = "Template Selector", CreateDemo = ()=> new ControlExplorer.Controls.OrgChart.TemplateSample(), SampleIconKey="orgChartTemplateSelector", Description = "Select different templates based on features of specific data items using a DataTemplateSelector." },
                    new SampleViewModel { Title = "Hierarchical Templates", CreateDemo = ()=> new ControlExplorer.Controls.OrgChart.HierarchicalSample(), SampleIconKey="orgChartHierarchicalSample", Description = "Use different templates for certain nodes using a HierarchialDataTemplate." },
                    new SampleViewModel { Title = "Collapse Expand", CreateDemo = ()=> new ControlExplorer.Controls.OrgChart.CollapseExpand(), SampleIconKey="orgChartCollapseExpand", Description = "Demonstrates binding elements to properties of the C1OrgChart to create collapsible nodes." },
                },
                Categories = { ControlCat.all, ControlCat.data }
            });
            Controls.Add(new ControlViewModel("Pdf")
            {
                Samples =
                {
                    new SampleViewModel { Title = "", CreateDemo = ()=> new ControlExplorer.Controls.Pdf.DemoPdf(), Description = "" },
                },
                Categories = { ControlCat.all, ControlCat.libraries }
            });
            Controls.Add(new ControlViewModel("PdfViewer")
            {
                Samples =
                {
                    new SampleViewModel { Title = "See in action", CreateDemo = ()=> new ControlExplorer.Controls.PdfViewer.DemoPDFViewer(), Description = "Display PDF documents in your Windows Store apps with ComponentOne PdfViewer for Windows phone",SampleIconKey = "IconC1PdfViewer"},
                    new SampleViewModel { Title = "Save PDF", CreateDemo = ()=> new ControlExplorer.Controls.PdfViewer.DemoSavePDF(), Description = "This demo shows how to save pdf to local and OneDrive from the C1PdfViewer control",SampleIconKey = "pdfviewerSave"},
                },
                Categories = { ControlCat.all, ControlCat.favorites }
            });
            Controls.Add(new ControlViewModel("RichTextBox")
            {
                Samples =
                {
                    new SampleViewModel { Title = "input", CreateDemo = ()=> new ControlExplorer.Controls.RichTextBox.DemoRichTextBox(), SampleIconKey = "richtextboxInput", Description = "Edit HTML or RTF text with support for common commands such as bold, italic and underline." },
                    new SampleViewModel { Title = "formatting", CreateDemo = ()=> new ControlExplorer.Controls.RichTextBox.RichTextBoxFormatting(), SampleIconKey = "richtextboxFormatting", Description = "Display formatted text as HTML or RTF with support for most common tags." },
                    new SampleViewModel { Title = "facebook feed", CreateDemo = ()=> new ControlExplorer.Controls.RichTextBox.FacebookRSS(), SampleIconKey = "richtextboxFacebookFeed", Description = "Display HTML content from RSS feeds such as Facebook and Twitter." },
                    new SampleViewModel { Title = "syntax highlight", CreateDemo = ()=> new ControlExplorer.Controls.RichTextBox.SyntaxHighlight(), SampleIconKey = "richtextboxSyntaxHightLight", Description = "Customize the control to look like a code editor." },
                },
                Categories = { ControlCat.all, ControlCat.favorites, ControlCat.input }
            });
            Controls.Add(new ControlViewModel("Sparkline")
            {
                Samples =
                {
                    new SampleViewModel { Title = "See it in action", CreateDemo = ()=> new ControlExplorer.Controls.Sparkline.SparklineSample(), SampleIconKey="sparkline", Description = "Shows how to create different types of sparkline." },
                    new SampleViewModel { Title = "Bound ListBox", CreateDemo = ()=> new ControlExplorer.Controls.Sparkline.RegionSales(), SampleIconKey="sparklineListBox", Description = "Shows sparklines in a data bound ListBox." },
                },
                Categories = { ControlCat.all, ControlCat.data }
            });
            Controls.Add(new ControlViewModel("Tiles")
            {
                Samples =
                {
                    new SampleViewModel 
                    { 
                        Title = "tile types",
                        CreateDemo = ()=> new ControlExplorer.Controls.Tile.TileTypes(),
                        SampleIconKey = "tiletypes",
                        Description = "Shows flipping and sliding tiles.",
                    },
                    new SampleViewModel 
                    { 
                        Title = "flickr tags",
                        CreateDemo = ()=> new ControlExplorer.Controls.Tile.ContentSourceSample(),
                        SampleIconKey = "flickrtags",
                        Description = "Shows tiles with ContentSource set",
                    },
                    new SampleViewModel 
                    { 
                        Title = "photo viewer",
                        CreateDemo = ()=> new ControlExplorer.Controls.Tile.ListBoxSample(),
                        SampleIconKey = "photoviewer",
                        Description = "Shows C1FlipTile control as ItemTemplate in the ListBox. Also demonstrates how to bind custom delegate command to C1Tile control",
                    },
                },
                Categories = { ControlCat.all, ControlCat.favorites }
            });

            Controls.Add(new ControlViewModel("TreeView")
            {
                Samples =
                {
                    new SampleViewModel { Title = "See it in action", CreateDemo = ()=> new ControlExplorer.Controls.TreeView.TreeViewSample(), SampleIconKey="treeview", Description = "Shows a hierarchical list of items in nodes that can be collapsed or expanded." },
                    //new SampleViewModel { Title = "Editable Nodes", CreateDemo = ()=> new ControlExplorer.Controls.TreeView.Edit(), SampleIconKey="inputMaskedTextBox", Description = "Add editing support to the nodes of the C1TreeView. You can press and hold the node to edit in touch mode." },
                    new SampleViewModel { Title = "Checkbox Nodes", CreateDemo = ()=> new ControlExplorer.Controls.TreeView.CheckBox(), SampleIconKey="treeviewCheckbox", Description = "Display check boxes on the nodes of the C1TreeView." },
                    //new SampleViewModel { Title = "Drag &amp; drop", CreateDemo = ()=> new ControlExplorer.Controls.TreeView.DragDrop(), SampleIconKey="inputMaskedTextBox", Description = "Shows built-in support for drag-and-drop operations. The Beta version supports drag-and-drop by mouse only." },
                    new SampleViewModel { Title = "Hierarchical Templates", CreateDemo = ()=> new ControlExplorer.Controls.TreeView.HierarchicalTemplate(), SampleIconKey="treeviewHierarchical", Description = "Support for Hierarchical Data Templates allows you to easily customize the appearance of the C1Treeview nodes based upon the data items." }
                },
                Categories = { ControlCat.all, ControlCat.favorites }
            });
            #endregion

            // fill categories
            foreach (var category in TypeEx.GetEnumValues<ControlCat>(typeof(ControlCat)))
            {
                var item = new CategoryViewModel() { Category = category };
                foreach (var control in Controls.Where(c => c.Categories.Contains(category)))
                {
                    item.Controls.Add(control);
                }
                Categories.Add(item);
            }
        }


        /// <summary>
        /// Gets or sets the version of the suite bein showcased.
        /// </summary>
        /// <value>The controls version.</value>
        public string ControlsVersion { get; set; }

        /// <summary>
        /// Gets or sets the state of the sample.
        /// Used when samples go to dormant state, for instance, when lunching a chooser.
        /// </summary>
        /// <value>The state of the sample.</value>
        public object SampleState { get; set; }


        bool _inheritPhoneTheme;

        /// <summary>
        /// Gets or sets a value indicating whether to inherit or not the phone theme for this app.
        /// </summary>
        /// <value><c>true</c> if is inheriting the phone theme; otherwise, <c>false</c>.</value>
        public bool InheritPhoneTheme
        {
            get
            {
                return _inheritPhoneTheme;
            }
            set
            {
                if (_inheritPhoneTheme != value)
                {
                    _inheritPhoneTheme = value;
                    UpdateApplicationTheme();

                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("InheritPhoneTheme"));
                    }
                }
            }
        }


        const string AppThemeUri = "ms-appx:///CE/AppTheme.xaml";

        /// <summary>
        /// Updates the application theme.
        /// </summary>
        internal void UpdateApplicationTheme()
        {
            var appThemeDictionaries = Application.Current.Resources.ThemeDictionaries;
            if (InheritPhoneTheme)
            {
                object dict;
                if(appThemeDictionaries.TryGetValue("Default", out dict))
                {
                    appThemeDictionaries.Remove("Default");
                }
            }
            else
            {
                object dict;
                if (!appThemeDictionaries.TryGetValue("Default", out dict))
                {
                    appThemeDictionaries.Add("Default", new ResourceDictionary() { Source = new Uri(AppThemeUri) });
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }


    public enum ControlCat
    {
        all,
        favorites,
        data,
        input,
        libraries
    }
}
