using System;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

using Library2D;

namespace GraveyardGraph
{
	public class Wave : CircleCollidable
	{
		//Size increase in units (pixels?) / millisecond.
		public const float DELTA = .15f;
		private float DEPTH = 15f;
		private float SIZE_LIMIT = 800f;
		private float RADIUS_RESOLUTION = .75f;

		public bool dead {
			get { return this._dead; }
		}
		private bool _dead;

		public Wave (Vector2 center)
		{
			this.Center = center;
		}

		public override void CalculateNewVel(CircleCollidable that)
		{
			return;
		}

		public override void Draw(Rectangle drawArea, SpriteBatch sb, GameTime time)
		{
			//TODO: insert wav
			sb.Draw(ArtFetcher.Circle, new Rectangle((int) Game1.CenterToUpperLeft(Center).X,
															(int) Game1.CenterToUpperLeft(Center).Y,
															   	  Game1.TILE_SIZE,
																  Game1.TILE_SIZE), Color.White);
		}

		public float getForce()
		{
			float force = 64.0f / (this.Radius);
			return force;
		}

		public void update(GameTime dT)
		{
			this.Radius += DELTA * (float) dT.ElapsedGameTime.TotalMilliseconds;
			if (this.Radius > this.SIZE_LIMIT) {
				this._dead = true;
			} else {
				this._dead = false;
			}
		}

		public override bool isCollidingWith(CircleCollidable that)
		{
			float distanceBetweenCenters = (that.Center - this.Center).Length();
			float sumOfRadii = this.Radius + that.Radius;
			return distanceBetweenCenters <= sumOfRadii + DEPTH && distanceBetweenCenters >= sumOfRadii - DEPTH;
		}

		public Texture2D makeMap(GraphicsDevice gd)
		{
			int size = (int)(2 * (DEPTH + Radius) + 1);
			Texture2D result = new Texture2D (gd, size, size);
			Color[] resultColor = new Color[size * size];

			float curDepth = DEPTH * (1 - (Radius/SIZE_LIMIT));

			for (float r = Radius - curDepth; r < Radius + curDepth; r += RADIUS_RESOLUTION)
			{
				if (r < 0) //This can sometimes happen with small circles
				{
					r = 0;
					continue;
				}
				float rez = 1/r;
				for (float theta = 0; theta < 2 * Math.PI; theta += rez)
				{
					float cos = (float)Math.Cos(theta);
					float sin = (float)Math.Sin(theta);
					int x = (int)((r * cos) + Radius + curDepth);
					int y = (int)((r * sin) + Radius + curDepth);
					float sign = (r - Radius)/curDepth;
					float red = 0.5f + sign * cos / 2;
					float grn = 0.5f + sign * sin / 2;
					resultColor[x*size+y] = new Color(new Vector3(red, grn, 0f));
				}
			}

			result.SetData (resultColor);
			return result;
		}
	}
}