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.Media;
using System.Windows.Media.Media3D;
using Earthblend.Tts.Common.Core.Members;

namespace Earthblend.Tts.Common.Core.MeshGenerators
{
    public class EllipsoidMeshGenerator : CylindricalMeshBase
    {
        public EllipsoidMeshGenerator()
        {
            //Slices = 16;
            //Stacks = 16;
            PropertyChanged(new DependencyPropertyChangedEventArgs());
        }

        public static IList<String> Properties = new List<String>() { "CenterX", "CenterY", "CenterZ", "RadiusX", "RadiusY","RadiusZ","Slices","Stacks" };

        public static readonly DependencyProperty RadiusXProperty = DependencyProperty.Register("RadiusX", typeof(Double), typeof(EllipsoidMeshGenerator), new PropertyMetadata(1.0D, PropertyChanged));
        public static readonly DependencyProperty RadiusYProperty = DependencyProperty.Register("RadiusY", typeof(Double), typeof(EllipsoidMeshGenerator), new PropertyMetadata(2.0D, PropertyChanged));
        public static readonly DependencyProperty RadiusZProperty = DependencyProperty.Register("RadiusZ", typeof(Double), typeof(EllipsoidMeshGenerator), new PropertyMetadata(1.0D, PropertyChanged));
        public static readonly DependencyProperty CenterProperty = DependencyProperty.Register("Center", typeof(Point3D), typeof(EllipsoidMeshGenerator), new PropertyMetadata(new Point3D(-1, 0, 0), PropertyChanged));

        public static readonly DependencyProperty CenterXProperty = DependencyProperty.Register("CenterX", typeof(Double), typeof(EllipsoidMeshGenerator), new PropertyMetadata(0.0D, CenterXYZPropertyChanged));
        public static readonly DependencyProperty CenterYProperty = DependencyProperty.Register("CenterY", typeof(Double), typeof(EllipsoidMeshGenerator), new PropertyMetadata(0.0D, CenterXYZPropertyChanged));
        public static readonly DependencyProperty CenterZProperty = DependencyProperty.Register("CenterZ", typeof(Double), typeof(EllipsoidMeshGenerator), new PropertyMetadata(0.0D, CenterXYZPropertyChanged));

        public Double CenterX { set { SetValue(CenterXProperty, value); } get { return (Double)GetValue(CenterXProperty); } }
        public Double CenterY { set { SetValue(CenterYProperty, value); } get { return (Double)GetValue(CenterYProperty); } }
        public Double CenterZ { set { SetValue(CenterZProperty, value); } get { return (Double)GetValue(CenterZProperty); } }

        public Point3D Center { set { SetValue(CenterProperty, value); } get { return (Point3D)GetValue(CenterProperty); } }
        public Double RadiusX { set { SetValue(RadiusXProperty, value); } get { return (Double)GetValue(RadiusXProperty); } }
        public Double RadiusY { set { SetValue(RadiusYProperty, value); } get { return (Double)GetValue(RadiusYProperty); } }
        public Double RadiusZ { set { SetValue(RadiusZProperty, value); } get { return (Double)GetValue(RadiusZProperty); } }

        protected static void CenterXYZPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            (obj as EllipsoidMeshGenerator).PropertyChanged(args);
            (obj as EllipsoidMeshGenerator).Center = new Point3D((obj as EllipsoidMeshGenerator).CenterX, (obj as EllipsoidMeshGenerator).CenterY, (obj as EllipsoidMeshGenerator).CenterZ);
        }

        public EllipsoidMeshGenerator Duplicate()
        {
            EllipsoidMeshGenerator meshGenerator = new EllipsoidMeshGenerator();

            meshGenerator.CenterX = CenterX;
            meshGenerator.CenterY = CenterY;
            meshGenerator.CenterZ = CenterZ;
            meshGenerator.Center = Center;

            meshGenerator.RadiusX = RadiusX;
            meshGenerator.RadiusY = RadiusY;
            meshGenerator.RadiusZ = RadiusZ;

            meshGenerator.Stacks = Stacks;

            return meshGenerator;
        }

        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.AddEllipsoid(Center, RadiusX,RadiusY,RadiusZ, Slices,10,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));
        }
    }
}
