using Office2016InspiredApplication.ViewModel;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using Telerik.Windows.Controls;
using Office2016InspiredApplication.Appearance;

namespace Office2016InspiredApplication.Appearance
{
    public static class AppearanceManager
    {
        private static readonly string StylesFolderName = "Styles";
        private static readonly string visualStudio2013Theme = "VisualStudio2013";
        private static IEnumerable<string> xamlFiles;
        private static IEnumerable<string> customStyles;

        private static IEnumerable<string> GetXamlFilesList()
        {
            var filesList = new List<string> 
            { 
                "System.Windows.xaml",
                "Telerik.Windows.Controls.xaml",
                "Telerik.Windows.Controls.Input.xaml",
                "Telerik.Windows.Controls.Navigation.xaml",
                "Telerik.Windows.Controls.GridView.xaml",
                "Telerik.Windows.Controls.RibbonView.xaml",
                "Telerik.Windows.Controls.Spreadsheet.xaml",
                "Telerik.Windows.Controls.RichTextBoxUI.xaml",
                "Telerik.Windows.Controls.ImageEditor.xaml",
                "Telerik.Windows.Documents.xaml"
            };

            return filesList;
        }

        private static IEnumerable<string> GetCustomStylesList()
        {
            var customStyles = new List<string> 
            {
                "ApplicationStyles.xaml",
                "QuickAccessToolbarStyles.xaml",
                "BackstageStyles.xaml",
                "RibbonWindowStyles.xaml",
                "RibbonViewStyles.xaml",
                "RibbonButtonsStyles.xaml",
                "RichTextBoxStyles.xaml",
                "SpreadsheetStyles.xaml",
                "RadWindowStyles.xaml"
            };

            return customStyles;
        }

        static AppearanceManager()
        {
            xamlFiles = GetXamlFilesList();
            customStyles = GetCustomStylesList();
        }

        public static void ChangeAppearance(Office2016ColorVariations colorVariation, Office2016AccentBrushes accentBrush)
        {
            SetThemeWithSpecificColorVariation(colorVariation);

            switch (colorVariation)
            {
                case Office2016ColorVariations.Colorful:
                    ChangeColorfulPaletteColors(accentBrush);

                    Office2016Palette.Palette.SliderBackground = Office2016Palette.ColorfulSliderBackgroundColor;
                    Office2016Palette.Palette.SliderForeground = Office2016Palette.ColorfulSliderForegroundColor;
                    Office2016Palette.Palette.SelectedSheetForeground = Office2016Palette.ColorfulSelectedSheetForegroundColor;
                    Office2016Palette.Palette.PageMarginBackground = Office2016Palette.ColorfulPageMarginBackgroundColor;
                    Office2016Palette.Palette.PageRectangleFill = Office2016Palette.ColorfulPageRectangleFillColor;

                    VisualStudio2013Palette.Palette.MouseOverColor = (Color)ColorConverter.ConvertFromString("#FFC5C5C5");
                    VisualStudio2013Palette.Palette.AccentDarkColor = (Color)ColorConverter.ConvertFromString("#FFAEAEAE");
                    VisualStudio2013Palette.Palette.PrimaryColor = (Color)ColorConverter.ConvertFromString("#FFF1F1F1");
                    VisualStudio2013Palette.Palette.SelectedColor = (Color)ColorConverter.ConvertFromString("#FFFFFFFF");
                    VisualStudio2013Palette.Palette.BasicColor = (Color)ColorConverter.ConvertFromString("#FFAEAEAE");
                    VisualStudio2013Palette.Palette.StrongColor = (Color)ColorConverter.ConvertFromString("#FF777777");
                    VisualStudio2013Palette.Palette.MainColor = (Color)ColorConverter.ConvertFromString("#FFFFFFFF");
                    break;
                case Office2016ColorVariations.White:
                    ChangeWhitePaletteColors(accentBrush);

                    Office2016Palette.Palette.SliderBackground = Office2016Palette.WhiteSliderBackgroundColor;
                    Office2016Palette.Palette.SliderForeground = Office2016Palette.WhiteSliderForegroundColor;
                    Office2016Palette.Palette.SelectedSheetForeground = Office2016Palette.WhiteSelectedSheetForegroundColor;
                    Office2016Palette.Palette.PageMarginBackground = Office2016Palette.WhitePageMarginBackgroundColor;
                    Office2016Palette.Palette.PageRectangleFill = Office2016Palette.WhitePageRectangleFillColor;
                    //ribbon titlebackground color
                    VisualStudio2013Palette.Palette.HeaderColor = (Color)ColorConverter.ConvertFromString("#FFFFFFFF");
                    //background of RibbonView (where all groups reside)
                    VisualStudio2013Palette.Palette.PrimaryColor = (Color)ColorConverter.ConvertFromString("#FFFFFFFF");
                    //all text colors in RibbonView
                    VisualStudio2013Palette.Palette.SelectedColor = (Color)ColorConverter.ConvertFromString("#FF000000");
                    //borderbrush color
                    VisualStudio2013Palette.Palette.AccentColor = (Color)ColorConverter.ConvertFromString("#FF000000");
                    //all path geometries normal fill
                    VisualStudio2013Palette.Palette.StrongColor = (Color)ColorConverter.ConvertFromString("#FF777777");
                    //background of combobox and quickstyles gallery
                    VisualStudio2013Palette.Palette.MainColor = (Color)ColorConverter.ConvertFromString("#FFFFFFFF");
                    break;
                case Office2016ColorVariations.Dark:
                    ChangeDarkPaletteColors(accentBrush);

                    Office2016Palette.Palette.SliderBackground = Office2016Palette.DarkSliderBackgroundColor;
                    Office2016Palette.Palette.SliderForeground = Office2016Palette.DarkSliderForegroundColor;
                    Office2016Palette.Palette.SelectedSheetForeground = Office2016Palette.DarkSelectedSheetForegroundColor;
                    Office2016Palette.Palette.PageMarginBackground = Office2016Palette.DarkPageMarginBackgroundColor;
                    Office2016Palette.Palette.PageRectangleFill = Office2016Palette.DarkPageRectangleFillColor;

                    VisualStudio2013Palette.Palette.HeaderColor = (Color)ColorConverter.ConvertFromString("#FF444444");
                    VisualStudio2013Palette.Palette.MouseOverColor = (Color)ColorConverter.ConvertFromString("#FF969696");
                    VisualStudio2013Palette.Palette.AccentDarkColor = (Color)ColorConverter.ConvertFromString("#FF808080");
                    VisualStudio2013Palette.Palette.PrimaryColor = (Color)ColorConverter.ConvertFromString("#FFB2B2B2");
                    VisualStudio2013Palette.Palette.SelectedColor = (Color)ColorConverter.ConvertFromString("#FFFFFFFF");
                    VisualStudio2013Palette.Palette.AccentColor = (Color)ColorConverter.ConvertFromString("#FF444444");
                    VisualStudio2013Palette.Palette.BasicColor = (Color)ColorConverter.ConvertFromString("#FF808080");
                    VisualStudio2013Palette.Palette.StrongColor = Colors.Black;
                    VisualStudio2013Palette.Palette.MainColor = (Color)ColorConverter.ConvertFromString("#FFD4D4D4");
                    break;
                default:
                    break;
            }

            OnColorVariationChanged(colorVariation);
        }

        private static void ChangeDarkPaletteColors(Office2016AccentBrushes accentBrush)
        {
            if (accentBrush == Office2016AccentBrushes.WordBased)
            {
                Office2016Palette.Palette.ApplicationButtonBackground = Office2016Palette.DarkApplicationButtonBackgroundColor;
                Office2016Palette.Palette.BackstageBackground = Office2016Palette.DarkBackstageBackgroundColor;
                Office2016Palette.Palette.MouseOverBackground = Office2016Palette.DarkMouseOverBackgroundColor;
                Office2016Palette.Palette.PressedBackground = Office2016Palette.DarkPressedBackgroundColor;
                Office2016Palette.Palette.TabMouseOverForeground = Office2016Palette.DarkTabMouseOverForegroundColor;
                Office2016Palette.Palette.TabSelectedForeground = Office2016Palette.DarkTabSelectedForegroundColor;
                Office2016Palette.Palette.TabMouseOverBackground = Office2016Palette.DarkTabMouseOverBackgroundColor;
                Office2016Palette.Palette.TabMouseOverBorderBrush = Office2016Palette.DarkTabMouseOverBorderBrushColor;
                Office2016Palette.Palette.MouseOverCheckedBorderBrush = Office2016Palette.DarkMouseOverCheckedBorderBrushColor;
                Office2016Palette.Palette.StatusBarBackground = Office2016Palette.DarkStatusBarBackgroundColor;
                Office2016Palette.Palette.DocumentBackground = Office2016Palette.DarkDocumentBackgroundColor;

                VisualStudio2013Palette.Palette.AccentMainColor = (Color)ColorConverter.ConvertFromString("#FF3E6DB6");
                VisualStudio2013Palette.Palette.SemiBasicColor = (Color)ColorConverter.ConvertFromString("#FF19478A");
            }
            //ExcelBased colors
            else
            {
                Office2016Palette.Palette.ApplicationButtonBackground = Office2016Palette.DarkApplicationButtonBackgroundColor;
                Office2016Palette.Palette.BackstageBackground = Office2016Palette.DarkBackstageBackgroundColor;
                Office2016Palette.Palette.MouseOverBackground = (Color)ColorConverter.ConvertFromString("#FF575757");
                Office2016Palette.Palette.PressedBackground = (Color)ColorConverter.ConvertFromString("#FF303030");
                Office2016Palette.Palette.TabMouseOverForeground = (Color)ColorConverter.ConvertFromString("#FFFFFFFF");
                Office2016Palette.Palette.TabSelectedForeground = Office2016Palette.DarkTabSelectedForegroundColor;
                Office2016Palette.Palette.TabMouseOverBackground = (Color)ColorConverter.ConvertFromString("#FF217346");
                Office2016Palette.Palette.TabMouseOverBorderBrush = (Color)ColorConverter.ConvertFromString("#FF217346");
                Office2016Palette.Palette.MouseOverCheckedBorderBrush = Office2016Palette.DarkMouseOverCheckedBorderBrushColor;
                Office2016Palette.Palette.StatusBarBackground = Office2016Palette.DarkStatusBarBackgroundColor;
                Office2016Palette.Palette.DocumentBackground = Office2016Palette.DarkDocumentBackgroundColor;

                VisualStudio2013Palette.Palette.AccentMainColor = (Color)ColorConverter.ConvertFromString("#FF439467");
                VisualStudio2013Palette.Palette.SemiBasicColor = (Color)ColorConverter.ConvertFromString("#FF0A6332");
            }
        }

        private static void ChangeWhitePaletteColors(Office2016AccentBrushes accentBrush)
        {
            if (accentBrush == Office2016AccentBrushes.WordBased)
            {
                Office2016Palette.Palette.ApplicationButtonBackground = Office2016Palette.WhiteApplicationButtonBackgroundColor;
                Office2016Palette.Palette.BackstageBackground = Office2016Palette.WhiteBackstageBackgroundColor;
                //RibbonWindow Button's MouseOver
                Office2016Palette.Palette.MouseOverBackground = Office2016Palette.WhiteMouseOverBackgroundColor;
                //RibbonWindow Button's Pressed
                Office2016Palette.Palette.PressedBackground = Office2016Palette.WhitePressedBackgroundColor;
                Office2016Palette.Palette.TabMouseOverForeground = Office2016Palette.WhiteTabMouseOverForegroundColor;
                Office2016Palette.Palette.TabSelectedForeground = Office2016Palette.WhiteTabSelectedForegroundColor;
                Office2016Palette.Palette.TabMouseOverBackground = Office2016Palette.WhiteTabMouseOverBackgroundColor;
                Office2016Palette.Palette.TabMouseOverBorderBrush = Office2016Palette.WhiteTabMouseOverBorderBrushColor;
                Office2016Palette.Palette.MouseOverCheckedBorderBrush = Office2016Palette.WhiteMouseOverCheckedBorderBrushColor;
                Office2016Palette.Palette.StatusBarBackground = (Color)ColorConverter.ConvertFromString("#FF2A579A");
                Office2016Palette.Palette.DocumentBackground = Office2016Palette.WhiteDocumentBackgroundColor;

                // mouse over color
                VisualStudio2013Palette.Palette.MouseOverColor = (Color)ColorConverter.ConvertFromString("#FFC2D5F2");
                // pressed color
                VisualStudio2013Palette.Palette.AccentDarkColor = (Color)ColorConverter.ConvertFromString("#FFA3BDE3");
                //Border around Ribbon items when checked
                VisualStudio2013Palette.Palette.BasicColor = (Color)ColorConverter.ConvertFromString("#FFD4D4D4");
                //Backstage Item Background when selected
                VisualStudio2013Palette.Palette.AccentMainColor = (Color)ColorConverter.ConvertFromString("#FF3E6DB6");
                //Backstage Item Background when hovered
                VisualStudio2013Palette.Palette.SemiBasicColor = (Color)ColorConverter.ConvertFromString("#FF19478A");
            }
            //ExcelBased colors
            else
            {
                Office2016Palette.Palette.ApplicationButtonBackground = (Color)ColorConverter.ConvertFromString("#FF217346");
                Office2016Palette.Palette.BackstageBackground = (Color)ColorConverter.ConvertFromString("#FF227447");
                //RibbonWindow Button's MouseOver
                Office2016Palette.Palette.MouseOverBackground = Office2016Palette.WhiteMouseOverBackgroundColor;
                //RibbonWindow Button's MouseOver
                Office2016Palette.Palette.PressedBackground = Office2016Palette.WhitePressedBackgroundColor;
                Office2016Palette.Palette.TabMouseOverForeground = (Color)ColorConverter.ConvertFromString("#FF217346");
                Office2016Palette.Palette.TabSelectedForeground = (Color)ColorConverter.ConvertFromString("#FF217346");
                Office2016Palette.Palette.TabMouseOverBackground = Office2016Palette.WhiteTabMouseOverBackgroundColor;
                Office2016Palette.Palette.TabMouseOverBorderBrush = Office2016Palette.WhiteTabMouseOverBorderBrushColor;
                Office2016Palette.Palette.MouseOverCheckedBorderBrush = (Color)ColorConverter.ConvertFromString("#FF9FD5B7");
                Office2016Palette.Palette.StatusBarBackground = Office2016Palette.WhiteStatusBarBackgroundColor;
                Office2016Palette.Palette.DocumentBackground = Office2016Palette.WhiteDocumentBackgroundColor;

                //ribbon buttons mouse over color
                VisualStudio2013Palette.Palette.MouseOverColor = (Color)ColorConverter.ConvertFromString("#FFD3F0E0");
                //ribbon buttons pressed color
                VisualStudio2013Palette.Palette.AccentDarkColor = (Color)ColorConverter.ConvertFromString("#FF9FD5B7");
                //Border around Ribbon items when checked
                VisualStudio2013Palette.Palette.BasicColor = (Color)ColorConverter.ConvertFromString("#FFD4D4D4");
                //Backstage Item Background when selected
                VisualStudio2013Palette.Palette.AccentMainColor = (Color)ColorConverter.ConvertFromString("#FF439467");
                //Backstage Item Background when hovered
                VisualStudio2013Palette.Palette.SemiBasicColor = (Color)ColorConverter.ConvertFromString("#FF0A6332");
            }
        }

        private static void ChangeColorfulPaletteColors(Office2016AccentBrushes accentBrush)
        {
            if (accentBrush == Office2016AccentBrushes.WordBased)
            {
                Office2016Palette.Palette.ApplicationButtonBackground = Office2016Palette.ColorfulApplicationButtonBackgroundColor;
                Office2016Palette.Palette.BackstageBackground = Office2016Palette.ColorfulBackstageBackgroundColor;
                Office2016Palette.Palette.MouseOverBackground = Office2016Palette.ColorfulMouseOverBackgroundColor;
                Office2016Palette.Palette.PressedBackground = Office2016Palette.ColorfulPressedBackgroundColor;
                Office2016Palette.Palette.TabMouseOverForeground = Office2016Palette.ColorfulTabMouseOverForegroundColor;
                Office2016Palette.Palette.TabSelectedForeground = Office2016Palette.ColorfulTabSelectedForegroundColor;
                Office2016Palette.Palette.TabMouseOverBackground = Office2016Palette.ColorfulTabMouseOverBackgroundColor;
                Office2016Palette.Palette.TabMouseOverBorderBrush = Office2016Palette.ColorfulTabMouseOverBorderBrushColor;
                Office2016Palette.Palette.MouseOverCheckedBorderBrush = Office2016Palette.ColorfulMouseOverCheckedBorderBrushColor;
                Office2016Palette.Palette.StatusBarBackground = Office2016Palette.ColorfulStatusBarBackgroundColor;
                Office2016Palette.Palette.DocumentBackground = Office2016Palette.ColorfulDocumentBackgroundColor;

                VisualStudio2013Palette.Palette.HeaderColor = (Color)ColorConverter.ConvertFromString("#FF2A579A");
                VisualStudio2013Palette.Palette.AccentColor = (Color)ColorConverter.ConvertFromString("#FF2A579A");
                VisualStudio2013Palette.Palette.AccentMainColor = (Color)ColorConverter.ConvertFromString("#FF3E6DB6");
                VisualStudio2013Palette.Palette.SemiBasicColor = (Color)ColorConverter.ConvertFromString("#FF19478A");
            }
            //ExcelBased colors
            else
            {
                Office2016Palette.Palette.ApplicationButtonBackground = (Color)ColorConverter.ConvertFromString("#FF227447");
                Office2016Palette.Palette.BackstageBackground = (Color)ColorConverter.ConvertFromString("#FF227447");
                Office2016Palette.Palette.MouseOverBackground = (Color)ColorConverter.ConvertFromString("#FF439467");
                Office2016Palette.Palette.PressedBackground = (Color)ColorConverter.ConvertFromString("#FF1B5D39");
                Office2016Palette.Palette.TabMouseOverForeground = Office2016Palette.ColorfulTabMouseOverForegroundColor;
                Office2016Palette.Palette.TabSelectedForeground = (Color)ColorConverter.ConvertFromString("#FF217346");
                Office2016Palette.Palette.TabMouseOverBackground = (Color)ColorConverter.ConvertFromString("#FF439467");
                Office2016Palette.Palette.TabMouseOverBorderBrush = (Color)ColorConverter.ConvertFromString("#FF439467");
                Office2016Palette.Palette.MouseOverCheckedBorderBrush = Office2016Palette.ColorfulMouseOverCheckedBorderBrushColor;
                Office2016Palette.Palette.StatusBarBackground = Office2016Palette.ColorfulStatusBarBackgroundColor;
                Office2016Palette.Palette.SliderBackground = Office2016Palette.ColorfulSliderBackgroundColor;
                Office2016Palette.Palette.SliderForeground = Office2016Palette.ColorfulSliderForegroundColor;
                Office2016Palette.Palette.SelectedSheetForeground = Office2016Palette.ColorfulSelectedSheetForegroundColor;
                Office2016Palette.Palette.DocumentBackground = Office2016Palette.ColorfulDocumentBackgroundColor;

                VisualStudio2013Palette.Palette.HeaderColor = (Color)ColorConverter.ConvertFromString("#FF227447");
                VisualStudio2013Palette.Palette.AccentColor = (Color)ColorConverter.ConvertFromString("#FF227447");
                VisualStudio2013Palette.Palette.AccentMainColor = (Color)ColorConverter.ConvertFromString("#FF439467");
                VisualStudio2013Palette.Palette.SemiBasicColor = (Color)ColorConverter.ConvertFromString("#FF0A6332");
            }
        }

        private static void SetThemeWithSpecificColorVariation(Office2016ColorVariations colorVariation)
        {
            MainViewModel.SelectedColorVariation = colorVariation;

            Application.Current.Resources.MergedDictionaries.Clear();

            foreach (var file in xamlFiles)
            {
                string path = string.Format(@"/Telerik.Windows.Themes.{0};component/Themes/" + file, visualStudio2013Theme);
                Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary()
                {
                    Source = new Uri(path, UriKind.RelativeOrAbsolute)
                });
            }

            foreach (var item in customStyles)
            {
                Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary()
                {
                    Source = new Uri(string.Format(@"pack://application:,,,/Office2016InspiredApplication;component/{0}/{1}", AppearanceManager.StylesFolderName, item), UriKind.RelativeOrAbsolute)
                });
            }
        }

        public static event EventHandler<AppearanceChangedEventArgs> ColorVariationChanged;
        private static void OnColorVariationChanged(Office2016ColorVariations colorVariation)
        {
            if (ColorVariationChanged != null)
            {
                ColorVariationChanged(null, new AppearanceChangedEventArgs(colorVariation));
            }
        }
    }
}
