package jas.common.spawner.creature.handler.parsing.keys;

import jas.common.JASLog;
import jas.common.spawner.creature.handler.parsing.ParsingHelper;
import jas.common.spawner.creature.handler.parsing.TypeValuePair;
import jas.common.spawner.creature.handler.parsing.settings.OptionalSettings.Operand;

import java.util.ArrayList;
import java.util.HashMap;

import net.minecraft.entity.EntityLiving;
import net.minecraft.world.World;

public abstract class KeyParserRange extends KeyParserBase {

    public KeyParserRange(Key key) {
        super(key, true, KeyType.CHAINABLE);
    }

    @Override
    public boolean parseChainable(String parseable, ArrayList<TypeValuePair> parsedChainable,
            ArrayList<Operand> operandvalue) {
        String[] pieces = parseable.split(",");
        Operand operand = parseOperand(pieces);

        if (pieces.length == 3) {
            int min = ParsingHelper.parseFilteredInteger(pieces[1], 16, "1st " + key.key);
            int max = ParsingHelper.parseFilteredInteger(pieces[2], -1, "2nd " + key.key);
            TypeValuePair typeValue = new TypeValuePair(key, new Object[] { isInverted(pieces[0]), min, max });
            parsedChainable.add(typeValue);
            operandvalue.add(operand);
            return true;
        } else {
            JASLog.log().severe("Error Parsing %s Parameter. Invalid Argument Length.", key.key);
            return false;
        }
    }

    @Override
    public boolean parseValue(String parseable, HashMap<String, Object> valueCache) {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean isValidLocation(World world, EntityLiving entity, int xCoord, int yCoord, int zCoord,
            TypeValuePair typeValuePair, HashMap<String, Object> valueCache) {
        Object[] values = (Object[]) typeValuePair.getValue();
        boolean isInverted = (Boolean) values[0];

        int current = getCurrent(world, entity, xCoord, yCoord, zCoord, typeValuePair, valueCache);
        int minRange = (Integer) values[1];
        int maxRange = (Integer) values[2];

        boolean isValid = !(current <= maxRange && current >= minRange);
        if (minRange <= maxRange) {
            isValid = (current <= maxRange && current >= minRange);
        } else {
            isValid = !(current < minRange && current > maxRange);
        }
        return isInverted ? isValid : !isValid;
    }

    abstract int getCurrent(World world, EntityLiving entity, int xCoord, int yCoord, int zCoord,
            TypeValuePair typeValuePair, HashMap<String, Object> valueCache);
    
	@Override
	public String toExpression(String parseable) {
		String[] pieces = parseable.split(",");
		Operand operand = parseOperand(pieces);

		if (pieces.length == 3) {
			int minRange = ParsingHelper.parseFilteredInteger(pieces[1], 16, "1st " + key.key);
			int maxRange = ParsingHelper.parseFilteredInteger(pieces[2], -1, "2nd " + key.key);
			return toExpression(minRange, maxRange);
		}
		return "";
	}

	public abstract String toExpression(int minRange, int maxRange);

}
