/*
 *  Copyright 2002-2009 Mikhail Kryshen <mikhail@kryshen.net>
 *
 *  This file is part of BMTron.
 *
 *  BMTron is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  BMTron is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with BMTron.  If not, see <http://www.gnu.org/licenses/>.
 */

package kryshen.bmtron;

import java.awt.Color;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Point;
import java.awt.image.FilteredImageSource;

public abstract class Player {
    protected final Field field;

    private int direction = -1;

    //Color color;
    final String name;
    final int team;
    
    private boolean stoped = true;
    
    int points = 0;
    
    private int x = 0;
    private int y = 0;

    private Image appearU;
    private Image appearD;
    private Animator blowAnimator = null;
    private Animator appearAnimatorU = null;
    private Animator appearAnimatorD = null;
    
    private Image[] snake;
    
    Player(Field field, String name, Color color, int team) {
        this.name = name;
        this.field = field;
        this.team = team;
        
        MediaTracker mt = new MediaTracker(field.game);
        
        PlayerColorFilter filter = new PlayerColorFilter(color);
        snake = new Image[field.game.skin.snake.length];
        for (int i = 0; i < snake.length; i++) {
            snake[i] = field.game.createImage(new FilteredImageSource
            (field.game.skin.snake[i].getSource(), filter));
	    mt.addImage(snake[i], i + 1);
	}
        
        appearU = field.game.createImage(new FilteredImageSource
                (field.game.skin.appearUp.getSource(), filter));       
        appearD = field.game.createImage(new FilteredImageSource
                (field.game.skin.appearDown.getSource(), filter));
        
        mt.addImage(appearU, 0);
        mt.addImage(appearD, 0);
        
        try {
            mt.waitForAll(); 
        } catch (Exception e) { 
            System.err.println(e);
        }
    }

    synchronized int getDirection() {
	return direction;
    }
    
    synchronized void setDirection(int dir) {
	this.direction = dir;
    }
    
    synchronized void setLocation(int x, int y) {
	this.x = x;
	this.y = y;
    }
    
    synchronized Point getLocation() {
	return new Point(x, y);
    }

    Image getImage(int part) {
        return snake[part];
    }
    
    synchronized Animator getBlow() {
        if (blowAnimator == null)
            blowAnimator = new Animator(field.game.skin.explosion, 
                 field.c2x * 5, field.r2y * 5, 50);
        return blowAnimator;
    }
    
    synchronized Animator getAppearU() {
        if (appearAnimatorU == null)
            appearAnimatorU = new Animator(appearU, 
                field.c2x * 5, field.r2y * 5, 100);
        return appearAnimatorU;
    }
    
    synchronized Animator getAppearD() {
        if (appearAnimatorD == null)
            appearAnimatorD = new Animator(appearD, 
                field.c2x * 5, field.r2y * 5, 100);
        return appearAnimatorD;
    }
    
    synchronized void stop() {
        stoped = true;
    }
    
    synchronized void start() {
        stoped = false;
    }
    
    synchronized boolean isStoped() {
	return stoped;
    }
    
    synchronized void reset() {
        if (!stoped) stop();
        blowAnimator = null;
        appearAnimatorU = null;
        appearAnimatorD = null;
        direction = -1;
    }
    
    synchronized void update() {
    }
    
    protected int randomMove() {
        int dir = -1;
        boolean free = false;
        
        while (!free) {            
            dir = Game.nextRandom(0, 3);               
            
            switch (dir) {
            case Field.UP:
                free = field.isFree(x, y - 1);
                break;
            case Field.DOWN:
                free = field.isFree(x, y + 1);
                break;
            case Field.LEFT:
                free = field.isFree(x - 1, y);
                break;
            case Field.RIGHT:
                free = field.isFree(x + 1, y);
                break;
            }
        }
        
        return dir;
    }
}
