2016-09-02 20:32:37 +02:00
package org.warp.picalculator.screens ;
2016-12-05 19:58:49 +01:00
import static org.warp.picalculator.device.graphicengine.Display.Render.clearcolor ;
import static org.warp.picalculator.device.graphicengine.Display.Render.glClearColor ;
import static org.warp.picalculator.device.graphicengine.Display.Render.glColor ;
import static org.warp.picalculator.device.graphicengine.Display.Render.glDrawStringLeft ;
import static org.warp.picalculator.device.graphicengine.Display.Render.glDrawStringRight ;
import static org.warp.picalculator.device.graphicengine.Display.Render.glFillRect ;
import static org.warp.picalculator.device.graphicengine.Display.Render.glGetStringWidth ;
import static org.warp.picalculator.device.graphicengine.Display.Render.glSetFont ;
2016-09-02 20:32:37 +02:00
import java.io.PrintWriter ;
import java.io.StringWriter ;
2016-10-02 16:01:41 +02:00
import java.util.ArrayList ;
2017-01-16 17:57:09 +01:00
import java.util.Collections ;
2016-11-25 22:40:43 +01:00
import java.util.Iterator ;
2017-01-16 17:57:09 +01:00
import java.util.LinkedHashSet ;
import java.util.List ;
import java.util.Set ;
2016-09-02 20:32:37 +02:00
2016-09-12 16:30:51 +02:00
import org.warp.picalculator.Error ;
import org.warp.picalculator.Errors ;
2016-11-25 22:40:43 +01:00
import org.warp.picalculator.Main ;
2016-09-02 20:32:37 +02:00
import org.warp.picalculator.Utils ;
2016-11-25 22:40:43 +01:00
import org.warp.picalculator.device.Keyboard ;
2016-09-19 18:48:27 +02:00
import org.warp.picalculator.device.Keyboard.Key ;
2016-11-25 22:40:43 +01:00
import org.warp.picalculator.device.PIDisplay ;
2016-09-19 18:48:27 +02:00
import org.warp.picalculator.device.graphicengine.Display ;
2016-11-25 22:40:43 +01:00
import org.warp.picalculator.device.graphicengine.RAWFont ;
2016-09-19 18:48:27 +02:00
import org.warp.picalculator.device.graphicengine.Screen ;
2017-01-16 17:57:09 +01:00
import org.warp.picalculator.math.AngleMode ;
2016-09-19 18:48:27 +02:00
import org.warp.picalculator.math.Calculator ;
2016-11-25 22:40:43 +01:00
import org.warp.picalculator.math.MathematicalSymbols ;
2017-01-16 17:57:09 +01:00
import org.warp.picalculator.math.functions.AnteriorFunction ;
2016-09-19 18:48:27 +02:00
import org.warp.picalculator.math.functions.Function ;
2017-01-16 17:57:09 +01:00
import org.warp.picalculator.math.functions.FunctionMultipleValues ;
import org.warp.picalculator.math.functions.FunctionTwoValues ;
import org.warp.picalculator.math.functions.Variable ;
import org.warp.picalculator.math.functions.Variable.VariableValue ;
import org.warp.picalculator.math.functions.equations.Equation ;
import org.warp.picalculator.math.functions.Number ;
2016-11-02 21:56:40 +01:00
2016-12-04 22:22:16 +01:00
public class MathInputScreen extends Screen {
2016-09-02 20:32:37 +02:00
public volatile String equazioneCorrente = " " ;
public volatile String nuovaEquazione = " " ;
public volatile int caretPos = 0 ;
public volatile boolean showCaret = true ;
public volatile float showCaretDelta = 0f ;
2016-11-25 22:40:43 +01:00
public ArrayList < Function > f ;
public ArrayList < Function > f2 ;
2017-01-16 17:57:09 +01:00
public ArrayList < VariableValue > variablesValues ;
2016-11-02 21:56:40 +01:00
public int resultsCount ;
2016-09-02 20:32:37 +02:00
public boolean autoscroll ;
2016-11-25 22:40:43 +01:00
public int scrollX = 0 ;
2016-09-02 20:32:37 +02:00
public int errorLevel = 0 ; // 0 = nessuno, 1 = risultato, 2 = tutto
boolean mustRefresh = true ;
2016-11-25 22:40:43 +01:00
boolean afterDoNextStep = false ;
2017-01-16 17:57:09 +01:00
public final Calculator calc ;
2016-12-04 22:22:16 +01:00
public MathInputScreen ( ) {
2016-09-02 20:32:37 +02:00
super ( ) ;
canBeInHistory = true ;
2017-01-16 17:57:09 +01:00
calc = new Calculator ( ) ;
2016-09-02 20:32:37 +02:00
}
@Override
public void created ( ) throws InterruptedException {
2016-11-25 22:40:43 +01:00
2016-09-02 20:32:37 +02:00
}
@Override
public void init ( ) throws InterruptedException {
2016-10-02 16:01:41 +02:00
/* Fine caricamento */
2016-09-02 20:32:37 +02:00
2016-10-02 16:01:41 +02:00
// Parentesi f = new
// Parentesi("(â’¶(2X)*3Y)/(5Z^2)+(â’¶(11A)*13B)/(7CZ)=19XZ");
// PARENTESI CON CALCOLI
// Funzione f = new Sottrazione(new Somma(new Parentesi("â’¶9/2+â’¶7/2",
// "").calcola(), new Termine("3.5")), new
// Parentesi("3*2√14","").calcola());
// PARENTESI CON DUE NUMERI FRAZIONALI COMPLETI CON INCOGNITE:
// Funzione f = new
// Parentesi("(â’¶(2X)*3Y)/(5Z^2)+(â’¶(11A)*13B)/(7CZ)", "");
// PARENTESI CON DUE NUMERI FRAZIONALI DISALLINEATI GRAFICAMENTE:
// Funzione f = new Parentesi("((5^2-1)/2)/5-5/(5/2)=2", "");
// TERMINE DI PROVA COMPLETO:
// Funzione f = new Termine(new NumeroAvanzato(new Rational(3, 2),
// new Rational(7, 1), new Incognite(new Incognita('X',
// Rational.ONE)), new Incognite(new Incognita('Y', Rational.ONE)),
// new Incognite(new Incognita('z', Rational.ONE))));
// PARENTESI REALISTICA CON INCOGNITE:
// Funzione f = new Equazione(new
// Parentesi("X^2+(MX-M+4)^2-4X-4(MX-M+4)^2+7", ""), new
// Termine("0"));
// POTENZA:
// Funzione f = new Parentesi("(MX-M+4)^2", "");
// NUMERO SEMPLICE LUNGO:
// Funzione f = new Parentesi("-1219999799999996934.42229", "");
// :
// Funzione f = new Parentesi("5Y+XY=2", "")
2016-09-02 20:32:37 +02:00
// calcola("((5^2+3√(100/0.1))+Ⓐ(7)+9/15*2√(26/2))/21");
2016-11-02 21:56:40 +01:00
if ( f = = null & f2 = = null ) {
f = new ArrayList < Function > ( ) ;
f2 = new ArrayList < Function > ( ) ;
2017-01-16 17:57:09 +01:00
variablesValues = new ArrayList < > ( ) ;
2016-11-02 21:56:40 +01:00
resultsCount = 0 ;
}
2016-09-02 20:32:37 +02:00
// interpreta("{(5X*(15X/3X))+(25X/(5X*(15X/3X)))=15{X=5"); //TODO RIMUOVERE
2016-10-02 16:01:41 +02:00
// long start = System.nanoTime();
// Termine result =
// Calculator.calcolarisultato("((5Ⓑ2+3√(100/0.1))*Ⓐ7+9/15*2√(26/2))/21");
// long end = System.nanoTime();
// long timeElapsed = end-start;
// System.out.println("RESULT: " + result);
// System.out.println("DECIMAl RESULT: " +
// result.getTerm().toBigDecimal());
// System.out.println("Time elapsed: " + (double) timeElapsed /
// 1000000 + " milliseconds\n");
//
//
// start = System.nanoTime();
// RisultatoEquazione eresult =
// Calculator.calcolaequazione("((5Ⓑ2+3√(100/0.1))*Ⓐ7+9/15*2√(26/2))/21=(175*(2√7)+3*(2√13))/105");
// end = System.nanoTime();
// timeElapsed = end-start;
// System.out.println("Is an equation: " + eresult.isAnEquation);
// System.out.println("L-R: " + eresult.LR);
// System.out.println("Time elapsed: " + (double) timeElapsed /
// 1000000 + " milliseconds\n");
2016-09-02 20:32:37 +02:00
}
2016-11-25 22:40:43 +01:00
public void interpreta ( boolean temporary ) throws Error {
String eqn = nuovaEquazione ;
if ( ! temporary ) {
equazioneCorrente = eqn ;
}
ArrayList < Function > fncs = new ArrayList < Function > ( ) ;
if ( eqn . length ( ) > 0 ) {
2016-12-04 22:22:16 +01:00
try {
2017-01-16 17:57:09 +01:00
fncs . add ( calc . parseString ( eqn . replace ( " sqrt " , " â’¶ " ) . replace ( " ^ " , " â’· " ) ) ) ;
2016-12-04 22:22:16 +01:00
} catch ( Exception ex ) {
}
2016-11-25 22:40:43 +01:00
}
2016-10-02 16:01:41 +02:00
f = fncs ;
for ( Function f : f ) {
2016-11-25 22:40:43 +01:00
try {
f . generateGraphics ( ) ;
} catch ( NullPointerException ex ) {
throw new Error ( Errors . SYNTAX_ERROR ) ;
}
2016-10-02 16:01:41 +02:00
}
2016-09-02 20:32:37 +02:00
}
@Override
public void beforeRender ( float dt ) {
showCaretDelta + = dt ;
if ( showCaretDelta > = 0 . 5f ) {
mustRefresh = true ;
showCaret = ! showCaret ;
showCaretDelta = 0f ;
}
2016-11-25 22:40:43 +01:00
if ( caretPos > nuovaEquazione . length ( ) ) {
caretPos = nuovaEquazione . length ( ) ;
}
if ( PIDisplay . error = = null ) {
glClearColor ( 0xFFc5c2af ) ;
} else {
glClearColor ( 0xFFDC3C32 ) ;
}
2016-09-02 20:32:37 +02:00
}
2016-11-25 22:40:43 +01:00
private static final RAWFont fontBig = Utils . getFont ( false ) ;
2016-09-02 20:32:37 +02:00
@Override
public void render ( ) {
2016-11-25 22:40:43 +01:00
Display . Render . glSetFont ( fontBig ) ;
final int textColor = 0xFF000000 ;
final int padding = 4 ;
glColor ( textColor ) ;
2016-12-04 22:22:16 +01:00
final int caretRealPos = MathematicalSymbols . getGraphicRepresentation ( nuovaEquazione . substring ( 0 , caretPos ) ) . length ( ) * ( fontBig . charW + 1 ) ;
final String inputTextWithoutCaret = MathematicalSymbols . getGraphicRepresentation ( nuovaEquazione ) ;
2016-11-25 22:40:43 +01:00
final boolean tooLongI = padding + glGetStringWidth ( fontBig , nuovaEquazione ) + padding > = Main . screenSize [ 0 ] ;
int scrollI = 0 ;
if ( tooLongI ) {
scrollI = - scrollX ;
if ( - scrollI > = Main . screenSize [ 0 ] ) {
scrollI + = Main . screenSize [ 0 ] ;
} else {
scrollI = 0 ;
}
}
2016-12-04 22:22:16 +01:00
glDrawStringLeft ( padding + scrollI , padding + 20 , inputTextWithoutCaret ) ;
if ( showCaret ) {
glDrawStringLeft ( padding + scrollI + caretRealPos , padding + 20 , " | " ) ;
}
2016-11-25 22:40:43 +01:00
if ( tooLongI ) {
glColor ( clearcolor ) ;
glFillRect ( Main . screenSize [ 0 ] - 16 - 2 , padding + 20 , fontBig . charH , Main . screenSize [ 0 ] ) ;
glColor ( textColor ) ;
PIDisplay . drawSkinPart ( Main . screenSize [ 0 ] - 16 , padding + 20 + fontBig . charH / 2 - 16 / 2 , 304 , 0 , 304 + 16 , 16 ) ;
}
2016-10-02 16:01:41 +02:00
if ( f ! = null ) {
int topSpacing = 0 ;
2016-11-25 22:40:43 +01:00
Iterator < Function > iter = f . iterator ( ) ;
while ( iter . hasNext ( ) ) {
Function fnc = iter . next ( ) ;
try {
final boolean tooLong = padding + fnc . getWidth ( ) + padding > = Main . screenSize [ 0 ] ;
int scrollA = 0 ;
if ( tooLong ) {
scrollA = - scrollX ;
if ( - scrollA > = Main . screenSize [ 0 ] ) {
scrollA + = Main . screenSize [ 0 ] ;
} else {
scrollA = 0 ;
}
}
final int y = padding + 20 + padding + fontBig . charH + 1 + topSpacing ;
fnc . draw ( padding + scrollA , y ) ;
if ( tooLong ) {
glColor ( clearcolor ) ;
glFillRect ( Main . screenSize [ 0 ] - 16 - 2 , y , fnc . getHeight ( ) , Main . screenSize [ 0 ] ) ;
glColor ( textColor ) ;
PIDisplay . drawSkinPart ( Main . screenSize [ 0 ] - 16 , y + fnc . getHeight ( ) / 2 - 16 / 2 , 304 , 0 , 304 + 16 , 16 ) ;
}
} catch ( NullPointerException e ) {
iter . remove ( ) ;
}
topSpacing + = fnc . getHeight ( ) + 2 ;
2016-10-02 16:01:41 +02:00
}
}
2016-09-18 14:33:25 +02:00
if ( f2 ! = null ) {
int bottomSpacing = 0 ;
for ( Function f : f2 ) {
bottomSpacing + = f . getHeight ( ) + 2 ;
f . draw ( Display . getWidth ( ) - 2 - f . getWidth ( ) , Display . getHeight ( ) - bottomSpacing ) ;
}
2016-11-02 21:56:40 +01:00
if ( resultsCount > 1 & & resultsCount ! = f2 . size ( ) ) {
String resultsCountText = resultsCount + " total results " . toUpperCase ( ) ;
glColor ( 0xFF9AAEA0 ) ;
glSetFont ( Utils . getFont ( true ) ) ;
2016-11-25 22:40:43 +01:00
bottomSpacing + = fontBig . charH + 2 ;
2016-11-02 21:56:40 +01:00
glDrawStringRight ( Display . getWidth ( ) - 2 , Display . getHeight ( ) - bottomSpacing , resultsCountText ) ;
}
2016-09-18 14:33:25 +02:00
}
2016-09-02 20:32:37 +02:00
}
@Override
public boolean mustBeRefreshed ( ) {
if ( mustRefresh ) {
mustRefresh = false ;
return true ;
} else {
return false ;
}
}
@Override
public boolean keyPressed ( Key k ) {
switch ( k ) {
case SIMPLIFY :
if ( nuovaEquazione . length ( ) > 0 ) {
2017-01-16 17:57:09 +01:00
if ( ! afterDoNextStep ) {
2016-11-25 22:40:43 +01:00
try {
2017-01-16 17:57:09 +01:00
try {
interpreta ( true ) ;
showVariablesDialog ( new Runnable ( ) {
@Override
public void run ( ) {
equazioneCorrente = nuovaEquazione ;
f2 = f ;
afterDoNextStep = true ;
simplify ( MathInputScreen . this ) ;
}
} ) ;
} catch ( Exception ex ) {
if ( Utils . debugOn )
ex . printStackTrace ( ) ;
throw new Error ( Errors . SYNTAX_ERROR ) ;
2016-11-25 22:40:43 +01:00
}
2017-01-16 17:57:09 +01:00
} catch ( Error e ) {
StringWriter sw = new StringWriter ( ) ;
PrintWriter pw = new PrintWriter ( sw ) ;
e . printStackTrace ( pw ) ;
d . errorStackTrace = sw . toString ( ) . toUpperCase ( ) . replace ( " \ t " , " " ) . replace ( " \ r " , " " ) . split ( " \ n " ) ;
PIDisplay . error = e . id . toString ( ) ;
System . err . println ( e . id ) ;
2016-11-25 22:40:43 +01:00
}
2017-01-16 17:57:09 +01:00
} else {
simplify ( this ) ;
2016-11-25 22:40:43 +01:00
}
2016-09-02 20:32:37 +02:00
}
return true ;
case SOLVE :
if ( PIDisplay . error ! = null ) {
Utils . debug . println ( " Resetting after error... " ) ;
PIDisplay . error = null ;
2016-11-25 22:40:43 +01:00
this . equazioneCorrente = null ;
this . f = null ;
this . f2 = null ;
this . resultsCount = 0 ;
2016-09-02 20:32:37 +02:00
return true ;
} else {
2016-11-25 22:40:43 +01:00
try {
2016-09-02 20:32:37 +02:00
try {
2016-11-25 22:40:43 +01:00
if ( afterDoNextStep ) {
2017-01-16 17:57:09 +01:00
simplify ( this ) ;
2016-11-25 22:40:43 +01:00
} else {
if ( nuovaEquazione ! = equazioneCorrente & & nuovaEquazione . length ( ) > 0 ) {
changeEquationScreen ( ) ;
2017-01-16 17:57:09 +01:00
interpreta ( true ) ;
showVariablesDialog ( new Runnable ( ) {
@Override
public void run ( ) {
equazioneCorrente = nuovaEquazione ;
solve ( ) ;
} } ) ;
2016-09-18 14:33:25 +02:00
}
2016-09-02 20:32:37 +02:00
}
2016-11-25 22:40:43 +01:00
} catch ( Exception ex ) {
if ( Utils . debugOn ) {
ex . printStackTrace ( ) ;
}
throw new Error ( Errors . SYNTAX_ERROR ) ;
2016-09-02 20:32:37 +02:00
}
2016-11-25 22:40:43 +01:00
} catch ( Error e ) {
StringWriter sw = new StringWriter ( ) ;
PrintWriter pw = new PrintWriter ( sw ) ;
e . printStackTrace ( pw ) ;
d . errorStackTrace = sw . toString ( ) . toUpperCase ( ) . replace ( " \ t " , " " ) . replace ( " \ r " , " " ) . split ( " \ n " ) ;
PIDisplay . error = e . id . toString ( ) ;
System . err . println ( e . id ) ;
2016-09-02 20:32:37 +02:00
}
return true ;
}
case NUM0 :
typeChar ( " 0 " ) ;
return true ;
case NUM1 :
typeChar ( " 1 " ) ;
return true ;
case NUM2 :
typeChar ( " 2 " ) ;
return true ;
case NUM3 :
typeChar ( " 3 " ) ;
return true ;
case NUM4 :
typeChar ( " 4 " ) ;
return true ;
case NUM5 :
typeChar ( " 5 " ) ;
return true ;
case NUM6 :
typeChar ( " 6 " ) ;
return true ;
case NUM7 :
typeChar ( " 7 " ) ;
return true ;
case NUM8 :
typeChar ( " 8 " ) ;
return true ;
case NUM9 :
typeChar ( " 9 " ) ;
return true ;
case PLUS :
typeChar ( " + " ) ;
return true ;
case MINUS :
typeChar ( " - " ) ;
return true ;
2016-09-18 14:33:25 +02:00
case PLUS_MINUS :
typeChar ( " ± " ) ;
return true ;
2016-09-02 20:32:37 +02:00
case MULTIPLY :
typeChar ( " * " ) ;
return true ;
case DIVIDE :
typeChar ( " / " ) ;
return true ;
case PARENTHESIS_OPEN :
typeChar ( " ( " ) ;
return true ;
case PARENTHESIS_CLOSE :
typeChar ( " ) " ) ;
return true ;
case DOT :
typeChar ( " . " ) ;
return true ;
case EQUAL :
typeChar ( " = " ) ;
return true ;
case SQRT :
typeChar ( " â’¶ " ) ;
return true ;
case ROOT :
typeChar ( " √ " ) ;
return true ;
case POWER_OF_2 :
2016-12-04 22:22:16 +01:00
typeChar ( MathematicalSymbols . POWER + " 2 " ) ;
2016-09-02 20:32:37 +02:00
return true ;
case POWER_OF_x :
2016-12-04 22:22:16 +01:00
typeChar ( MathematicalSymbols . POWER ) ;
2016-09-02 20:32:37 +02:00
return true ;
2017-01-16 17:57:09 +01:00
case PI :
typeChar ( MathematicalSymbols . PI ) ;
return true ;
2016-09-18 14:33:25 +02:00
case LETTER_X :
2016-11-25 22:40:43 +01:00
typeChar ( MathematicalSymbols . variables ( ) [ 23 ] ) ;
2016-09-18 14:33:25 +02:00
return true ;
case LETTER_Y :
2016-11-25 22:40:43 +01:00
typeChar ( MathematicalSymbols . variables ( ) [ 24 ] ) ;
2016-09-18 14:33:25 +02:00
return true ;
2016-12-04 22:22:16 +01:00
case SINE :
typeChar ( MathematicalSymbols . SINE ) ;
return true ;
case COSINE :
typeChar ( MathematicalSymbols . COSINE ) ;
return true ;
case TANGENT :
typeChar ( MathematicalSymbols . TANGENT ) ;
return true ;
case ARCSINE :
typeChar ( MathematicalSymbols . ARC_SINE ) ;
return true ;
case ARCCOSINE :
typeChar ( MathematicalSymbols . ARC_COSINE ) ;
return true ;
case ARCTANGENT :
typeChar ( MathematicalSymbols . ARC_TANGENT ) ;
return true ;
2016-09-02 20:32:37 +02:00
case DELETE :
if ( nuovaEquazione . length ( ) > 0 ) {
if ( caretPos > 0 ) {
caretPos - = 1 ;
nuovaEquazione = nuovaEquazione . substring ( 0 , caretPos ) + nuovaEquazione . substring ( caretPos + 1 , nuovaEquazione . length ( ) ) ;
} else {
nuovaEquazione = nuovaEquazione . substring ( 1 ) ;
}
2016-11-25 22:40:43 +01:00
try { interpreta ( true ) ; } catch ( Error e ) { }
2016-09-02 20:32:37 +02:00
}
2016-11-25 22:40:43 +01:00
afterDoNextStep = false ;
2016-09-02 20:32:37 +02:00
return true ;
case LEFT :
if ( caretPos > 0 ) {
caretPos - = 1 ;
2016-11-25 22:40:43 +01:00
} else {
caretPos = nuovaEquazione . length ( ) ;
2016-09-02 20:32:37 +02:00
}
2016-11-25 22:40:43 +01:00
scrollX = glGetStringWidth ( fontBig , nuovaEquazione . substring ( 0 , caretPos ) + " ||| " ) ;
showCaret = true ;
showCaretDelta = 0L ;
2016-09-02 20:32:37 +02:00
return true ;
case RIGHT :
if ( caretPos < nuovaEquazione . length ( ) ) {
caretPos + = 1 ;
2016-11-25 22:40:43 +01:00
} else {
caretPos = 0 ;
2016-09-02 20:32:37 +02:00
}
2016-11-25 22:40:43 +01:00
scrollX = glGetStringWidth ( fontBig , nuovaEquazione . substring ( 0 , caretPos ) + " ||| " ) ;
showCaret = true ;
showCaretDelta = 0L ;
2016-09-02 20:32:37 +02:00
return true ;
case RESET :
if ( PIDisplay . error ! = null ) {
Utils . debug . println ( " Resetting after error... " ) ;
PIDisplay . error = null ;
return true ;
} else {
caretPos = 0 ;
nuovaEquazione = " " ;
2016-11-25 22:40:43 +01:00
afterDoNextStep = false ;
2016-12-03 16:37:22 +01:00
if ( f ! = null ) {
f . clear ( ) ;
}
2016-09-02 20:32:37 +02:00
return true ;
}
2016-12-05 19:58:49 +01:00
case SURD_MODE :
2017-01-16 17:57:09 +01:00
calc . exactMode = ! calc . exactMode ;
if ( calc . exactMode = = false ) {
f2 = solveExpression ( f2 ) ;
} else {
equazioneCorrente = " " ;
Keyboard . keyPressed ( Key . SOLVE ) ;
2016-11-25 22:40:43 +01:00
}
return true ;
2016-09-02 20:32:37 +02:00
case debug1 :
PIDisplay . INSTANCE . setScreen ( new EmptyScreen ( ) ) ;
return true ;
2016-11-25 22:40:43 +01:00
case HISTORY_BACK :
if ( PIDisplay . INSTANCE . canGoBack ( ) ) {
2017-01-16 17:57:09 +01:00
if ( equazioneCorrente ! = null & & equazioneCorrente . length ( ) > 0 & PIDisplay . sessions [ PIDisplay . currentSession + 1 ] instanceof MathInputScreen ) {
2016-11-25 22:40:43 +01:00
nuovaEquazione = equazioneCorrente ;
try {
interpreta ( true ) ;
} catch ( Error e ) {
}
}
}
return false ;
case HISTORY_FORWARD :
if ( PIDisplay . INSTANCE . canGoForward ( ) ) {
2017-01-16 17:57:09 +01:00
if ( equazioneCorrente ! = null & & equazioneCorrente . length ( ) > 0 & PIDisplay . sessions [ PIDisplay . currentSession - 1 ] instanceof MathInputScreen ) {
2016-11-25 22:40:43 +01:00
nuovaEquazione = equazioneCorrente ;
try {
interpreta ( true ) ;
} catch ( Error e ) {
}
}
}
return false ;
2017-01-16 17:57:09 +01:00
case debug_DEG :
if ( calc . angleMode . equals ( AngleMode . DEG ) = = false ) {
calc . angleMode = AngleMode . DEG ;
return true ;
}
return false ;
case debug_RAD :
if ( calc . angleMode . equals ( AngleMode . RAD ) = = false ) {
calc . angleMode = AngleMode . RAD ;
return true ;
}
return false ;
case debug_GRA :
if ( calc . angleMode . equals ( AngleMode . GRA ) = = false ) {
calc . angleMode = AngleMode . GRA ;
return true ;
}
return false ;
case DRG_CYCLE :
if ( calc . angleMode . equals ( AngleMode . DEG ) = = true ) {
calc . angleMode = AngleMode . RAD ;
} else if ( calc . angleMode . equals ( AngleMode . RAD ) = = true ) {
calc . angleMode = AngleMode . GRA ;
} else {
calc . angleMode = AngleMode . DEG ;
}
return true ;
2016-09-02 20:32:37 +02:00
default :
return false ;
}
}
2017-01-16 17:57:09 +01:00
private ArrayList < Function > solveExpression ( ArrayList < Function > f22 ) {
try {
try {
return calc . solveExpression ( f22 ) ;
} catch ( Exception ex ) {
if ( Utils . debugOn ) {
ex . printStackTrace ( ) ;
}
throw new Error ( Errors . SYNTAX_ERROR ) ;
}
} catch ( Error e ) {
StringWriter sw = new StringWriter ( ) ;
PrintWriter pw = new PrintWriter ( sw ) ;
e . printStackTrace ( pw ) ;
d . errorStackTrace = sw . toString ( ) . toUpperCase ( ) . replace ( " \ t " , " " ) . replace ( " \ r " , " " ) . split ( " \ n " ) ;
PIDisplay . error = e . id . toString ( ) ;
System . err . println ( e . id ) ;
}
return null ;
}
protected void simplify ( MathInputScreen mathInputScreen ) {
try {
try {
showVariablesDialog ( ) ;
ArrayList < Function > results = new ArrayList < > ( ) ;
ArrayList < Function > partialResults = new ArrayList < > ( ) ;
for ( Function f : f2 ) {
if ( f instanceof Equation ) {
PIDisplay . INSTANCE . setScreen ( new SolveEquationScreen ( this ) ) ;
} else {
results . add ( f ) ;
for ( Function itm : results ) {
if ( itm . isSolved ( ) = = false ) {
List < Function > dt = itm . solveOneStep ( ) ;
partialResults . addAll ( dt ) ;
} else {
partialResults . add ( itm ) ;
}
}
results = new ArrayList < Function > ( partialResults ) ;
partialResults . clear ( ) ;
}
}
if ( results . size ( ) = = 0 ) {
resultsCount = 0 ;
} else {
resultsCount = results . size ( ) ;
Collections . reverse ( results ) ;
// add elements to al, including duplicates
Set < Function > hs = new LinkedHashSet < > ( ) ;
hs . addAll ( results ) ;
results . clear ( ) ;
results . addAll ( hs ) ;
f2 = results ;
for ( Function rf : f2 ) {
rf . generateGraphics ( ) ;
}
}
} catch ( Exception ex ) {
if ( Utils . debugOn ) {
ex . printStackTrace ( ) ;
}
throw new Error ( Errors . SYNTAX_ERROR ) ;
}
} catch ( Error e ) {
StringWriter sw = new StringWriter ( ) ;
PrintWriter pw = new PrintWriter ( sw ) ;
e . printStackTrace ( pw ) ;
d . errorStackTrace = sw . toString ( ) . toUpperCase ( ) . replace ( " \ t " , " " ) . replace ( " \ r " , " " ) . split ( " \ n " ) ;
PIDisplay . error = e . id . toString ( ) ;
System . err . println ( e . id ) ;
}
}
protected void solve ( ) {
try {
try {
for ( Function f : f ) {
if ( f instanceof Equation ) {
PIDisplay . INSTANCE . setScreen ( new SolveEquationScreen ( this ) ) ;
return ;
}
}
ArrayList < Function > results = solveExpression ( f ) ;
if ( results . size ( ) = = 0 ) {
resultsCount = 0 ;
} else {
resultsCount = results . size ( ) ;
Collections . reverse ( results ) ;
// add elements to al, including duplicates
Set < Function > hs = new LinkedHashSet < > ( ) ;
hs . addAll ( results ) ;
results . clear ( ) ;
results . addAll ( hs ) ;
f2 = results ;
for ( Function rf : f2 ) {
rf . generateGraphics ( ) ;
}
}
} catch ( Exception ex ) {
if ( Utils . debugOn ) {
ex . printStackTrace ( ) ;
}
throw new Error ( Errors . SYNTAX_ERROR ) ;
}
} catch ( Error e ) {
StringWriter sw = new StringWriter ( ) ;
PrintWriter pw = new PrintWriter ( sw ) ;
e . printStackTrace ( pw ) ;
d . errorStackTrace = sw . toString ( ) . toUpperCase ( ) . replace ( " \ t " , " " ) . replace ( " \ r " , " " ) . split ( " \ n " ) ;
PIDisplay . error = e . id . toString ( ) ;
System . err . println ( e . id ) ;
}
}
2016-11-02 21:56:40 +01:00
private void changeEquationScreen ( ) {
if ( equazioneCorrente ! = null & & equazioneCorrente . length ( ) > 0 ) {
2016-12-04 22:22:16 +01:00
MathInputScreen cloned = clone ( ) ;
2016-11-02 21:56:40 +01:00
cloned . caretPos = cloned . equazioneCorrente . length ( ) ;
cloned . nuovaEquazione = cloned . equazioneCorrente ;
2016-11-25 22:40:43 +01:00
cloned . scrollX = glGetStringWidth ( fontBig , cloned . equazioneCorrente ) ;
try { cloned . interpreta ( true ) ; } catch ( Error e ) { }
2016-11-02 21:56:40 +01:00
PIDisplay . INSTANCE . replaceScreen ( cloned ) ;
this . initialized = false ;
PIDisplay . INSTANCE . setScreen ( this ) ;
}
}
2016-09-02 20:32:37 +02:00
public void typeChar ( String chr ) {
2016-11-25 22:40:43 +01:00
int len = chr . length ( ) ;
2016-09-02 20:32:37 +02:00
nuovaEquazione = nuovaEquazione . substring ( 0 , caretPos ) + chr + nuovaEquazione . substring ( caretPos , nuovaEquazione . length ( ) ) ;
2016-11-25 22:40:43 +01:00
caretPos + = len ;
scrollX = glGetStringWidth ( fontBig , nuovaEquazione . substring ( 0 , caretPos ) + " ||| " ) ;
2016-09-02 20:32:37 +02:00
showCaret = true ;
showCaretDelta = 0L ;
2016-11-25 22:40:43 +01:00
afterDoNextStep = false ;
try {
interpreta ( true ) ;
} catch ( Error e ) {
}
2016-11-02 21:56:40 +01:00
// f.clear(); //TODO: I removed this line to prevent input blanking when pressing EQUALS button and cloning this screen, but I must see why I created this part of code.
2016-09-02 20:32:37 +02:00
}
@Override
public boolean keyReleased ( Key k ) {
return false ;
}
2016-11-02 21:56:40 +01:00
2017-01-16 17:57:09 +01:00
public void showVariablesDialog ( final Runnable runnable ) {
Thread ct = new Thread ( ( ) - > {
ArrayList < Function > variablesInFunctions = getVariables ( f . toArray ( new Function [ f . size ( ) ] ) ) ;
for ( VariableValue f : variablesValues ) {
if ( variablesInFunctions . contains ( f . v ) ) {
variablesInFunctions . remove ( f . v ) ;
}
}
boolean cancelled = false ;
for ( Function f : variablesInFunctions ) {
ChooseVariableValueScreen cvs = new ChooseVariableValueScreen ( this , new VariableValue ( ( Variable ) f , new Number ( null , 0 ) ) ) ;
PIDisplay . INSTANCE . setScreen ( cvs ) ;
try {
while ( PIDisplay . screen = = cvs ) {
Utils . debug . println ( Thread . currentThread ( ) . getName ( ) ) ;
Thread . sleep ( 200 ) ;
}
} catch ( InterruptedException e ) { }
if ( cvs . resultNumberValue = = null ) {
cancelled = true ;
break ;
} else {
final int is = variablesValues . size ( ) ;
for ( int i = 0 ; i < is ; i + + ) {
if ( variablesValues . get ( i ) . v = = f ) {
variablesValues . remove ( i ) ;
}
}
variablesValues . add ( new VariableValue ( ( Variable ) f , ( Number ) cvs . resultNumberValue ) ) ;
}
}
if ( ! cancelled ) {
runnable . run ( ) ;
Utils . debug . println ( f . toString ( ) ) ;
}
} ) ;
ct . setName ( " Variables user-input queue thread " ) ;
ct . setPriority ( Thread . MIN_PRIORITY ) ;
ct . setDaemon ( true ) ;
ct . start ( ) ;
}
private ArrayList < Function > getVariables ( Function [ ] fncs ) {
ArrayList < Function > res = new ArrayList < > ( ) ;
for ( Function f : fncs ) {
if ( f instanceof FunctionTwoValues ) {
res . addAll ( getVariables ( new Function [ ] { ( ( FunctionTwoValues ) f ) . getVariable1 ( ) , ( ( FunctionTwoValues ) f ) . getVariable2 ( ) } ) ) ;
} else if ( f instanceof FunctionMultipleValues ) {
res . addAll ( getVariables ( ( ( FunctionMultipleValues ) f ) . getVariables ( ) ) ) ;
} else if ( f instanceof AnteriorFunction ) {
res . addAll ( getVariables ( new Function [ ] { ( ( AnteriorFunction ) f ) . getVariable ( ) } ) ) ;
} else if ( f instanceof Variable ) {
if ( ! res . contains ( f ) ) {
res . add ( f ) ;
}
}
}
return res ;
}
2016-11-02 21:56:40 +01:00
@Override
2016-12-04 22:22:16 +01:00
public MathInputScreen clone ( ) {
MathInputScreen es = this ;
MathInputScreen es2 = new MathInputScreen ( ) ;
2016-11-25 22:40:43 +01:00
es2 . scrollX = es . scrollX ;
2016-11-02 21:56:40 +01:00
es2 . nuovaEquazione = es . nuovaEquazione ;
es2 . equazioneCorrente = es . equazioneCorrente ;
es2 . showCaret = es . showCaret ;
es2 . showCaretDelta = es . showCaretDelta ;
es2 . caretPos = es . caretPos ;
es2 . f = Utils . cloner . deepClone ( es . f ) ;
es2 . f2 = Utils . cloner . deepClone ( es . f2 ) ;
es2 . resultsCount = es . resultsCount ;
es2 . autoscroll = es . autoscroll ;
es2 . errorLevel = es . errorLevel ;
es2 . mustRefresh = es . mustRefresh ;
2016-11-25 22:40:43 +01:00
es2 . afterDoNextStep = es . afterDoNextStep ;
2017-01-16 17:57:09 +01:00
es2 . variablesValues = Utils . cloner . deepClone ( es . variablesValues ) ;
2016-11-02 21:56:40 +01:00
return es2 ;
}
2016-09-02 20:32:37 +02:00
}