package common.potion;

import common.entity.types.EntityLiving;
import common.log.Log;
import common.tags.TagObject;

public class PotionEffect {
	private final Potion potion;
	private final int duration;
	private final int amplifier;
	private final boolean ambient;
	private final boolean particles;

	private int remaining;
	private boolean thrown;
	
	public PotionEffect(Potion id, int duration, int amplifier) {
		this(id, duration, amplifier, false, true);
	}

	public PotionEffect(Potion id, int duration, int amplifier, boolean ambient, boolean showParticles) {
		this.potion = id;
		this.duration = this.remaining = duration;
		this.amplifier = amplifier;
		this.ambient = ambient;
		this.particles = showParticles;
	}

	public PotionEffect(PotionEffect other) {
		this.potion = other.potion;
		this.duration = this.remaining = other.duration;
		this.amplifier = other.amplifier;
		this.ambient = other.ambient;
		this.particles = other.particles;
	}

	public PotionEffect combine(PotionEffect other) {
		if(this.potion != other.potion)
			Log.TICK.warn("PotionEffect.combine(): Diese Methode sollte nur für gleiche Effekte aufgerufen werden!");
		int duration = this.duration;
		int amplifier = this.amplifier;
		int remaining = this.remaining;
		boolean ambient = this.ambient;
		if(other.amplifier > this.amplifier) {
			amplifier = other.amplifier;
			duration = other.duration;
			remaining = other.remaining;
		}
		else if(other.amplifier == this.amplifier && this.remaining < other.remaining) {
			duration = other.duration;
			remaining = other.remaining;
		}
		else if(!other.ambient && this.ambient) {
			ambient = other.ambient;
		}
		return new PotionEffect(this.potion, duration, amplifier, ambient, other.particles).setRemaining(remaining);
	}

	public Potion getPotion() {
		return this.potion;
	}

	public int getDuration() {
		return this.duration;
	}

	public boolean isInfinite() {
		return this.duration == Integer.MAX_VALUE;
	}

	public int getRemaining() {
		return this.remaining;
	}

	public int getAmplifier() {
		return this.amplifier;
	}

	public PotionEffect setThrown(boolean thrown) {
		this.thrown = thrown;
		return this;
	}

	public PotionEffect setRemaining(int remaining) {
		this.remaining = remaining;
		return this;
	}

	public boolean isAmbient() {
		return this.ambient;
	}

	public boolean getIsShowParticles() {
		return this.particles;
	}

	public boolean onUpdate(EntityLiving entityIn) {
		if(this.isInfinite() && this.remaining < 20 * 60)
			this.remaining = Integer.MAX_VALUE;
		if(this.remaining > 0) {
			this.potion.onUpdate(entityIn, this.remaining, this.amplifier);
			--this.remaining;
		}
		return this.remaining > 0;
	}

	public String getEffectName() {
		return this.potion.getDisplay(this.amplifier);
	}

	public String getPotionName() {
		return this.potion.getPotionDisplay(this.amplifier);
	}

	public String getDurationString() {
		if(this.isInfinite())
			return "**:**";
		int secs = this.remaining / 20;
		int hrs = secs / (60 * 60);
		secs = secs % (60 * 60);
		int mins = secs / 60;
		secs = secs % 60;
		return (hrs > 0 ? hrs + ":" + (mins < 10 ? "0" : "") : "") + mins + ":" + (secs < 10 ? "0" : "") + secs;
	}

	public int hashCode() {
		return this.potion.ordinal();
	}

	public boolean equals(Object obj) {
		if(!(obj instanceof PotionEffect))
			return false;
		PotionEffect other = (PotionEffect)obj;
		return this.potion == other.potion && this.amplifier == other.amplifier && this.duration == other.duration
				&& this.thrown == other.thrown && this.remaining == other.remaining && this.ambient == other.ambient;
	}

	public TagObject toTags() {
		TagObject tag = new TagObject();
		tag.setString("Type", this.potion.getName());
		tag.setByte("Amplifier", (byte)this.amplifier);
		tag.setInt("Duration", this.duration);
		tag.setInt("Remaining", this.remaining);
		tag.setBool("Ambient", this.ambient);
		tag.setBool("Particles", this.particles);
		return tag;
	}

	public static PotionEffect fromTags(TagObject tag) {
		Potion potion = Potion.getByName(tag.getString("Type"));
		return potion == null ? null : new PotionEffect(potion, tag.getInt("Duration"), (int)(tag.getByte("Amplifier") & 255), tag.getBool("Ambient"), tag.getBool("Particles"))
			.setRemaining(tag.getInt("Remaining"));
	}
}
