#include "scripts/bpong/common.txt"
#include "scripts/Math.txt"

namespace BPong {
	//pivot point of pads is bottom center
	class Pad {
		kActor @actor;
		bool leftSide;
		bool aiEnabled;
		float aiSpeed = 20.0f;
		float width = 100.0f;
		float height = 160.0f;
		float widthHalf = 50.0f;
		float heightHalf = 80.0f;
		//------------------------------------------------------------------------------------------------------------------------
		Pad(kActor @newActor, const bool newLeftSide) {
			@actor = newActor;
			leftSide = newLeftSide;
		}
		//------------------------------------------------------------------------------------------------------------------------
		~Pad() {
			actor.Remove();
		}
		//------------------------------------------------------------------------------------------------------------------------
		kVec3 Pos {
			get const {
				return actor.Origin();
			}
			set {
				//keep the position in the play area
				if (leftSide) {
					value.x = Math::Clampf(value.x, PadAreaLeftMinX, PadAreaLeftMaxX);
				} else {
					value.x = Math::Clampf(value.x, PadAreaRightMinX, PadAreaRightMaxX);
				}
				value.z = Math::Clampf(value.z, PadAreaMinZ, PadAreaMaxZ);
				
				actor.Origin() = value;
			}
		}
		//------------------------------------------------------------------------------------------------------------------------
		kVec3 Scale {
			get const {
				return actor.Scale();
			}
			set {
				actor.Scale() = value;
			}
		}
		//------------------------------------------------------------------------------------------------------------------------
		bool Visible {
			get const {
				return (actor.Flags() & AF_NODRAW) == 0;
			}
			set {
				if (value) {
					actor.Flags() &= ~AF_NODRAW;
				}
				else {
					actor.Flags() |= AF_NODRAW;
				}
			}
		}
		//------------------------------------------------------------------------------------------------------------------------
		// Returns true if point is inside a Rect
		//------------------------------------------------------------------------------------------------------------------------
		bool PointInRectXZ(const kVec3 point, const kVec3 rMin, const kVec3 rMax) {
			return (point.x >= rMin.x and point.x <= rMax.x) and (point.z >= rMin.z and point.z <= rMax.z);
		}
		//------------------------------------------------------------------------------------------------------------------------
		bool PointCollided(const kVec3 point) {
			return PointInRectXZ(point, kVec3(Pos.x - widthHalf, 0.0f, Pos.z), kVec3(Pos.x + widthHalf, 0.0f, Pos.z + height));
		}
		//------------------------------------------------------------------------------------------------------------------------
		void Update(const Main@ &in main) {
			if (!Visible) {
				return;
			}
			
			if (aiEnabled) {
				float targetZ = Pos.z;
				//if ball is moving away then go to center of screen
				//if ( main.ball.velocity.x < 0) {
				
				bool incomingBall = false;
				//check if all visible balls are heading left.
				for (uint i = 0; i < main.balls.length(); i++) {
					bool incomingVel = leftSide ? (main.balls[i].velocity.x < 0) : (main.balls[i].velocity.x > 0);
					if (main.balls[i].Visible and incomingVel) {
						incomingBall = true;
						break;
					}
				}

				if (!incomingBall) {
					targetZ = PadCenterZ;
				} else { //if ball is not moving away then go to closest ball
				
					//ball.Pos.Distance(pad2.Pos)
					float closestDistance = 99999.0f;
					for (uint i = 0; i < main.balls.length(); i++) {
						if (main.balls[i].Visible) {
							float d = Pos.Distance(main.balls[i].Pos);
							if (d < closestDistance) {
								closestDistance = d;
								targetZ = main.balls[i].Pos.z;
							}
						}
					}

					//targetZ = main.ball.Pos.z; //closest ball
				}
				if (Pos.z + heightHalf > targetZ) {
					//only move if it doesn't go over the size of move speed
					if (Pos.z + heightHalf - aiSpeed > targetZ) {
						Pos = kVec3(Pos.x, Pos.y, Pos.z - aiSpeed);
					}
				} else if (Pos.z + heightHalf < targetZ) {
					//only move if it doesn't go over the size of move speed
					if (Pos.z + heightHalf + aiSpeed < targetZ) {
						Pos = kVec3(Pos.x, Pos.y, Pos.z + aiSpeed);
					}
				}
			}
		}
		//------------------------------------------------------------------------------------------------------------------------
	}
}
