package main;

import java.util.Iterator;
import java.util.Random;
import java.util.LinkedList;
import java.awt.geom.Point2D;
import java.util.HashMap;
import java.awt.Point;

public class Enemy extends Creature
{
    int xpReward;
    Point patrolTarget;
    public int spotRadius;
    public int patrolRadius;
    boolean pursuing;
    private HashMap<Item, Double> itemDrops;
    
    public Enemy(final String name, final int xOffset, final int yOffset, final int xpReward) {
        super(name, xOffset, yOffset);
        this.pursuing = false;
        this.xpReward = xpReward;
        this.pursuing = false;
        this.itemDrops = new HashMap<Item, Double>();
    }
    
    public Enemy(final Enemy cr) {
        super(cr);
        this.pursuing = false;
        this.xpReward = cr.xpReward;
        this.spotRadius = cr.spotRadius;
        this.patrolRadius = cr.patrolRadius;
        this.itemDrops = cr.itemDrops;
    }
    
    @Override
    public Enemy copy(final Point newLoc) {
        final Enemy newCr = new Enemy(this);
        newCr.initLoc(newLoc);
        return newCr;
    }
    
    @Override
    protected void initLoc(final Point newLoc) {
        super.initLoc(newLoc);
        this.patrolTarget = new Point(newLoc);
    }
    
    @Override
    public void AI_move(final Player player, final Map map) {
        if (this.pursuing) {
            if (player.dead || this.patrolTarget.distance(player.loc) > this.patrolRadius) {
                this.setEnemyTarget(null, map);
                this.setTarget(this.patrolTarget, map);
                this.pursuing = false;
            }
            else if (this.path == null || this.path.getLast().distance(player.loc) > this.loc.distance(this.path.getLast()) || this.loc.distance(player.loc) * 2.0 < player.loc.distance(this.path.getLast())) {
                this.setEnemyTarget(player, map);
            }
        }
        else if (this.patrolTarget.distance(player.loc) < this.spotRadius && !player.dead) {
            this.setEnemyTarget(player, map);
            this.pursuing = true;
        }
    }
    
    @Override
    public void AI_react(final Map map) {
        if (this.enemyTarget != null) {
            final double distance = this.loc.distance(this.enemyTarget.loc);
            if (this.getModel().action != Action.Attacking && this.getModel().action != Action.BeenHit && distance <= this.startRange) {
                this.startAttack(this.enemyTarget);
            }
            if (this.readyToAttack() && this.minRange <= distance && distance <= this.maxRange) {
                this.attack(this.enemyTarget);
            }
        }
    }
    
    public void addItemDrop(final Item i, final double dropChance) {
        if (0.0 <= dropChance && dropChance <= 1.0) {
            this.itemDrops.put(i, dropChance);
            return;
        }
        throw new IllegalArgumentException("dropChance must be between 0.0 and 1.0");
    }
    
    public LinkedList<Item> generateDrops() {
        final LinkedList<Item> drops = new LinkedList<Item>();
        final Iterator<java.util.Map.Entry<Item, Double>> iter = this.itemDrops.entrySet().iterator();
        final Random rand = new Random();
        while (iter.hasNext()) {
            final java.util.Map.Entry<Item, Double> cur = iter.next();
            if (rand.nextDouble() < cur.getValue()) {
                drops.add(cur.getKey().copy(new Point(0, 0)));
            }
        }
        return drops;
    }
}
