// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
#if SURVIVAL_TEST
using System;
using OpenTK;

namespace ClassicalSharp.Entities.Mobs {

	public abstract class AI {
		
		protected Game game;
		protected Entity entity;
		static Random random = new Random();
		
		public Vector3 MoveVelocity;
		
		public AI(Game game, Entity entity) {
			this.game = game;
			this.entity = entity;
		}
		
		public abstract void Tick(Entity target);
		
		public abstract void AttackedBy(Entity source);
		
		
		int randomCount;
		Vector3 randomDir;
		protected void MoveRandomly(Entity source) {
			// Move in new direction
			if (randomCount == 0) {
				randomDir.X = (float)(random.NextDouble() - 0.5);
				randomDir.Z = (float)(random.NextDouble() - 0.5);
			}
			
			randomCount = (randomCount + 1) & 0x1F;
			MoveInDirection(source, randomDir);
		}
		
		protected void MoveInDirection(Entity source, Vector3 dir) {
			double rotYRadians, headXRadians;
			Utils.GetHeading(dir, out rotYRadians, out headXRadians);
			
			float rotY =  (float)(rotYRadians * Utils.Rad2Deg);
			float headX = (float)(headXRadians * Utils.Rad2Deg);
			LocationUpdate update = LocationUpdate.MakeOri(rotY, headX);
			source.SetLocation(update, false);
			MoveVelocity = dir * 0.9f;
		}
	}
	
	public sealed class FleeAI : AI {
		
		public FleeAI(Game game, Entity entity) : base(game, entity) { }
		
		public override void Tick(Entity target) {
			MoveRandomly(entity);
		}
		
		public override void AttackedBy(Entity source) {
			Vector3 fleeDir = -Vector3.Normalize(source.Position - entity.Position);
			MoveInDirection(source, fleeDir * 5);
		}
	}
	
	public sealed class HostileAI : AI {
		
		public HostileAI(Game game, Entity entity) : base(game, entity) { }
		
		public override void Tick(Entity target) {
			float distSq = (target.Position - entity.Position).LengthSquared;
			if (distSq > 16 * 16) {
				MoveRandomly(entity);
			} else {
				Vector3 dir = Vector3.Normalize(target.Position - entity.Position);
				dir.Y = 0;
				MoveInDirection(entity, dir);
			}
		}
		
		public override void AttackedBy(Entity source) {
		}
	}
}
#endif