// /home/epsilon/Projects/Asteroid/ABot/Framework1/Bot1Alpha/Bot.cs created with MonoDevelop
// User: epsilon at 19:40 19.04.2008
//

using System;
using Framework1;

namespace Bot1Alpha
{
	public class Bot : Framework1.BotPluginTemplate
	{
		// fields
		private Framework1.KeySet theCurrentKeys = new KeySet();
		private Framework1.Playfield thePlayfield;
		
		// constructor
		public Bot()
		{
			LogOutput.LogInfo("Bot1Alpha", "Starting Bot1Alpha");
		}
		
		// methods
		public override void UpdatePlayfield (Framework1.Playfield playfield)
		{
			thePlayfield = playfield;
			
			bool shouldFire = true;
			if (theCurrentKeys.IsPushed(KeySet.Keys.Fire))
				shouldFire = false;
			
			theCurrentKeys.ReleaseKeys();

			if (thePlayfield.ShipPresent)
			{
				Framework1.Sprite nextTarget = null;
				Framework1.Point2D distance = null;
				
				if (thePlayfield.AsteroidsByDistance.Count > 0)
				{
					// target nearest asteroid
					nextTarget = thePlayfield.AsteroidsByDistance[0];
					distance = nextTarget.Position - thePlayfield.ShipSprite.Position;
				}
					
				// target ufo if nearest
				if (thePlayfield.SaucerPresent)
				{
					if (nextTarget == null
					    || (thePlayfield.SaucerSprite.Position - thePlayfield.ShipSprite.Position).Abs() < distance.Abs())
					{
						nextTarget = thePlayfield.SaucerSprite;
						distance = nextTarget.Position - thePlayfield.ShipSprite.Position;
						LogOutput.LogDebug("Bot1Alpha", "Targetting ufo");
					}
				}
				
				//LogOutput.LogDebug("Bot1Alpha", "Ship position: " + thePlayfield.ShipSprite.Position.ToString());
				//LogOutput.LogDebug("Bot1Alpha", "Ship direction: " + thePlayfield.ShipSprite.Direction.ToString());

				// is there a target?
				if (nextTarget != null)
				{
					LogOutput.LogDebug("Bot1Alpha", "Target position: " + nextTarget.Position.ToString());
					LogOutput.LogDebug("Bot1Alpha", "Distance: " + distance.ToString());
					
					// turn to the nearest asteroid
					// calculation of the direction done by vector product and addition theorems
					if ( Math.Sin(thePlayfield.ShipSprite.Phi - distance.Phi())  > 0)
					{
						theCurrentKeys.PushKey(KeySet.Keys.Right);
					}
					else
					{
						theCurrentKeys.PushKey(KeySet.Keys.Left);
					}
					
					// hyperspace if asteroid gets to close
					if (distance.Abs() < 45)
						theCurrentKeys.PushKey(KeySet.Keys.HyperSpace);

								// toggle fire
					if (shouldFire)
						theCurrentKeys.PushKey(KeySet.Keys.Fire);
					
					// move if asteroid is to far away 
					if (distance.Abs() > 400)
						theCurrentKeys.PushKey(KeySet.Keys.Thrust);
				}
			}			
			
			// request key pushing
			Framework1.ChangeKeysEventArgs args = new ChangeKeysEventArgs();
			args.keys = theCurrentKeys;
			
			OnChangeKeys(args);
		}
		
		public override string ToString ()
		{
			return "Bot1Alpha";
		}

	}
}
