/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package logic.players;

import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.game.TiledLayer;
import logic.BricksLayerManager;
import logic.GameInfo;

/**
 *
 * @author avk
 */
public class PhonePlayer extends AbstractPlayer{

    public PhonePlayer(Sprite sprite, SpriteAnimator animator, GameInfo info) {
        super(sprite, animator, info);
    }

    public String getName() {
        return "Opponent";
    }

    public boolean isReadyToMove() {
        return true;
    }

    // TODO doesn't work
    public int move(int keyState) {
        try {
            Thread.sleep(MS_TO_SLEEP_ON_STEP);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
        int[] opponentSprite = getSpritePosition(getOpponentSprite());
        int[] sprite = getSpritePosition(getSprite());
        int[] brick = getNearestBrick(getBricksLayer(), sprite);

        int blockedDirection = BricksLayerManager.MOVE_NONE;

        if (sprite[0] < brick[0]){
            if (!collidesAfterMove(sprite, opponentSprite, BricksLayerManager.MOVE_RIGTH)){
                return BricksLayerManager.MOVE_RIGTH;
            }
            blockedDirection = BricksLayerManager.MOVE_RIGTH;
        }
        if (sprite[0] > brick[0]){
            if (!collidesAfterMove(sprite, opponentSprite, BricksLayerManager.MOVE_LEFT)){
                return BricksLayerManager.MOVE_LEFT;
            }
            blockedDirection = BricksLayerManager.MOVE_LEFT;
        }
        if (sprite[1] < brick[1]){
            if (!collidesAfterMove(sprite, opponentSprite, BricksLayerManager.MOVE_DOWN)){
                return BricksLayerManager.MOVE_DOWN;
            }
            blockedDirection = BricksLayerManager.MOVE_DOWN;
        }
        if (sprite[1] > brick[1]){
            if (!collidesAfterMove(sprite, opponentSprite, BricksLayerManager.MOVE_UP)){
                return BricksLayerManager.MOVE_UP;
            }
            blockedDirection = BricksLayerManager.MOVE_UP;
        }
        if (blockedDirection == BricksLayerManager.MOVE_RIGTH
                || blockedDirection == BricksLayerManager.MOVE_LEFT)
        {
            if (isNoWallsAtCell(sprite[0], sprite[1] - 1)){
                return BricksLayerManager.MOVE_UP;
            }
            if (isNoWallsAtCell(sprite[0], sprite[1] + 1)){
                return BricksLayerManager.MOVE_DOWN;
            }
        }
        if (blockedDirection == BricksLayerManager.MOVE_UP
                || blockedDirection == BricksLayerManager.MOVE_DOWN)
        {
            if (isNoWallsAtCell(sprite[0] - 1, sprite[1])){
                return BricksLayerManager.MOVE_LEFT;
            }
            if (isNoWallsAtCell(sprite[0] + 1, sprite[1])){
                return BricksLayerManager.MOVE_RIGTH;
            }
        }
        return BricksLayerManager.MOVE_RIGTH;
    }

    /**
     * is sprite moved in move direction will collide with opponent opp.
     * @param toMove
     * @param opp
     * @param move
     * @return
     */
    private boolean collidesAfterMove(int[] toMove, int[] opp, int move){
        if (move == BricksLayerManager.MOVE_NONE){
            return false;
        }
        int[] moved = toMove;
        if (move == BricksLayerManager.MOVE_LEFT){
            moved[0]--;
        }
        if (move == BricksLayerManager.MOVE_RIGTH){
            moved[0]++;
        }
        if (move == BricksLayerManager.MOVE_UP){
            moved[1]--;
        }
        if (move == BricksLayerManager.MOVE_DOWN){
            moved[1]++;
        }
        return moved[0] == opp[0] && moved[1] == opp[1];
    }

    private boolean isNoWallsAtCell(int x, int y){
        return getWallsLayer().getCell(x, y) == 0;
    }

    private int[] getSpritePosition(Sprite sprite){
        int col = sprite.getRefPixelX() / getSprite().getWidth();
        int row = sprite.getRefPixelY() / getSprite().getWidth();
        return new int[]{col, row};
    }

    private int[] getNearestBrick(TiledLayer bricksLayer, int[] sprite) {
        int[] brick = new int[]{bricksLayer.getColumns(), bricksLayer.getRows()};
        int dist = getDistance(brick, sprite);
        int newDist = dist;
        
        for (int i = 0; i < bricksLayer.getColumns(); i++) {
            for (int j = 0; j < bricksLayer.getRows(); j++) {
                if (bricksLayer.getCell(i, j) != EMPTY_TILE_INDEX) {
                    newDist = getDistance(i, j, sprite[0], sprite[1]);
                    if (newDist < dist){
                        dist = newDist;
                        brick = new int[]{i, j};
                    }
                }
            }
        }
        return brick;
    }

    private int getDistance(int[] c1, int[] c2){
        return getDistance(c1[0], c1[1], c2[0], c2[1]);
    }

    private int getDistance(int x1, int y1, int x2, int y2){
        return Math.abs(x1 - x2) + Math.abs(y1 - y2);
    }

}
