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

import apfloatextraclasses.ApfloatMatrixException;
import apfloatextraclasses.ApfloatMatrixMath;
import expressiontree.ExpressionTreeElement;
import expressiontree.operands.Matrix;
import expressiontree.operands.NumberType;
import expressiontree.operators.BinaryOperator;
import expressiontree.operators.IncompatibleNumberFormatException;

/**
 * A szorzás operátorok osztálya.
 * @author Esta
 */
public class Multiplication 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) {
            //ha számot találtunk, számot adunk vissza.
            NumberType a = (NumberType) op1;
            NumberType b = (NumberType) op2;
            NumberType retValue = new NumberType(this.precision,false);
            retValue.setValue(a.getNumericValue().multiply(b.getNumericValue()));
            return retValue;
        } else if (op1 instanceof Matrix && op2 instanceof Matrix) {
            //ha mátrixot találtunk, és a dimenziók egyeznek, ok.
            Matrix a = (Matrix) op1;
            Matrix b = (Matrix) op2;
            if (a.getCols() == b.getRows()) {
                try {
                    Matrix retValue;
                    if (a.getRows() != 1 || b.getCols() != 1) {
                        //Ha az eredmény mátrix, akkor mátrixszal fogunk visszatérni
                        retValue = new Matrix(a.getRows(), b.getCols());
                    } else {
                        //Ha csak egy számot kapunk, akkor azt adjuk vissza.
                        retValue = new NumberType(this.precision,false);
                    }
                    retValue.setValues(ApfloatMatrixMath.multiply(a.getMatrixValues(), b.getMatrixValues()));
                    return retValue;
                } catch (ApfloatMatrixException ex) {
                    //Ha hiba volt kivételt dobunk.
                    throw new IncompatibleNumberFormatException(ex.getMessage());
                }
            } else if (a.getRows() == b.getRows() && a.getCols() == 1 && b.getCols() == 1) {
                try {
                    //A skalár szorzás mindenképpen számot ad eredményül.
                    NumberType retValue = new NumberType(this.precision,false);
                    retValue.setValue(ApfloatMatrixMath.scalarColoumnMultiply(a.getMatrixValues(), b.getMatrixValues()));
                    return retValue;
                } catch (ApfloatMatrixException ex) {
                    //Ha hiba volt kivételt dobunk.
                    throw new IncompatibleNumberFormatException(ex.getMessage());
                }
            } else if (a.getCols() == b.getCols() && a.getRows() == 1 && b.getRows() == 1) {
                try {
                    //A skalár szorzás mindenképpen számot ad eredményül.
                    NumberType retValue = new NumberType(this.precision,false);
                    retValue.setValue(ApfloatMatrixMath.scalarRowMultiply(a.getMatrixValues(), b.getMatrixValues()));
                    return retValue;
                } catch (ApfloatMatrixException ex) {
                    //Ha hiba volt kivételt dobunk.
                    throw new IncompatibleNumberFormatException(ex.getMessage());
                }
            } else { //rossz mátrix >> exception
                throw new IncompatibleNumberFormatException("ERROR_MUL");
            }
        } else { //EZ SOHA NEM FORDULHAT ELŐ
            throw new IncompatibleNumberFormatException("ERROR_MUL_UNKNOWN");
        }
    }

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

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