using Earthblend.Tts.Common.Core.MeshGenerators.Base;
using Earthblend.Tts.Common.Core.CustomEventArgs;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using System.Xml.Serialization;
using Earthblend.DynamicCompile;
using Earthblend.Tts.Common.Core.Members;

namespace Earthblend.Tts.Common.Core.MeshGenerators
{
    public class ArrowMeshGenerator : CylindricalMeshBase
    {
        public ArrowMeshGenerator()
        {
            PropertyChanged(new DependencyPropertyChangedEventArgs());
        }

        private ICommand _decreaseHeadLengthCommandIc;[XmlIgnore] public ICommand DecreaseHeadLengthCommandIc => _decreaseHeadLengthCommandIc ?? (_decreaseHeadLengthCommandIc = new RelayCommand<Object>(DecreaseHeadLengthCommandIcExecuted));
        public void DecreaseHeadLengthCommandIcExecuted(Object sender) { HeadLength -= MovementValue; }
        private ICommand _increaseHeadLengthCommandIc;[XmlIgnore] public ICommand IncreaseHeadLengthCommandIc => _increaseHeadLengthCommandIc ?? (_increaseHeadLengthCommandIc = new RelayCommand<Object>(IncreaseHeadLengthCommandIcExecuted));
        public void IncreaseHeadLengthCommandIcExecuted(Object sender) { HeadLength += MovementValue; }

        public static IList<String> Properties = new List<String>() { "HeadLength", "Point1X", "Point1Y", "Point1Z", "Point2X", "Point2Y", "Point2Z", "Radius", "Slices" }; //, "Stacks" };

        public static readonly DependencyProperty HeadLengthProperty = DependencyProperty.Register("HeadLength",typeof(Double),typeof(ArrowMeshGenerator),new PropertyMetadata(1.0D, PropertyChanged));
        public Double HeadLength { set { SetValue(HeadLengthProperty, value); } get { return (Double)GetValue(HeadLengthProperty); }}

        public ArrowMeshGenerator Duplicate()
        {
            ArrowMeshGenerator arrowMeshGenerator = new ArrowMeshGenerator();
            arrowMeshGenerator.HeadLength = HeadLength;
            arrowMeshGenerator.Radius = Radius;
            arrowMeshGenerator.Slices = Slices;

            arrowMeshGenerator.Point1X = Point1X;
            arrowMeshGenerator.Point1Y = Point1Y;
            arrowMeshGenerator.Point1Z = Point1Z;
            arrowMeshGenerator.Point2X = Point2X;
            arrowMeshGenerator.Point2Y = Point2Y;
            arrowMeshGenerator.Point2Z = Point2Z;

            return arrowMeshGenerator;
        }

        protected override void Triangulate(DependencyPropertyChangedEventArgs args, Point3DCollection vertices, Vector3DCollection normals, Int32Collection indices, PointCollection textures)
        {
            vertices.Clear(); normals.Clear(); indices.Clear(); textures.Clear();

            CustomMeshBuilder meshBuilder = new CustomMeshBuilder();
            meshBuilder.AddArrow(Point1,  Point2,  Radius*2, HeadLength,Slices,ThetaStart,ThetaStop);

            vertices = meshBuilder.Positions;
            normals = meshBuilder.Normals;
            indices = meshBuilder.TriangleIndices;
            textures = meshBuilder.TextureCoordinates;

            Geometry = new MeshGeometry3D() { Positions = vertices,Normals = normals,TriangleIndices = indices,TextureCoordinates = textures };

            meshBuilder = null;

            OnMeshChanged(new MeshEventArgs(Geometry as MeshGeometry3D));
        }
    }
}
