package world;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;

import _texture.loader.Textures;
import engine.Game;
import engine.Handler;
import hud.Clock;
import hud.inventory.Inventory;
import interfaces.GameObject;
import interfaces.ItemIDs;
import player.Player;
import utils.Circle;
import utils.Point2f;
import utils.Utils;

/*  ------------- Nihilne ------------
    * Created by Mitch Weaver - 2016 *
      ~~~~ All Rights Reserved ~~~~ */

public final class DroppedItem implements GameObject, ItemIDs {

	public int x, y, itemId, radius, quantity, health, totalHealth;
	public float durability;
	public Point2f center;
	public boolean playerCollided, perishable, discovered;

	public DroppedItem(int x, int y, int itemId, int quantity, float durability) {
		this.x = x; this.y = y; this.itemId = itemId; this.quantity = quantity; this.durability = durability;
		
		switch(itemId){
			case PICKED_FLOWERS:  		perishable = true; health = Clock.FULL_DAY*14; break;
			case ASHES:  				perishable = true; health = Clock.FULL_DAY*5; break;
			case RABBIT_CARCASS:		perishable = true; health = Clock.FULL_DAY*3; break; 
		}
		
		this.radius = 10;
		this.center = new Point2f(x + radius, y + radius);
		Handler.droppedItems.add(this);
	}
	
	public DroppedItem(int x, int y, int itemId, int quantity) { new DroppedItem(x, y, itemId, quantity, 100);}
	public DroppedItem(Point2f p, int itemId, int quantity) { new DroppedItem((int)p.x, (int)p.y, itemId, quantity, 100);}
	public DroppedItem(Point2f p, int itemId, int quantity, float durability){ new DroppedItem((int)p.x, (int)p.y, itemId, quantity, durability);}
	public DroppedItem(Point2f p, int itemId){ new DroppedItem((int)p.x, (int)p.y, itemId, 1, 100); }
	public DroppedItem(int x, int y, int itemId){ new DroppedItem(x, y, itemId, 1, 100); }
	
	
	public final static void dropItemsWithOffset(int itemId, int quantity, int offset, int centerX, int centerY, float durability) {
		final Circle bounds = new Circle(new Point2f(centerX, centerY), offset);
		int offsetX, offsetY;
		for (int i = 0; i < quantity; i++) {
			while(true) {
				offsetX = Utils.rand.nextInt(offset);
				offsetY = Utils.rand.nextInt(offset);
				if (Utils.rand.nextBoolean()) offsetX *= -1;
				if (Utils.rand.nextBoolean()) offsetY *= -1;
				if(bounds.contains(centerX + offsetX, centerY + offsetY)) {
					new DroppedItem(centerX + offsetX, centerY + offsetY, itemId, 1, durability);
					break;
				}
			}
		}
	} public final static void dropItemsWithOffset(int itemId, int quantity, int offset, float centerX, float centerY, float durability) { dropItemsWithOffset(itemId, quantity, offset, (int)centerX, (int)centerY, durability);}

	public final static void dropItemsWithOffsetAsStack(int itemId, int quantity, int offset, int centerX, int centerY, float durability) {
		final Circle bounds = new Circle(new Point2f(centerX, centerY), offset);
		while(true) {
				int offsetX = Utils.rand.nextInt(offset);
				int offsetY = Utils.rand.nextInt(offset);
				if (Utils.rand.nextBoolean()) offsetX *= -1;
				if (Utils.rand.nextBoolean()) offsetY *= -1;
				if(bounds.contains(centerX + offsetX, centerY + offsetY)) {
					new DroppedItem(centerX + offsetX, centerY + offsetY, itemId, quantity, durability);
					return;
				}
		}
	} public static void dropItemsWithOffsetAsStack(int itemId, int quantity, int offset, float centerX, float centerY, float durability) {dropItemsWithOffsetAsStack(itemId, quantity, offset, (int)centerX, (int)centerY, durability);}

	public final static void dropRandomAmountOfItemsWithOffset(int itemId, int baseQuantity, int ceiling, int offset, int centerX, int centerY, float durability) {
		final Circle bounds = new Circle(new Point2f(centerX, centerY), offset);
		int offsetX, offsetY, amount = (Utils.rand.nextInt(ceiling) + baseQuantity);
		for (int i = 0; i < amount; i++) {
			while(true) {
				offsetX = Utils.rand.nextInt(offset);
				offsetY = Utils.rand.nextInt(offset);
				if (Utils.rand.nextBoolean()) offsetX *= -1;
				if (Utils.rand.nextBoolean()) offsetY *= -1;
				if(bounds.contains(centerX + offsetX, centerY + offsetY)) {
					new DroppedItem(centerX + offsetX, centerY + offsetY, itemId, 1, durability);
					break;
				}
			}
		}
	} public static void dropRandomAmountOfItemsWithOffset(int itemId, int baseQuantity, int ceiling, int offset, float centerX, float centerY, float durability) {dropRandomAmountOfItemsWithOffset(itemId, baseQuantity, ceiling, offset, (int)centerX, (int)centerY, durability); }
      public static void dropRandomAmountOfItemsWithOffset(int itemId, int baseQuantity, int ceiling, int offset, float centerX, float centerY) {dropRandomAmountOfItemsWithOffset(itemId, baseQuantity, ceiling, offset, (int)centerX, (int)centerY, 100); }

	public final void tick() {
		if(!discovered) discovered = Player.DISCOVERY.contains(x, y);
		if(!discovered) return;

		if(perishable && --health <= 0) destroy();
		
		if (Player.using && playerCollided && !Inventory.isFull(itemId, quantity)) {
			Inventory.addItem(itemId, quantity, durability);
			Handler.droppedItems.remove(this);
		}
	}
	
	private final void destroy() {
		if(perishable) {
			switch(itemId) {  // SOME ITEMS, LIKE ASHES, SHOULDN"T DROP ROT
				case ASHES: break;
				default: new DroppedItem(x, y, ROT);
			}
		}
		
		Handler.droppedItems.remove(this);
	}

	private Graphics2D copy;
	private final AffineTransform transform = new AffineTransform();
	public final void render(final Graphics2D g2d) {
		copy = (Graphics2D) g2d.create(); transform.setToRotation(-Utils._45 * (Game.rotation - 1), center.x, center.y); copy.transform(transform);
		
		copy.drawImage(Textures.droppedItemIconSheet[itemId - 1], x, y, null);
		
		if (Game.drawCollisionBounds) {
			copy.setColor(Color.RED);
			copy.drawOval((int) (center.x - radius), (int) (center.y - radius), (int) radius * 2, (int) radius * 2);
		}
		
		copy.dispose(); copy = null;
	}

}
