using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace DirectXEksempel07B
{
    public partial class Engine : Form
    {
        // Global variables for this project
        private Device device = null; // Rendering device
        private Matrix view;          // Positions the camera in the scene
        private Matrix projection;    // Controls scene perspective
        private Model theModel;

        public Matrix View
        {
            set { view = value; }
            get { return view; }
        }

        public Matrix Projection
        {
            set { projection = value; }
            get { return projection; }
        }

        public Device GetDevice()
        {
            return device;
        }

        public Engine()
        {
            InitializeComponent();
        }

        private void UpdateModel()
        {
            // Her tilføjes opdateringer af modellen
        }

        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.View = this.View;
            device.Transform.Projection = this.Projection;
            theModel.Render();

            device.EndScene(); //End the scene
            device.Present();
        }
        
        private void RestoreDevice()
        {
            device.RenderState.ZBufferEnable = true; // Enable z-buffering
            device.RenderState.ZBufferWriteEnable = true;
            device.RenderState.Lighting = false; // 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, 10, 0);
            device.Lights[0].Diffuse = Color.White;        
            device.Lights[0].Enabled = true;

            //    projection transform
            float aspectRatio = this.Width / this.Height;
            projection = Matrix.PerspectiveFovLH((float)(Math.PI / 4.0f),
                1.0f, 1.0f, 400.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(-10, 10, -20), new Vector3(0, 5, 0), new Vector3(0, 1, 0));
            device.RenderState.Ambient = Color.White;
            device.RenderState.CullMode = Cull.None;
            this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Keydown);
            this.MouseDown += new MouseEventHandler(this.Mousedown);
            theModel = new Model(this);
            RestoreDevice();
        }

        private void Keydown(Object sender, System.Windows.Forms.KeyEventArgs e)
        {
            theModel.Keyboard = e.KeyCode;
            if (e.KeyCode == Keys.Escape)
                Application.Exit();
            
        }

        private void Mousedown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            // Update the mouse path with the mouse information
            Point mouseDownLocation = new Point(e.X, e.Y);

            string eventString = null;
            switch (e.Button)
            {
                case MouseButtons.Left: 
                    eventString = "L";
                    break;
                case MouseButtons.Right:
                    eventString = "R";
                    break;
                case MouseButtons.Middle:
                    eventString = "M";
                    break;
                case MouseButtons.XButton1:
                    eventString = "X1";
                    break;
                case MouseButtons.XButton2:
                    eventString = "X2";
                    break;
                case MouseButtons.None:
                default:
                    break;
            }
        }
            
        static void Main()
        {
            using (Engine engine = new Engine())
            {
                engine.InitializeGraphics();
                engine.Show();
                // While the form is still valid, render and process messages
                while (engine.Created)
                {
                    engine.Render();
                    engine.UpdateModel();
                    Application.DoEvents();
                }
            }
        }
    }
}