2016-09-19 18:48:27 +02:00
package org.warp.picalculator.math.functions ;
2016-09-02 20:32:37 +02:00
import static org.warp.picalculator.Utils.ArrayToRegex ;
import static org.warp.picalculator.Utils.concat ;
import java.math.BigDecimal ;
import java.util.ArrayList ;
2016-09-18 14:33:25 +02:00
import java.util.List ;
2016-09-02 20:32:37 +02:00
import java.util.regex.Matcher ;
import java.util.regex.Pattern ;
2016-09-19 18:48:27 +02:00
import org.warp.picalculator.Error ;
import org.warp.picalculator.Errors ;
import org.warp.picalculator.Utils ;
2017-01-31 22:29:49 +01:00
import org.warp.picalculator.gui.DisplayManager ;
2017-01-17 22:32:40 +01:00
import org.warp.picalculator.math.Calculator ;
2016-09-19 18:48:27 +02:00
import org.warp.picalculator.math.MathematicalSymbols ;
2016-12-04 22:22:16 +01:00
import org.warp.picalculator.math.functions.trigonometry.ArcCosine ;
import org.warp.picalculator.math.functions.trigonometry.ArcSine ;
import org.warp.picalculator.math.functions.trigonometry.ArcTangent ;
import org.warp.picalculator.math.functions.trigonometry.Cosine ;
import org.warp.picalculator.math.functions.trigonometry.Sine ;
import org.warp.picalculator.math.functions.trigonometry.Tangent ;
2016-11-02 21:56:40 +01:00
2016-09-19 18:48:27 +02:00
public class Expression extends FunctionMultipleValues {
2016-09-02 20:32:37 +02:00
2017-01-17 22:32:40 +01:00
public Expression ( Calculator root ) {
super ( root ) ;
2016-09-02 20:32:37 +02:00
}
2017-01-31 22:29:49 +01:00
2017-01-17 22:32:40 +01:00
public Expression ( Calculator root , Function [ ] values ) {
super ( root , values ) ;
2016-09-02 20:32:37 +02:00
}
2017-02-02 12:49:31 +01:00
public Expression ( Calculator root , Function value ) {
super ( root , new Function [ ] { value } ) ;
}
2016-09-12 16:30:51 +02:00
private boolean initialParenthesis = false ;
2016-09-02 20:32:37 +02:00
2017-01-17 22:32:40 +01:00
public Expression ( Calculator root , String string ) throws Error {
this ( root , string , " " , true ) ;
2016-09-02 20:32:37 +02:00
}
2017-01-17 22:32:40 +01:00
public Expression ( Calculator root , String string , String debugSpaces , boolean initialParenthesis ) throws Error {
super ( root ) ;
2016-09-12 16:30:51 +02:00
this . initialParenthesis = initialParenthesis ;
2016-09-02 20:32:37 +02:00
boolean isNumber = false ;
2016-09-12 16:30:51 +02:00
// Determine if the expression is already a number:
2016-09-02 20:32:37 +02:00
// Determina se l'espressione è già un numero:
try {
2017-01-17 22:32:40 +01:00
new Number ( root , string ) ;
2016-09-02 20:32:37 +02:00
isNumber = true ;
2017-01-31 22:29:49 +01:00
} catch ( final NumberFormatException ex ) {
2016-09-02 20:32:37 +02:00
isNumber = false ;
}
2017-01-31 22:29:49 +01:00
2016-09-02 20:32:37 +02:00
String processExpression = string ;
Utils . debug . println ( debugSpaces + " •Analyzing expression: " + processExpression ) ;
2017-01-31 22:29:49 +01:00
2016-11-02 21:56:40 +01:00
isNumber = false ; //TODO: rimuovere isNumber, alcune semplificazione come la divisione per zero altrimenti verrebbero saltate.
2017-01-31 22:29:49 +01:00
if ( isNumber ) {
2016-09-12 16:30:51 +02:00
// If the expression is already a number:
2016-09-02 20:32:37 +02:00
// Se l'espressione è già un numero:
2017-01-31 22:29:49 +01:00
final Number t = new Number ( root , string ) ;
2016-09-19 18:48:27 +02:00
setVariables ( new Function [ ] { t } ) ;
2016-09-02 20:32:37 +02:00
Utils . debug . println ( debugSpaces + " •Result: " + t . toString ( ) ) ;
} else {
2016-09-12 16:30:51 +02:00
// Else prepare the expression:
2016-09-02 20:32:37 +02:00
// Altrimenti prepara l'espressione:
debugSpaces + = " " ;
2016-09-12 16:30:51 +02:00
// IF the expression is not a number:
2016-09-02 20:32:37 +02:00
// Se l'espressione non è già un numero:
2016-09-12 16:30:51 +02:00
// Check if there are more than one equal symbol (=)
// Controlla se ci sono più di un uguale (=)
2016-09-02 20:32:37 +02:00
int equationsFound = 0 ;
int systemsFound = 0 ;
2017-01-31 22:29:49 +01:00
for ( final char c : processExpression . toCharArray ( ) ) {
2016-09-12 16:30:51 +02:00
if ( ( " " + c ) . equals ( MathematicalSymbols . EQUATION ) ) {
2016-09-02 20:32:37 +02:00
equationsFound + = 1 ;
}
2016-09-12 16:30:51 +02:00
if ( ( " " + c ) . equals ( MathematicalSymbols . SYSTEM ) ) {
2016-09-02 20:32:37 +02:00
equationsFound + = 1 ;
}
}
if ( equationsFound = = 1 & & systemsFound = = 0 ) {
2016-09-12 16:30:51 +02:00
processExpression = MathematicalSymbols . SYSTEM + processExpression ;
2016-09-02 20:32:37 +02:00
systemsFound + = 1 ;
}
if ( equationsFound ! = systemsFound ) {
2016-09-12 16:30:51 +02:00
throw new Error ( Errors . SYNTAX_ERROR ) ;
2016-09-02 20:32:37 +02:00
}
2016-09-12 16:30:51 +02:00
//Solve the exceeding symbols ++ and --
2016-09-02 20:32:37 +02:00
// Correggi i segni ++ e -- in eccesso
Pattern pattern = Pattern . compile ( " \\ + \\ ++?| \\ - \\ -+? " ) ;
Matcher matcher = pattern . matcher ( processExpression ) ;
2016-09-12 16:30:51 +02:00
boolean symbolsChanged = false ;
2016-09-02 20:32:37 +02:00
while ( matcher . find ( ) ) {
2016-09-12 16:30:51 +02:00
symbolsChanged = true ;
2017-01-31 22:29:49 +01:00
final String correzione = " + " ;
2016-11-02 21:56:40 +01:00
processExpression = processExpression . substring ( 0 , matcher . start ( 0 ) ) + correzione + processExpression . substring ( matcher . start ( 0 ) + matcher . group ( 0 ) . length ( ) , processExpression . length ( ) ) ;
2016-09-02 20:32:37 +02:00
matcher = pattern . matcher ( processExpression ) ;
}
2016-09-12 16:30:51 +02:00
// Correct the exceeding symbols +- and -+
2016-09-02 20:32:37 +02:00
// Correggi i segni +- e -+ in eccesso
pattern = Pattern . compile ( " \\ + \\ -| \\ - \\ + " ) ;
matcher = pattern . matcher ( processExpression ) ;
while ( matcher . find ( ) ) {
2016-09-12 16:30:51 +02:00
symbolsChanged = true ;
2017-01-31 22:29:49 +01:00
final String correzione = " - " ;
2016-09-02 20:32:37 +02:00
processExpression = processExpression . substring ( 0 , matcher . start ( 0 ) ) + correzione + processExpression . substring ( matcher . start ( 0 ) + matcher . group ( 0 ) . length ( ) , processExpression . length ( ) ) ;
matcher = pattern . matcher ( processExpression ) ;
}
2017-01-31 22:29:49 +01:00
2016-09-02 20:32:37 +02:00
// Rimuovi i segni appena dopo le parentesi
if ( processExpression . contains ( " (+ " ) ) {
2016-09-12 16:30:51 +02:00
symbolsChanged = true ;
2016-09-02 20:32:37 +02:00
processExpression = processExpression . replace ( " (+ " , " ( " ) ;
}
2016-11-02 21:56:40 +01:00
// // Cambia i segni appena prima le parentesi
// if (processExpression.contains("-(")) {
// symbolsChanged = true;
// processExpression = processExpression.replace("-(", "-1*(");
// }
2016-09-02 20:32:37 +02:00
// Rimuovi i segni appena dopo l'inizio
if ( processExpression . startsWith ( " + " ) ) {
2016-09-12 16:30:51 +02:00
symbolsChanged = true ;
2016-09-02 20:32:37 +02:00
processExpression = processExpression . substring ( 1 , processExpression . length ( ) ) ;
}
// Rimuovi i + in eccesso
2016-11-25 22:40:43 +01:00
pattern = Pattern . compile ( " [ " + ArrayToRegex ( Utils . add ( concat ( MathematicalSymbols . signums ( true ) , MathematicalSymbols . functions ( ) ) , " ( " ) ) + " ] \\ +[^ " + ArrayToRegex ( concat ( concat ( MathematicalSymbols . signums ( true ) , MathematicalSymbols . functions ( ) ) , new String [ ] { " ( " , " ) " } ) ) + " ]+?[ " + ArrayToRegex ( concat ( MathematicalSymbols . signums ( true ) , MathematicalSymbols . functions ( ) ) ) + " ]|[ " + ArrayToRegex ( concat ( MathematicalSymbols . signums ( true ) , MathematicalSymbols . functions ( ) ) ) + " ]+? \\ +[^ " + ArrayToRegex ( concat ( concat ( MathematicalSymbols . signums ( true ) , MathematicalSymbols . functions ( ) ) , new String [ ] { " ( " , " ) " } ) ) + " ] " ) ;
2016-09-02 20:32:37 +02:00
matcher = pattern . matcher ( processExpression ) ;
2016-09-12 16:30:51 +02:00
symbolsChanged = false ;
2016-09-02 20:32:37 +02:00
while ( matcher . find ( ) ) {
2016-09-12 16:30:51 +02:00
symbolsChanged = true ;
2017-01-31 22:29:49 +01:00
final String correzione = matcher . group ( 0 ) . replaceFirst ( Matcher . quoteReplacement ( " + " ) , " " ) ;
2016-09-02 20:32:37 +02:00
processExpression = processExpression . substring ( 0 , matcher . start ( 0 ) + 1 ) + correzione + processExpression . substring ( matcher . start ( 0 ) + matcher . group ( 0 ) . length ( ) , processExpression . length ( ) ) ;
matcher = pattern . matcher ( processExpression ) ;
}
2017-01-31 22:29:49 +01:00
2016-11-02 21:56:40 +01:00
// Correggi i segni - in −
processExpression = processExpression . replace ( " - " , MathematicalSymbols . SUBTRACTION ) ;
2016-09-02 20:32:37 +02:00
2016-11-02 21:56:40 +01:00
// Correggi i segni − dopo di espressioni o funzioni SN in -
2016-11-25 22:40:43 +01:00
pattern = Pattern . compile ( " [ " + Utils . ArrayToRegex ( concat ( concat ( MathematicalSymbols . functions ( ) , new String [ ] { MathematicalSymbols . PARENTHESIS_OPEN } ) , MathematicalSymbols . signums ( true ) ) ) + " ] " + MathematicalSymbols . SUBTRACTION ) ;
2016-09-02 20:32:37 +02:00
matcher = pattern . matcher ( processExpression ) ;
while ( matcher . find ( ) ) {
2016-09-12 16:30:51 +02:00
symbolsChanged = true ;
2017-01-31 22:29:49 +01:00
final String correzione = MathematicalSymbols . MINUS ;
2016-11-02 21:56:40 +01:00
processExpression = processExpression . substring ( 0 , matcher . start ( 0 ) + 1 ) + correzione + processExpression . substring ( matcher . start ( 0 ) + 2 , processExpression . length ( ) ) ;
2016-09-02 20:32:37 +02:00
matcher = pattern . matcher ( processExpression ) ;
}
2017-01-31 22:29:49 +01:00
2016-11-02 21:56:40 +01:00
// Cambia il segno iniziale − in -
if ( processExpression . startsWith ( " − " ) ) {
symbolsChanged = true ;
processExpression = " - " + processExpression . substring ( 1 , processExpression . length ( ) ) ;
}
2016-09-02 20:32:37 +02:00
2016-09-12 16:30:51 +02:00
if ( symbolsChanged ) {
2016-09-02 20:32:37 +02:00
Utils . debug . println ( debugSpaces + " •Resolved signs: " + processExpression ) ;
}
2016-12-04 22:22:16 +01:00
// // Aggiungi le parentesi implicite per le potenze con una incognita
// pattern = Pattern.compile("(?<!(?:\\(|^))(["+Utils.ArrayToRegex(MathematicalSymbols.variables())+"]+"+MathematicalSymbols.POWER+"[^" + Utils.ArrayToRegex(Utils.add(concat(MathematicalSymbols.functionsNSN(), concat(MathematicalSymbols.signums(true), MathematicalSymbols.genericSyntax())), ")")) + "])(?!\\))");
// matcher = pattern.matcher(processExpression);
// symbolsChanged = false;
// while (matcher.find()) {
// symbolsChanged = true;
// String correzione = matcher.group().replace(MathematicalSymbols.POWER, "â‘´");
// processExpression = processExpression.substring(0, matcher.start(0)) + correzione + processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length());
// matcher = pattern.matcher(processExpression);
// }
//
// processExpression = processExpression.replace("â‘´", MathematicalSymbols.POWER);
2016-11-02 21:56:40 +01:00
2016-09-02 20:32:37 +02:00
// Aggiungi i segni * accanto alle parentesi
pattern = Pattern . compile ( " \\ ([^ \\ (]+? \\ ) " ) ;
matcher = pattern . matcher ( processExpression ) ;
while ( matcher . find ( ) ) {
2016-09-12 16:30:51 +02:00
symbolsChanged = true ;
2016-09-02 20:32:37 +02:00
// sistema i segni * impliciti prima e dopo l'espressione.
String beforeexp = processExpression . substring ( 0 , matcher . start ( 0 ) ) ;
2017-01-31 22:29:49 +01:00
final String newexp = matcher . group ( 0 ) . substring ( 1 , matcher . group ( 0 ) . length ( ) - 1 ) ;
2016-09-02 20:32:37 +02:00
String afterexp = processExpression . substring ( matcher . start ( 0 ) + matcher . group ( 0 ) . length ( ) , processExpression . length ( ) ) ;
2016-11-25 22:40:43 +01:00
if ( Pattern . compile ( " [^ \\ - " + Utils . ArrayToRegex ( Utils . add ( concat ( MathematicalSymbols . functions ( ) , concat ( MathematicalSymbols . signums ( true ) , MathematicalSymbols . genericSyntax ( ) ) ) , " ( " ) ) + " ]$ " ) . matcher ( beforeexp ) . find ( ) ) {
2016-09-02 20:32:37 +02:00
// Se la stringa precedente finisce con un numero
2016-09-12 16:30:51 +02:00
beforeexp + = MathematicalSymbols . MULTIPLICATION ;
2016-09-02 20:32:37 +02:00
}
2016-11-25 22:40:43 +01:00
if ( Pattern . compile ( " ^[^ \\ - " + Utils . ArrayToRegex ( Utils . add ( concat ( MathematicalSymbols . functions ( ) , concat ( MathematicalSymbols . signums ( true ) , MathematicalSymbols . genericSyntax ( ) ) ) , " ) " ) ) + " ] " ) . matcher ( afterexp ) . find ( ) ) {
2016-09-02 20:32:37 +02:00
// Se la stringa successiva inizia con un numero
2016-09-12 16:30:51 +02:00
afterexp = MathematicalSymbols . MULTIPLICATION + afterexp ;
2016-09-02 20:32:37 +02:00
}
processExpression = beforeexp + " ⑴ " + newexp + " ⑵ " + afterexp ;
matcher = pattern . matcher ( processExpression ) ;
}
processExpression = processExpression . replace ( " ⑴ " , " ( " ) . replace ( " ⑵ " , " ) " ) ;
2016-09-12 16:30:51 +02:00
if ( symbolsChanged ) {
2016-09-02 20:32:37 +02:00
Utils . debug . println ( debugSpaces + " •Added implicit multiplications: " + processExpression ) ;
}
Utils . debug . println ( debugSpaces + " •Subdivision in classes: " ) ;
debugSpaces + = " " ;
2016-09-12 16:30:51 +02:00
// Convert the expression to a list of objects
2017-01-31 22:29:49 +01:00
final Expression imputRawParenthesis = new Expression ( root ) ;
2016-09-19 18:48:27 +02:00
imputRawParenthesis . setVariables ( new Function [ ] { } ) ;
2016-09-02 20:32:37 +02:00
String tmp = " " ;
2016-11-25 22:40:43 +01:00
final String [ ] functions = concat ( concat ( concat ( concat ( MathematicalSymbols . functions ( ) , MathematicalSymbols . parentheses ( ) ) , MathematicalSymbols . signums ( true ) ) , MathematicalSymbols . variables ( ) ) , MathematicalSymbols . genericSyntax ( ) ) ;
2016-09-02 20:32:37 +02:00
for ( int i = 0 ; i < processExpression . length ( ) ; i + + ) {
// Per ogni carattere cerca se è un numero o una funzione:
2017-01-31 22:29:49 +01:00
final String charI = processExpression . charAt ( i ) + " " ;
2016-09-12 16:30:51 +02:00
if ( Utils . isInArray ( charI , functions ) ) {
2016-09-02 20:32:37 +02:00
2016-09-12 16:30:51 +02:00
// Finds the type of function fron the following list
2016-09-02 20:32:37 +02:00
// Cerca il tipo di funzione tra le esistenti
2016-09-19 18:48:27 +02:00
Function f = null ;
2016-09-02 20:32:37 +02:00
switch ( charI ) {
2016-09-12 16:30:51 +02:00
case MathematicalSymbols . SUM :
2017-01-17 22:32:40 +01:00
f = new Sum ( root , null , null ) ;
2016-09-02 20:32:37 +02:00
break ;
2016-09-18 14:33:25 +02:00
case MathematicalSymbols . SUM_SUBTRACTION :
2017-01-17 22:32:40 +01:00
f = new SumSubtraction ( root , null , null ) ;
2016-11-02 21:56:40 +01:00
break ;
case MathematicalSymbols . SUBTRACTION :
2017-01-17 22:32:40 +01:00
f = new Subtraction ( root , null , null ) ;
2016-11-02 21:56:40 +01:00
break ;
case MathematicalSymbols . MINUS :
2017-01-17 22:32:40 +01:00
f = new Negative ( root , null ) ;
2016-09-18 14:33:25 +02:00
break ;
2016-09-12 16:30:51 +02:00
case MathematicalSymbols . MULTIPLICATION :
2017-01-17 22:32:40 +01:00
f = new Multiplication ( root , null , null ) ;
2016-09-02 20:32:37 +02:00
break ;
2016-09-12 16:30:51 +02:00
case MathematicalSymbols . DIVISION :
2017-01-17 22:32:40 +01:00
f = new Division ( root , null , null ) ;
2016-09-02 20:32:37 +02:00
break ;
2016-09-12 16:30:51 +02:00
case MathematicalSymbols . NTH_ROOT :
2017-01-17 22:32:40 +01:00
f = new Root ( root , null , null ) ;
2016-09-02 20:32:37 +02:00
break ;
2016-09-12 16:30:51 +02:00
case MathematicalSymbols . SQUARE_ROOT :
2017-01-17 22:32:40 +01:00
f = new RootSquare ( root , null ) ;
2016-09-02 20:32:37 +02:00
break ;
2016-09-12 16:30:51 +02:00
case MathematicalSymbols . POWER :
2017-01-17 22:32:40 +01:00
f = new Power ( root , null , null ) ;
2016-09-02 20:32:37 +02:00
break ;
2016-12-04 22:22:16 +01:00
case MathematicalSymbols . SINE :
2017-01-17 22:32:40 +01:00
f = new Sine ( root , null ) ;
2016-12-04 22:22:16 +01:00
break ;
case MathematicalSymbols . COSINE :
2017-01-17 22:32:40 +01:00
f = new Cosine ( root , null ) ;
2016-12-04 22:22:16 +01:00
break ;
case MathematicalSymbols . TANGENT :
2017-01-17 22:32:40 +01:00
f = new Tangent ( root , null ) ;
2016-12-04 22:22:16 +01:00
break ;
case MathematicalSymbols . ARC_SINE :
2017-01-17 22:32:40 +01:00
f = new ArcSine ( root , null ) ;
2016-12-04 22:22:16 +01:00
break ;
case MathematicalSymbols . ARC_COSINE :
2017-01-17 22:32:40 +01:00
f = new ArcCosine ( root , null ) ;
2016-12-04 22:22:16 +01:00
break ;
case MathematicalSymbols . ARC_TANGENT :
2017-01-17 22:32:40 +01:00
f = new ArcTangent ( root , null ) ;
2016-12-04 22:22:16 +01:00
break ;
2016-09-12 16:30:51 +02:00
case MathematicalSymbols . PARENTHESIS_OPEN :
// Find the last closed parenthesis
2016-09-02 20:32:37 +02:00
// cerca l'ultima parentesi chiusa
int startIndex = i ;
int endIndex = - 1 ;
int jumps = - 1 ;
for ( int i2 = startIndex ; i2 < processExpression . length ( ) ; i2 + + ) {
2016-09-12 16:30:51 +02:00
if ( ( processExpression . charAt ( i2 ) + " " ) . equals ( MathematicalSymbols . PARENTHESIS_CLOSE ) ) {
2016-09-02 20:32:37 +02:00
if ( jumps = = 0 ) {
endIndex = i2 ;
break ;
} else if ( jumps > 0 ) {
jumps - = 1 ;
} else if ( jumps < 0 ) {
2016-09-12 16:30:51 +02:00
throw new Error ( Errors . UNBALANCED_BRACKETS ) ;
2016-09-02 20:32:37 +02:00
}
2016-09-12 16:30:51 +02:00
} else if ( ( processExpression . charAt ( i2 ) + " " ) . equals ( MathematicalSymbols . PARENTHESIS_OPEN ) ) {
2016-09-02 20:32:37 +02:00
jumps + = 1 ;
}
}
if ( endIndex = = - 1 | | endIndex < startIndex ) {
2016-09-12 16:30:51 +02:00
throw new Error ( Errors . UNBALANCED_BRACKETS ) ;
2016-09-02 20:32:37 +02:00
}
startIndex + = 1 ;
i = startIndex ;
String tmpExpr = " " ;
while ( i < endIndex ) {
tmpExpr + = processExpression . charAt ( i ) ;
i + + ;
}
2017-01-17 22:32:40 +01:00
f = new Expression ( root , tmpExpr , debugSpaces , false ) ;
2016-09-02 20:32:37 +02:00
break ;
default :
2016-09-12 16:30:51 +02:00
if ( Utils . isInArray ( charI , MathematicalSymbols . variables ( ) ) ) {
2017-02-06 21:38:17 +01:00
f = new Variable ( root , charI , Variable . V_TYPE . UNKNOWN ) ;
2016-09-02 20:32:37 +02:00
} else {
2016-11-25 22:40:43 +01:00
if ( charI = = " ( " | | charI = = " ) " ) {
throw new Error ( Errors . UNBALANCED_BRACKETS ) ;
} else {
2017-01-17 22:32:40 +01:00
System . err . println ( " Unexpected character while parsing expression: " + charI ) ;
2016-11-25 22:40:43 +01:00
throw new Error ( Errors . SYNTAX_ERROR ) ;
}
// throw new java.lang.RuntimeException("Il carattere " + charI + " non è tra le funzioni designate!\nAggiungerlo ad esse o rimuovere il carattere dall'espressione!");
2016-09-02 20:32:37 +02:00
}
}
2016-09-12 16:30:51 +02:00
if ( f instanceof Expression ) {
2016-09-02 20:32:37 +02:00
tmp = " " ;
2016-11-25 22:40:43 +01:00
} else if ( f instanceof Variable ) {
2016-09-12 16:30:51 +02:00
if ( imputRawParenthesis . getVariablesLength ( ) = = 0 ) {
2016-09-02 20:32:37 +02:00
if ( tmp . length ( ) > 0 ) {
2017-01-17 22:32:40 +01:00
imputRawParenthesis . addFunctionToEnd ( new Number ( root , tmp ) ) ;
2016-11-25 22:40:43 +01:00
Utils . debug . println ( debugSpaces + " •Added number to expression: " + tmp ) ;
2017-01-17 22:32:40 +01:00
imputRawParenthesis . addFunctionToEnd ( new Multiplication ( root , null , null ) ) ;
Utils . debug . println ( debugSpaces + " •Added multiplication to expression: " + new Multiplication ( root , null , null ) . getSymbol ( ) ) ;
2016-09-02 20:32:37 +02:00
}
} else {
2017-01-31 22:29:49 +01:00
final Function precedentFunction = imputRawParenthesis . getVariable ( imputRawParenthesis . getVariablesLength ( ) - 1 ) ;
2016-09-02 20:32:37 +02:00
if ( tmp . length ( ) > 0 ) {
2016-11-25 22:40:43 +01:00
if ( precedentFunction instanceof Number | | precedentFunction instanceof Variable ) {
2017-01-17 22:32:40 +01:00
imputRawParenthesis . addFunctionToEnd ( new Multiplication ( root , null , null ) ) ;
Utils . debug . println ( debugSpaces + " •Added multiplication to expression: " + new Multiplication ( root , null , null ) . getSymbol ( ) ) ;
2016-09-02 20:32:37 +02:00
}
if ( tmp . equals ( " - " ) ) {
2017-01-17 22:32:40 +01:00
imputRawParenthesis . addFunctionToEnd ( new Subtraction ( root , null , null ) ) ;
2016-11-02 21:56:40 +01:00
} else {
2017-01-17 22:32:40 +01:00
imputRawParenthesis . addFunctionToEnd ( new Number ( root , tmp ) ) ;
2016-11-25 22:40:43 +01:00
Utils . debug . println ( debugSpaces + " •Added number to expression: " + tmp ) ;
2016-09-02 20:32:37 +02:00
}
}
2016-11-25 22:40:43 +01:00
if ( tmp . length ( ) > 0 | | ( precedentFunction instanceof Number | | precedentFunction instanceof Variable ) ) {
2017-01-17 22:32:40 +01:00
imputRawParenthesis . addFunctionToEnd ( new Multiplication ( root , null , null ) ) ;
Utils . debug . println ( debugSpaces + " •Added multiplication to expression: " + new Multiplication ( root , null , null ) . getSymbol ( ) ) ;
2016-09-02 20:32:37 +02:00
}
}
} else {
if ( tmp . length ( ) ! = 0 ) {
2016-11-02 21:56:40 +01:00
if ( tmp . equals ( " - " ) ) {
if ( tmp . equals ( " - " ) ) {
tmp = " -1 " ;
}
}
2017-01-17 22:32:40 +01:00
imputRawParenthesis . addFunctionToEnd ( new Number ( root , tmp ) ) ;
2016-11-25 22:40:43 +01:00
Utils . debug . println ( debugSpaces + " •Added number to expression: " + tmp ) ;
2016-09-02 20:32:37 +02:00
}
}
2016-11-25 22:40:43 +01:00
imputRawParenthesis . addFunctionToEnd ( f ) ;
Utils . debug . println ( debugSpaces + " •Added variable to expression: " + f . getSymbol ( ) + ( f instanceof Number ? " (number) " : " (variable) " ) ) ;
2016-09-02 20:32:37 +02:00
tmp = " " ;
} else {
try {
if ( charI . equals ( " - " ) = = false & & charI . equals ( " . " ) = = false ) {
new BigDecimal ( tmp + charI ) ;
}
// Se il carattere è un numero intero, un segno
// negativo, o un punto
tmp + = charI ;
2017-01-31 22:29:49 +01:00
} catch ( final Exception exc ) {
2016-09-02 20:32:37 +02:00
throw new java . lang . RuntimeException ( " Il carattere " + tmp + charI + " non è nè un numero nè un espressione presente nella lista completa! \ nAggiungerlo ad essa o rimuovere il carattere dall'espressione! " ) ;
}
}
}
if ( tmp . length ( ) > 0 ) {
Utils . debug . println ( debugSpaces + " •Added variable to expression: " + tmp ) ;
try {
2017-01-17 22:32:40 +01:00
imputRawParenthesis . addFunctionToEnd ( new Number ( root , tmp ) ) ;
2017-01-31 22:29:49 +01:00
} catch ( final NumberFormatException ex ) {
2016-09-12 16:30:51 +02:00
throw new Error ( Errors . SYNTAX_ERROR ) ;
2016-09-02 20:32:37 +02:00
}
tmp = " " ;
}
int dsl = debugSpaces . length ( ) ;
debugSpaces = " " ;
for ( int i = 0 ; i < dsl - 2 ; i + + ) {
debugSpaces + = " " ;
}
Utils . debug . println ( debugSpaces + " •Finished the subdivision in classes. " ) ;
// Fine suddivisione di insieme
Utils . debug . println ( debugSpaces + " •Removing useless parentheses " ) ;
2016-11-25 22:40:43 +01:00
for ( int i = 0 ; i < imputRawParenthesis . functions . length ; i + + ) {
if ( imputRawParenthesis . functions [ i ] instanceof Expression ) {
2017-01-31 22:29:49 +01:00
final Expression par = ( Expression ) imputRawParenthesis . functions [ i ] ;
2016-11-25 22:40:43 +01:00
if ( par . functions . length = = 1 ) {
2017-01-31 22:29:49 +01:00
final Function subFunz = par . functions [ 0 ] ;
2016-11-25 22:40:43 +01:00
if ( subFunz instanceof Expression | | subFunz instanceof Number | | subFunz instanceof Variable ) {
imputRawParenthesis . functions [ i ] = subFunz ;
2016-09-02 20:32:37 +02:00
Utils . debug . println ( debugSpaces + " •Useless parentheses removed " ) ;
}
}
}
}
2017-01-31 22:29:49 +01:00
2016-09-02 20:32:37 +02:00
// Inizia l'affinazione dell'espressione
Utils . debug . println ( debugSpaces + " •Pushing classes... " ) ;
2017-01-31 22:29:49 +01:00
final Function [ ] oldFunctionsArray = imputRawParenthesis . getVariables ( ) ;
final ArrayList < Function > oldFunctionsList = new ArrayList < > ( ) ;
2016-09-12 16:30:51 +02:00
for ( int i = 0 ; i < oldFunctionsArray . length ; i + + ) {
2016-09-19 18:48:27 +02:00
Function funzione = oldFunctionsArray [ i ] ;
2016-09-02 20:32:37 +02:00
if ( funzione ! = null ) {
//Affinazione
2017-01-31 22:29:49 +01:00
if ( funzione instanceof Root ) {
if ( ( i - 1 ) > = 0 & & oldFunctionsArray [ i - 1 ] instanceof Number & & ( ( Number ) oldFunctionsArray [ i - 1 ] ) . getTerm ( ) . compareTo ( new BigDecimal ( 2 ) ) = = 0 ) {
2016-09-12 16:30:51 +02:00
oldFunctionsArray [ i ] = null ;
2017-01-31 22:29:49 +01:00
oldFunctionsArray [ i - 1 ] = null ;
oldFunctionsList . remove ( oldFunctionsList . size ( ) - 1 ) ;
2016-09-02 20:32:37 +02:00
i - = 1 ;
2017-01-17 22:32:40 +01:00
funzione = new RootSquare ( root , null ) ;
2016-09-02 20:32:37 +02:00
}
}
//Aggiunta della funzione alla lista grezza
2016-09-12 16:30:51 +02:00
oldFunctionsList . add ( funzione ) ;
2016-09-02 20:32:37 +02:00
}
}
2016-09-12 16:30:51 +02:00
if ( oldFunctionsList . size ( ) > 1 ) {
2016-09-02 20:32:37 +02:00
Utils . debug . println ( debugSpaces + " •Correcting classes: " ) ;
int before = 0 ;
2016-09-12 16:30:51 +02:00
String step = " SN Functions " ;
2016-09-02 20:32:37 +02:00
int n = 0 ;
do {
2016-09-12 16:30:51 +02:00
before = oldFunctionsList . size ( ) ;
2016-09-02 20:32:37 +02:00
int i = 0 ;
boolean change = false ;
2016-11-25 22:40:43 +01:00
if ( Utils . areThereOnlyEmptySNFunctions ( oldFunctionsList ) ) {
2016-09-12 16:30:51 +02:00
step = " SN Functions " ; // SECONDA FASE
} else if ( Utils . areThereOnlyEmptyNSNFunctions ( oldFunctionsList ) ) {
step = " NSN Functions " ; // TERZA FASE
} else if ( Utils . areThereEmptyMultiplications ( oldFunctionsList ) ) {
step = " multiplications " ; // QUARTA FASE
} else if ( Utils . areThereEmptySums ( oldFunctionsList ) ) {
step = " sums " ; // QUINTA FASE
2016-09-02 20:32:37 +02:00
} else {
// fase = "errore";
System . out . println ( " WARN: ---> POSSIBILE ERRORE????? <--- " ) ; // BOH
// throw new Errore(Errori.SYNTAX_ERROR);
2016-09-12 16:30:51 +02:00
while ( oldFunctionsList . size ( ) > 1 ) {
2017-01-17 22:32:40 +01:00
oldFunctionsList . set ( 0 , new Multiplication ( root , oldFunctionsList . get ( 0 ) , oldFunctionsList . remove ( 1 ) ) ) ;
2016-09-02 20:32:37 +02:00
}
}
2017-01-31 22:29:49 +01:00
Utils . debug . println ( debugSpaces + " •Phase: " + step ) ;
2016-09-12 16:30:51 +02:00
while ( i < oldFunctionsList . size ( ) & & change = = false & & oldFunctionsList . size ( ) > 1 ) {
2017-01-31 22:29:49 +01:00
final Function funzioneTMP = oldFunctionsList . get ( i ) ;
2016-09-19 18:48:27 +02:00
if ( funzioneTMP instanceof FunctionTwoValues ) {
2016-09-12 16:30:51 +02:00
if ( step ! = " SN Functions " ) {
2017-01-31 22:29:49 +01:00
if ( ( step = = " sums " & & ( funzioneTMP instanceof Sum | | funzioneTMP instanceof SumSubtraction | | funzioneTMP instanceof Subtraction ) = = true & & ( ( funzioneTMP instanceof AnteriorFunction & & ( ( AnteriorFunction ) funzioneTMP ) . variable = = null ) | | ( funzioneTMP instanceof FunctionTwoValues & & ( ( FunctionTwoValues ) funzioneTMP ) . variable1 = = null & & ( ( FunctionTwoValues ) funzioneTMP ) . variable2 = = null ) | | ( ! ( funzioneTMP instanceof AnteriorFunction ) & & ! ( funzioneTMP instanceof FunctionTwoValues ) ) ) ) | | ( step . equals ( " multiplications " ) & & ( ( funzioneTMP instanceof Multiplication ) | | ( funzioneTMP instanceof Division ) ) & & ( ( FunctionTwoValues ) funzioneTMP ) . variable1 = = null & & ( ( FunctionTwoValues ) funzioneTMP ) . variable2 = = null ) | | ( step = = " NSN Functions " & & ( funzioneTMP instanceof Sum ) = = false & & ( funzioneTMP instanceof SumSubtraction ) = = false & & ( funzioneTMP instanceof Subtraction ) = = false & & ( funzioneTMP instanceof Multiplication ) = = false & & ( funzioneTMP instanceof Division ) = = false & & ( ( funzioneTMP instanceof AnteriorFunction & & ( ( AnteriorFunction ) funzioneTMP ) . variable = = null ) | | ( funzioneTMP instanceof FunctionTwoValues & & ( ( FunctionTwoValues ) funzioneTMP ) . variable1 = = null & & ( ( FunctionTwoValues ) funzioneTMP ) . variable2 = = null ) | | ( ! ( funzioneTMP instanceof AnteriorFunction ) & & ! ( funzioneTMP instanceof FunctionTwoValues ) ) ) ) ) {
2016-09-02 20:32:37 +02:00
change = true ;
2016-09-12 16:30:51 +02:00
if ( i + 1 < oldFunctionsList . size ( ) & & i - 1 > = 0 ) {
2017-01-17 22:32:40 +01:00
( ( FunctionTwoValues ) funzioneTMP ) . setVariable1 ( oldFunctionsList . get ( i - 1 ) ) ;
( ( FunctionTwoValues ) funzioneTMP ) . setVariable2 ( oldFunctionsList . get ( i + 1 ) ) ;
2016-09-12 16:30:51 +02:00
oldFunctionsList . set ( i , funzioneTMP ) ;
2016-09-02 20:32:37 +02:00
// è importante togliere prima gli elementi
// in fondo e poi quelli davanti, perché gli
// indici scalano da destra a sinistra.
2016-09-12 16:30:51 +02:00
oldFunctionsList . remove ( i + 1 ) ;
oldFunctionsList . remove ( i - 1 ) ;
2016-09-02 20:32:37 +02:00
2016-09-12 16:30:51 +02:00
Utils . debug . println ( debugSpaces + " •Set variable to expression: " + funzioneTMP . getSymbol ( ) ) ;
2016-09-02 20:32:37 +02:00
try {
2016-09-19 18:48:27 +02:00
Utils . debug . println ( debugSpaces + " " + " var1= " + ( ( FunctionTwoValues ) funzioneTMP ) . getVariable1 ( ) . toString ( ) ) ;
2017-01-31 22:29:49 +01:00
} catch ( final NullPointerException ex2 ) { }
2016-09-02 20:32:37 +02:00
try {
2016-09-19 18:48:27 +02:00
Utils . debug . println ( debugSpaces + " " + " var2= " + ( ( FunctionTwoValues ) funzioneTMP ) . getVariable2 ( ) . toString ( ) ) ;
2017-01-31 22:29:49 +01:00
} catch ( final NullPointerException ex2 ) { }
2016-09-02 20:32:37 +02:00
try {
2016-09-19 18:48:27 +02:00
Utils . debug . println ( debugSpaces + " " + " (result)= " + ( ( FunctionTwoValues ) funzioneTMP ) . toString ( ) ) ;
2017-01-31 22:29:49 +01:00
} catch ( final NullPointerException ex2 ) { }
2016-09-02 20:32:37 +02:00
} else {
2016-11-25 22:40:43 +01:00
throw new Error ( Errors . SYNTAX_ERROR ) ;
2016-09-02 20:32:37 +02:00
}
}
}
2016-09-19 18:48:27 +02:00
} else if ( funzioneTMP instanceof AnteriorFunction ) {
if ( ( step = = " SN Functions " & & ( ( AnteriorFunction ) funzioneTMP ) . variable = = null ) ) {
2016-09-12 16:30:51 +02:00
if ( i + 1 < oldFunctionsList . size ( ) ) {
2017-01-31 22:29:49 +01:00
final Function nextFunc = oldFunctionsList . get ( i + 1 ) ;
if ( nextFunc instanceof AnteriorFunction & & ( ( AnteriorFunction ) nextFunc ) . variable = = null ) {
2016-09-02 20:32:37 +02:00
} else {
change = true ;
2017-01-17 22:32:40 +01:00
( ( AnteriorFunction ) funzioneTMP ) . setVariable ( nextFunc ) ;
2016-09-12 16:30:51 +02:00
oldFunctionsList . set ( i , funzioneTMP ) ;
2016-09-02 20:32:37 +02:00
// è importante togliere prima gli elementi in
// fondo e poi quelli davanti, perché gli indici
// scalano da destra a sinistra.
2016-09-12 16:30:51 +02:00
oldFunctionsList . remove ( i + 1 ) ;
2016-09-02 20:32:37 +02:00
2016-09-12 16:30:51 +02:00
Utils . debug . println ( debugSpaces + " •Set variable to expression: " + funzioneTMP . getSymbol ( ) ) ;
2017-01-31 22:29:49 +01:00
final Function var = ( ( AnteriorFunction ) funzioneTMP ) . getVariable ( ) ;
2016-09-02 20:32:37 +02:00
if ( var = = null ) {
Utils . debug . println ( debugSpaces + " " + " var=null " ) ;
} else {
Utils . debug . println ( debugSpaces + " " + " var= " + var . toString ( ) ) ;
}
}
} else {
2016-11-25 22:40:43 +01:00
throw new Error ( Errors . SYNTAX_ERROR ) ;
2016-09-02 20:32:37 +02:00
}
}
2016-11-25 22:40:43 +01:00
} else if ( funzioneTMP instanceof Number | | funzioneTMP instanceof Variable | | funzioneTMP instanceof Expression ) {
2016-09-02 20:32:37 +02:00
if ( n < 300 ) {
// Utils.debug.println(debugSpaces+" •Set variable
// to number:"+funzioneTMP.calcola());
}
} else {
throw new java . lang . RuntimeException ( " Tipo sconosciuto " ) ;
}
i + + ;
n + + ;
}
2016-09-12 16:30:51 +02:00
} while ( ( ( oldFunctionsList . size ( ) ! = before | | step ! = " sums " ) & & oldFunctionsList . size ( ) > 1 ) ) ;
2016-09-02 20:32:37 +02:00
}
2017-01-31 22:29:49 +01:00
if ( oldFunctionsList . isEmpty ( ) ) {
setVariables ( new Function [ ] { new Number ( root , 0 ) } ) ;
2016-12-04 22:22:16 +01:00
} else {
setVariables ( oldFunctionsList ) ;
}
2016-09-02 20:32:37 +02:00
dsl = debugSpaces . length ( ) ;
debugSpaces = " " ;
for ( int i = 0 ; i < dsl - 2 ; i + + ) {
debugSpaces + = " " ;
}
Utils . debug . println ( debugSpaces + " •Finished correcting classes. " ) ;
2017-01-31 22:29:49 +01:00
final String result = toString ( ) ;
2016-09-02 20:32:37 +02:00
Utils . debug . println ( debugSpaces + " •Result: " + result ) ;
}
}
@Override
2016-09-12 16:30:51 +02:00
public String getSymbol ( ) {
2016-09-02 20:32:37 +02:00
return " Parentesi " ;
}
2016-10-02 16:01:41 +02:00
@Override
protected boolean isSolvable ( ) {
2016-11-25 22:40:43 +01:00
if ( functions . length > 1 ) {
2016-10-02 16:01:41 +02:00
return true ;
2016-11-25 22:40:43 +01:00
} else if ( functions . length = = 1 ) {
2017-01-31 22:29:49 +01:00
final Function f = functions [ 0 ] ;
2016-11-25 22:40:43 +01:00
if ( f . isSolved ( ) = = false ) {
return true ;
} else {
return ! parenthesisNeeded ( ) ;
}
2016-10-02 16:01:41 +02:00
}
return false ;
}
2017-01-31 22:29:49 +01:00
2016-09-02 20:32:37 +02:00
@Override
2016-09-18 14:33:25 +02:00
public List < Function > solveOneStep ( ) throws Error {
2017-01-31 22:29:49 +01:00
final List < Function > ret = new ArrayList < > ( ) ;
2016-11-25 22:40:43 +01:00
if ( functions . length = = 1 ) {
if ( functions [ 0 ] . isSolved ( ) | | ! parenthesisNeeded ( ) ) {
ret . add ( functions [ 0 ] ) ;
2016-10-02 16:01:41 +02:00
return ret ;
} else {
2017-01-31 22:29:49 +01:00
final List < Function > l = functions [ 0 ] . solveOneStep ( ) ;
for ( final Function f : l ) {
2016-11-25 22:40:43 +01:00
if ( f instanceof Number | | f instanceof Variable ) {
2016-09-18 14:33:25 +02:00
ret . add ( f ) ;
} else {
2017-01-31 22:29:49 +01:00
ret . add ( new Expression ( root , new Function [ ] { f } ) ) ;
2016-09-18 14:33:25 +02:00
}
}
return ret ;
}
2016-09-02 20:32:37 +02:00
} else {
2017-01-31 22:29:49 +01:00
for ( final Function f : functions ) {
2016-10-02 16:01:41 +02:00
if ( f . isSolved ( ) = = false ) {
2017-01-31 22:29:49 +01:00
final List < Function > partial = f . solveOneStep ( ) ;
for ( final Function fnc : partial ) {
ret . add ( new Expression ( root , new Function [ ] { fnc } ) ) ;
2016-09-18 14:33:25 +02:00
}
}
2016-09-02 20:32:37 +02:00
}
2016-09-18 14:33:25 +02:00
return ret ;
2016-09-02 20:32:37 +02:00
}
}
@Override
2016-09-12 16:30:51 +02:00
public void generateGraphics ( ) {
2017-01-31 22:29:49 +01:00
for ( final Function var : functions ) {
2016-09-02 20:32:37 +02:00
var . setSmall ( small ) ;
2016-09-12 16:30:51 +02:00
var . generateGraphics ( ) ;
2016-09-02 20:32:37 +02:00
}
2017-01-31 22:29:49 +01:00
2016-09-02 20:32:37 +02:00
width = calcWidth ( ) ;
height = calcHeight ( ) ;
line = calcLine ( ) ;
}
2017-01-31 22:29:49 +01:00
2016-11-25 22:40:43 +01:00
public boolean parenthesisNeeded ( ) {
boolean parenthesisneeded = true ;
2017-01-17 22:32:40 +01:00
if ( initialParenthesis ) {
2016-11-25 22:40:43 +01:00
parenthesisneeded = false ;
2016-09-02 20:32:37 +02:00
} else {
2016-11-25 22:40:43 +01:00
if ( functions . length = = 1 ) {
2017-01-31 22:29:49 +01:00
final Function f = functions [ 0 ] ;
2017-02-02 12:49:31 +01:00
if ( f instanceof Number | | f instanceof Variable | | f instanceof Expression | | f instanceof Division | | f instanceof Joke | | f instanceof Undefined | | f instanceof Power | | f instanceof Sine | | f instanceof Cosine | | f instanceof Tangent | | f instanceof ArcSine | | f instanceof ArcCosine | | f instanceof ArcTangent | | f instanceof RootSquare ) {
2016-11-25 22:40:43 +01:00
parenthesisneeded = false ;
}
if ( f instanceof Multiplication ) {
2017-01-31 22:29:49 +01:00
if ( ( ( Multiplication ) f ) . getVariable1 ( ) instanceof Number ) {
parenthesisneeded = ! ( ( ( Multiplication ) f ) . getVariable2 ( ) instanceof Variable ) ;
} else if ( ( ( Multiplication ) f ) . getVariable2 ( ) instanceof Number ) {
parenthesisneeded = ! ( ( ( Multiplication ) f ) . getVariable1 ( ) instanceof Variable ) ;
} else if ( ( ( Multiplication ) f ) . getVariable1 ( ) instanceof Variable | | ( ( Multiplication ) f ) . getVariable2 ( ) instanceof Variable ) {
2016-11-25 22:40:43 +01:00
parenthesisneeded = false ;
2016-11-02 21:56:40 +01:00
}
2016-09-02 20:32:37 +02:00
}
}
}
2016-11-25 22:40:43 +01:00
return parenthesisneeded ;
2016-09-02 20:32:37 +02:00
}
2017-01-31 22:29:49 +01:00
2016-09-02 20:32:37 +02:00
@Override
public void draw ( int x , int y ) {
2016-11-25 22:40:43 +01:00
if ( parenthesisNeeded ( ) = = false ) {
2017-01-31 22:29:49 +01:00
functions [ 0 ] . draw ( x , y ) ;
2016-09-02 20:32:37 +02:00
} else {
2017-01-31 22:29:49 +01:00
final float miny = y ;
final float maxy = y + getHeight ( ) ;
final int h = getHeight ( ) ;
2016-09-02 20:32:37 +02:00
x + = 1 ;
2017-02-02 18:46:35 +01:00
DisplayManager . renderer . glDrawLine ( x , y + 2 , x , y + 2 ) ;
DisplayManager . renderer . glDrawLine ( x + 1 , y + 1 , x + 1 , y + 1 ) ;
DisplayManager . renderer . glDrawLine ( x + 2 , y , x + 2 , y ) ;
2017-01-31 22:29:49 +01:00
DisplayManager . renderer . glDrawLine ( x , y + 2 , x , y + h - 3 ) ;
2017-02-02 18:46:35 +01:00
DisplayManager . renderer . glDrawLine ( x , y + h - 3 , x , y + h - 3 ) ;
DisplayManager . renderer . glDrawLine ( x + 1 , y + h - 2 , x + 1 , y + h - 2 ) ;
DisplayManager . renderer . glDrawLine ( x + 2 , y + h - 1 , x + 2 , y + h - 1 ) ;
2016-09-02 20:32:37 +02:00
x + = 4 ;
2017-01-31 22:29:49 +01:00
for ( final Function f : functions ) {
final float fheight = f . getHeight ( ) ;
final float y2 = miny + ( ( maxy - miny ) / 2 - fheight / 2 ) ;
2016-09-02 20:32:37 +02:00
f . draw ( x , ( int ) y2 ) ;
x + = f . getWidth ( ) ;
}
x + = 2 ;
2017-02-02 18:46:35 +01:00
DisplayManager . renderer . glDrawLine ( x , y , x , y ) ;
DisplayManager . renderer . glDrawLine ( x + 1 , y + 1 , x + 1 , y + 1 ) ;
DisplayManager . renderer . glDrawLine ( x + 2 , y + 2 , x + 2 , y + 2 ) ;
2017-01-31 22:29:49 +01:00
DisplayManager . renderer . glDrawLine ( x + 2 , y + 2 , x + 2 , y + h - 3 ) ;
2017-02-02 18:46:35 +01:00
DisplayManager . renderer . glDrawLine ( x , y + h - 1 , x , y + h - 1 ) ;
DisplayManager . renderer . glDrawLine ( x + 1 , y + h - 2 , x + 1 , y + h - 2 ) ;
DisplayManager . renderer . glDrawLine ( x + 2 , y + h - 3 , x + 2 , y + h - 3 ) ;
2016-09-02 20:32:37 +02:00
x + = 4 ;
}
}
@Override
public int getWidth ( ) {
return width ;
}
private int calcWidth ( ) {
2016-11-25 22:40:43 +01:00
if ( parenthesisNeeded ( ) = = false ) {
2017-01-31 22:29:49 +01:00
return functions [ 0 ] . getWidth ( ) ;
2016-09-02 20:32:37 +02:00
} else {
int w = 0 ;
2017-01-31 22:29:49 +01:00
for ( final Function f : functions ) {
2016-09-02 20:32:37 +02:00
w + = f . getWidth ( ) ;
}
return 1 + 4 + w + 2 + 4 ;
}
}
2017-01-31 22:29:49 +01:00
2016-09-02 20:32:37 +02:00
@Override
public int getHeight ( ) {
return height ;
}
2017-01-31 22:29:49 +01:00
2016-09-02 20:32:37 +02:00
private int calcHeight ( ) {
2016-11-25 22:40:43 +01:00
if ( initialParenthesis | | functions . length = = 1 ) {
2017-01-31 22:29:49 +01:00
return functions [ 0 ] . getHeight ( ) ;
2016-09-02 20:32:37 +02:00
} else {
2016-09-12 16:30:51 +02:00
Function tmin = null ;
Function tmax = null ;
2017-01-31 22:29:49 +01:00
for ( final Function t : functions ) {
2016-09-02 20:32:37 +02:00
if ( tmin = = null | | t . getLine ( ) > = tmin . getLine ( ) ) {
tmin = t ;
}
if ( tmax = = null | | t . getHeight ( ) - t . getLine ( ) > = tmax . getHeight ( ) - tmax . getLine ( ) ) {
tmax = t ;
}
}
2017-01-31 22:29:49 +01:00
if ( tmin = = null ) {
2016-09-02 20:32:37 +02:00
return Utils . getFontHeight ( small ) ;
2017-01-31 22:29:49 +01:00
}
2016-09-02 20:32:37 +02:00
return tmin . getLine ( ) + tmax . getHeight ( ) - tmax . getLine ( ) ;
}
}
@Override
public int getLine ( ) {
return line ;
}
2017-01-31 22:29:49 +01:00
2016-09-02 20:32:37 +02:00
private int calcLine ( ) {
2016-11-25 22:40:43 +01:00
if ( initialParenthesis | | functions . length = = 1 ) {
2017-01-31 22:29:49 +01:00
return functions [ 0 ] . getLine ( ) ;
2016-09-02 20:32:37 +02:00
} else {
2016-09-12 16:30:51 +02:00
Function tl = null ;
2017-01-31 22:29:49 +01:00
for ( final Function t : functions ) {
2016-09-02 20:32:37 +02:00
if ( tl = = null | | t . getLine ( ) > = tl . getLine ( ) ) {
tl = t ;
}
}
2017-01-31 22:29:49 +01:00
if ( tl = = null ) {
2016-09-02 20:32:37 +02:00
return Utils . getFontHeight ( small ) / 2 ;
2017-01-31 22:29:49 +01:00
}
2016-09-02 20:32:37 +02:00
return tl . getLine ( ) ;
}
}
2017-01-31 22:29:49 +01:00
2016-11-25 22:40:43 +01:00
@Override
public String toString ( ) {
String vars = " null " ;
if ( functions ! = null & & functions . length > 0 ) {
if ( functions . length = = 1 ) {
if ( functions [ 0 ] ! = null ) {
vars = functions [ 0 ] . toString ( ) ;
}
} else {
2017-01-31 22:29:49 +01:00
for ( final Function variable : functions ) {
2016-11-25 22:40:43 +01:00
if ( variable ! = null ) {
vars + = " , " + variable . toString ( ) ;
}
}
vars = vars . substring ( 2 ) ;
}
}
2017-01-31 22:29:49 +01:00
return " ( " + vars + " ) " ;
2016-11-25 22:40:43 +01:00
}
2017-01-31 22:29:49 +01:00
2016-11-25 22:40:43 +01:00
@Override
public boolean equals ( Object o ) {
if ( o instanceof Expression ) {
2017-01-31 22:29:49 +01:00
final Expression f = ( Expression ) o ;
final Function [ ] exprFuncs1 = functions ;
final Function [ ] exprFuncs2 = f . functions ;
2016-11-25 22:40:43 +01:00
if ( exprFuncs1 . length = = exprFuncs2 . length ) {
for ( int i = 0 ; i < exprFuncs1 . length ; i + + ) {
if ( exprFuncs1 [ i ] . equals ( exprFuncs2 [ i ] ) = = false ) {
return false ;
}
}
return true ;
}
} else if ( o ! = null & getVariablesLength ( ) = = 1 ) {
2017-01-31 22:29:49 +01:00
final Function f = ( Function ) o ;
2016-11-25 22:40:43 +01:00
return ( functions [ 0 ] . equals ( f ) ) ;
} else if ( o = = null & getVariablesLength ( ) = = 0 ) {
return true ;
}
return false ;
}
2016-09-02 20:32:37 +02:00
}