import standard;
import node;
import random;

//constants
var SPEED: int const = 4;

var SPRITE_WIDTH: int const = 64;
var SPRITE_HEIGHT: int const = 64;

var TILE_WIDTH: int const = 32;
var TILE_HEIGHT: int const = 32;


//variables
var parent: opaque = null; //cache the parent for quick access

var gridX: int = 1; //position on the game grid
var gridY: int = 1;

var realX: int = 0; //will change until realX = gridX * SPRITE_WIDTH
var realY: int = 0;

var motionX: int = 0; //normalized movement direction
var motionY: int = 0;

var direction: int = null; //BUGFIX: animation not looping properly

var stepAI: int = 0;

//polyfills - animating different cycles on one image 
var stepCount: int = 0;

fn faceDown(node: opaque) {
	if (direction == 0) return;
	direction = 0;
	node.setNodeRect(0, 0, 32, 32);
	node.setNodeFrames(2);
}

fn faceUp(node: opaque) {
	if (direction == 1) return;
	direction = 1;
	node.setNodeRect(32 * 2, 0, 32, 32);
	node.setNodeFrames(2);
}

fn faceRight(node: opaque) {
	if (direction == 2) return;
	direction = 2;
	node.setNodeRect(32 * 4, 0, 32, 32);
	node.setNodeFrames(2);
}

fn faceLeft(node: opaque) {
	if (direction == 3) return;
	direction = 3;
	node.setNodeRect(32 * 6, 0, 32, 32);
	node.setNodeFrames(2);
}


//accessors & mutators
fn setGridPos(node: opaque, x: int, y: int) {
	gridX = x;
	gridY = y;

	if (realX == null) {
		realX = gridX * TILE_WIDTH;
	}

	if (realY == null) {
		realY = gridY * TILE_HEIGHT;
	}
}

fn setRealPos(node: opaque, x: int, y: int) {
	realX = x;
	realY = y;
}

fn getGridPos(node: opaque) {
	return [gridX, gridY];
}

fn getRealPos(node: opaque) {
	return [realX, realY];
}


//lifecycle functions
fn onLoad(node: opaque) {
	node.loadTexture("sprites:/drone.png");
	node.faceDown();
}

fn onInit(node: opaque) {
	parent = node.getParentNode();
}

fn onStep(node: opaque) {
	if (++stepCount >= 5) {
		node.incrementCurrentNodeFrame();
		stepCount = 0;
	}

	//calc movement
	var distX = gridX * TILE_WIDTH - realX;
	var distY = gridY * TILE_HEIGHT - realY;

	motionX = normalize(distX);
	motionY = normalize(distY);

	//make movement
	realX += abs(distX) > SPEED ? SPEED * motionX : distX;
	realY += abs(distY) > SPEED ? SPEED * motionY : distY;
}

fn onFree(node: opaque) {
	node.freeTexture();
}

fn customOnDraw(node: opaque) {
	var px = 0;
	var py = 0;

	if (parent != null) {
		px = parent.callNodeFn("getX");
		py = parent.callNodeFn("getY");

		px = px != null ? px : 0;
		py = py != null ? py : 0;
	}

	node.drawNode(realX + px - SPRITE_WIDTH / 4, realY + py - SPRITE_HEIGHT / 2, SPRITE_WIDTH, SPRITE_HEIGHT);
}


//gameplay functions
fn runAI(node: opaque, rng: opaque) {
	if ((stepAI++) >= 1) { //TODO: Toy bug here, something to do with precedence of postfix++?
		stepAI = 0;

		var dir = rng.generateRandomNumber() % 4;
		var moveX = 0;
		var moveY = 0;

		if (dir == 0) {
			moveY += 1;
			node.faceDown();
		}

		if (dir == 1) {
			moveY -= 1;
			node.faceUp();
		}

		if (dir == 2) {
			moveX += 1;
			node.faceRight();
		}

		if (dir == 3) {
			moveX -= 1;
			node.faceLeft();
		}

		if (parent.callNodeFn("getCollisionAt", gridX + moveX, gridY + moveY)) {
			gridX += moveX;
			gridY += moveY;
		}
	}
}


//polyfills - move these to standard
fn normalize(x): int {
	if (x > 0) {
		return 1;
	}
	if (x < 0) {
		return -1;
	}
	return 0;
}