/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package expressiontree.operators.binary;

import expressiontree.ExpressionTreeElement;
import expressiontree.operands.NumberType;
import expressiontree.operators.BinaryOperator;
import expressiontree.operators.IncompatibleNumberFormatException;
import org.apfloat.ApfloatMath;

/**
 * A gyökvonás operátorok osztálya.
 * @author Esta
 */
public class Root extends BinaryOperator {

    @Override
    public ExpressionTreeElement getValue() throws IncompatibleNumberFormatException {
        ExpressionTreeElement op1 = this.operands.get(0).getValue();
        ExpressionTreeElement op2 = this.operands.get(1).getValue();
        if (op1 instanceof NumberType &&
                op2 instanceof NumberType &&
                ((NumberType) op2).isLongValue()) {
            //csak akkor lehet számolni, ha számot találtunk, és a második szám hosszú egész
            NumberType a = (NumberType) op1;
            NumberType b = (NumberType) op2;
            NumberType retValue = new NumberType(this.precision,false);
            try {
                if (b.getNumericValue().longValue() == 2) {
                    retValue.setValue(ApfloatMath.sqrt(a.getNumericValue().precision(a.getNumericValue().toString(true).length() * 1000)));
                } else if (b.getNumericValue().longValue() == 3) {
                    retValue.setValue(ApfloatMath.cbrt(a.getNumericValue()));
                } else {
                    retValue.setValue(ApfloatMath.root(a.getNumericValue(), b.getNumericValue().longValue()));
                }
            } catch (ArithmeticException e) {
                if (a.getNumericValue().longValue() == 0) {
                    throw new ArithmeticException("ROOT_X_IS_ZERO");
                } else {
                    throw new ArithmeticException("ROOT_X_IS_NEGATIVE_AND_N_IS_EVEN");
                }
            }
            return retValue;
        } else { //mátrix, vagy a második szám nem OK >> exception
            throw new IncompatibleNumberFormatException("ERROR_ROOT");
        }
    }

    @Override
    public String toText(boolean b) {
        if (b) {
            return "() root ()";
        } else {
            return "root ";
        }
    }

    @Override
    public String getLocalizedName() {
        return java.util.ResourceBundle.getBundle("languages/operators").getString("ROOT");
    }
}
