using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;

namespace Ika.Graphics
{
    public class MeshInstance
    {
        Mesh m_mesh;
        public Mesh Mesh
        {
            get { return m_mesh; }
            set { m_mesh = value; }
        }

        Material m_material;
        public Material Material
        {
            get { return m_material; }
            set { m_material = value; }
        }

        Matrix m_world;
        public Matrix World
        {
            get { return m_world; }
            set { m_world = value; }
        }

        public MeshInstance(Mesh mesh)
        {
            m_mesh = mesh;
            m_world = Matrix.Identity;
            m_material = Material.Default;
        }

        public MeshInstance(Mesh mesh, Matrix World, Material material)
        {
            m_mesh = mesh;
            m_world = World;
            m_material = material;
        }

        public MeshInstance(ModelMesh modelMesh, Matrix meshWorld, Matrix modelWorld)
        {
            m_mesh = new MeshImpl(modelMesh, meshWorld);
            m_world = meshWorld * modelWorld;
            m_material = Material.Default;
        }

        public MeshInstance(ModelMesh modelMesh, Matrix meshWorld, Matrix modelWorld, Material material)
        {
            m_mesh = new MeshImpl(modelMesh, meshWorld);
            m_world = meshWorld * modelWorld;
            m_material = material;
        }

        public MeshInstance(Model model, Matrix modelWorld, Material material)
        {
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);

            ModelMesh modelMesh = model.Meshes[0];
            Matrix meshWorld = transforms[modelMesh.ParentBone.Index];

            m_mesh = new MeshImpl(modelMesh, meshWorld);
            m_world = meshWorld * modelWorld;
            m_material = material;

        }

        public static MeshInstance[] LoadModel(Model model)
        {
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);

            MeshInstance[] meshes = new MeshInstance[model.Meshes.Count];
            for (int i = 0; i < model.Meshes.Count; i++)
            {
                ModelMesh modelMesh = model.Meshes[i];
                Matrix meshWorld = transforms[modelMesh.ParentBone.Index];

                meshes[i] = new MeshInstance(modelMesh, meshWorld, Matrix.Identity);
                if(modelMesh.Effects[0] is BasicEffect)
                {
                    BasicEffect effect = (BasicEffect)modelMesh.Effects[0];
                    meshes[i].Material.UseDiffuseTexture = effect.TextureEnabled;
                    meshes[i].Material.Texture = effect.Texture;
                    meshes[i].Material.SpecularPower = effect.SpecularPower;
                    meshes[i].Material.SpecularIntensity = effect.SpecularColor.Length() / (float)Math.Sqrt(3);
                }
            }

            return meshes;
        }
    }
}
