//BSD License  
//DXGfx® - http://www.eteractions.com
//Copyright (c) 2005
//by Guillaume Randon
//Permission is hereby granted, free of charge, to any person obtaining a copy of this software
//and associated documentation files (the "Software"), to deal in the Software without restriction,
//including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
//and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
//subject to the following conditions:
//The above copyright notice and this permission notice shall be included in all copies or substantial
//portions of the Software.
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
//INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 
//AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
//DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Drawing;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Microsoft.Samples.DirectX.UtilityToolkit;
using System.Collections;
using System.Windows;
using System.Windows.Forms;
using System.Xml;
using System.Diagnostics;

namespace DXGfxLib
{
    public interface IHaveID
    {
        string ID { get; }
    }

    public class HaveID : IHaveID
    {
        public string id;

        public string ID
        {
            get { return id; }
        }
    }

    public class FloatArray : HaveID
    {
        public int count;
        public float[] floats;
    }

    public class ColladaSource : HaveID
    {
        public List<FloatArray> floatArrays;

        public ColladaSource()
        {
            floatArrays = new List<FloatArray>();
        }
    }

    public class VerticesMapping : HaveID
    {
        public string positionSource;
    }

    public class ColladaMaterial : HaveID
    {
        public string effectInstance;
    }

    public class ColladaEffectProp
    {
        public float thefloat;
        public System.Drawing.Color color;
        public string texture;

        public ColladaEffectProp()
        {
        }

        public ColladaEffectProp(XmlNode xmlNode, XmlNamespaceManager nsmgr)
        {
            SetValues(xmlNode, nsmgr);
        }

        public void SetValues(XmlNode xmlNode, XmlNamespaceManager nsmgr)
        {
            XmlNode xmlColor = xmlNode.SelectSingleNode("colladans:color", nsmgr);

            if (xmlColor != null)
            {
                string[] stringValues = xmlColor.InnerText.Split(new char[] { ' ' });
                byte r = (byte)(float.Parse(stringValues[0], new System.Globalization.CultureInfo("en-US")));
                byte g = (byte)(float.Parse(stringValues[1], new System.Globalization.CultureInfo("en-US")));
                byte b = (byte)(float.Parse(stringValues[2], new System.Globalization.CultureInfo("en-US")));
                byte a = (byte)(float.Parse(stringValues[3], new System.Globalization.CultureInfo("en-US")));

                color = System.Drawing.Color.FromArgb(a, r, g, b);
            }

            XmlNode xmlTex = xmlNode.SelectSingleNode("colladans:texture", nsmgr);

            if (xmlTex != null)
            {
                texture = (string)xmlTex.Attributes["texture"].Value;
            }

            XmlNode xmlFloat = xmlNode.SelectSingleNode("colladans:float", nsmgr);

            if (xmlFloat != null)
            {
                thefloat = float.Parse(xmlFloat.InnerText, new System.Globalization.CultureInfo("en-US"));
            }
        }
    }

    public class ColladaEffect : HaveID
    {
        public ColladaEffectProp emission;
        public ColladaEffectProp ambiant;
        public ColladaEffectProp diffuse;
        public ColladaEffectProp specular;
        public ColladaEffectProp shininess;
        public ColladaEffectProp reflectivity;
        public ColladaEffectProp transparent;
        public ColladaEffectProp transparency;
    }

    public class ColladaImage : HaveID
    {
        public string filename;
    }

    public class Triangles
    {
        public string vertices;
        public int voffset;
        public string normals;
        public int noffset;
        public string texcoords;
        public int toffset;
        public List<int> indices;
        public int numPrimitives;

        public string material;

        public Triangles()
        {
            indices = new List<int>();
        }
    }

    public class LoadedEntity
    {
        public VertexBuffer vBuff;
        public IndexBuffer iBuff;
        public int numVertices = 0;
        public int numPrimitives = 0;
        public Material[] materials = null;
        public Texture[] textures = null;
    }

    public class ColladaGeometry : HaveID
    {
        public List<LoadedEntity> models;

        public ColladaGeometry()
        {
            models = new List<LoadedEntity>();
        }
    }

    public class ColladaLoader
    {
        public Device d3ddevice = null;
        public XmlDocument colladaDocument;
        public Hashtable colladaGeometries;
        public Hashtable colladaImages;
        public Hashtable colladaMaterials;
        public Hashtable colladaEffects;



        public ColladaLoader(Device device)
        {
            d3ddevice = device;

            colladaGeometries = new Hashtable();
            colladaImages = new Hashtable();
            colladaMaterials = new Hashtable();
            colladaEffects = new Hashtable();
        }


        public void Load(string fileName)
        {
            colladaGeometries.Clear();
            colladaImages.Clear();
            colladaMaterials.Clear();
            colladaEffects.Clear();

            if (File.Exists(fileName))
            {
                ParseColladaFile(fileName);
            }
            else
            {
                string currentFolder = Directory.GetCurrentDirectory();

                OpenFileDialog opdlg = new OpenFileDialog();

                opdlg.Filter = "collada files (*.dae)|*.dae|All files (*.*)|*.*";
                opdlg.FilterIndex = 2;

                if (opdlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    ParseColladaFile(opdlg.FileName);
                }

                Directory.SetCurrentDirectory(currentFolder);
            }
        }

        public void ParseColladaFile(string fileName)
        { 
            // 1.Load DOM
            // 2.Parse Geometry_Library
            // 3.For each Geometry_Library defer work to ParseGeometryLibrary
            colladaDocument = new XmlDocument();
            colladaDocument.Load(fileName);

            XmlNode root = colladaDocument.DocumentElement;

            XmlNamespaceManager nsmgr = new XmlNamespaceManager(colladaDocument.NameTable);
            nsmgr.AddNamespace("colladans", "http://www.collada.org/2005/11/COLLADASchema");

            XmlNode imagesLib = root.SelectSingleNode("colladans:library_images", nsmgr);
            XmlNodeList images = imagesLib.SelectNodes("colladans:image", nsmgr);

            foreach (XmlNode colladaImage in images)
            {
                ColladaImage img = ParseImage(colladaImage, nsmgr);
                colladaImages.Add(img.ID, img);
            }

            XmlNode materialsLib = root.SelectSingleNode("colladans:library_materials", nsmgr);
            XmlNodeList materials = materialsLib.SelectNodes("colladans:material", nsmgr);

            foreach (XmlNode colladaMaterial in materials)
            {
                ColladaMaterial mate = ParseMaterial(colladaMaterial, nsmgr);
                colladaMaterials.Add(mate.ID, mate);
            }

            XmlNode effectsLib = root.SelectSingleNode("colladans:library_effects", nsmgr);
            XmlNodeList effects = effectsLib.SelectNodes("colladans:effect", nsmgr);

            foreach (XmlNode colladaEffect in effects)
            {
                ColladaEffect eff = ParseEffect(colladaEffect, nsmgr);
                colladaEffects.Add(eff.ID, eff);
            }

            XmlNode geometryLib = root.SelectSingleNode("colladans:library_geometries", nsmgr);
            XmlNodeList geometries = geometryLib.SelectNodes("colladans:geometry", nsmgr);

            foreach (XmlNode geometry in geometries)
            {
                ColladaGeometry geom = ParseGeometry(geometry, nsmgr);
                colladaGeometries.Add(geom.ID, geom);
            }

            // TODO ! Here we should parse the scene information and modify the geometries transform accordingly!!
        }

        public ColladaImage ParseImage(XmlNode colladaImage, XmlNamespaceManager nsmgr)
        {
            ColladaImage output = new ColladaImage();
            output.id = (string)colladaImage.Attributes["id"].Value;

            output.filename = colladaImage.SelectSingleNode("colladans:init_from", nsmgr).InnerText;

            return output;
        }

        public ColladaMaterial ParseMaterial(XmlNode colladaMaterial, XmlNamespaceManager nsmgr)
        {
            ColladaMaterial output = new ColladaMaterial();

            output.id = (string)colladaMaterial.Attributes["id"].Value;

            XmlNode instEff = colladaMaterial.SelectSingleNode("colladans:instance_effect", nsmgr);
            output.effectInstance = (string)instEff.Attributes["url"].Value;
            // remove # at beginning of string
            output.effectInstance = output.effectInstance.Substring(1);

            return output;
        }

        public ColladaEffect ParseEffect(XmlNode colladaEffect, XmlNamespaceManager nsmgr)
        {
            ColladaEffect output = new ColladaEffect();

            output.id = (string)colladaEffect.Attributes["id"].Value;

            output.emission = new ColladaEffectProp(colladaEffect.SelectSingleNode("colladans:profile_COMMON/colladans:technique/colladans:phong/colladans:emission", nsmgr), nsmgr);
            output.ambiant = new ColladaEffectProp(colladaEffect.SelectSingleNode("colladans:profile_COMMON/colladans:technique/colladans:phong/colladans:ambient", nsmgr), nsmgr);
            output.diffuse = new ColladaEffectProp(colladaEffect.SelectSingleNode("colladans:profile_COMMON/colladans:technique/colladans:phong/colladans:diffuse", nsmgr), nsmgr);
            output.specular = new ColladaEffectProp(colladaEffect.SelectSingleNode("colladans:profile_COMMON/colladans:technique/colladans:phong/colladans:specular", nsmgr), nsmgr);
            output.shininess = new ColladaEffectProp(colladaEffect.SelectSingleNode("colladans:profile_COMMON/colladans:technique/colladans:phong/colladans:shininess", nsmgr), nsmgr);
            output.reflectivity = new ColladaEffectProp(colladaEffect.SelectSingleNode("colladans:profile_COMMON/colladans:technique/colladans:phong/colladans:reflectivity", nsmgr), nsmgr);
            output.transparent = new ColladaEffectProp(colladaEffect.SelectSingleNode("colladans:profile_COMMON/colladans:technique/colladans:phong/colladans:transparent", nsmgr), nsmgr);
            output.transparency = new ColladaEffectProp(colladaEffect.SelectSingleNode("colladans:profile_COMMON/colladans:technique/colladans:phong/colladans:transparency", nsmgr), nsmgr);

            return output;
        }

        public  ColladaGeometry ParseGeometry(XmlNode colladaGeom, XmlNamespaceManager nsmgr)
        {
            // On Cherche le mesh pour chaque mesh on cherche triangles.
            // A partir des données de triangles on lit le reste pour construire le bon GeometryModel3D!
            ColladaGeometry output = new ColladaGeometry();
            output.id = (string)colladaGeom.Attributes["id"].Value;
            List<LoadedEntity> computedModels = output.models;

            // Get the mesh. There should be only one mesh.
            XmlNode colladaMesh = colladaGeom.SelectSingleNode("colladans:mesh", nsmgr);
            Hashtable sources = new Hashtable();

            XmlNodeList colladaSources = colladaMesh.SelectNodes("colladans:source", nsmgr);
            foreach (XmlNode colladaSource in colladaSources)
            {
                ColladaSource src = ParseSource(colladaSource, nsmgr);
                sources.Add(src.id, src);
            }

            Hashtable mappings = new Hashtable();
            XmlNodeList colladaVertices = colladaMesh.SelectNodes("colladans:vertices", nsmgr);
            foreach (XmlNode colladaVertice in colladaVertices)
            {
                VerticesMapping mapp = ParseVertices(colladaVertice, nsmgr);
                mappings.Add(mapp.id, mapp);
            }

            List<Triangles> trianglesList = new List<Triangles>();
            XmlNodeList colladaTrianglesList = colladaMesh.SelectNodes("colladans:triangles", nsmgr);
            foreach (XmlNode colladaTriangles in colladaTrianglesList)
            {
                trianglesList.Add(ParseTriangles(colladaTriangles, nsmgr));
            }

            // We have finished loading everything we need to build our GeometryModel3D, let's do it.
            foreach (Triangles triang in trianglesList)
            {
                computedModels.Add(BuildGeometryModel3D(ref sources, ref mappings, triang));
            }

            return output;
        }

        public ColladaSource ParseSource(XmlNode colladaSource, XmlNamespaceManager nsmgr)
        {
            ColladaSource source = new ColladaSource();

            source.id = colladaSource.Attributes["id"].Value;

            XmlNodeList colladaarrays = colladaSource.SelectNodes("colladans:float_array", nsmgr);
            foreach (XmlNode colladafarray in colladaarrays)
            {
                FloatArray farray = new FloatArray();
                farray.id = colladafarray.Attributes["id"].Value;
                farray.count = int.Parse(colladafarray.Attributes["count"].Value);

                string[] stringValues = colladafarray.InnerText.Split(new Char[] { ' ' });

                farray.floats = new float[farray.count];

                for (int findex = 0; findex < farray.count; findex++)
                {
                    farray.floats[findex] = float.Parse(stringValues[findex], new System.Globalization.CultureInfo("en-US"));
                }

                source.floatArrays.Add(farray);
            }
            return source;
        }

        public VerticesMapping ParseVertices(XmlNode colladaVertices, XmlNamespaceManager nsmgr)
        {
            VerticesMapping mapping = new VerticesMapping();

            mapping.id = (string)(colladaVertices.Attributes["id"].Value);

            XmlNode positionSource = colladaVertices.SelectSingleNode("colladans:input[@semantic='POSITION']", nsmgr);
            mapping.positionSource = (string)(positionSource.Attributes["source"].Value);
            // remove starting # to have the id of the source in the positionSource string.
            mapping.positionSource = mapping.positionSource.Substring(1);

            return mapping;
        }

        public Triangles ParseTriangles(XmlNode colladaTriangles, XmlNamespaceManager nsmgr)
        {
            Triangles triangles = new Triangles();

            triangles.material = (string)colladaTriangles.Attributes["material"].Value;

            XmlNode vertices = colladaTriangles.SelectSingleNode("colladans:input[@semantic='VERTEX']", nsmgr);
            triangles.vertices = (string)(vertices.Attributes["source"].Value);
            // remove starting # to have the id of the source in the positionSource string.
            triangles.vertices = triangles.vertices.Substring(1);
            triangles.voffset = int.Parse(vertices.Attributes["offset"].Value);

            XmlNode normals = colladaTriangles.SelectSingleNode("colladans:input[@semantic='NORMAL']", nsmgr);
            triangles.normals = (string)(normals.Attributes["source"].Value);
            // remove starting # to have the id of the source in the positionSource string.
            triangles.normals = triangles.normals.Substring(1);
            triangles.noffset = int.Parse(normals.Attributes["offset"].Value);

            XmlNode texcoords = colladaTriangles.SelectSingleNode("colladans:input[@semantic='TEXCOORD']", nsmgr);
            if (texcoords != null)
            {
                triangles.texcoords = (string)(texcoords.Attributes["source"].Value);
                // remove starting # to have the id of the source in the positionSource string.
                triangles.texcoords = triangles.texcoords.Substring(1);
                triangles.toffset = int.Parse(texcoords.Attributes["offset"].Value);
            }
            else
            {
                triangles.texcoords = "";
                triangles.toffset = -1;
            }

            triangles.numPrimitives = int.Parse(colladaTriangles.Attributes["count"].Value);
            string[] stringValues = colladaTriangles.InnerText.Split(new Char[] { ' ' });

            // Last string is empty don't forget to remove it.
            for (int sindex = 0; sindex < stringValues.Length - 1; sindex++)
            {
                triangles.indices.Add(int.Parse(stringValues[sindex]));
            }

            return triangles;
        }

        public LoadedEntity BuildGeometryModel3D(ref Hashtable sources, ref Hashtable mappings, Triangles triangles)
        {
            VerticesMapping map = (VerticesMapping)mappings[triangles.vertices];
            ColladaSource positions = (ColladaSource)sources[map.positionSource];


            int res;
            int n = Math.DivRem(positions.floatArrays[0].floats.Length, 3, out res);

            List<Vector3> points = new List<Vector3>();
            List<Vector3> normals = new List<Vector3>();

            if (res != 0)
            {
                throw new Exception("This is terribly wrong! Check input file.");
            }

            for (int i = 0; i < n; i++)
            {
                float X = positions.floatArrays[0].floats[3*i];
                float Z = positions.floatArrays[0].floats[3*i+1];
                float Y = positions.floatArrays[0].floats[3*i+2];
                points.Add(new Vector3(X,Y,Z));
            }

            int indicesStride = 1;


            if (!triangles.normals.Equals(""))
            {
                indicesStride++;

               
                ColladaSource normalsSrc = (ColladaSource)sources[triangles.normals];

                n = Math.DivRem(normalsSrc.floatArrays[0].floats.Length, 3, out res);

                if (res != 0)
                {
                    throw new Exception("This is terribly wrong! Check input file.");
                }

                for (int j = 0; j < n; j++)
                {
                    float X = normalsSrc.floatArrays[0].floats[3 * j];
                    float Z = normalsSrc.floatArrays[0].floats[3 * j + 1];
                    float Y = normalsSrc.floatArrays[0].floats[3 * j + 2];
                    normals.Add(new Vector3(X, Y, Z));
                }
            }

            List<Vector2> myTextureCoordinatesCollection = new List<Vector2>();
            // Create a collection of texture coordinates for the MeshGeometry3D.
            if (!triangles.texcoords.Equals(""))
            {
                indicesStride++;

                ColladaSource texcoords = (ColladaSource)sources[triangles.texcoords];

                n = Math.DivRem(texcoords.floatArrays[0].floats.Length, 2, out res);

                if (res != 0)
                {
                    throw new Exception("This is terribly wrong! Check input file.");
                }

                myTextureCoordinatesCollection = new List<Vector2>();

                for (int k = 0; k < n; k++)
                {
                    float U = texcoords.floatArrays[0].floats[2*k];
                    float V = 1 - texcoords.floatArrays[0].floats[2*k + 1];
                    myTextureCoordinatesCollection.Add(new Vector2(U, V));
                }
            }

            // We should have position normal texcoord so this makes 3 and num of indices divided by 3 
            // should give an int. Let's Check it!
            n = Math.DivRem(triangles.indices.Count, indicesStride * triangles.numPrimitives, out res);

            if (res != 0)
            {
                throw new Exception("This is terribly wrong! Check input file.");
            }

            // Create a collection of triangle indices for the MeshGeometry3D.
            List<Int32> myTriangleIndicesCollection = new List<Int32>();
            List<Vector3> destPoints = new List<Vector3>();
            List<Vector3> destNormals = new List<Vector3>();;
            List<Vector2> destTexCoord = new List<Vector2>();


            for (int h = 0; h < triangles.numPrimitives; h++)
            {
                // This is tricky in list of indices first refers to vertices (offset 0)
                // then second to normal (offset 1)
                // then third to texcoord (offset 2)
                // technically as I can not guarantee I can share any vertex it is here I should build 
                // vertex/normal/tex association for each indice in the list !
                destPoints.Add(points[triangles.indices[3 * indicesStride * h]]);
                if (indicesStride >= 2)
                {
                    destNormals.Add(normals[triangles.indices[3 * indicesStride * h + 1]]);
                }
                if (indicesStride == 3)
                {
                    destTexCoord.Add(myTextureCoordinatesCollection[triangles.indices[3 * indicesStride * h + 2]]);
                }

                destPoints.Add(points[triangles.indices[3 * (indicesStride * h + 2)]]);
                if (indicesStride >= 2)
                {
                    destNormals.Add(normals[triangles.indices[3 * (indicesStride * h + 2) + 1]]);
                }
                if (indicesStride == 3)
                {
                    destTexCoord.Add(myTextureCoordinatesCollection[triangles.indices[3 * (indicesStride * h + 2) + 2]]);
                }

                destPoints.Add(points[triangles.indices[3 * (indicesStride * h + 1)]]);
                if (indicesStride >= 2)
                {
                    destNormals.Add(normals[triangles.indices[3 * (indicesStride * h + 1) + 1]]);
                }
                if (indicesStride == 3)
                {
                    destTexCoord.Add(myTextureCoordinatesCollection[triangles.indices[3 * (indicesStride * h + 1) + 2]]);
                }

                myTriangleIndicesCollection.Add(3*h);
                myTriangleIndicesCollection.Add(3*h + 1);
                myTriangleIndicesCollection.Add(3*h + 2);
            }


            LoadedEntity entity = new LoadedEntity();

            if (!triangles.normals.Equals(""))
            {
                if (!triangles.texcoords.Equals(""))
                {
                    int numVertices = triangles.numPrimitives * 3;
                    
                    CustomVertex.PositionNormalTextured[] vertices = new CustomVertex.PositionNormalTextured[numVertices];
                    for (int i = 0; i < numVertices; i++)
                    {
                        vertices[i].Position = destPoints[i];
                        vertices[i].Normal = destNormals[i];
                        vertices[i].Tu = destTexCoord[i].X;
                        vertices[i].Tv = destTexCoord[i].Y;
                    }

                    entity.vBuff = new VertexBuffer(typeof(CustomVertex.PositionNormalTextured),
                        numVertices, d3ddevice, Usage.Dynamic, CustomVertex.PositionNormalTextured.Format, Pool.SystemMemory);


                    GraphicsStream stm = entity.vBuff.Lock(0, 0, LockFlags.NoOverwrite);
                    stm.Write(vertices);
                    entity.vBuff.Unlock();

                    entity.iBuff = new IndexBuffer(typeof(Int32), numVertices, d3ddevice, Usage.Dynamic, Pool.SystemMemory);

                    GraphicsStream stmi = entity.iBuff.Lock(0, 0, LockFlags.NoOverwrite);
                    stmi.Write(myTriangleIndicesCollection.ToArray());
                    entity.iBuff.Unlock();

                    entity.numPrimitives = triangles.numPrimitives;
                    entity.numVertices = numVertices;
                }
                else
                {
                    //entity.geometry = new Mesh(triangles.numPrimitives, n, MeshFlags.WriteOnly, CustomVertex.PositionNormal.Format, d3ddevice);
                }
            }
            else
            {
                if (!triangles.texcoords.Equals(""))
                {
                    //entity.geometry = new Mesh(triangles.numPrimitives, n, MeshFlags.WriteOnly, CustomVertex.PositionTextured.Format, d3ddevice);
                }
                else
                {
                    //entity.geometry = new Mesh(triangles.numPrimitives, n, MeshFlags.WriteOnly, CustomVertex.PositionColored.Format, d3ddevice);
                }
            }

            //Define material and apply to the mesh geometries.
            List<Material> destMaterials = new List<Material>();
            List<Texture> destTextures = new List<Texture>();

            if (!triangles.material.Equals(""))
            {
                ColladaMaterial mat = colladaMaterials[triangles.material] as ColladaMaterial;

                if (mat != null)
                {
                    ColladaEffect eff = colladaEffects[mat.effectInstance] as ColladaEffect;

                    if (eff != null)
                    {
                        if (eff.diffuse.texture != null)
                        {
                            if (!eff.diffuse.texture.Equals(""))
                            {
                                string filename = ((ColladaImage)colladaImages[eff.diffuse.texture]).filename;


                                Microsoft.DirectX.Direct3D.Material mate = new Microsoft.DirectX.Direct3D.Material();
                                mate.Ambient = System.Drawing.Color.AliceBlue;
                                mate.Diffuse = System.Drawing.Color.Beige;
                                mate.Emissive = System.Drawing.Color.White;
                                mate.Specular = System.Drawing.Color.Red;
                                mate.SpecularSharpness = 2;

                                destMaterials.Add(mate);

                                Texture currTex = TextureLoader.FromFile(d3ddevice, filename);
                                destTextures.Add(currTex);
                            }
                        }
                    }
                }
            }

            entity.materials = destMaterials.ToArray();
            entity.textures = destTextures.ToArray();

            

            return entity;
        }

//        To use
//            collada = new ColladaLoader(e.Device);

//collada.Load("Villada.dae");

//Puis utiliser le code suivant pour effectuer le rendu de ce qui a été chargé:

//IDictionaryEnumerator enumGeometrie = collada.colladaGeometries.GetEnumerator();

//while (enumGeometrie.MoveNext())

//{

//   ColladaGeometry collGeom = enumGeometrie.Value as ColladaGeometry;

//   if (collGeom == null)

//      continue;

//   foreach (LoadedEntity entity in collGeom.models)

//   {

//            if (entity.materials.Length == 0)

//               continue;

//            if (entity.textures.Length == 0)

//               continue;

//            device.SetTransform(TransformType.World, 

//                        Matrix.Multiply(Matrix.Scaling(0.1f, 0.1f, 0.1f),  Matrix.Translation(0.0f, 5.0f, 0.0f)));

//            device.Indices = entity.iBuff;

//            device.SetStreamSource(0, entity.vBuff, 0);

//            device.Material = entity.materials[0];

//            device.SetTexture(0, entity.textures[0]);

//            device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 

//                        entity.numVertices, 0,   entity.numPrimitives);

//    }}

    }
}
