2017-01-22 13:46:38 +01:00
package org.warp.picalculator.gui.screens ;
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 ;
2017-01-31 22:29:49 +01:00
import org.warp.picalculator.gui.DisplayManager ;
2017-02-02 10:30:45 +01:00
import org.warp.picalculator.gui.graphicengine.BinaryFont ;
2017-01-31 22:29:49 +01:00
import org.warp.picalculator.gui.graphicengine.Renderer ;
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 ;
2017-01-17 22:32:40 +01:00
public Calculator calc ;
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-31 22:29:49 +01:00
2016-12-04 22:22:16 +01:00
public MathInputScreen ( ) {
2016-09-02 20:32:37 +02:00
super ( ) ;
canBeInHistory = true ;
2017-01-31 22:29:49 +01:00
2017-01-16 17:57:09 +01:00
calc = new Calculator ( ) ;
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 created ( ) throws InterruptedException {
2017-01-31 22:29:49 +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");
2017-01-17 22:32:40 +01:00
calc . init ( ) ;
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 {
2017-01-31 22:29:49 +01:00
final String eqn = nuovaEquazione ;
2016-11-25 22:40:43 +01:00
if ( ! temporary ) {
equazioneCorrente = eqn ;
}
2017-01-31 22:29:49 +01:00
2017-01-17 22:32:40 +01:00
calc . parseInputString ( eqn ) ;
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 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 ( ) ;
}
2017-01-31 22:29:49 +01:00
if ( DisplayManager . error = = null ) {
DisplayManager . renderer . glClearColor ( 0xFFc5c2af ) ;
2016-11-25 22:40:43 +01:00
} else {
2017-01-31 22:29:49 +01:00
DisplayManager . renderer . glClearColor ( 0xFFDC3C32 ) ;
2016-11-25 22:40:43 +01:00
}
2016-09-02 20:32:37 +02:00
}
2017-02-02 10:30:45 +01:00
private static final BinaryFont fontBig = Utils . getFont ( false ) ;
2017-01-31 22:29:49 +01:00
2017-01-22 13:46:38 +01:00
@Override
public void renderStatusbar ( ) {
2017-01-31 22:29:49 +01:00
Renderer renderer = DisplayManager . renderer ;
renderer . glColor3f ( 1 , 1 , 1 ) ;
final int pos = 2 ;
final int spacersNumb = 1 ;
2017-01-22 13:46:38 +01:00
int skinN = 0 ;
if ( calc . exactMode ) {
skinN = 22 ;
} else {
skinN = 21 ;
}
2017-01-31 22:29:49 +01:00
renderer . glFillRect ( 2 + 18 * pos + 2 * spacersNumb , 2 , 16 , 16 , 16 * skinN , 16 * 0 , 16 , 16 ) ;
2017-01-22 13:46:38 +01:00
}
2017-01-31 22:29:49 +01:00
2016-09-02 20:32:37 +02:00
@Override
public void render ( ) {
2017-02-02 10:30:45 +01:00
fontBig . use ( DisplayManager . engine ) ;
2016-11-25 22:40:43 +01:00
final int textColor = 0xFF000000 ;
final int padding = 4 ;
2017-01-31 22:29:49 +01:00
DisplayManager . renderer . glColor ( textColor ) ;
final int caretRealPos = MathematicalSymbols . getGraphicRepresentation ( nuovaEquazione . substring ( 0 , caretPos ) ) . length ( ) * ( fontBig . getCharacterWidth ( ) + 1 ) ;
2016-12-04 22:22:16 +01:00
final String inputTextWithoutCaret = MathematicalSymbols . getGraphicRepresentation ( nuovaEquazione ) ;
2017-01-31 22:29:49 +01:00
final boolean tooLongI = padding + fontBig . getStringWidth ( nuovaEquazione ) + padding > = Main . screenSize [ 0 ] ;
2016-11-25 22:40:43 +01:00
int scrollI = 0 ;
if ( tooLongI ) {
scrollI = - scrollX ;
if ( - scrollI > = Main . screenSize [ 0 ] ) {
scrollI + = Main . screenSize [ 0 ] ;
} else {
scrollI = 0 ;
}
}
2017-01-31 22:29:49 +01:00
DisplayManager . renderer . glDrawStringLeft ( padding + scrollI , padding + 20 , inputTextWithoutCaret ) ;
2016-12-04 22:22:16 +01:00
if ( showCaret ) {
2017-01-31 22:29:49 +01:00
DisplayManager . renderer . glDrawStringLeft ( padding + scrollI + caretRealPos , padding + 20 , " | " ) ;
2016-12-04 22:22:16 +01:00
}
2016-11-25 22:40:43 +01:00
if ( tooLongI ) {
2017-01-31 22:29:49 +01:00
DisplayManager . renderer . glColor ( DisplayManager . renderer . glGetClearColor ( ) ) ;
DisplayManager . renderer . glFillColor ( Main . screenSize [ 0 ] - 16 - 2 , padding + 20 , fontBig . getCharacterHeight ( ) , Main . screenSize [ 0 ] ) ;
DisplayManager . renderer . glColor ( textColor ) ;
DisplayManager . drawSkinPart ( Main . screenSize [ 0 ] - 16 , padding + 20 + fontBig . getCharacterHeight ( ) / 2 - 16 / 2 , 304 , 0 , 304 + 16 , 16 ) ;
2016-11-25 22:40:43 +01:00
}
2017-01-17 22:32:40 +01:00
if ( calc . f ! = null ) {
2016-10-02 16:01:41 +02:00
int topSpacing = 0 ;
2017-01-31 22:29:49 +01:00
final Iterator < Function > iter = calc . f . iterator ( ) ;
2016-11-25 22:40:43 +01:00
while ( iter . hasNext ( ) ) {
2017-01-31 22:29:49 +01:00
final Function fnc = iter . next ( ) ;
2016-11-25 22:40:43 +01:00
try {
2017-01-31 22:29:49 +01:00
final boolean tooLong = padding + fnc . getWidth ( ) + padding > = Main . screenSize [ 0 ] ;
2016-11-25 22:40:43 +01:00
int scrollA = 0 ;
if ( tooLong ) {
scrollA = - scrollX ;
if ( - scrollA > = Main . screenSize [ 0 ] ) {
scrollA + = Main . screenSize [ 0 ] ;
} else {
scrollA = 0 ;
}
}
2017-01-31 22:29:49 +01:00
final int y = padding + 20 + padding + fontBig . getCharacterHeight ( ) + 1 + topSpacing ;
fnc . draw ( padding + scrollA , y ) ;
2016-11-25 22:40:43 +01:00
if ( tooLong ) {
2017-01-31 22:29:49 +01:00
DisplayManager . renderer . glColor ( DisplayManager . renderer . glGetClearColor ( ) ) ;
DisplayManager . renderer . glFillColor ( Main . screenSize [ 0 ] - 16 - 2 , y , fnc . getHeight ( ) , Main . screenSize [ 0 ] ) ;
DisplayManager . renderer . glColor ( textColor ) ;
DisplayManager . drawSkinPart ( Main . screenSize [ 0 ] - 16 , y + fnc . getHeight ( ) / 2 - 16 / 2 , 304 , 0 , 304 + 16 , 16 ) ;
2016-11-25 22:40:43 +01:00
}
2017-01-31 22:29:49 +01:00
} catch ( final NullPointerException e ) {
2016-11-25 22:40:43 +01:00
iter . remove ( ) ;
}
topSpacing + = fnc . getHeight ( ) + 2 ;
2016-10-02 16:01:41 +02:00
}
}
2017-01-17 22:32:40 +01:00
if ( calc . f2 ! = null ) {
2016-09-18 14:33:25 +02:00
int bottomSpacing = 0 ;
2017-01-31 22:29:49 +01:00
for ( final Function f : calc . f2 ) {
bottomSpacing + = f . getHeight ( ) + 2 ;
2017-02-02 10:30:45 +01:00
f . draw ( DisplayManager . engine . getWidth ( ) - 2 - f . getWidth ( ) , DisplayManager . engine . getHeight ( ) - bottomSpacing ) ;
2016-09-18 14:33:25 +02:00
}
2017-01-17 22:32:40 +01:00
if ( calc . resultsCount > 1 & & calc . resultsCount ! = calc . f2 . size ( ) ) {
2017-01-31 22:29:49 +01:00
final String resultsCountText = calc . resultsCount + " total results " . toUpperCase ( ) ;
DisplayManager . renderer . glColor ( 0xFF9AAEA0 ) ;
2017-02-02 10:30:45 +01:00
Utils . getFont ( true ) . use ( DisplayManager . engine ) ;
2017-01-31 22:29:49 +01:00
bottomSpacing + = fontBig . getCharacterHeight ( ) + 2 ;
2017-02-02 10:30:45 +01:00
DisplayManager . renderer . glDrawStringRight ( DisplayManager . engine . getWidth ( ) - 2 , DisplayManager . engine . getHeight ( ) - bottomSpacing , resultsCountText ) ;
2016-11-02 21:56:40 +01:00
}
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 ) ;
2017-01-31 22:29:49 +01:00
showVariablesDialog ( ( ) - > {
equazioneCorrente = nuovaEquazione ;
calc . f2 = calc . f ;
afterDoNextStep = true ;
2017-02-02 12:49:31 +01:00
simplify ( ) ;
2017-01-16 17:57:09 +01:00
} ) ;
2017-01-31 22:29:49 +01:00
} catch ( final Exception ex ) {
if ( Utils . debugOn ) {
2017-01-16 17:57:09 +01:00
ex . printStackTrace ( ) ;
2017-01-31 22:29:49 +01:00
}
2017-01-16 17:57:09 +01:00
throw new Error ( Errors . SYNTAX_ERROR ) ;
2016-11-25 22:40:43 +01:00
}
2017-01-31 22:29:49 +01:00
} catch ( final Error e ) {
final StringWriter sw = new StringWriter ( ) ;
final PrintWriter pw = new PrintWriter ( sw ) ;
2017-01-16 17:57:09 +01:00
e . printStackTrace ( pw ) ;
d . errorStackTrace = sw . toString ( ) . toUpperCase ( ) . replace ( " \ t " , " " ) . replace ( " \ r " , " " ) . split ( " \ n " ) ;
2017-01-31 22:29:49 +01:00
DisplayManager . error = e . id . toString ( ) ;
2017-01-16 17:57:09 +01:00
System . err . println ( e . id ) ;
2016-11-25 22:40:43 +01:00
}
2017-01-16 17:57:09 +01:00
} else {
2017-02-02 12:49:31 +01:00
simplify ( ) ;
2016-11-25 22:40:43 +01:00
}
2016-09-02 20:32:37 +02:00
}
return true ;
case SOLVE :
2017-01-31 22:29:49 +01:00
if ( DisplayManager . error ! = null ) {
2016-09-02 20:32:37 +02:00
Utils . debug . println ( " Resetting after error... " ) ;
2017-01-31 22:29:49 +01:00
DisplayManager . error = null ;
equazioneCorrente = null ;
2017-01-17 22:32:40 +01:00
calc . f = null ;
calc . f2 = null ;
calc . 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-02-02 12:49:31 +01:00
simplify ( ) ;
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 ) ;
2017-01-31 22:29:49 +01:00
showVariablesDialog ( ( ) - > {
equazioneCorrente = nuovaEquazione ;
solve ( ) ;
} ) ;
2016-09-18 14:33:25 +02:00
}
2016-09-02 20:32:37 +02:00
}
2017-01-31 22:29:49 +01:00
} catch ( final Exception ex ) {
2016-11-25 22:40:43 +01:00
if ( Utils . debugOn ) {
ex . printStackTrace ( ) ;
}
throw new Error ( Errors . SYNTAX_ERROR ) ;
2016-09-02 20:32:37 +02:00
}
2017-01-31 22:29:49 +01:00
} catch ( final Error e ) {
final StringWriter sw = new StringWriter ( ) ;
final PrintWriter pw = new PrintWriter ( sw ) ;
2016-11-25 22:40:43 +01:00
e . printStackTrace ( pw ) ;
d . errorStackTrace = sw . toString ( ) . toUpperCase ( ) . replace ( " \ t " , " " ) . replace ( " \ r " , " " ) . split ( " \ n " ) ;
2017-01-31 22:29:49 +01:00
DisplayManager . error = e . id . toString ( ) ;
2016-11-25 22:40:43 +01:00
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 :
2017-01-31 22:29:49 +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 ) {
2017-01-31 22:29:49 +01:00
caretPos - = 1 ;
nuovaEquazione = nuovaEquazione . substring ( 0 , caretPos ) + nuovaEquazione . substring ( caretPos + 1 , nuovaEquazione . length ( ) ) ;
2016-09-02 20:32:37 +02:00
} else {
nuovaEquazione = nuovaEquazione . substring ( 1 ) ;
}
2017-01-31 22:29:49 +01:00
try {
interpreta ( true ) ;
} catch ( final 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
}
2017-01-31 22:29:49 +01:00
scrollX = fontBig . getStringWidth ( nuovaEquazione . substring ( 0 , caretPos ) + " ||| " ) ;
2016-11-25 22:40:43 +01:00
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
}
2017-01-31 22:29:49 +01:00
scrollX = fontBig . getStringWidth ( nuovaEquazione . substring ( 0 , caretPos ) + " ||| " ) ;
2016-11-25 22:40:43 +01:00
showCaret = true ;
showCaretDelta = 0L ;
2016-09-02 20:32:37 +02:00
return true ;
case RESET :
2017-01-31 22:29:49 +01:00
if ( DisplayManager . error ! = null ) {
2016-09-02 20:32:37 +02:00
Utils . debug . println ( " Resetting after error... " ) ;
2017-01-31 22:29:49 +01:00
DisplayManager . error = null ;
2016-09-02 20:32:37 +02:00
return true ;
} else {
caretPos = 0 ;
2017-01-31 22:29:49 +01:00
nuovaEquazione = " " ;
2016-11-25 22:40:43 +01:00
afterDoNextStep = false ;
2017-01-17 22:32:40 +01:00
if ( calc . f ! = null ) {
2017-02-02 12:49:31 +01:00
calc . f = new ArrayList < > ( ) ;
2016-12-03 16:37:22 +01:00
}
2016-09-02 20:32:37 +02:00
return true ;
}
2017-01-31 22:29:49 +01:00
case SURD_MODE :
2017-01-16 17:57:09 +01:00
calc . exactMode = ! calc . exactMode ;
2017-01-31 22:29:49 +01:00
if ( calc . exactMode = = false ) {
2017-01-17 22:32:40 +01:00
calc . f2 = solveExpression ( calc . f2 ) ;
2017-01-16 17:57:09 +01:00
} 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 :
2017-01-31 22:29:49 +01:00
DisplayManager . INSTANCE . setScreen ( new EmptyScreen ( ) ) ;
2016-09-02 20:32:37 +02:00
return true ;
2016-11-25 22:40:43 +01:00
case HISTORY_BACK :
2017-01-31 22:29:49 +01:00
if ( DisplayManager . INSTANCE . canGoBack ( ) ) {
if ( equazioneCorrente ! = null & & equazioneCorrente . length ( ) > 0 & DisplayManager . sessions [ DisplayManager . currentSession + 1 ] instanceof MathInputScreen ) {
2016-11-25 22:40:43 +01:00
nuovaEquazione = equazioneCorrente ;
try {
interpreta ( true ) ;
2017-01-31 22:29:49 +01:00
} catch ( final Error e ) { }
2016-11-25 22:40:43 +01:00
}
}
return false ;
case HISTORY_FORWARD :
2017-01-31 22:29:49 +01:00
if ( DisplayManager . INSTANCE . canGoForward ( ) ) {
if ( equazioneCorrente ! = null & & equazioneCorrente . length ( ) > 0 & DisplayManager . sessions [ DisplayManager . currentSession - 1 ] instanceof MathInputScreen ) {
2016-11-25 22:40:43 +01:00
nuovaEquazione = equazioneCorrente ;
try {
interpreta ( true ) ;
2017-01-31 22:29:49 +01:00
} catch ( final Error e ) { }
2016-11-25 22:40:43 +01:00
}
}
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-31 22:29:49 +01:00
2017-01-16 17:57:09 +01:00
private ArrayList < Function > solveExpression ( ArrayList < Function > f22 ) {
try {
try {
return calc . solveExpression ( f22 ) ;
2017-01-31 22:29:49 +01:00
} catch ( final Exception ex ) {
2017-01-16 17:57:09 +01:00
if ( Utils . debugOn ) {
ex . printStackTrace ( ) ;
}
throw new Error ( Errors . SYNTAX_ERROR ) ;
}
2017-01-31 22:29:49 +01:00
} catch ( final Error e ) {
final StringWriter sw = new StringWriter ( ) ;
final PrintWriter pw = new PrintWriter ( sw ) ;
2017-01-16 17:57:09 +01:00
e . printStackTrace ( pw ) ;
d . errorStackTrace = sw . toString ( ) . toUpperCase ( ) . replace ( " \ t " , " " ) . replace ( " \ r " , " " ) . split ( " \ n " ) ;
2017-01-31 22:29:49 +01:00
DisplayManager . error = e . id . toString ( ) ;
2017-01-16 17:57:09 +01:00
System . err . println ( e . id ) ;
}
return null ;
}
2017-02-02 12:49:31 +01:00
protected void simplify ( ) {
2017-01-16 17:57:09 +01:00
try {
try {
showVariablesDialog ( ) ;
ArrayList < Function > results = new ArrayList < > ( ) ;
2017-01-31 22:29:49 +01:00
final ArrayList < Function > partialResults = new ArrayList < > ( ) ;
for ( final Function f : calc . f2 ) {
2017-01-16 17:57:09 +01:00
if ( f instanceof Equation ) {
2017-01-31 22:29:49 +01:00
DisplayManager . INSTANCE . setScreen ( new SolveEquationScreen ( this ) ) ;
2017-01-16 17:57:09 +01:00
} else {
results . add ( f ) ;
2017-01-31 22:29:49 +01:00
for ( final Function itm : results ) {
2017-01-16 17:57:09 +01:00
if ( itm . isSolved ( ) = = false ) {
2017-01-31 22:29:49 +01:00
final List < Function > dt = itm . solveOneStep ( ) ;
2017-01-16 17:57:09 +01:00
partialResults . addAll ( dt ) ;
} else {
partialResults . add ( itm ) ;
}
}
2017-01-17 22:32:40 +01:00
results = new ArrayList < > ( partialResults ) ;
2017-01-16 17:57:09 +01:00
partialResults . clear ( ) ;
}
}
2017-01-31 22:29:49 +01:00
2017-01-16 17:57:09 +01:00
if ( results . size ( ) = = 0 ) {
2017-01-17 22:32:40 +01:00
calc . resultsCount = 0 ;
2017-01-16 17:57:09 +01:00
} else {
2017-01-17 22:32:40 +01:00
calc . resultsCount = results . size ( ) ;
2017-01-16 17:57:09 +01:00
Collections . reverse ( results ) ;
// add elements to al, including duplicates
2017-01-31 22:29:49 +01:00
final Set < Function > hs = new LinkedHashSet < > ( ) ;
2017-01-16 17:57:09 +01:00
hs . addAll ( results ) ;
results . clear ( ) ;
results . addAll ( hs ) ;
2017-01-17 22:32:40 +01:00
calc . f2 = results ;
2017-01-31 22:29:49 +01:00
for ( final Function rf : calc . f2 ) {
2017-01-16 17:57:09 +01:00
rf . generateGraphics ( ) ;
}
}
2017-02-02 12:49:31 +01:00
Utils . debug . println ( calc . f2 . toString ( ) ) ;
2017-01-31 22:29:49 +01:00
} catch ( final Exception ex ) {
2017-01-16 17:57:09 +01:00
if ( Utils . debugOn ) {
ex . printStackTrace ( ) ;
}
throw new Error ( Errors . SYNTAX_ERROR ) ;
}
2017-01-31 22:29:49 +01:00
} catch ( final Error e ) {
final StringWriter sw = new StringWriter ( ) ;
final PrintWriter pw = new PrintWriter ( sw ) ;
2017-01-16 17:57:09 +01:00
e . printStackTrace ( pw ) ;
d . errorStackTrace = sw . toString ( ) . toUpperCase ( ) . replace ( " \ t " , " " ) . replace ( " \ r " , " " ) . split ( " \ n " ) ;
2017-01-31 22:29:49 +01:00
DisplayManager . error = e . id . toString ( ) ;
2017-01-16 17:57:09 +01:00
System . err . println ( e . id ) ;
}
}
protected void solve ( ) {
try {
try {
2017-01-31 22:29:49 +01:00
for ( final Function f : calc . f ) {
2017-01-16 17:57:09 +01:00
if ( f instanceof Equation ) {
2017-01-31 22:29:49 +01:00
DisplayManager . INSTANCE . setScreen ( new SolveEquationScreen ( this ) ) ;
2017-01-16 17:57:09 +01:00
return ;
}
}
2017-01-31 22:29:49 +01:00
final ArrayList < Function > results = solveExpression ( calc . f ) ;
2017-01-16 17:57:09 +01:00
if ( results . size ( ) = = 0 ) {
2017-01-17 22:32:40 +01:00
calc . resultsCount = 0 ;
2017-01-16 17:57:09 +01:00
} else {
2017-01-17 22:32:40 +01:00
calc . resultsCount = results . size ( ) ;
2017-01-16 17:57:09 +01:00
Collections . reverse ( results ) ;
// add elements to al, including duplicates
2017-01-31 22:29:49 +01:00
final Set < Function > hs = new LinkedHashSet < > ( ) ;
2017-01-16 17:57:09 +01:00
hs . addAll ( results ) ;
results . clear ( ) ;
results . addAll ( hs ) ;
2017-01-17 22:32:40 +01:00
calc . f2 = results ;
2017-01-31 22:29:49 +01:00
for ( final Function rf : calc . f2 ) {
2017-01-16 17:57:09 +01:00
rf . generateGraphics ( ) ;
}
}
2017-01-31 22:29:49 +01:00
} catch ( final Exception ex ) {
2017-01-16 17:57:09 +01:00
if ( Utils . debugOn ) {
ex . printStackTrace ( ) ;
}
throw new Error ( Errors . SYNTAX_ERROR ) ;
}
2017-01-31 22:29:49 +01:00
} catch ( final Error e ) {
final StringWriter sw = new StringWriter ( ) ;
final PrintWriter pw = new PrintWriter ( sw ) ;
2017-01-16 17:57:09 +01:00
e . printStackTrace ( pw ) ;
d . errorStackTrace = sw . toString ( ) . toUpperCase ( ) . replace ( " \ t " , " " ) . replace ( " \ r " , " " ) . split ( " \ n " ) ;
2017-01-31 22:29:49 +01:00
DisplayManager . error = e . id . toString ( ) ;
2017-01-16 17:57:09 +01:00
System . err . println ( e . id ) ;
}
}
2016-11-02 21:56:40 +01:00
private void changeEquationScreen ( ) {
if ( equazioneCorrente ! = null & & equazioneCorrente . length ( ) > 0 ) {
2017-01-31 22:29:49 +01:00
final MathInputScreen cloned = clone ( ) ;
2016-11-02 21:56:40 +01:00
cloned . caretPos = cloned . equazioneCorrente . length ( ) ;
cloned . nuovaEquazione = cloned . equazioneCorrente ;
2017-01-31 22:29:49 +01:00
cloned . scrollX = fontBig . getStringWidth ( cloned . equazioneCorrente ) ;
try {
cloned . interpreta ( true ) ;
} catch ( final Error e ) { }
DisplayManager . INSTANCE . replaceScreen ( cloned ) ;
initialized = false ;
DisplayManager . INSTANCE . setScreen ( this ) ;
2016-11-02 21:56:40 +01:00
}
}
2016-09-02 20:32:37 +02:00
public void typeChar ( String chr ) {
2017-01-31 22:29:49 +01:00
final int len = chr . length ( ) ;
nuovaEquazione = nuovaEquazione . substring ( 0 , caretPos ) + chr + nuovaEquazione . substring ( caretPos , nuovaEquazione . length ( ) ) ;
caretPos + = len ;
scrollX = fontBig . getStringWidth ( 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 ) ;
2017-01-31 22:29:49 +01:00
} catch ( final 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 ;
}
2017-01-31 22:29:49 +01:00
2017-01-17 22:32:40 +01:00
public void showVariablesDialog ( ) {
showVariablesDialog ( null ) ;
}
2017-01-31 22:29:49 +01:00
2017-01-16 17:57:09 +01:00
public void showVariablesDialog ( final Runnable runnable ) {
2017-01-31 22:29:49 +01:00
final Thread ct = new Thread ( ( ) - > {
final ArrayList < Function > variablesInFunctions = getVariables ( calc . f . toArray ( new Function [ calc . f . size ( ) ] ) ) ;
for ( final VariableValue f : calc . variablesValues ) {
2017-01-16 17:57:09 +01:00
if ( variablesInFunctions . contains ( f . v ) ) {
variablesInFunctions . remove ( f . v ) ;
}
}
2017-01-31 22:29:49 +01:00
2017-01-16 17:57:09 +01:00
boolean cancelled = false ;
2017-01-31 22:29:49 +01:00
for ( final Function f : variablesInFunctions ) {
final ChooseVariableValueScreen cvs = new ChooseVariableValueScreen ( this , new VariableValue ( ( Variable ) f , new Number ( calc , 0 ) ) ) ;
DisplayManager . INSTANCE . setScreen ( cvs ) ;
2017-01-16 17:57:09 +01:00
try {
2017-01-31 22:29:49 +01:00
while ( DisplayManager . screen = = cvs ) {
2017-01-16 17:57:09 +01:00
Utils . debug . println ( Thread . currentThread ( ) . getName ( ) ) ;
Thread . sleep ( 200 ) ;
}
2017-01-31 22:29:49 +01:00
} catch ( final InterruptedException e ) { }
2017-01-16 17:57:09 +01:00
if ( cvs . resultNumberValue = = null ) {
cancelled = true ;
break ;
} else {
2017-01-17 22:32:40 +01:00
final int is = calc . variablesValues . size ( ) ;
2017-01-16 17:57:09 +01:00
for ( int i = 0 ; i < is ; i + + ) {
2017-01-17 22:32:40 +01:00
if ( calc . variablesValues . get ( i ) . v = = f ) {
calc . variablesValues . remove ( i ) ;
2017-01-16 17:57:09 +01:00
}
}
2017-01-17 22:32:40 +01:00
calc . variablesValues . add ( new VariableValue ( ( Variable ) f , ( Number ) cvs . resultNumberValue ) ) ;
2017-01-16 17:57:09 +01:00
}
}
2017-01-31 22:29:49 +01:00
if ( ! cancelled ) {
2017-01-17 22:32:40 +01:00
if ( runnable ! = null ) {
runnable . run ( ) ;
}
2017-01-16 17:57:09 +01:00
}
} ) ;
ct . setName ( " Variables user-input queue thread " ) ;
ct . setPriority ( Thread . MIN_PRIORITY ) ;
ct . setDaemon ( true ) ;
ct . start ( ) ;
}
2017-01-31 22:29:49 +01:00
2017-01-16 17:57:09 +01:00
private ArrayList < Function > getVariables ( Function [ ] fncs ) {
2017-01-31 22:29:49 +01:00
final ArrayList < Function > res = new ArrayList < > ( ) ;
for ( final Function f : fncs ) {
2017-01-16 17:57:09 +01:00
if ( f instanceof FunctionTwoValues ) {
2017-01-31 22:29:49 +01:00
res . addAll ( getVariables ( new Function [ ] { ( ( FunctionTwoValues ) f ) . getVariable1 ( ) , ( ( FunctionTwoValues ) f ) . getVariable2 ( ) } ) ) ;
2017-01-16 17:57:09 +01:00
} else if ( f instanceof FunctionMultipleValues ) {
2017-01-31 22:29:49 +01:00
res . addAll ( getVariables ( ( ( FunctionMultipleValues ) f ) . getVariables ( ) ) ) ;
2017-01-16 17:57:09 +01:00
} else if ( f instanceof AnteriorFunction ) {
2017-01-31 22:29:49 +01:00
res . addAll ( getVariables ( new Function [ ] { ( ( AnteriorFunction ) f ) . getVariable ( ) } ) ) ;
2017-01-16 17:57:09 +01:00
} else if ( f instanceof Variable ) {
if ( ! res . contains ( f ) ) {
res . add ( f ) ;
}
}
}
return res ;
}
2017-01-31 22:29:49 +01:00
2016-11-02 21:56:40 +01:00
@Override
2016-12-04 22:22:16 +01:00
public MathInputScreen clone ( ) {
2017-01-31 22:29:49 +01:00
final MathInputScreen es = this ;
final 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 ;
2017-01-17 22:32:40 +01:00
// es2.calc.f = Utils.cloner.deepClone(es.calc.f);
// es2.calc.f2 = Utils.cloner.deepClone(es.calc.f2);
// es2.calc.resultsCount = es.calc.resultsCount;
2016-11-02 21:56:40 +01:00
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-17 22:32:40 +01:00
// es2.calc.variablesValues = Utils.cloner.deepClone(es.calc.variablesValues);
es2 . calc = Utils . cloner . deepClone ( es . calc ) ;
2016-11-02 21:56:40 +01:00
return es2 ;
}
2016-09-02 20:32:37 +02:00
}