using Earthblend.Tts.Common.Core.MeshGenerators.Base;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Media3D;

namespace Earthblend.Tts.Common.Core.MeshGenerators
{
    [Serializable]
    public class HollowCylinderMeshGenerator : CylindricalMeshBase
    {
        public HollowCylinderMeshGenerator()
        {
            PropertyChanged(new DependencyPropertyChangedEventArgs());
        }

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


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

            meshGenerator.Point1X = Point1X;
            meshGenerator.Point1Y = Point1Y;
            meshGenerator.Point1Z = Point1Z;
            meshGenerator.Point2X = Point2X;
            meshGenerator.Point2Y = Point2Y;
            meshGenerator.Point2Z = Point2Z;
            meshGenerator.Radius = Radius;
            meshGenerator.Slices = Slices;
            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();

            // Fill the vertices, normals, and textures collections.
            for (int stack = 0; stack <= Stacks; stack++)
            {
                double y = Length - stack * Length / Stacks;

                for (int slice = 0; slice <= Slices; slice++)
                {
                    double theta = slice * 2 * Math.PI / Slices;
                    double x = -Radius * Math.Sin(theta);
                    double z = -Radius * Math.Cos(theta);

                    normals.Add(new Vector3D(x, 0, z));
                    vertices.Add(new Point3D(x, y, z));
                    textures.Add(new Point((double)slice / Slices,
                                           (double)stack / Stacks));
                }
            }

            // Fill the indices collection.
            for (int stack = 0; stack < Stacks; stack++)
            {
                for (int slice = 0; slice < Slices; slice++)
                {
                    indices.Add((stack + 0) * (Slices + 1) + slice);
                    indices.Add((stack + 1) * (Slices + 1) + slice);
                    indices.Add((stack + 0) * (Slices + 1) + slice + 1);

                    indices.Add((stack + 0) * (Slices + 1) + slice + 1);
                    indices.Add((stack + 1) * (Slices + 1) + slice);
                    indices.Add((stack + 1) * (Slices + 1) + slice + 1);
                }
            }
        }

        /// <summary>
        ///     Creates a new instance of the HollowCylinderMesh class.
        /// </summary>
        /// <returns>
        ///     A new instance of HollowCylinderMesh.
        /// </returns>
        /// <remarks>
        ///     Overriding this method is required when deriving 
        ///     from the Freezable class.
        /// </remarks>
        //protected override Freezable CreateInstanceCore()
        //{
        //    return new HollowCylinderMeshGenerator();
        //}
    }
}

