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 ;
2016-09-19 18:48:27 +02:00
import static org.warp.picalculator.device.graphicengine.Display.Render.glColor3f ;
import static org.warp.picalculator.device.graphicengine.Display.Render.glDrawLine ;
2016-09-02 20:32:37 +02:00
import java.math.BigDecimal ;
import java.math.BigInteger ;
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 ;
import org.nevec.rjm.NumeroAvanzato ;
2016-09-19 18:48:27 +02:00
import org.warp.picalculator.Error ;
import org.warp.picalculator.Errors ;
import org.warp.picalculator.Utils ;
import org.warp.picalculator.math.MathematicalSymbols ;
import org.warp.picalculator.math.Variable ;
import org.warp.picalculator.math.Variables ;
2016-09-02 20:32:37 +02:00
2016-09-19 18:48:27 +02:00
public class Expression extends FunctionMultipleValues {
2016-09-02 20:32:37 +02:00
2016-09-12 16:30:51 +02:00
public Expression ( ) {
2016-09-02 20:32:37 +02:00
super ( ) ;
}
2016-09-19 18:48:27 +02:00
public Expression ( Function [ ] values ) {
2016-09-02 20:32:37 +02:00
super ( values ) ;
}
2016-09-12 16:30:51 +02:00
private boolean initialParenthesis = false ;
2016-09-02 20:32:37 +02:00
2016-09-12 16:30:51 +02:00
public Expression ( String string ) throws Error {
2016-09-02 20:32:37 +02:00
this ( string , " " , true ) ;
}
2016-09-12 16:30:51 +02:00
public Expression ( String string , String debugSpaces , boolean initialParenthesis ) throws Error {
2016-09-02 20:32:37 +02:00
super ( ) ;
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 {
2016-09-12 16:30:51 +02:00
new Number ( string ) ;
2016-09-02 20:32:37 +02:00
isNumber = true ;
} catch ( NumberFormatException ex ) {
isNumber = false ;
}
String processExpression = string ;
Utils . debug . println ( debugSpaces + " •Analyzing expression: " + processExpression ) ;
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:
2016-09-12 16:30:51 +02:00
Number t = new Number ( 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 ;
for ( 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 ;
2016-09-02 20:32:37 +02:00
String correzione = " + " ;
processExpression = processExpression . substring ( 0 , matcher . start ( 0 ) + 1 ) + correzione + processExpression . substring ( matcher . start ( 0 ) + matcher . group ( 0 ) . length ( ) , processExpression . length ( ) ) ;
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 ;
2016-09-02 20:32:37 +02:00
String correzione = " - " ;
processExpression = processExpression . substring ( 0 , matcher . start ( 0 ) ) + correzione + processExpression . substring ( matcher . start ( 0 ) + matcher . group ( 0 ) . length ( ) , processExpression . length ( ) ) ;
matcher = pattern . matcher ( processExpression ) ;
}
2016-09-12 16:30:51 +02: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 ( " (+ " , " ( " ) ;
}
// Cambia i segni appena prima 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 ( " -( " , " -1*( " ) ;
}
// 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-09-12 16:30:51 +02:00
pattern = Pattern . compile ( " [ " + ArrayToRegex ( Utils . add ( concat ( MathematicalSymbols . signums ( true , true ) , MathematicalSymbols . functions ( ) ) , " ( " ) ) + " ] \\ +[^ " + ArrayToRegex ( concat ( concat ( MathematicalSymbols . signums ( true , true ) , MathematicalSymbols . functions ( ) ) , new String [ ] { " ( " , " ) " } ) ) + " ]+?[ " + ArrayToRegex ( concat ( MathematicalSymbols . signums ( true , true ) , MathematicalSymbols . functions ( ) ) ) + " ]|[ " + ArrayToRegex ( concat ( MathematicalSymbols . signums ( true , true ) , MathematicalSymbols . functions ( ) ) ) + " ]+? \\ +[^ " + ArrayToRegex ( concat ( concat ( MathematicalSymbols . signums ( true , 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 ;
2016-09-02 20:32:37 +02:00
String correzione = matcher . group ( 0 ) . replaceFirst ( Matcher . quoteReplacement ( " + " ) , " " ) ;
processExpression = processExpression . substring ( 0 , matcher . start ( 0 ) + 1 ) + correzione + processExpression . substring ( matcher . start ( 0 ) + matcher . group ( 0 ) . length ( ) , processExpression . length ( ) ) ;
matcher = pattern . matcher ( processExpression ) ;
}
// Correggi i segni - in +-
2016-09-12 16:30:51 +02:00
pattern = Pattern . compile ( " [^ " + Utils . ArrayToRegex ( concat ( concat ( MathematicalSymbols . functions ( ) , new String [ ] { MathematicalSymbols . PARENTHESIS_OPEN } ) , MathematicalSymbols . signums ( true , true ) ) ) + " ]- " ) ;
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 ;
2016-09-02 20:32:37 +02:00
String correzione = " +- " ;
processExpression = processExpression . substring ( 0 , matcher . start ( 0 ) + 1 ) + correzione + processExpression . substring ( matcher . start ( 0 ) + matcher . group ( 0 ) . length ( ) , processExpression . length ( ) ) ;
matcher = pattern . matcher ( processExpression ) ;
}
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 ) ;
}
// Aggiungi i segni * accanto alle parentesi
pattern = Pattern . compile ( " \\ ([^ \\ (]+? \\ ) " ) ;
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 ;
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 ) ) ;
String newexp = matcher . group ( 0 ) . substring ( 1 , matcher . group ( 0 ) . length ( ) - 1 ) ;
String afterexp = processExpression . substring ( matcher . start ( 0 ) + matcher . group ( 0 ) . length ( ) , processExpression . length ( ) ) ;
2016-09-12 16:30:51 +02:00
if ( Pattern . compile ( " [^ \\ - " + Utils . ArrayToRegex ( Utils . add ( concat ( MathematicalSymbols . functions ( ) , concat ( MathematicalSymbols . signums ( true , 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-09-12 16:30:51 +02:00
if ( Pattern . compile ( " ^[^ \\ - " + Utils . ArrayToRegex ( Utils . add ( concat ( MathematicalSymbols . functions ( ) , concat ( MathematicalSymbols . signums ( true , 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
Expression imputRawParenthesis = new Expression ( ) ;
2016-09-19 18:48:27 +02:00
imputRawParenthesis . setVariables ( new Function [ ] { } ) ;
2016-09-02 20:32:37 +02:00
String tmp = " " ;
2016-09-12 16:30:51 +02:00
final String [ ] functions = concat ( concat ( concat ( concat ( MathematicalSymbols . functions ( ) , MathematicalSymbols . parentheses ( ) ) , MathematicalSymbols . signums ( true , 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:
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 :
f = new Sum ( null , null ) ;
2016-09-02 20:32:37 +02:00
break ;
2016-09-18 14:33:25 +02:00
case MathematicalSymbols . SUM_SUBTRACTION :
f = new SumSubtraction ( null , null ) ;
break ;
2016-09-12 16:30:51 +02:00
case MathematicalSymbols . MULTIPLICATION :
f = new Multiplication ( null , null ) ;
2016-09-02 20:32:37 +02:00
break ;
2016-09-12 16:30:51 +02:00
case MathematicalSymbols . PRIORITARY_MULTIPLICATION :
f = new PrioritaryMultiplication ( null , null ) ;
2016-09-02 20:32:37 +02:00
break ;
2016-09-12 16:30:51 +02:00
case MathematicalSymbols . DIVISION :
f = new Division ( null , null ) ;
2016-09-02 20:32:37 +02:00
break ;
2016-09-12 16:30:51 +02:00
case MathematicalSymbols . NTH_ROOT :
f = new Root ( null , null ) ;
2016-09-02 20:32:37 +02:00
break ;
2016-09-12 16:30:51 +02:00
case MathematicalSymbols . SQUARE_ROOT :
f = new RootSquare ( null ) ;
2016-09-02 20:32:37 +02:00
break ;
2016-09-12 16:30:51 +02:00
case MathematicalSymbols . POWER :
f = new Power ( null , null ) ;
2016-09-02 20:32:37 +02: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 + + ;
}
2016-09-12 16:30:51 +02:00
f = new Expression ( 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 ( ) ) ) {
2016-09-02 20:32:37 +02:00
// Fallback
NumeroAvanzato na = NumeroAvanzato . ONE ;
2016-09-12 16:30:51 +02:00
Variables iy = na . getVariableY ( ) ;
2016-10-02 16:01:41 +02:00
Variable var1 = new Variable ( charI . charAt ( 0 ) , 1 , 1 ) ;
List < Variable > newVariableList = iy . getVariablesList ( ) ;
newVariableList . add ( var1 ) ;
iy = new Variables ( newVariableList . toArray ( new Variable [ newVariableList . size ( ) ] ) ) ;
2016-09-12 16:30:51 +02:00
na = na . setVariableY ( iy ) ;
f = new Number ( na ) ;
2016-09-02 20:32:37 +02:00
} else {
throw new java . lang . RuntimeException ( " Il carattere " + charI + " non è tra le funzioni designate! \ nAggiungerlo ad esse o rimuovere il carattere dall'espressione! " ) ;
}
}
2016-09-12 16:30:51 +02:00
if ( f instanceof Expression ) {
2016-09-02 20:32:37 +02:00
tmp = " " ;
2016-09-12 16:30:51 +02:00
} else if ( f instanceof Number ) {
if ( imputRawParenthesis . getVariablesLength ( ) = = 0 ) {
2016-09-02 20:32:37 +02:00
if ( tmp . length ( ) > 0 ) {
2016-09-12 16:30:51 +02:00
imputRawParenthesis . addVariableToEnd ( new Number ( tmp ) ) ;
2016-09-02 20:32:37 +02:00
Utils . debug . println ( debugSpaces + " •Added value to expression: " + tmp ) ;
2016-09-12 16:30:51 +02:00
imputRawParenthesis . addVariableToEnd ( new PrioritaryMultiplication ( null , null ) ) ;
Utils . debug . println ( debugSpaces + " •Added variable to expression: " + new PrioritaryMultiplication ( null , null ) . getSymbol ( ) ) ;
2016-09-02 20:32:37 +02:00
}
} else {
if ( tmp . length ( ) > 0 ) {
2016-09-12 16:30:51 +02:00
if ( imputRawParenthesis . getVariable ( imputRawParenthesis . getVariablesLength ( ) - 1 ) instanceof Number ) {
imputRawParenthesis . addVariableToEnd ( new PrioritaryMultiplication ( null , null ) ) ;
Utils . debug . println ( debugSpaces + " •Added variable to expression: " + new PrioritaryMultiplication ( null , null ) . getSymbol ( ) ) ;
2016-09-02 20:32:37 +02:00
}
if ( tmp . equals ( " - " ) ) {
tmp = " -1 " ;
}
2016-09-12 16:30:51 +02:00
imputRawParenthesis . addVariableToEnd ( new Number ( tmp ) ) ;
2016-09-02 20:32:37 +02:00
Utils . debug . println ( debugSpaces + " •Added value to expression: " + tmp ) ;
}
2016-09-12 16:30:51 +02:00
if ( tmp . length ( ) > 0 | | imputRawParenthesis . getVariable ( imputRawParenthesis . getVariablesLength ( ) - 1 ) instanceof Number ) {
imputRawParenthesis . addVariableToEnd ( new PrioritaryMultiplication ( null , null ) ) ;
Utils . debug . println ( debugSpaces + " •Added variable to expression: " + new PrioritaryMultiplication ( null , null ) . getSymbol ( ) ) ;
2016-09-02 20:32:37 +02:00
}
}
} else {
if ( tmp . length ( ) ! = 0 ) {
2016-09-12 16:30:51 +02:00
imputRawParenthesis . addVariableToEnd ( new Number ( tmp ) ) ;
2016-09-02 20:32:37 +02:00
Utils . debug . println ( debugSpaces + " •Added variable to expression: " + tmp ) ;
}
}
2016-09-12 16:30:51 +02:00
imputRawParenthesis . addVariableToEnd ( f ) ;
Utils . debug . println ( debugSpaces + " •Added variable to expression: " + f . getSymbol ( ) ) ;
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 ;
} catch ( Exception exc ) {
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 {
2016-09-12 16:30:51 +02:00
imputRawParenthesis . addVariableToEnd ( new Number ( tmp ) ) ;
2016-09-02 20:32:37 +02:00
} catch ( 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-09-12 16:30:51 +02:00
for ( int i = 0 ; i < imputRawParenthesis . variables . length ; i + + ) {
if ( imputRawParenthesis . variables [ i ] instanceof Expression ) {
Expression par = ( Expression ) imputRawParenthesis . variables [ i ] ;
2016-09-02 20:32:37 +02:00
if ( par . variables . length = = 1 ) {
2016-09-19 18:48:27 +02:00
Function subFunz = par . variables [ 0 ] ;
2016-09-12 16:30:51 +02:00
if ( subFunz instanceof Expression | | subFunz instanceof Number ) {
imputRawParenthesis . variables [ i ] = subFunz ;
2016-09-02 20:32:37 +02:00
Utils . debug . println ( debugSpaces + " •Useless parentheses removed " ) ;
}
}
}
}
// Inizia l'affinazione dell'espressione
Utils . debug . println ( debugSpaces + " •Pushing classes... " ) ;
2016-09-19 18:48:27 +02:00
Function [ ] oldFunctionsArray = imputRawParenthesis . getVariables ( ) ;
ArrayList < Function > oldFunctionsList = new ArrayList < Function > ( ) ;
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
2016-09-12 16:30:51 +02:00
if ( funzione instanceof Root ) {
2016-09-12 16:57:59 +02:00
if ( ( i - 1 ) > = 0 & & oldFunctionsArray [ i - 1 ] instanceof Number & & ( ( Number ) oldFunctionsArray [ i - 1 ] ) . getTerm ( ) . isBigInteger ( false ) & & ( ( Number ) oldFunctionsArray [ i - 1 ] ) . getTerm ( ) . toBigInteger ( false ) . compareTo ( new BigInteger ( " 2 " ) ) = = 0 ) {
2016-09-12 16:30:51 +02:00
oldFunctionsArray [ i ] = null ;
oldFunctionsArray [ i - 1 ] = null ;
oldFunctionsList . remove ( oldFunctionsList . size ( ) - 1 ) ;
2016-09-02 20:32:37 +02:00
i - = 1 ;
2016-09-12 16:30:51 +02:00
funzione = new RootSquare ( 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-09-12 16:30:51 +02:00
if ( Utils . areThereEmptyPrioritaryMultiplications ( oldFunctionsList ) ) {
step = " prioritary multiplications " ; // PRIMA FASE
} else if ( Utils . areThereOnlyEmptySNFunctions ( oldFunctionsList ) ) {
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 ) {
oldFunctionsList . set ( 0 , new Multiplication ( oldFunctionsList . get ( 0 ) , oldFunctionsList . remove ( 1 ) ) ) ;
2016-09-02 20:32:37 +02:00
}
}
2016-09-12 16:30:51 +02:00
Utils . debug . println ( debugSpaces + " •Phase: " + step ) ;
while ( i < oldFunctionsList . size ( ) & & change = = false & & oldFunctionsList . size ( ) > 1 ) {
2016-09-19 18:48:27 +02:00
Function funzioneTMP = oldFunctionsList . get ( i ) ;
if ( funzioneTMP instanceof FunctionTwoValues ) {
2016-09-12 16:30:51 +02:00
if ( step ! = " SN Functions " ) {
2016-09-02 20:32:37 +02:00
if (
2016-09-19 18:48:27 +02:00
( step = = " sums " & & ( funzioneTMP instanceof Sum | | funzioneTMP instanceof SumSubtraction ) = = 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 ) ) ) )
2016-09-02 20:32:37 +02:00
| |
(
2016-09-12 16:30:51 +02:00
step . equals ( " prioritary multiplications " )
2016-09-02 20:32:37 +02:00
& &
2016-09-12 16:30:51 +02:00
( funzioneTMP instanceof PrioritaryMultiplication )
2016-09-02 20:32:37 +02:00
& &
2016-09-19 18:48:27 +02:00
( ( FunctionTwoValues ) funzioneTMP ) . variable1 = = null
2016-09-02 20:32:37 +02:00
& &
2016-09-19 18:48:27 +02:00
( ( FunctionTwoValues ) funzioneTMP ) . variable2 = = null
2016-09-02 20:32:37 +02:00
)
| |
(
2016-09-12 16:30:51 +02:00
step . equals ( " multiplications " )
2016-09-02 20:32:37 +02:00
& &
(
2016-09-12 16:30:51 +02:00
( funzioneTMP instanceof Multiplication )
2016-09-02 20:32:37 +02:00
| |
2016-09-12 16:30:51 +02:00
( funzioneTMP instanceof Division )
2016-09-02 20:32:37 +02:00
)
& &
2016-09-19 18:48:27 +02:00
( ( FunctionTwoValues ) funzioneTMP ) . variable1 = = null
2016-09-02 20:32:37 +02:00
& &
2016-09-19 18:48:27 +02:00
( ( FunctionTwoValues ) funzioneTMP ) . variable2 = = null
2016-09-02 20:32:37 +02:00
)
| |
(
2016-09-12 16:30:51 +02:00
step = = " NSN Functions "
2016-09-02 20:32:37 +02:00
& &
2016-09-12 16:30:51 +02:00
( funzioneTMP instanceof Sum ) = = false
2016-09-02 20:32:37 +02:00
& &
2016-09-18 14:33:25 +02:00
( funzioneTMP instanceof SumSubtraction ) = = false
& &
2016-09-12 16:30:51 +02:00
( funzioneTMP instanceof Multiplication ) = = false
2016-09-02 20:32:37 +02:00
& &
2016-09-12 16:30:51 +02:00
( funzioneTMP instanceof PrioritaryMultiplication ) = = false
2016-09-02 20:32:37 +02:00
& &
2016-09-12 16:30:51 +02:00
( funzioneTMP instanceof Division ) = = false
2016-09-02 20:32:37 +02:00
& &
(
(
2016-09-19 18:48:27 +02:00
funzioneTMP instanceof AnteriorFunction
2016-09-02 20:32:37 +02:00
& &
2016-09-19 18:48:27 +02:00
( ( AnteriorFunction ) funzioneTMP ) . variable = = null
2016-09-02 20:32:37 +02:00
)
| |
(
2016-09-19 18:48:27 +02:00
funzioneTMP instanceof FunctionTwoValues
2016-09-02 20:32:37 +02:00
& &
2016-09-19 18:48:27 +02:00
( ( FunctionTwoValues ) funzioneTMP ) . variable1 = = null
2016-09-02 20:32:37 +02:00
& &
2016-09-19 18:48:27 +02:00
( ( FunctionTwoValues ) funzioneTMP ) . variable2 = = null
2016-09-02 20:32:37 +02:00
)
| |
(
2016-09-19 18:48:27 +02:00
! ( funzioneTMP instanceof AnteriorFunction )
2016-09-02 20:32:37 +02:00
& &
2016-09-19 18:48:27 +02:00
! ( 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 ) {
2016-09-19 18:48:27 +02:00
( ( FunctionTwoValues ) funzioneTMP ) . setVariable1 ( ( Function ) oldFunctionsList . get ( i - 1 ) ) ;
( ( FunctionTwoValues ) funzioneTMP ) . setVariable2 ( ( Function ) 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 ( ) ) ;
2016-09-02 20:32:37 +02:00
} catch ( NullPointerException ex2 ) { }
try {
2016-09-19 18:48:27 +02:00
Utils . debug . println ( debugSpaces + " " + " var2= " + ( ( FunctionTwoValues ) funzioneTMP ) . getVariable2 ( ) . toString ( ) ) ;
2016-09-02 20:32:37 +02:00
} catch ( NullPointerException ex2 ) { }
try {
2016-09-19 18:48:27 +02:00
Utils . debug . println ( debugSpaces + " " + " (result)= " + ( ( FunctionTwoValues ) funzioneTMP ) . toString ( ) ) ;
2016-09-02 20:32:37 +02:00
} catch ( NullPointerException ex2 ) { }
} else {
throw new java . lang . RuntimeException ( " Argomenti mancanti! Sistemare l'equazione! " ) ;
}
}
}
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 ( ) ) {
2016-09-19 18:48:27 +02:00
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 ;
2016-09-19 18:48:27 +02:00
( ( AnteriorFunction ) funzioneTMP ) . setVariable ( ( Function ) 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 ( ) ) ;
2016-09-19 18:48:27 +02:00
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 {
throw new java . lang . RuntimeException ( " Argomenti mancanti! Sistemare l'equazione! " ) ;
}
}
2016-09-12 16:30:51 +02:00
} else if ( funzioneTMP instanceof Number | | 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
}
2016-09-12 16:30:51 +02:00
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. " ) ;
2016-09-18 14:33:25 +02:00
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 ( ) {
if ( variables . length > = 1 ) {
return true ;
}
return false ;
}
2016-09-02 20:32:37 +02:00
@Override
2016-09-18 14:33:25 +02:00
public List < Function > solveOneStep ( ) throws Error {
List < Function > ret = new ArrayList < > ( ) ;
2016-10-02 16:01:41 +02:00
if ( variables . length = = 1 ) {
if ( variables [ 0 ] . isSolved ( ) ) {
ret . add ( variables [ 0 ] ) ;
return ret ;
} else {
2016-09-18 14:33:25 +02:00
List < Function > l = variables [ 0 ] . solveOneStep ( ) ;
for ( Function f : l ) {
if ( f instanceof Number ) {
ret . add ( f ) ;
} else {
2016-09-19 18:48:27 +02:00
ret . add ( new Expression ( new Function [ ] { ( Function ) f } ) ) ;
2016-09-18 14:33:25 +02:00
}
}
return ret ;
}
2016-09-02 20:32:37 +02:00
} else {
2016-09-12 16:30:51 +02:00
for ( Function f : variables ) {
2016-10-02 16:01:41 +02:00
if ( f . isSolved ( ) = = false ) {
2016-09-18 14:33:25 +02:00
List < Function > partial = f . solveOneStep ( ) ;
for ( Function fnc : partial ) {
2016-09-19 18:48:27 +02:00
ret . add ( new Expression ( new Function [ ] { ( 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 ( ) {
for ( Function var : variables ) {
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
}
width = calcWidth ( ) ;
height = calcHeight ( ) ;
line = calcLine ( ) ;
}
public boolean parenthesesNeeded ( ) {
boolean parenthesesneeded = true ;
2016-09-12 16:30:51 +02:00
if ( initialParenthesis ) {
2016-09-02 20:32:37 +02:00
parenthesesneeded = false ;
} else {
if ( variables . length = = 1 ) {
2016-09-12 16:30:51 +02:00
if ( variables [ 0 ] instanceof Division ) {
2016-09-02 20:32:37 +02:00
parenthesesneeded = false ;
} else {
parenthesesneeded = true ;
}
}
}
return parenthesesneeded ;
}
@Override
public void draw ( int x , int y ) {
if ( parenthesesNeeded ( ) = = false ) {
this . variables [ 0 ] . draw ( x , y ) ;
} else {
float miny = y ;
float maxy = y + getHeight ( ) ;
int h = getHeight ( ) ;
x + = 1 ;
glColor3f ( 0 , 0 , 0 ) ;
glDrawLine ( x , y + 2 , x + 2 , y ) ;
glDrawLine ( x , y + 2 , x , y + h - 3 ) ;
glDrawLine ( x , y + h - 3 , x + 2 , y + h - 1 ) ;
x + = 4 ;
2016-09-12 16:30:51 +02:00
for ( Function f : variables ) {
2016-09-02 20:32:37 +02:00
float fheight = f . getHeight ( ) ;
float y2 = miny + ( ( maxy - miny ) / 2 - fheight / 2 ) ;
f . draw ( x , ( int ) y2 ) ;
x + = f . getWidth ( ) ;
}
x + = 2 ;
glDrawLine ( x , y , x + 2 , y + 2 ) ;
glDrawLine ( x + 2 , y + 2 , x + 2 , y + h - 3 ) ;
glDrawLine ( x , y + h - 1 , x + 2 , y + h - 3 ) ;
x + = 4 ;
}
}
@Override
public int getWidth ( ) {
return width ;
}
private int calcWidth ( ) {
if ( parenthesesNeeded ( ) = = false ) {
return this . variables [ 0 ] . getWidth ( ) ;
} else {
int w = 0 ;
2016-09-12 16:30:51 +02:00
for ( Function f : variables ) {
2016-09-02 20:32:37 +02:00
w + = f . getWidth ( ) ;
}
return 1 + 4 + w + 2 + 4 ;
}
}
@Override
public int getHeight ( ) {
return height ;
}
private int calcHeight ( ) {
2016-09-12 16:30:51 +02:00
if ( initialParenthesis | | variables . length = = 1 ) {
2016-09-02 20:32:37 +02:00
return this . variables [ 0 ] . getHeight ( ) ;
} else {
2016-09-12 16:30:51 +02:00
Function tmin = null ;
Function tmax = null ;
for ( Function t : variables ) {
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 ;
}
}
if ( tmin = = null )
return Utils . getFontHeight ( small ) ;
return tmin . getLine ( ) + tmax . getHeight ( ) - tmax . getLine ( ) ;
}
}
@Override
public int getLine ( ) {
return line ;
}
private int calcLine ( ) {
2016-09-12 16:30:51 +02:00
if ( initialParenthesis | | variables . length = = 1 ) {
2016-09-02 20:32:37 +02:00
return this . variables [ 0 ] . getLine ( ) ;
} else {
2016-09-12 16:30:51 +02:00
Function tl = null ;
for ( Function t : variables ) {
2016-09-02 20:32:37 +02:00
if ( tl = = null | | t . getLine ( ) > = tl . getLine ( ) ) {
tl = t ;
}
}
if ( tl = = null )
return Utils . getFontHeight ( small ) / 2 ;
return tl . getLine ( ) ;
}
}
}