using System.IO;
using System.Text;
using System.Windows;
using Syncfusion.Windows.Controls.RichTextBoxAdv;
namespace InABox.DynamicGrid
{
    /// 
    ///     Represents the extension class for SfRichTextBoxAdv.
    /// 
    public class ExtendedRichTextEditor : SfRichTextBoxAdv
    {
        #region Static Dependency Properties
        /// 
        ///     Using as a backing store for Text dependency property to enable styling, animation etc.
        /// 
        public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(ExtendedRichTextEditor),
            new PropertyMetadata("", OnTextChanged));
        #endregion
        #region Fields
        private bool skipUpdating;
        #endregion
        #region Constructor
        /// 
        ///     Initializes the instance of SfRichTextBoxAdvExtension class.
        /// 
        public ExtendedRichTextEditor()
        {
            // Wires the ContentChanged event.
            ContentChanged += RTE_ContentChanged;
        }
        #endregion
        #region Properties
        /// 
        ///     Gets or Sets the text.
        /// 
        public string Text
        {
            get => (string)GetValue(TextProperty);
            set => SetValue(TextProperty, value);
        }
        #endregion
        #region Static Events
        /// 
        ///     Called when text changed.
        /// 
        /// 
        /// 
        private static void OnTextChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var richTextBox = (ExtendedRichTextEditor)obj;
            //Update the document with the text.
            richTextBox.UpdateDocument((string)e.NewValue);
        }
        #endregion
        #region Events
        /// 
        ///     Called when content changes in SfRichTextBoxAdv.
        /// 
        /// 
        /// 
        private void RTE_ContentChanged(object obj, ContentChangedEventArgs args)
        {
            if (Document != null)
            {
                // To skip internal updation of document on setting Text property.
                skipUpdating = true;
                Stream stream = new MemoryStream();
                // Saves the document as text Stream.
                Save(stream, FormatType.Html);
                stream.Position = 0;
                // Reads the stream and assigned the string to Text property
                using (var reader = new StreamReader(stream))
                {
                    Text = reader.ReadToEnd();
                }
                skipUpdating = false;
            }
        }
        #endregion
        #region Implementation
        /// 
        ///     Updates the document.
        /// 
        /// The text.
        private void UpdateDocument(string text)
        {
            // If text property is set internally means, skip updating the document.
            if (!skipUpdating && !string.IsNullOrEmpty(text))
            {
                Stream stream = new MemoryStream();
                // Convert the text string to byte array.
                var bytes = Encoding.UTF8.GetBytes(text);
                // Writes the byte array to stream.
                stream.Write(bytes, 0, bytes.Length);
                stream.Position = 0;
                //Load the Text stream.
                Load(stream, FormatType.Html);
            }
        }
        /// 
        ///     Disposes the instance.
        /// 
        public void Dispose()
        {
            ContentChanged -= RTE_ContentChanged;
            ClearValue(TextProperty);
            base.Dispose();
        }
        #endregion
    }
}