using System;
using System.Collections.Generic;
using System.Text;
using Vortex.SceneFramework;
using Vortex.Drawing;

namespace Vortex.Demo.Pacman {

	class Unit : Node, ISceneComponent	{
		public const float TURN_THRESOLD = 0.05f;

		/// <summary>
		/// Gets or sets the direction of unit.
		/// </summary>
		/// <value>The direction of unit.</value>
		public Vector2 Direction { get; set; }

		/// <summary>
		/// Gets or sets the speed of the unit.
		/// </summary>
		/// <value>The speed of the unit.</value>
		public float Speed { get; set; }

		/// <summary>
		/// Gets a value indicating whether this unit is stopped.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if this unit is stopped; otherwise, <c>false</c>.
		/// </value>
		public bool IsStopped {
			get { return Direction.IsEmpty; }
		}

		/// <summary>
		/// Gets the world object of this unit.
		/// </summary>
		/// <value>The world of this unit.</value>
		public GameWorld World {
			get {
				return Parent as GameWorld;
			}
		}

		#region ISceneComponent Members

		/// <summary>
		/// Invoked on domain component is loaded.
		/// </summary>
		/// <param name="resources">The domain resource collection.</param>
		public virtual void ComponentLoad(Vortex.Resources.IResourceCollection resources) {
			;
		}

		/// <summary>
		/// Invoked on domain component is loaded. Note, component should be attached to domain to receive this event on domain unload.
		/// </summary>
		public virtual void ComponentUnload() {
			;
		}

		#endregion

		/// <summary>
		/// Checks the world bounds for unit.
		/// </summary>
		protected void CheckWorldBounds() {
			WorldMap map = World.Map;
			Vector2 mapSize = new Vector2(map.Width - 1, map.Height - 1);
			if (LocationX < 0.0f) {
				LocationX += mapSize.X;
			}
			if (LocationX > mapSize.X) {
				LocationX -= mapSize.X;
			}
			if (LocationY < 0.0f) {
				LocationY += mapSize.Y;
			}
			if (LocationY > mapSize.Y) {
				LocationY -= mapSize.Y;
			}
		}

		/// <summary>
		/// Determines whether this unit can go to the specified location.
		/// </summary>
		/// <param name="location">The location.</param>
		/// <returns>
		/// 	<c>true</c> if this unit can go to the specified location; otherwise, <c>false</c>.
		/// </returns>
		protected bool CanGoTo(Vector2 location) {
			return World.Map.IsAccessible((int)(location.X + 0.5f), (int)(location.Y + 0.5f));
		}

		/// <summary>
		/// Determines whether this instance [can go to] the specified location.
		/// </summary>
		/// <param name="location">The location.</param>
		/// <param name="step">The step which unit is going to do.</param>
		/// <returns>
		/// 	<c>true</c> if this instance [can go to] the specified location; otherwise, <c>false</c>.
		/// </returns>
		protected bool CanGoTo(Vector2 location, Vector2 step) {
			return CanGoTo(location + step);
		}

		/// <summary>
		/// Snaps the location to map cell.
		/// </summary>
		public void SnapCell() {
			Location = Location.Rounded;
		}

		/// <summary>
		/// Stops pacman unit.
		/// </summary>
		public void Stop() {
			//snap location
			SnapCell();
			//make zero direction
			Direction = Vector2.Zero;
		}

	}
}
