import java.awt.Color;
import java.util.Random;

public class ComputerTank extends Tank{
	// OVERVIEW: A ComputerTank is a Tank object that walks randomly when the UserTank
	//	is not in its line of sight.  When the UserTank is in its line of sight, it will
	//	the UserTank and try to move toward the UserTank. 
	private boolean inTurn;
	protected int pts;	//points earned when this got kill
	protected int xps;	//experiences earned when this got kill
	protected int iq;	//how smart this is.  0< iq <20
		//used with rd to statistically determine the action to take in executeTurn()
	protected Random rd = new Random();

	public ComputerTank() {
		inTurn = false;
		this.hp = 2;
		this.speed = 200;
		this.orient = Direction.SOUTH;
		this.pts = 10;
		this.xps = 5;
		this.iq = 10;
	}
	public ComputerTank(int speed,int hp,Direction or){
		inTurn = false;
		this.hp = hp;
		this.speed = speed;
		this.orient = or;
		this.pts = 10;
		this.xps = 5;
		this.iq = 10;
	}
	public ComputerTank(int speed,int hp,Direction or,int pts, int xps, int iq){
		inTurn = false;
		this.hp = hp;
		this.speed = speed;
		this.orient = or;
		this.pts = pts;
		this.xps = xps;
		this.iq = iq;
	}
	public void setPoint(int pts){
		this.pts = pts;
	}
	public void setXp(int xps){
		this.xps = xps;
	}
	synchronized public void die(){
		super.die();
		dropItem();
		decreaseNumEnemies();
		increaseStatus(pts,xps);
		//System.out.println("Number of enemies left : "+numEnemies);
	}
	public void dropItem(){
		if(items[0]!=null){
			synchronized(getGrid()){
				try{
					items[0].mx=getX();
					items[0].my=getY();
					getGrid().setObjectAt(getX(),getY(),items[0]);
				}catch(BadLocationException be){
					;
				}
			}
		}
	}
	public Direction isInLineOfSight(){
	//Effects: return the Direction of a UserTank object if it is in this's line of sight.
	//	Otherwise, return null.
	//	line of sight mean this can see a UserTank directly(=with nothing between them)
		int x = getX();
		int y = getY();
		//West
		for(int i=x-1;i>=0;i--){
			SimObject so = getGrid().getObjectAt(i,y);
			if(so==null) continue;
			if( (so instanceof Block)||(so instanceof ComputerTank) ){
				break;
			}else{
				if(so instanceof UserTank){
					return Direction.WEST;
				}
			}
		}
		//East
		for(int i=x+1;i<getGrid().numHorizontal();i++){
			SimObject so = getGrid().getObjectAt(i,y);
			if(so==null) continue;
			if( (so instanceof Block)||(so instanceof ComputerTank) ){
				break;
			}else{
				if(so instanceof UserTank){
					return Direction.EAST;
				}
			}
		}
		//North
		for(int i=y-1;i>=0;i--){
			SimObject so = getGrid().getObjectAt(x,i);
			if(so==null) continue;
			if( (so instanceof Block)||(so instanceof ComputerTank) ){
				break;
			}else{
				if(so instanceof UserTank){
					return Direction.NORTH;
				}
			}
		}
		//South
		for(int i=y+1;i<getGrid().numVertical();i++){
			SimObject so = getGrid().getObjectAt(x,i);
			if(so==null) continue;
			if( (so instanceof Block)||(so instanceof ComputerTank) ){
				break;
			}else{
				if(so instanceof UserTank){
					return Direction.SOUTH;
				}
			}
		}
		return null;
	}
	public void executeTurn() throws RuntimeException
	// Note: requires isInitialized is inherited from SimObject
	// EFFECTS: If there is an UserTank in this's line of sight,
	//		move or shoot toward that direction.
	//		Otherwise, move randomly.

	{
		super.executeTurn();
		delay(TURN_DELAY+speed);
		if(shooting==true){
			delay(gun.getSpeed());
			shooting=false;
		}
		synchronized(getGrid()){
			inTurn = true;
			Direction dir =isInLineOfSight();
			if(dir!=null){
				if(rd.nextInt(20)>iq){
					moveDir(dir);
				}else{
					if(orient.equals(dir)){
						shoot();
					}else{
						moveDir(dir);
					}
				}
			}else{
				dir = Direction.randomDirection4();
				moveDir(dir);
			}
			
			inTurn = false;

		}
	}

	public Color getColor() {
		if(inTurn){
			return Color.white;
		} else{
			return Color.red;
		}
	} //@nowarn Post // ESC/Java doesn't know Color constants are not null
}