/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package kanjiflash;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.effect.DropShadow;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaException;
import javafx.scene.media.MediaPlayer;
import javafx.scene.paint.Color;
public class KanjiFlashController implements Initializable {
    static final boolean USE_FLUSH = false;
    Preferences PREF;
    private static URI CHING_URI;
    private static URI FLIP_URI;
    Media finalSound, flipSound;
    MediaPlayer playSound, playFlip;
    int testCount;
    int remCount;
    public int errCount;
    int gradeLevel;
    Show displayState;
    Show currentDisplay;
    State TestState;
    ArrayList<Kanji> KanjiTab;
    ArrayList<KanjiError> KanjiErr;
    Connection C;  
    DBAccess DBA; 
    Iterator it;
    Kanji KJ;
    Properties prop;
    boolean useLowerGrades;
    ObservableList<String> scoreTable;
    @FXML private Label kanjiTextField; 
    @FXML private AnchorPane TopPane;
    @FXML private RadioButton grade1;
    @FXML private RadioButton grade2;  
    @FXML private RadioButton grade3;
    @FXML private RadioButton grade4;  
    @FXML private RadioButton grade5;
    @FXML private RadioButton grade6;  
    @FXML private RadioButton grade8;
    @FXML private RadioButton grade9;
    @FXML private RadioButton grade10;    
    @FXML private RadioButton gradeAll;  
    @FXML private RadioButton gradeErrList;
    @FXML private TextField testSize;
    @FXML private RadioButton kanjiRadioButton;
    @FXML private RadioButton readingRadioButton;
    @FXML private TextArea onField;
    @FXML private TextArea kunField;
    @FXML private TextArea engField;
    @FXML private Button startTestButton;
    @FXML private Button repeatTestButton;
    @FXML private Label remainTextField;
    @FXML private Label errTextField;
    @FXML private Button clearHisButton;
    @FXML private Button clearErrButton;
    @FXML private ListView<String> scoreList;
    @FXML private Button clearScoreButton;
    @FXML private Label unicodeTextField;
    @FXML private Label gradeTextField;
    @FXML private Label topLabel;
    @FXML private RadioButton useLGButton;
    @FXML private TextArea messageText;
   
    public KanjiFlashController(){
        try {
            CHING_URI = getClass().getResource("qopen_chimes.WAV").toURI();
            FLIP_URI = getClass().getResource("qmem2.WAV").toURI();
        } catch (URISyntaxException us){
            us.printStackTrace();
        }
        try {
            finalSound = new Media(CHING_URI.toString());
            flipSound = new Media(FLIP_URI.toString());
        } catch (Exception e){
            e.printStackTrace();
        }
        // Preferences to store current user settings
        PREF = Preferences.userNodeForPackage(KanjiFlashController.class);
        gradeLevel = PREF.getInt("gradeLevel", 9);
        useLowerGrades = PREF.getBoolean("useLower", false);
        testCount = PREF.getInt("testSize", 200);
        int dispState = PREF.getInt("dispState", 1);
        TestState = State.NOT_STARTED;
        KanjiTab = null;
        remCount = testCount;
        errCount = 0;
        if (dispState == 1){
            displayState = Show.YOMI;
            currentDisplay = Show.YOMI;
        }
        else {
            displayState = Show.KANJI;
            currentDisplay = Show.KANJI;            
        }
        // end of Preferences
        KJ = null;
        it = null;
        if (!checkDB()){
            KanjiLoader jsc = new KanjiLoader();
            KanjiTab = jsc.getKanji();
            C = connectDB(); 
            if (C != null){
//                System.out.println("DB created and connected");
                KanjiTab.clear();
            }    
        }
        else {
            C = connectDB();
            if (C != null){
//                System.out.println("DB connected");
                KanjiTab = new ArrayList<Kanji>();
            }    
        }
        DBA = new DBAccess(C, this);
//        DBA.getProblemKanji(8);
        scoreTable = DBA.getScores();      
        KanjiErr = new ArrayList<KanjiError>();
    }
    @FXML protected void handleLGButton(ActionEvent event){
        if (useLGButton.isSelected())
            useLowerGrades = true;
        else
            useLowerGrades = false;
        PREF.putBoolean("useLower", useLowerGrades);
        if (USE_FLUSH){
            try {
                PREF.flush();
            } catch (BackingStoreException be){
                if (kanjiflash.KanjiFlash.STACK_TRACE)
                    be.printStackTrace();
            } 
        }    
        resetTest();
        event.consume();
    }
 
    @FXML protected void handleGrade1(ActionEvent event) {
        gradeLevel = 1;
        saveGradeLevel();
        resetTest();       
        event.consume();
    }
    @FXML protected void handleGrade2(ActionEvent event) {
        gradeLevel = 2;
        saveGradeLevel();        
        resetTest();        
        event.consume();
    } 
    @FXML protected void handleGrade3(ActionEvent event) {
        gradeLevel = 3;
         saveGradeLevel();       
        resetTest();        
        event.consume();
    }
    @FXML protected void handleGrade4(ActionEvent event) {
        gradeLevel = 4;
        saveGradeLevel();        
        resetTest();        
        event.consume();
    } 
    @FXML protected void handleGrade5(ActionEvent event) {
        gradeLevel = 5;
        saveGradeLevel();        
        resetTest();        
        event.consume();
    }
    @FXML protected void handleGrade6 (ActionEvent event) {
        gradeLevel = 6;
        saveGradeLevel();        
        resetTest();        
        event.consume();
    } 
    @FXML protected void handleGrade8(ActionEvent event) {
        gradeLevel = 8;
        saveGradeLevel();        
        resetTest();        
        event.consume();
    }  
    @FXML protected void handleGrade9 (ActionEvent event) {
        gradeLevel = 9;
        saveGradeLevel();        
        resetTest();        
        event.consume();
    } 
    @FXML protected void handleGrade10 (ActionEvent event) {
        gradeLevel = 10;
        saveGradeLevel();        
        resetTest();        
        event.consume();
    }     
    @FXML protected void handleGradeAll(ActionEvent event) {
        gradeLevel = 13;
        saveGradeLevel();        
        resetTest();        
        event.consume();
    }
    @FXML protected void handleGradeErr(ActionEvent event) {
        gradeLevel = 14;
        saveGradeLevel();        
        resetTest();        
        event.consume();
    } 
    @FXML protected void handleKanji(ActionEvent event) {
        displayState = Show.KANJI;
        PREF.putInt("dispState", 0);
        if (USE_FLUSH){        
            try {
                PREF.flush();
            } catch (BackingStoreException be){
                if (kanjiflash.KanjiFlash.STACK_TRACE)
                    be.printStackTrace();
            }
        }    
        resetTest();        
        event.consume();
    }  
    @FXML protected void handleReading (ActionEvent event) {
        displayState = Show.YOMI;
        PREF.putInt("dispState", 1);
        if (USE_FLUSH){        
            try {
                PREF.flush();
            } catch (BackingStoreException be){
                if (kanjiflash.KanjiFlash.STACK_TRACE)
                    be.printStackTrace();
            } 
        }    
        resetTest();
        event.consume();
    }
    @FXML protected void handleTestSize(ActionEvent event){
        try {
            testCount = Integer.parseInt(testSize.getText());
        } catch (NumberFormatException ex){
            testCount = 100;
            testSize.setText(Integer.toString(testCount));
        }
        PREF.putInt("testSize", testCount);
        if (USE_FLUSH){        
            try {
                PREF.flush();
            } catch (BackingStoreException be){
                if (kanjiflash.KanjiFlash.STACK_TRACE)
                    be.printStackTrace();
            }
        }    
        resetTest();
        event.consume();
    }
      private Connection connectDB(){
        String dbDriver = "org.apache.derby.jdbc.EmbeddedDriver";
        try {
            Class.forName(dbDriver);
        } catch (ClassNotFoundException ex){
            return null;
        }
        String dbDir = "c:\\Program Files\\KanjiDB";
        System.setProperty("derby.system.home",dbDir);
        Connection dbConnection = null;
        String dbURL = "jdbc:derby:c:/Program Files/KanjiDB";
        Properties props = new Properties();
        props.put("user", "App");
        props.put("password", "abcdefg");
        try {
            dbConnection = DriverManager.getConnection(dbURL, props);
        }  catch (SQLException sqle){ // Could not find existing DB, so create a new one
//            System.out.print("DB connection does not exist, creating from scratch\n");
            dbConnection = null;
            String dbURL2 = "jdbc:derby:c:/Program Files/KanjiDB;create=true";
            try {
                dbConnection = DriverManager.getConnection(dbURL2, props);
            } catch (SQLException sql2){
                if (kanjiflash.KanjiFlash.STACK_TRACE)
                    sql2.printStackTrace();
            }
            if (dbConnection != null){
//                System.out.print("Creating DB tables\n");
                DBSetup DBS = new DBSetup(dbConnection, KanjiTab);
                if(DBS.setupDBTables()){
                    return dbConnection;
                }
                else
                    return null;
            }
        }
        return dbConnection;
     } 
    private boolean checkDB(){
        File f = new File("c:\\Program Files\\KanjiDB");
        if (!f.exists()){
            return false;
        }
        else
            return true;
    }

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        // Tooltips
         startTestButton.setTooltip(new Tooltip("Click to select Kanji and start test"));
         repeatTestButton.setTooltip(new Tooltip("Click to repeat previous test"));
         clearHisButton.setTooltip(new Tooltip("Click to erase history list\n"+
                                                "(Items in history list will not be used in new tests)"));
         clearScoreButton.setTooltip(new Tooltip("Click to erase scores in list"));
         clearErrButton.setTooltip(new Tooltip("Click to clear error list"));
         kanjiRadioButton.setTooltip(new Tooltip("Select this to show Kanji first, then readings"));
         readingRadioButton.setTooltip(new Tooltip("Select this to show reading first, then Kanji"));
         useLGButton.setTooltip(new Tooltip("Select this to include Kanji from all grades up to the selected grade level in test\n"+
                                            "(If not selected, only Kanji for selected grade level will be used)"));
         testSize.setTooltip(new Tooltip("Enter number of Kanji for the test here"));
         // Select button for current grade level
         switch (gradeLevel){
             case 1:
                 grade1.setSelected(true);
                 break;
             case 2:
                 grade2.setSelected(true);
                 break;   
             case 3:
                 grade3.setSelected(true);
                 break;
             case 4:
                 grade4.setSelected(true);
                 break;
             case 5:
                 grade5.setSelected(true);
                 break;
             case 6:
                 grade6.setSelected(true);
                 break;   
             case 8:
                 grade8.setSelected(true);
                 break;
            case 9:
                 grade9.setSelected(true);
                 break;
            case 10:
                 grade10.setSelected(true);
                 break;                
             case 13:
                 gradeAll.setSelected(true);
                 break;   
             case 14:
                 gradeErrList.setSelected(true);
                 break;
             default:
                 grade1.setSelected(true);
         }
         // Select button for current display type
         switch (displayState){
             case KANJI:
                 kanjiRadioButton.setSelected(true);
                 break;
             case YOMI:
                 readingRadioButton.setSelected(true);
                 break;
             default:
                 break;
         }
         // Select button for "use lower grades" function
         if (useLowerGrades){
             useLGButton.setSelected(true);
         }
         else {
             useLGButton.setSelected(false);
         }
         // Initialize fonts and fields 
         testSize.setText(Integer.toString(testCount));
         scoreList.setItems(scoreTable);
         StringBuilder fontSB = new StringBuilder();
         fontSB.append("-fx-font: 20px ");
         fontSB.append('"');
         fontSB.append("Arial");
         fontSB.append('"');
         String fontStr = fontSB.toString();
         fontSB = new StringBuilder();
         fontSB.append("-fx-font: 20px ");
         fontSB.append('"');
         fontSB.append("MS Mincho");
         fontSB.append('"');
         String fontJap= fontSB.toString();         
         onField.setStyle(fontJap);
         kunField.setStyle(fontJap); 
         engField.setStyle(fontStr);         
         // Event filters
         startTestButton.addEventFilter(MouseEvent.MOUSE_CLICKED, new handleStartButton());
         repeatTestButton.addEventFilter(MouseEvent.MOUSE_CLICKED, new handleRepeatButton());
         clearErrButton.addEventFilter(MouseEvent.MOUSE_CLICKED, new handleClearErrorButton());
         clearHisButton.addEventFilter(MouseEvent.MOUSE_CLICKED, new handleClearHistoryButton()); 
         clearScoreButton.addEventFilter(MouseEvent.MOUSE_CLICKED, new handleClearScoreButton());
         useLGButton.setSelected(useLowerGrades);
         // Title for frame (in Japanese characters)
         byte[] topLabB = {0x34, 0x41, 0x3b, 0x7a, 0x25, 0x55, 0x25, 0x69, 0x25, 0x43,
                0x25, 0x37, 0x25, 0x65};
         topLabel.setText(new String(topLabB, 0, 14, Charset.forName("x-JIS0208")));
         DropShadow ds = new DropShadow();
         ds.setOffsetX(3.0);
         ds.setOffsetY(3.0);
         ds.setColor(Color.LIGHTPINK);
         topLabel.setEffect(ds);
         // Initial user message
         messageText.setText("Select grade level and test size\n and then click Start");
//         DBA.printKanjiHistory();
    }
    /*
     *   Main State Machine for handling test sequence
     */
    public void nextState(){ 
        switch (TestState){
            case NOT_STARTED:
                try {
                    testCount = Integer.parseInt(testSize.getText());
                } catch (NumberFormatException ex){
                   testCount = 100;
                   testSize.setText(Integer.toString(testCount));
                }
                PREF.putInt("testSize", testCount);
                if (USE_FLUSH){                
                    try {
                        PREF.flush();
                    } catch (BackingStoreException be){
                        if (kanjiflash.KanjiFlash.STACK_TRACE)
                            be.printStackTrace();
                    }   
                }    
                KanjiTab.clear();
                KanjiErr.clear();
                if (gradeLevel <= 13){
                    KanjiTab = DBA.getKanjiSampleByMaxGrade(testCount, gradeLevel, useLowerGrades); 
                }     
                if (gradeLevel == 14)
                    KanjiTab = DBA.getKanjiSampleFromErrList(testCount);
                remCount = KanjiTab.size();
                errCount = 0;
                remainTextField.setText(Integer.toString(remCount));
                errTextField.setText(Integer.toString(errCount));
                it = KanjiTab.iterator();
                if (it.hasNext()){
                    KJ = (Kanji)it.next();
                    playNextKanjiSound();
                    messageText.setText("");
                    switch (currentDisplay){
                        case KANJI:
                            kanjiTextField.setText(KJ.JISChar);
                            gradeTextField.setText("Grade: "+KJ.gradeLevel);
                            unicodeTextField.setText("Unicode: "+String.format("%x",KJ.unicode));
                            onField.setText("");
                            kunField.setText("");
                            engField.setText("");
                            break;
                        case YOMI:
                            kanjiTextField.setText("");
                            StringBuilder sb1 = new StringBuilder();
                            StringBuilder sb2 = new StringBuilder();
                            StringBuilder sb3 = new StringBuilder();                            
                            for (String str : KJ.onVal){
                                sb1.append(str+"\n");
                            }
                            for (String str : KJ.kunVal){
                                sb2.append(str+"\n");
                            }
                            for (String str : KJ.englishDef){
                                sb3.append(str+"\n");
                            }  
                            onField.setText(sb1.toString());
                            kunField.setText(sb2.toString());
                            engField.setText(sb3.toString());
                            break;
                        default:
                            break;
                    }
                    toggleCurrentDisplay();
                    TestState = State.STARTED;                     
                }
                else {
                    if (gradeLevel != 14){
                        int hisCount = DBA.getHistoryCount();
                        StringBuilder msgSB = new StringBuilder();
                        msgSB.append("History list contains ");
                        msgSB.append(Integer.toString(hisCount));
                        msgSB.append(" items\n");
                        if (hisCount > 0)
                            msgSB.append("Clear history list?");
                        else
                            msgSB.append("No items found!");
                        messageText.setText(msgSB.toString());
                    }
                    else {
                        messageText.setText("Error list has no current entries");
                    }
                    finishTest();
                    TestState = State.FINISHED;
                }    
                break;
            case STARTED:
                if (currentDisplay == displayState){ // Back at the beginning of the cycle
                    remCount--;
                    if (gradeLevel != 14)
                        DBA.addItemToHistory(KJ);
                    remainTextField.setText(Integer.toString(remCount));
                    errTextField.setText(Integer.toString(errCount));
                    if (it.hasNext()){
                        playNextKanjiSound();
                        KJ = (Kanji)it.next();
                        switch (currentDisplay){
                            case KANJI:
                                kanjiTextField.setText(KJ.JISChar);
                                gradeTextField.setText("Grade: "+KJ.gradeLevel);
                                unicodeTextField.setText("Unicode: "+String.format("%x",KJ.unicode));                                   
                                onField.setText("");
                                kunField.setText("");
                                engField.setText("");
                                break;
                            case YOMI:
                                kanjiTextField.setText("");
                                StringBuilder sb1 = new StringBuilder();
                                StringBuilder sb2 = new StringBuilder();
                                StringBuilder sb3 = new StringBuilder();                            
                                for (String str : KJ.onVal){
                                    sb1.append(str+"\n");
                                }
                                for (String str : KJ.kunVal){
                                    sb2.append(str+"\n");
                                }
                                for (String str : KJ.englishDef){
                                    sb3.append(str+"\n");
                                }  
                                onField.setText(sb1.toString());
                                kunField.setText(sb2.toString());
                                engField.setText(sb3.toString());
                                gradeTextField.setText("");
                                unicodeTextField.setText("");
                                break;
                            default:
                                break;
                        }
                        toggleCurrentDisplay();
                    }
                    else {
                        finishTest();
                        TestState = State.FINISHED;
                    }    
                } 
                else {  // Show the second display in the test sequence
                    switch (currentDisplay){
                        case KANJI:
                            kanjiTextField.setText(KJ.JISChar);
                            gradeTextField.setText("Grade: "+KJ.gradeLevel);
                            unicodeTextField.setText("Unicode: "+String.format("%x",KJ.unicode));               
                            break;
                        case YOMI:
                            StringBuilder sb1 = new StringBuilder();
                            StringBuilder sb2 = new StringBuilder();
                            StringBuilder sb3 = new StringBuilder();                            
                            for (String str : KJ.onVal){
                                sb1.append(str+"\n");
                            }
                            for (String str : KJ.kunVal){
                                sb2.append(str+"\n");
                            }
                            for (String str : KJ.englishDef){
                                sb3.append(str+"\n");
                            }  
                            onField.setText(sb1.toString());
                            kunField.setText(sb2.toString());
                            engField.setText(sb3.toString());
                            break;
                        default:
                            break;
                    }
                    toggleCurrentDisplay();                    
                }
                break;
            case RESTARTED:
                it = KanjiTab.iterator();
                currentDisplay = displayState;
                remCount = KanjiTab.size();
                errCount = 0;
                remainTextField.setText(Integer.toString(remCount));
                errTextField.setText(Integer.toString(errCount));
                if (it.hasNext()){
                    playNextKanjiSound();
                    KJ = (Kanji)it.next();
                    switch (currentDisplay){
                        case KANJI:
                            kanjiTextField.setText(KJ.JISChar);
                            gradeTextField.setText("Grade: "+KJ.gradeLevel);
                            unicodeTextField.setText("Unicode: "+String.format("%x",KJ.unicode));               
                            onField.setText("");
                            kunField.setText("");
                            engField.setText("");
                            break;
                        case YOMI:
                            kanjiTextField.setText("");
                            StringBuilder sb1 = new StringBuilder();
                            StringBuilder sb2 = new StringBuilder();
                            StringBuilder sb3 = new StringBuilder();                            
                            for (String str : KJ.onVal){
                                sb1.append(str+"\n");
                            }
                            for (String str : KJ.kunVal){
                                sb2.append(str+"\n");
                            }
                            for (String str : KJ.englishDef){
                                sb3.append(str+"\n");
                            }  
                            onField.setText(sb1.toString());
                            kunField.setText(sb2.toString());
                            engField.setText(sb3.toString());
                            break;
                        default:
                            break;
                    }
                    toggleCurrentDisplay();
                    TestState = State.STARTED;                    
                }
                else {
                    finishTest();
                    TestState = State.FINISHED; 
                }    
                break;
            case FINISHED:
                break;
                
        }
    }

    enum State {
        NOT_STARTED,
        STARTED,
        RESTARTED,
        FINISHED;
    }
    enum Show {
        KANJI,
        YOMI;
    }
    private void toggleCurrentDisplay(){
        if (currentDisplay == Show.KANJI)
            currentDisplay = Show.YOMI;
        else
            currentDisplay = Show.KANJI;
    }
    private void finishTest(){
        if (CHING_URI != null){
            try {
                playSound = new MediaPlayer(finalSound);
                playSound.setAutoPlay(false);
                playSound.play();
            } catch (MediaException me){
                CHING_URI = null;
                if (kanjiflash.KanjiFlash.STACK_TRACE)                 
                    me.printStackTrace();
            } 
        }  
        if (gradeLevel != 14) // Don't add errors to database if we are already testing the error list
            DBA.addErrorsToList(KanjiErr);
        if (KanjiTab.size() > 0){ // Don't calculate a score if there are no Kanji in the test!
            messageText.setText("Test Finished!");            
            double finalScore = 100. * (double)(KanjiTab.size() - errCount)/(double)KanjiTab.size();
            String scoreStr = String.format("%.1f", finalScore);
            scoreTable.add(scoreStr);
            DBA.addScoreToList(scoreStr);   
        }     
    }
    private void playNextKanjiSound(){
        if (FLIP_URI != null){ 
            try {
                playFlip = new MediaPlayer(flipSound);
                playFlip.setAutoPlay(false);
                playFlip.play();     
            } catch (MediaException me){
                FLIP_URI = null;
                if (kanjiflash.KanjiFlash.STACK_TRACE)                            
                    me.printStackTrace();
            }    
        }
    }
    private void resetTest(){
        TestState = State.NOT_STARTED;
        messageText.setText("");
        currentDisplay = displayState;
        kanjiTextField.setText("");
        onField.setText("");
        kunField.setText("");
        engField.setText("");
        remainTextField.setText("");
        errTextField.setText("");
        
    }
    class handleStartButton implements EventHandler<MouseEvent> {
        @Override
        public void handle(MouseEvent mouseEv) {
            mouseEv.consume();    
            resetTest();
            nextState();
        }
    }
    class handleClearHistoryButton implements EventHandler<MouseEvent> {
        @Override
        public void handle(MouseEvent mouseEv) {
            mouseEv.consume();
            DBA.clearHistoryList();
            messageText.setText("History list cleared");
        }
    }  
    class handleClearErrorButton implements EventHandler<MouseEvent> {
        @Override
        public void handle(MouseEvent mouseEv) {
            mouseEv.consume();
            DBA.clearErrorList();
            messageText.setText("Error list cleared");
        }
    }   
    class handleClearScoreButton implements EventHandler<MouseEvent> {
        @Override
        public void handle(MouseEvent mouseEv) {
            mouseEv.consume();
            DBA.clearScoreList();
            scoreTable.clear();
        }
    }
    class handleRepeatButton implements EventHandler<MouseEvent> {
        @Override
        public void handle(MouseEvent mouseEv) {
            TestState = State.RESTARTED;
            kanjiTextField.setText("");
            onField.setText("");
            kunField.setText("");
            engField.setText("");            
            nextState();
            mouseEv.consume();
        }
    } 
    public void addError(){
        if (currentDisplay == displayState){
            errCount++;
            if (gradeLevel != 14) // Don't re-add errors to the error list!
                KanjiErr.add(new KanjiError(KJ.unicode, 1));
        } 
        nextState();
    }
    public void dropError(){
        if (currentDisplay == displayState){
            if (gradeLevel == 14){ // Only remove from error list if we are using error list as Kanji source
                DBA.removeError(KJ);
            }
            else {
                messageText.setText("Not using error list as source");                
            }
        }    
        nextState();
    }
    private void saveGradeLevel(){
        PREF.putInt("gradeLevel", gradeLevel);
        if (USE_FLUSH){        
            try {
                PREF.flush();
            } catch (BackingStoreException be){
                if (kanjiflash.KanjiFlash.STACK_TRACE)
                    be.printStackTrace();
            }
        }    
    }

}

