using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace KinPortal {
	public class Game : Microsoft.Xna.Framework.Game {
		private GraphicsDeviceManager Graphics {get; set;}
		private Cursor m_leftCursor;
		private Cursor m_rightCursor;

		public Scene Scene {get; private set;}
		public HandsTracker HandsTracker {get; private set;}

		public Game() {
			Graphics = new GraphicsDeviceManager(this);
			Content.RootDirectory = "Resources";
		}

		protected override void Initialize() {
			Window.AllowUserResizing = true;
			Window.ClientSizeChanged += new EventHandler<EventArgs>(Window_ClientSizeChanged);
			Graphics.PreferredBackBufferWidth = 900;
			Graphics.PreferredBackBufferHeight = 512;
			Graphics.ApplyChanges();

			HandsTracker = new HandsTracker(900, 512);
			//HandsTracker.Run();

			Scene = new Scene(this, new Camera(this, new Vector3(-15, -15, 15), 45, -30, 0, 70, 0.1f, 1000));
			this.Components.Add(Scene);
			base.Initialize();
		}

		protected override void LoadContent() {
			Scene.AddComponent(new DynamicObject(
				"models\\cube",
				new Vector3(0, 0, 5f), Quaternion.Identity,
				Scene, ShapeType.BOX, false, new GrabStrategy()
			));
			Scene.AddComponent(new DynamicObject(
				"models\\monkey",
				new Vector3(0, 4, 5f), Quaternion.Identity,
				Scene, ShapeType.SPHERE, false, new GrabStrategy()
			));
			Scene.AddComponent(new DynamicObject(
				"models\\cube",
				new Vector3(3, 0, 5f), Quaternion.Identity,
				Scene, ShapeType.BOX, false, new GrabStrategy()
			));
			Scene.AddComponent(new DynamicObject(
				"models\\monkey",
				new Vector3(0, -4, 5f), Quaternion.Identity,
				Scene, ShapeType.SPHERE, false, new GrabStrategy()
			));
			Scene.AddComponent(new DynamicObject(
				"models\\sphere",
				new Vector3(-3, 0, 5f), Quaternion.Identity,
				Scene, ShapeType.SPHERE, false, new GrabStrategy()
			));
			Scene.AddComponent(new DynamicObject("models\\level",
				new Vector3(0, 0, 0), Quaternion.Identity, Scene, ShapeType.TRIANGULATE, true, new DrawPortalStrategy()
			));
			Scene.AddComponent(new InterruptorObject(
				"models\\target",
				new Vector3(19.8f, 0, 10f), Quaternion.CreateFromYawPitchRoll(0, 0, MathHelper.ToRadians(180)),
				Scene, ShapeType.TRIANGULATE, true, new NoTargetingStrategy(), new TargetCollisionStrategy()
			));

			m_leftCursor = new Cursor(this, new SpriteBatch(GraphicsDevice), "textures\\tex_cursor_red", new Point(48, 48), HandsTracker.LeftHand);
			this.Components.Add(m_leftCursor);
			m_rightCursor = new Cursor(this, new SpriteBatch(GraphicsDevice), "textures\\tex_cursor_blue", new Point(48, 48), HandsTracker.RightHand);
			this.Components.Add(m_rightCursor);
		}

		protected override void UnloadContent() {}

		protected override void Update(GameTime gameTime) {
			/* Quit Game */
			if(Keyboard.GetState().IsKeyDown(Keys.Escape)) {
				Exit();
			}

			/* Move Forward */
			if(Keyboard.GetState().IsKeyDown(Keys.Z)) {
				Scene.Camera.MoveForward(0.08f);
			}

			/* Move Backware */
			if(Keyboard.GetState().IsKeyDown(Keys.S)) {
				Scene.Camera.MoveBackward(0.08f);
			}

			/* Move Left */
			if(Keyboard.GetState().IsKeyDown(Keys.Q)) {
				Scene.Camera.MoveLeft(0.08f);
			}

			/* Move Right */
			if(Keyboard.GetState().IsKeyDown(Keys.D)) {
				Scene.Camera.MoveRight(0.08f);
			}

			/* Move Up */
			if(Keyboard.GetState().IsKeyDown(Keys.Space)) {
				Scene.Camera.MoveUp(0.08f);
			}

			/* Move Down */
			if(Keyboard.GetState().IsKeyDown(Keys.LeftShift)) {
				Scene.Camera.MoveDown(0.08f);
			}
			
			/* Rotate Up */
			if(Keyboard.GetState().IsKeyDown(Keys.Up)) {
				Scene.Camera.Rotate(0, 1.8f, 0);
			}

			/* Rotate Down */
			if(Keyboard.GetState().IsKeyDown(Keys.Down)) {
				Scene.Camera.Rotate(0, -1.8f, 0);
			}

			/* Rotate Left */
			if(Keyboard.GetState().IsKeyDown(Keys.Left)) {
				Scene.Camera.Rotate(1.8f, 0, 0);
			}

			/* Rotate Right */
			if(Keyboard.GetState().IsKeyDown(Keys.Right)) {
				Scene.Camera.Rotate(-1.8f, 0, 0);
			}

			MouseState ms = Mouse.GetState();
			HandsTracker.LeftHand.Pos = new Point(ms.X, ms.Y);
			HandsTracker.RightHand.Pos = new Point(ms.X, ms.Y);
			HandsTracker.LeftHand.PrevIsClosed = HandsTracker.LeftHand.IsClosed;
			HandsTracker.LeftHand.IsClosed = (ms.LeftButton == ButtonState.Pressed);
			HandsTracker.RightHand.PrevIsClosed = HandsTracker.RightHand.IsClosed;
			HandsTracker.RightHand.IsClosed = (ms.RightButton == ButtonState.Pressed);
			HandsTracker.LeftHand.Depth = (double) ms.ScrollWheelValue / 1000.0f;
			HandsTracker.RightHand.Depth = (double) ms.ScrollWheelValue / 1000.0f;

			base.Update(gameTime);
		}

		protected override void Draw(GameTime gameTime) {
			GraphicsDevice.Clear(Color.SkyBlue);
			Scene.Draw(gameTime);
			m_leftCursor.Draw(gameTime);
			m_rightCursor.Draw(gameTime);
			base.Draw(gameTime);
		}

		public void Window_ClientSizeChanged(object sender, EventArgs e) {
			HandsTracker.InteractionRegionWidth = GraphicsDevice.Viewport.Width;
			HandsTracker.InteractionRegionHeight = GraphicsDevice.Viewport.Height;
		}
	}
}
