using System;
using System.IO;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace DirectXEksempel04
{
    public partial class Form1 : Form
    {
        // Global variables for this project
        private Device device = null; // Rendering device
        private Mesh teapotMesh;
        private Material teapotMaterial;

        private Matrix world;            //    positions the teapot in the scene
        private Matrix view;             //    positions the camera in the scene
        private Matrix projection;       //    controls scene perspective
        private float angle = 0.01F;

        public Form1()
        {
            // Set the initial size of the form
            this.ClientSize = new System.Drawing.Size(800, 600);
            // And its caption
            this.Text = "DirectX Eksempel 4A - Brug af Mesh";
        }

        private void Render()
        {
            //Clear the backbuffer to a blue color 
            device.Clear(ClearFlags.ZBuffer | ClearFlags.Target, System.Drawing.Color.DarkBlue, 1.0f, 0);

            device.BeginScene(); //Begin the scene
            device.Transform.World = world;
            device.Transform.View = view;
            device.Transform.Projection = projection;
            device.Material = teapotMaterial;
            device.SetTexture(0, null);
            teapotMesh.DrawSubset(0);
            device.EndScene(); //End the scene
            device.Present();
        }

        private void UpdateScene()
        {
            world = world * Matrix.Translation(0, 0, -5) * Matrix.RotationY(angle) *
                Matrix.Translation(0, 0, 5);
        }

        private void RestoreDevice()
        {
            device.RenderState.ZBufferEnable = true; // Enable z-buffering
            device.RenderState.ZBufferWriteEnable = true;
            device.RenderState.Lighting = true; // Enable lighting
            device.RenderState.Ambient = Color.Gray; // set the ambient color

            // Configure a directional light
            device.Lights[0].Type = LightType.Directional;
            device.Lights[0].Direction = new Vector3(10, 3, 0);
            device.Lights[0].Diffuse = Color.White;
            device.Lights[0].Enabled = true;

            //    projection transform
            projection = Matrix.PerspectiveFovLH((float)(Math.PI / 4.0f),
                (float)(this.Width / this.Height), 1.0f, 100.0f);
        }

        public void InitializeGraphics()
        {
            // Device til DirectX Rendering
            PresentParameters presentParams = new PresentParameters();
            presentParams.Windowed = true;
            presentParams.SwapEffect = SwapEffect.Discard;
            presentParams.AutoDepthStencilFormat = DepthFormat.D16;
            presentParams.EnableAutoDepthStencil = true;
            device = new Device(0, DeviceType.Hardware, this,
                CreateFlags.SoftwareVertexProcessing, presentParams);
            // Initial values for the view and world transforms
            view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 5), new Vector3(0, 1, 0));
            world = Matrix.Translation(0, 0, 5);
            //device.RenderState.CullMode = Cull.None;
            RestoreDevice();
            // Create the teapot mesh and material
            teapotMesh = Mesh.Teapot(device);
            teapotMaterial = new Material();
            teapotMaterial.AmbientColor = new ColorValue(Color.Red.R, Color.Red.G, Color.Red.B);
            teapotMaterial.DiffuseColor = new ColorValue(Color.Red.R, Color.Red.G, Color.Red.B);
        }

        public static void Main()
        {
            using (Form1 engine = new Form1())
            {
                engine.InitializeGraphics();
                engine.Show();
                // While the form is still valid, render and process messages
                while (engine.Created)
                {
                    engine.UpdateScene();
                    engine.Render();
                    Application.DoEvents(); // Windows events
                }
            }
        }

    }
}