﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;

namespace CoderOffice.Windows.Controls.Text
{
    public class CursorLayer : Control
    {
        private static DispatcherTimer _blinkTimer = new DispatcherTimer(DispatcherPriority.ApplicationIdle);

        static CursorLayer()
        {
            CursorLayer._blinkTimer.Interval = TimeSpan.FromSeconds(0.5);
            CursorLayer._blinkTimer.Start();
        }

        public CursorLayer()
        {
            this.Loaded += CursorLayerLoaded;
            this.Unloaded += CursorLayerUnloaded;
        }

        public TextView Owner
        {
            get
            {
                return this._owner;
            }
            internal set
            {
                if(this._owner != value)
                {
                    var oldOwner = this._owner;
                    this._owner = value;
                    this.OnOwnerChanged(oldOwner, value);
                }
            }
        }

        protected virtual void OnOwnerChanged(TextView oldOwner, TextView newOwner)
        {
            if(oldOwner != null)
            {
                //oldOwner.CursorChanged -= OnCursorChanged;
                oldOwner.VisualTextDocument.FormattedTextChanged -= OnVisualTextDocumentFormattedTextChanged;
            }
            if(newOwner != null)
            {
                //newOwner.CursorChanged += OnCursorChanged;
                newOwner.VisualTextDocument.FormattedTextChanged += OnVisualTextDocumentFormattedTextChanged;
            }
        }

        protected void OnCursorChanged(object sender, EventArgs e)
        {
            this._blanking = false;
            this.InvalidateVisual();
        }
        protected virtual void OnVisualTextDocumentFormattedTextChanged(object sender, TextFormatting.FormattedTextChangedEventArgs e)
        {
            this._blanking = false;
            this.InvalidateVisual();
        }
        protected override void OnRender(DrawingContext drawingContext)
        {
            if(this.Owner == null)
                return;
            // Change visible state
            this._visible = !this._visible;
            // Render
            if(!this._blanking || this._visible)
            {
                //foreach(var position in this.Owner.CursorLocation.Positions)
                //{
                //    var lineView = this.Owner[position.Line.Key];
                //    var point = lineView.TranslatePoint(new Point(position.RenderInfo.XDistance, position.RenderInfo.YDistance), this);
                //    drawingContext.DrawRectangle(Brushes.White, null, new Rect(point, new Size(1, position.RenderInfo.LineHeight)));
                //}
                //this._blanking = true;
            }
        }
        protected virtual void OnBlinkTimerTick(object sender, EventArgs e)
        {
            this.InvalidateVisual();
        }

        private void CursorLayerLoaded(object sender, RoutedEventArgs e)
        {
            this.Loaded -= CursorLayerLoaded;
            CursorLayer._blinkTimer.Tick += OnBlinkTimerTick;
        }

        private void CursorLayerUnloaded(object sender, RoutedEventArgs e)
        {
            this.Unloaded -= CursorLayerUnloaded;
            CursorLayer._blinkTimer.Tick -= OnBlinkTimerTick;
        }

        private bool _visible;
        private bool _blanking;
        private TextView _owner;
    }
}
