package mobs;

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;

import org.python.core.Py;
import org.python.core.PyFunction;
import org.python.core.PyObject;

import _texture.loader.Textures;
import engine.Game;
import engine.Handler;
import interfaces.Mob;
import utils.Animation;
import utils.Circle;
import utils.Point2f;
import utils.Utils;

/**  ------------- Nihilne ------------
    *** @author Mitch Weaver - 2016 ***
      ~~~~ All Rights Reserved ~~~~ */

public final class Goblin extends Mob {
	
	public Goblin(float x, float y) {
		super(MOB_ID.GOBLIN, new Point2f(x , y), GOBLIN_WIDTH, GOBLIN_HEIGHT, GOBLIN_HOME_RADIUS, randomizeNum(GOBLIN_AGGRO_RADIUS), true, GOBLIN_DAMAGE, GOBLIN_COMBAT_LEVEL, randomizeNum(GOBLIN_TERRITORY_AGGRO_DISTANCE), GOBLIN_TOTAL_HEALTH);

		walkingSpeed = GOBLIN_WALKING_SPEED; runningSpeed = GOBLIN_RUNNING_SPEED;
		attackBounds = new Circle(center, GOBLIN_ATTACK_BOUNDS_RADIUS);
		currentAnimation = ANIMATION.idleWalk;
		destroyingTimer = deaths.length * DEATH_ANIMATION_SPEED;
		idleMove(walkingSpeed);
	}

	public void tick() {
		pyTick.__call__(thisGoblin);

		/** uncomment for interactive scripting (SLOW) ******/
//		pi.exec(Utils.readTextFileAsString("/goblin_ai.py"));
//		pi.get("__goblin_tick__", PyFunction.class).__call__(thisGoblin);
	}
	
	public void destroy() {
		DROP_TABLES.dropItem(id, center);
		for(int i = 0; i < runs.length; i++) runs[i] = null;
		for(int i = 0; i < idle1s.length; i++) idle1s[i] = null;
		for(int i = 0; i < idle2s.length; i++) idle2s[i] = null;
		for(int i = 0; i < attacks.length; i++) attacks[i] = null;
		for(int i = 0; i < deaths.length; i++) deaths[i] = null;
		runs = idle1s = idle2s = attacks = deaths = null;
		copy = null; transform = null;
		NULL_ALL_FROM_SUPER_CLASS();
		Handler.mobs.remove(this);
	}
	
	
	// ----------------------------- RENDERING ---------------------------------------------------------------------------------------------------------------------------------------------- //
	private Graphics2D copy; private AffineTransform transform = new AffineTransform();
	public void render(Graphics2D g2d) {
		if(!discovered) return;
		copy = (Graphics2D) g2d.create(); drawCollisionBounds(copy); transform.setToRotation(-Utils._45 * (Game.rotation - 1), center.x, center.y); copy.transform(transform);

		if(alive()){
			if(GET_HIT_TIMER > 0) {
				copy.drawImage(getHits[facing - 1], (int)(pos.x - width / 3 + 1), (int)(pos.y - height / 3), null);
			} else {
				if(!attacking) {
					switch(currentAnimation) {
						case idleWalk: runs[facing  -  1].drawAnimation(copy, pos.x - width/3 + 1, pos.y - height/3); break;
						case idle1:    idle1s[facing - 1].drawAnimation(copy, pos.x - width/3 + 1, pos.y - height/3); break; 
						case idle2:    idle2s[facing - 1].drawAnimation(copy, pos.x - width/3 + 1, pos.y - height/3); break;
						default: break;
					}
				} else attacks[facing - 1].drawAnimation(copy, pos.x - width/3 + 1, pos.y - height/3);
			}
		} else deaths[facing - 1].drawAnimation(copy, pos.x - width/3 + 1, pos.y - height/3);
		
		drawCollisionBounds(copy);
		
		copy.dispose(); copy = null;
	}
	// -------------------------- END RENDERING ----------------------------------------------------------------------------------------------------------------------------------------//

// ----------------------------- JYTHON STUFF ----------------------------------------------------------------------------------------------------------------------------------------- //
	private final PyObject thisGoblin = Py.java2py(this);
	private static PyFunction pyTick;
	public static final void initPyScripts(){
		pi.exec(Utils.readTextFileAsString("/goblin_ai.py"));
		pyTick = pi.get("__goblin_tick__", PyFunction.class);
	}
// ---------------------------- END JYTHON STUFF -------------------------------------------------------------------------------------------------------------------------------------- //
	
// ----------------------------------------------------------------- ANIMATION STUFF --- IGNORE ---------------------------------------------------------------------------------------------- //
	private static final int RUN_ANIMATION_SPEED = 12, IDLE_1_ANIMATION_SPEED = 28, ATTACK_ANIMATION_SPEED = 12, DEATH_ANIMATION_SPEED = 11;
	public int idleAnimationTimer;
	
	public void runAnimations() {
		if(alive()) {
			if(!attacking) for(Animation a : runs) a.runAnimation();
			
			if(!inCombat && currentAnimation != ANIMATION.idleWalk) {
				idle1s[facing - 1].runAnimation();
				idle2s[facing - 1].runAnimation();
			}
			
			if(attacking) for (Animation a : attacks) a.runAnimation();
			else for(Animation a : attacks) a.restartAnimation();
		} else try { for(Animation a : deaths) if(a.currentFrame != deaths.length) a.playAnimationOnce(); } catch (NullPointerException npe) {}
	}
	
	private static final BufferedImage[] getHits = {
		Textures.goblinSheet[96],
		Textures.goblinSheet[97],
		Textures.goblinSheet[98],
		Textures.goblinSheet[99],
		Textures.goblinSheet[100],
		Textures.goblinSheet[101],
		Textures.goblinSheet[102],
		Textures.goblinSheet[103],
	};
	
	private int __count = 0;
	private Animation[] runs = {  // N NE E SE S SW W NW
			new Animation(RUN_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(RUN_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(RUN_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(RUN_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(RUN_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(RUN_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(RUN_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(RUN_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
	};
	
	private Animation[] idle1s = {
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++])
	};
	private Animation[] idle2s = {
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(IDLE_1_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++])
	};
	
	private Animation[] attacks = {  // N NE E SE S SW W NW
			new Animation(ATTACK_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(ATTACK_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(ATTACK_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(ATTACK_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(ATTACK_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(ATTACK_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(ATTACK_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
			new Animation(ATTACK_ANIMATION_SPEED, Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++], Textures.goblinSheet[__count++]),
	};
	
	private int __new_count = __count + 8;
	public Animation[] deaths = {
			new Animation(DEATH_ANIMATION_SPEED, Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++]),
			new Animation(DEATH_ANIMATION_SPEED, Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++]),
			new Animation(DEATH_ANIMATION_SPEED, Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++]),
			new Animation(DEATH_ANIMATION_SPEED, Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++]),
			new Animation(DEATH_ANIMATION_SPEED, Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++]),
			new Animation(DEATH_ANIMATION_SPEED, Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++]),
			new Animation(DEATH_ANIMATION_SPEED, Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++]),
			new Animation(DEATH_ANIMATION_SPEED, Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++], Textures.goblinSheet[__new_count++]),
	};
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//
	
}
