using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace ComeCapture.Controls
{
    public class ArrowTool : StackPanel
    {
        private readonly StreamGeometry geometry = new StreamGeometry();

        static ArrowTool()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ArrowTool), new FrameworkPropertyMetadata(typeof(ArrowTool)));
        }

        public ArrowTool()
        {
            _Current = this;
        }

        public List<Point> CreateArrow(Point start, Point end)
        {
            double tan = Math.Atan((end.Y - start.Y) / (end.X - start.X));
            double Move0 = tan - ArrowAngle;
            double Move1 = tan + ArrowAngle;
            int convert = end.X > start.X ? -1 : 1;
            double X0 = end.X + ((convert * ArrowLength) * Math.Cos(Move0));
            double Y0 = end.Y + ((convert * ArrowLength) * Math.Sin(Move0));
            double X1 = end.X + ((convert * ArrowLength) * Math.Cos(Move1));
            double Y1 = end.Y + ((convert * ArrowLength) * Math.Sin(Move1));
            Point point3 = new Point(X0, Y0);
            Point point5 = new Point(X1, Y1);
            Point point2 = new Point(X0 + 0.25 * (X1 - X0), Y0 + 0.25 * (Y1 - Y0));
            Point point4 = new Point(X0 + 0.75 * (X1 - X0), Y0 + 0.75 * (Y1 - Y0));
            return new List<Point>()
            {
                start,
                new Point(X0 + 0.25 * (X1 - X0), Y0 + 0.25 * (Y1 - Y0)),
                new Point(X0, Y0),
                end,
                new Point(X1, Y1),
                new Point(X0 + 0.75 * (X1 - X0), Y0 + 0.75 * (Y1 - Y0)),
                start
            };
        }

        #region 属性 Current

        private static ArrowTool _Current = null;

        public static ArrowTool Current => _Current;

        #endregion 属性 Current

        #region LineThickness DependencyProperty

        public double LineThickness
        {
            get => (double)GetValue(LineThicknessProperty);
            set => SetValue(LineThicknessProperty, value);
        }

        public static readonly DependencyProperty LineThicknessProperty =
                DependencyProperty.Register("LineThickness", typeof(double), typeof(ArrowTool),
                new PropertyMetadata(5.0, new PropertyChangedCallback(ArrowTool.OnLineThicknessPropertyChanged)));

        private static void OnLineThicknessPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (obj is ArrowTool)
            {
                (obj as ArrowTool).OnLineThicknessValueChanged();
            }
        }

        protected void OnLineThicknessValueChanged()
        {
            ArrowLength = LineThickness * 2 + 7;
        }

        #endregion LineThickness DependencyProperty

        #region LineBrush DependencyProperty

        public SolidColorBrush LineBrush
        {
            get => (SolidColorBrush)GetValue(LineBrushProperty);
            set => SetValue(LineBrushProperty, value);
        }

        public static readonly DependencyProperty LineBrushProperty =
                DependencyProperty.Register("LineBrush", typeof(SolidColorBrush), typeof(ArrowTool),
                new PropertyMetadata(new SolidColorBrush(Colors.Red), new PropertyChangedCallback(ArrowTool.OnLineBrushPropertyChanged)));

        private static void OnLineBrushPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (obj is ArrowTool)
            {
                (obj as ArrowTool).OnLineBrushValueChanged();
            }
        }

        protected void OnLineBrushValueChanged()
        {
        }

        #endregion LineBrush DependencyProperty

        #region ArrowLength DependencyProperty

        public double ArrowLength
        {
            get => (double)GetValue(ArrowLengthProperty);
            set => SetValue(ArrowLengthProperty, value);
        }

        public static readonly DependencyProperty ArrowLengthProperty =
                DependencyProperty.Register("ArrowLength", typeof(double), typeof(ArrowTool),
                new PropertyMetadata(17.0, new PropertyChangedCallback(ArrowTool.OnArrowLengthPropertyChanged)));

        private static void OnArrowLengthPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (obj is ArrowTool)
            {
                (obj as ArrowTool).OnArrowLengthValueChanged();
            }
        }

        protected void OnArrowLengthValueChanged()
        {
        }

        #endregion ArrowLength DependencyProperty

        #region ArrowAngle DependencyProperty

        public double ArrowAngle
        {
            get => (double)GetValue(ArrowAngleProperty);
            set => SetValue(ArrowAngleProperty, value);
        }

        public static readonly DependencyProperty ArrowAngleProperty =
                DependencyProperty.Register("ArrowAngle", typeof(double), typeof(ArrowTool),
                new PropertyMetadata(0.45, new PropertyChangedCallback(ArrowTool.OnArrowAnglePropertyChanged)));

        private static void OnArrowAnglePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (obj is ArrowTool)
            {
                (obj as ArrowTool).OnArrowAngleValueChanged();
            }
        }

        protected void OnArrowAngleValueChanged()
        {
        }

        #endregion ArrowAngle DependencyProperty
    }
}