package uk.co.bytemark.vm.enigma.inquisition.gui.quiz;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collection;
import java.util.Iterator;
import javax.swing.ImageIcon;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import uk.co.bytemark.vm.enigma.inquisition.gui.images.Icons;
import uk.co.bytemark.vm.enigma.inquisition.gui.misc.QuizConfig;
import uk.co.bytemark.vm.enigma.inquisition.gui.quizchooser.InquisitionMain;
import uk.co.bytemark.vm.enigma.inquisition.gui.screens.AbstractResultDialog;
import uk.co.bytemark.vm.enigma.inquisition.questions.QuestionSet;
import uk.co.bytemark.vm.enigma.inquisition.questions.QuestionSetManager;
import uk.co.bytemark.vm.enigma.inquisition.quiz.QuizState;
public class ResultsDialog extends AbstractResultDialog implements PropertyChangeListener {
private final QuizState quizState;
private final QuestionTableModel questionTableModel;
private boolean updating;
public ResultsDialog( Frame parent, QuizState quizState ) {
super( parent, false );
this.quizState = quizState;
questionTableModel = new QuestionTableModel( quizState );
getTable().setModel( questionTableModel );
getTable().getSelectionModel().setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
addEventHandlers();
quizState.addPropertyChangeListener( this );
updateFromModel();
}
private void addEventHandlers() {
getCloseButton().addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent e ) {
setVisible( false );
dispose();
}
} );
getTable().getSelectionModel().addListSelectionListener( new ListSelectionListener() {
public void valueChanged( ListSelectionEvent e ) {
boolean selected = ( getTable().getSelectedRowCount() == 1 );
if ( selected && !updating ) {
int selectedRow = getTable().getSelectedRow();
quizState.goToQuestion( selectedRow + 1 );
}
}
} );
}
public void propertyChange( PropertyChangeEvent evt ) {
updateFromModel();
}
private void updateFromModel() {
updating = true;
try {
questionTableModel.fireTableDataChanged();
int questionNumber = quizState.getQuestionNumber();
getTable().setRowSelectionInterval( questionNumber - 1, questionNumber - 1 );
updateScoreBar();
} finally {
updating = false;
}
}
private void updateScoreBar() {
int correctCount = quizState.getNumberOfCorrectQuestions();
int numberOfQuestions = quizState.getNumberOfQuestions();
String percentageString = String.format( " (%.0f%%)", 100.0 * correctCount / numberOfQuestions );
getScoreBar().setString( "" + correctCount + " / " + numberOfQuestions + percentageString );
getScoreBar().setValue( (int) ( correctCount * 100.0 / numberOfQuestions ) );
}
public static class QuestionTableModel extends AbstractTableModel {
private String[] columnHeadings = new String[] { "Question number", "Type", "Answered", "Marked for review", "Correct" };
private Class<?>[] columnClasses = new Class[] { Integer.class, String.class, Boolean.class, Boolean.class, ImageIcon.class }; // Boolean.class};
private QuizState quizState;
@Override
public String getColumnName( int column ) {
return columnHeadings[column];
}
@Override
public Class<?> getColumnClass( int column ) {
return columnClasses[column];
}
/** Creates a new instance of QuestionTableModel */
public QuestionTableModel( QuizState quizState ) {
this.quizState = quizState;
}
public int getRowCount() {
return quizState.getNumberOfQuestions();
}
public int getColumnCount() {
return 5;
}
public Object getValueAt( int rowIndex, int columnIndex ) {
switch ( columnIndex ) {
case 0 :
return rowIndex + 1;
case 1 :
return quizState.getQuestionType( rowIndex + 1 );
case 2 :
return quizState.isAnswered( rowIndex + 1 );
case 3 :
return quizState.isMarked( rowIndex + 1 );
case 4 :
boolean correct = quizState.isCorrect( rowIndex + 1 );
if ( correct ) {
if ( Icons.SMALL_TICK.isAvailable() )
return Icons.SMALL_TICK.getIcon();
} else {
if ( Icons.SMALL_CROSS.isAvailable() )
return Icons.SMALL_CROSS.getIcon();
}
return null;
default:
throw new AssertionError( "Should not reach here" );
}
}
@Override
public boolean isCellEditable( int rowIndex, int columnIndex ) {
return columnIndex == 3;
}
@Override
public void setValueAt( Object aValue, int rowIndex, int columnIndex ) {
if ( columnIndex == 3 ) {
boolean marked = ( (Boolean) aValue );
quizState.markQuestionForReview( rowIndex + 1, marked );
}
}
}
public static void main( String[] args ) {
InquisitionMain.setupLookAndFeel();
QuizConfig quizConfig = QuizConfig.createWithTimer( false, true, 30 );
Collection<QuestionSet> bundledQuestionSets = QuestionSetManager.loadBundledQuestionSets();
Iterator<QuestionSet> iterator = bundledQuestionSets.iterator();
iterator.next();
QuestionSet questionSet = iterator.next();
QuizState quizState_ = new QuizState( questionSet, quizConfig );
final ResultsDialog resultsDialog = new ResultsDialog( null, quizState_ );
SwingUtilities.invokeLater( new Runnable() {
public void run() {
resultsDialog.setDefaultCloseOperation( DISPOSE_ON_CLOSE );
resultsDialog.setVisible( true );
}
} );
}
}