using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace KinPortal {
	public abstract class Object : DrawableGameComponent {
		public string FilePath {get; private set;}
		public Scene Scene {get; private set;}
		public Model Model {get; private set;}

		private Matrix[] m_world;

		public abstract Vector3 Pos {get; set;}
		public abstract Quaternion Rot {get; set;}

		public bool EnableLighting {get; set;}

		public Object(string filepath, Scene scene)
				: base(scene.Game) {
			FilePath = filepath;
			Scene = scene;
			Model = Game.Content.Load<Model>(FilePath);

			m_world = new Matrix[Model.Bones.Count];
			Model.CopyAbsoluteBoneTransformsTo(m_world);
			EnableLighting = true;
			UpdateOrder = 2;
		}

		public override void Draw(GameTime gameTime) {
			BlendState bs = new BlendState();
			bs.AlphaBlendFunction = BlendFunction.Add;
			bs.AlphaSourceBlend = Blend.SourceAlpha;
			bs.ColorSourceBlend = Blend.SourceAlpha;
			bs.AlphaDestinationBlend = Blend.InverseSourceAlpha;
			bs.ColorDestinationBlend = Blend.InverseSourceAlpha;
			Game.GraphicsDevice.BlendState = bs;
			Game.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
			Game.GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;

			foreach(ModelMesh mesh in Model.Meshes) {
				foreach(BasicEffect effect in mesh.Effects) {
					if(EnableLighting) {
						effect.EnableDefaultLighting();
						effect.PreferPerPixelLighting = true;
					} else {
						effect.LightingEnabled = false;
					}
					effect.World = m_world[mesh.ParentBone.Index] *
					Matrix.CreateFromQuaternion(Rot) * Matrix.CreateTranslation(Pos);
					effect.View = Scene.Camera.LookAtMatrix;
					effect.Projection = Scene.Camera.ProjectionMatrix;
				}
				mesh.Draw();
			}
			base.Draw(gameTime);
		}
	}
}
