package projectzombie.entity;

import bdf.types.BdfNamedList;
import bdf.types.BdfObject;
import gl_engine.MathHelpers;
import gl_engine.vec.Vec3d;
import projectzombie.model.ModelItem;
import projectzombie.util.ItemStack;
import projectzombie.world.chunk.Chunk;
import projectzombie.world.layer.Layer;

public class EntityItem extends EntityParticle
{
	private ItemStack stack;
	private int pickup_time = 200;
	private long age = 0;
	
	public EntityItem(BdfObject bdf) {
		BdfClassLoad(bdf);
	}
	
	@Override
	public void BdfClassLoad(BdfObject bdf) {
		super.BdfClassLoad(bdf);
		
		BdfNamedList nl = bdf.getNamedList();
		
		stack = new ItemStack(nl.get("stack"));
		
		pickup_time = nl.get("pickup").getInteger();
		age = nl.get("age").getLong();
	}
	
	@Override
	public void BdfClassSave(BdfObject bdf) {
		super.BdfClassSave(bdf);
		
		BdfNamedList nl = bdf.getNamedList();
		
		stack.BdfClassSave(nl.get("stack"));
		
		nl.set("pickup", bdf.newObject().setInteger(pickup_time));
		nl.set("age", bdf.newObject().setLong(age));
	}
	
	public EntityItem(Vec3d pos, Vec3d velocity, ItemStack stack, double angle) {
		super(pos, velocity);
		
		this.emitsLight = true;
		this.stack = stack;
		
		push(MathHelpers.moveTowards2(0.05, angle).xny().add(new Vec3d(0, 0.1, 0)));
	}
	
	public EntityItem(Vec3d pos, Vec3d velocity, ItemStack stack) {
		this(pos, velocity, stack, rand.nextDouble() * MathHelpers.TWO_PI);
	}
	
	@Override
	public double getLightLevel() {
		if(stack.isEmpty()) return 0;
		return getLightWithHeight(stack.item.getLightLevel(stack));
	}
	
	@Override
	public void tick(Chunk chunk, Layer layer) {
		super.tick(chunk, layer);
		
		age += 1;
		pickup_time -= 1;
		
		// Merge nearby stacks
		for(Entity e : layer.getNearbyEntities(getPos().xz(), 2))
		{
			if(e instanceof EntityItem && e != this) {
				EntityItem ei = (EntityItem) e;
				
				if(
						ei.stack.stackEquals(this.stack) &&
						ei.stack.count + this.stack.count <= this.stack.item.max &&
						ei.age > this.age
				) {
					if(ei.getPos().squareDistance(getPos()) < 0.1) {
						this.pickup_time = 200;
						this.stack.count += ei.stack.count;
						setPos(ei.getPos().divide(2).add(getPos().divide(2)));
						setVelocity(ei.getVelocity().divide(2).add(getVelocity().divide(2)));
						ei.kill();
					}
					
					else {
						push(ei.getPos().subtract(getPos()).normalize().multiply(0.001));
					}
				}
			}
			
			if(pickup_time <= 0 && e instanceof EntityHasInventory)
			{
				if(e.getPos().squareDistance(getPos()) < 0.5) {
					stack.item.onPickedUp(stack, layer, chunk, e);
				} else {
					push(e.getPos().subtract(getPos()).normalize().multiply(0.05));
				}
			}
		}
		
		// Kill this entity if the stack is empty
		if(stack.isEmpty()) {
			kill();
			return;
		}
	}
	
	@Override
	public boolean shouldKillParticle() {
		return false;
	}

	@Override
	public EntityParticlePart getParticleAt(int id) {
		ModelItem model = stack.item.getModel(stack);
		EntityParticlePart particle = new EntityParticlePart(model.tex, getPos().add(new Vec3d(0, 0.25, 0)), 0.5, 0b1000);
		particle.animationSize = model.animationSize;
		particle.animationSpeed = model.animationSpeed;
		return particle;
	}
	
	@Override
	public int getParticleCount() {
		return 1;
	}
	
	
}
