// This file is part of MicropolisJ.
// Copyright (C) 2013 Jason Long
// Portions Copyright (C) 1989-2007 Electronic Arts Inc.
//
// MicropolisJ is free software; you can redistribute it and/or modify
// it under the terms of the GNU GPLv3, with additional terms.
// See the README file, included in this distribution, for details.

package micropolisj.engine;

import static micropolisj.engine.TileConstants.*;

public class ShipSprite extends Sprite
{
	static int [] BDx = {  0,  0,  1,  1,  1,  0, -1, -1, -1 };
	static int [] BDy = {  0, -1, -1,  0,  1,  1,  1,  0, -1 };
	static int [] BPx = {  0,  0,  2,  2,  2,  0, -2, -2, -2 };
	static int [] BPy = {  0, -2, -2,  0,  2,  2,  2,  0, -2 };
	static int [] BtClrTab = { RIVER, CHANNEL, POWERBASE, POWERBASE+1,
			RAILBASE, RAILBASE+1, BRWH, BRWV };

	int newDir;
	int count;
	int soundCount;

	public static final int NORTH_EDGE = 5;
	public static final int EAST_EDGE = 7;
	public static final int SOUTH_EDGE = 1;
	public static final int WEST_EDGE = 3;

	public ShipSprite(Micropolis engine, int xpos, int ypos, int edge)
	{
		super(engine, SpriteKind.SHI);
		this.x = xpos * 16 + 8;
		this.y = ypos * 16 + 8;
		this.width = 48;
		this.height = 48;
		this.offx = -24;
		this.offy = -24;
		this.frame = edge;
		this.newDir = edge;
		this.dir = 10;
		this.count = 1;
	}

	@Override
	public void moveImpl()
	{
		int t = RIVER;

		this.soundCount--;
		if (this.soundCount <= 0) {
			if (city.PRNG.nextInt(4) == 0) {
				city.makeSound(x/16,y/16,Sound.HONKHONK_LOW);
			}
			this.soundCount = 200;
		}

		this.count--;
		if (this.count <= 0) {
			this.count = 9;
			if (this.newDir != this.frame) {
				this.frame = turnTo(this.frame, this.newDir);
				return;
			}
			int tem = city.PRNG.nextInt(8);
			int pem;
			for (pem = tem; pem < (tem + 8); pem++) {
				int z = (pem % 8) + 1;
				if (z == this.dir)
					continue;
	
				int xpos = this.x / 16 + BDx[z];
				int ypos = this.y / 16 + BDy[z];
	
				if (city.testBounds(xpos, ypos)) {
					t = city.getTile(xpos, ypos) & LOMASK;
					if ((t == CHANNEL) || (t == BRWH) || (t == BRWV) ||
						tryOther(t, this.dir, z))
					{
						this.newDir = z;
						this.frame = turnTo(this.frame, this.newDir);
						this.dir = z + 4;
						if (this.dir > 8) { this.dir -= 8; }
						break;
					}
				}
			}
	
			if (pem == (tem + 8)) {
				this.dir = 10;
				this.newDir = city.PRNG.nextInt(8)+1;
			}
		}
		else {
			int z = this.frame;
			if (z == this.newDir) {
				this.x += BPx[z];
				this.y += BPy[z];
			}
		}

		if (!spriteInBounds()) {
			this.frame = 0;
			return;
		}

		boolean found = false;
		for (int z : BtClrTab) {
			if (t == z) {
				found = true;
			}
		}
		if (!found) {
			explodeSprite();
			destroyTile(x/16, y/16);
		}
	}

	boolean tryOther(int tile, int oldDir, int newDir)
	{
		int z = oldDir + 4;
		if (z > 8) z -= 8;
		if (newDir != z) return false;

		return (tile == POWERBASE || tile == POWERBASE+1 ||
			tile == RAILBASE || tile == RAILBASE+1);
	}

	boolean spriteInBounds()
	{
		int xpos = x / 16;
		int ypos = y / 16;
		return city.testBounds(xpos, ypos);
	}
}
