// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
//      Magicbane Emulator Project © 2013 - 2022
//                www.magicbane.com


package engine.powers.poweractions;

import engine.math.Vector3fImmutable;
import engine.objects.AbstractCharacter;
import engine.objects.AbstractWorldObject;
import engine.objects.Item;
import engine.powers.ActionsBase;
import engine.powers.EffectsBase;
import engine.powers.PowersBase;
import engine.wpak.data.PowerAction;


public abstract class AbstractPowerAction {

    protected PowersBase parent;
    protected int UUID;
    protected String IDString;
    protected String type;
    protected boolean isAggressive;
    protected long validItemFlags;

    /**
     * No Table ID Constructor
     */
    public AbstractPowerAction() {

    }

    /**
     * ResultSet Constructor
     */
    public AbstractPowerAction(PowerAction powerAction) {

        this.IDString = powerAction.action_id;
        this.type = powerAction.action_type;
        int flags = powerAction.itemFlag.ordinal();
        this.isAggressive = powerAction.isAggressive;
    }

    public AbstractPowerAction(int uUID, String iDString, String type, boolean isAggressive,
                               long validItemFlags) {
        super();
        UUID = uUID;
        IDString = iDString;
        this.type = type;
        this.isAggressive = false;
    }

    public void startAction(AbstractCharacter source, AbstractWorldObject awo, Vector3fImmutable targetLoc, int numTrains, ActionsBase ab, PowersBase pb) {
        this._startAction(source, awo, targetLoc, numTrains, ab, pb);
    }

    public void startAction(AbstractCharacter source, AbstractWorldObject awo, Vector3fImmutable targetLoc, int numTrains, ActionsBase ab, PowersBase pb, int duration) {
        this._startAction(source, awo, targetLoc, numTrains, ab, pb, duration);
    }

    protected abstract void _startAction(AbstractCharacter source, AbstractWorldObject awo, Vector3fImmutable targetLoc, int numTrains, ActionsBase ab, PowersBase pb);

    protected abstract void _startAction(AbstractCharacter source, AbstractWorldObject awo, Vector3fImmutable targetLoc, int numTrains, ActionsBase ab, PowersBase pb, int duration);

    public void handleChant(AbstractCharacter source, AbstractWorldObject target, Vector3fImmutable targetLoc, int numTrains, ActionsBase ab, PowersBase pb) {
        this._handleChant(source, target, targetLoc, numTrains, ab, pb);
    }

    protected abstract void _handleChant(AbstractCharacter source, AbstractWorldObject target, Vector3fImmutable targetLoc, int numTrains, ActionsBase ab, PowersBase pb);

    public int getUUID() {
        return this.UUID;
    }

    //	public String getMessageType() {
    //		return this.type;
    //	}

    public String getIDString() {
        return this.IDString;
    }

    public boolean isAggressive() {
        return this.isAggressive;
    }

    public PowersBase getParent() {
        return this.parent;
    }

    public void setParent(PowersBase value) {
        this.parent = value;
    }

    public void applyEffectForItem(Item item, int trains) {
        if (this instanceof ApplyEffectPowerAction)
            ((ApplyEffectPowerAction) this)._applyEffectForItem(item, trains);
        if (this instanceof ApplyEffectsPowerAction)
            ((ApplyEffectsPowerAction) this)._applyEffectForItem(item, trains);
    }

    public void applyBakedInStatsForItem(Item item, int trains) {
        if (this instanceof ApplyEffectPowerAction)
            ((ApplyEffectPowerAction) this)._applyBakedInStatsForItem(item, trains);
        if (this instanceof ApplyEffectsPowerAction)
            ((ApplyEffectsPowerAction) this)._applyBakedInStatsForItem(item, trains);
    }

    public EffectsBase getEffectsBase() {
        if (this instanceof ApplyEffectPowerAction)
            return ((ApplyEffectPowerAction) this).getEffect();
        else if (this instanceof ApplyEffectsPowerAction)
            return ((ApplyEffectsPowerAction) this).getEffect();
        return null;
    }

    public EffectsBase getEffectsBase2() {
        if (this instanceof ApplyEffectsPowerAction)
            return ((ApplyEffectsPowerAction) this).getEffect2();
        return null;
    }

    //These functions verify a powerAction is valid for an item type
    public long getValidItemFlags() {
        return this.validItemFlags;
    }

    public String getType() {
        return type;
    }

}
