﻿using Imagin.Common;
using Imagin.Common.Input;
using Imagin.Common.Linq;
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;

namespace Text
{
    [DisplayName("RichText")]
    [File(Extension = "rtf")]
    [Serializable]
    public class RichTextDocument : FileDocument
    {
        [field: NonSerialized]
        bool isBold;
        [Hidden]
        public bool IsBold
        {
            get => isBold;
            set => this.Change(ref isBold, value);
        }

        [field: NonSerialized]
        bool isItalic;
        [Hidden]
        public bool IsItalic
        {
            get => isItalic;
            set => this.Change(ref isItalic, value);
        }

        [field: NonSerialized]
        bool isUnderline;
        [Hidden]
        public bool IsUnderline
        {
            get => isUnderline;
            set => this.Change(ref isUnderline, value);
        }

        [field: NonSerialized]
        bool isStrike;
        [Hidden]
        public bool IsStrike
        {
            get => isStrike;
            set => this.Change(ref isStrike, value);
        }

        [field: NonSerialized]
        SolidColorBrush backgroundColor;
        [Hidden]
        public SolidColorBrush BackgroundColor
        {
            get => backgroundColor;
            set
            {
                this.Change(ref backgroundColor, value);
                if (backgroundColor != null)
                    RichTextBox?.Selection.ApplyPropertyValue(Inline.BackgroundProperty, backgroundColor);
            }
        }

        [field: NonSerialized]
        SolidColorBrush fontColor;
        [Hidden]
        public SolidColorBrush FontColor
        {
            get => fontColor;
            set
            {
                this.Change(ref fontColor, value);
                if (fontFamily != null)
                    RichTextBox?.Selection.ApplyPropertyValue(TextElement.ForegroundProperty, fontColor);
            }
        }

        [field: NonSerialized]
        FontFamily fontFamily;
        [Hidden]
        public FontFamily FontFamily
        {
            get => fontFamily;
            set
            {
                this.Change(ref fontFamily, value);
                if (fontFamily != null)
                    RichTextBox?.Selection.ApplyPropertyValue(TextElement.FontFamilyProperty, fontFamily);
            }
        }

        [field: NonSerialized]
        double fontSize;
        [Hidden]
        public double FontSize
        {
            get => fontSize;
            set
            {
                this.Change(ref fontSize, value);
                RichTextBox?.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, fontSize);
            }
        }

        [field: NonSerialized]
        [Hidden]
        public RichTextBox RichTextBox { get; private set; }

        protected RichTextDocument() : base() { }
        
        public RichTextDocument(string filePath, string fileText) : base(filePath, fileText) { }

        protected override bool Save(string filePath) => RichTextBox?.Save() ?? false;

        [field: NonSerialized]
        ICommand loadedCommand;
        [Hidden]
        public ICommand LoadedCommand => loadedCommand = loadedCommand ?? new RelayCommand<RichTextBox>(i =>
        {
            RichTextBox = i;
            i.SelectionChanged += OnSelectionChanged;
        });

        void OnSelectionChanged(object sender, RoutedEventArgs e)
        {
            object temp = RichTextBox.Selection.GetPropertyValue(TextElement.FontWeightProperty);
            IsBold = (temp != DependencyProperty.UnsetValue) && (temp.Equals(FontWeights.Bold));

            temp = RichTextBox.Selection.GetPropertyValue(TextElement.FontStyleProperty);
            IsItalic = (temp != DependencyProperty.UnsetValue) && (temp.Equals(FontStyles.Italic));


            temp = RichTextBox.Selection.GetPropertyValue(Inline.TextDecorationsProperty);
            IsUnderline = (temp != DependencyProperty.UnsetValue) && (temp.Equals(TextDecorations.Underline));

            temp = RichTextBox.Selection.GetPropertyValue(Inline.BackgroundProperty);
            backgroundColor = temp as SolidColorBrush;
            this.Changed(() => BackgroundColor);

            temp = RichTextBox.Selection.GetPropertyValue(TextElement.ForegroundProperty);
            fontColor = temp as SolidColorBrush;
            this.Changed(() => FontColor);

            temp = RichTextBox.Selection.GetPropertyValue(TextElement.FontFamilyProperty);
            fontFamily = temp as FontFamily;
            this.Changed(() => FontFamily);

            temp = RichTextBox.Selection.GetPropertyValue(TextElement.FontSizeProperty);
            fontSize = temp is double d ? d : double.NaN;
            this.Changed(() => FontSize);
        }
    }
}