package org.geogebra.web.web.gui.view.probcalculator;
import org.geogebra.common.gui.view.probcalculator.ChiSquareCell;
import org.geogebra.common.gui.view.probcalculator.ChiSquarePanel;
import org.geogebra.common.gui.view.probcalculator.StatisticsCalculator;
import org.geogebra.common.gui.view.probcalculator.StatisticsCalculator.Procedure;
import org.geogebra.common.gui.view.probcalculator.StatisticsCollection;
import org.geogebra.common.main.Localization;
import org.geogebra.common.util.debug.Log;
import org.geogebra.web.html5.gui.inputfield.AutoCompleteTextFieldW;
import org.geogebra.web.html5.gui.util.ListBoxApi;
import com.google.gwt.dom.client.Document;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
/**
* @author gabor
*
* ChiSquarePanel for Web
*
*/
public class ChiSquarePanelW extends ChiSquarePanel implements ValueChangeHandler<Boolean>, ChangeHandler, FocusHandler, KeyPressHandler {
private FlowPanel wrappedPanel;
private Label lblRows;
private Label lblColumns;
private CheckBox ckExpected;
private CheckBox ckChiDiff;
private CheckBox ckRowPercent;
private CheckBox ckColPercent;
private ListBox cbRows;
private ListBox cbColumns;
private FlowPanel pnlCount;
private ChiSquareCellW[][] cell;
private boolean showColumnMargin;
private FlowPanel pnlControl;
/**
* Constructs chisquarepanel for web
*
* @param loc
* application
* @param statcalc
* calculator
*
*/
public ChiSquarePanelW(Localization loc, StatisticsCalculator statcalc) {
super(loc, statcalc);
createGUI();
setLabels();
}
private void createGUI() {
this.wrappedPanel = new FlowPanel();
createGUIElements();
createCountPanel();
createControlPanel();
FlowPanel p = new FlowPanel();
p.add(pnlCount);
wrappedPanel.add(pnlControl);
wrappedPanel.add(p);
}
private void createControlPanel() {
pnlControl = new FlowPanel();
pnlControl.setStyleName("pnlControl");
pnlControl.add(lblRows);
pnlControl.add(cbRows);
pnlControl.getElement().appendChild(Document.get().createBRElement());
pnlControl.add(lblColumns);
pnlControl.add(cbColumns);
FlowPanel lineBreak = new FlowPanel();
lineBreak.setStyleName("lineBreak");
pnlControl.add(lineBreak);
pnlControl.add(ckRowPercent);
pnlControl.add(ckColPercent);
pnlControl.add(ckExpected);
pnlControl.add(ckChiDiff);
}
private void createCountPanel() {
if (pnlCount == null) {
pnlCount = new FlowPanel();
pnlCount.addStyleName("pnlCount");
}
pnlCount.clear();
cell = new ChiSquareCellW[getSc().rows + 2][getSc().columns + 2];
for (int r = 0; r < getSc().rows + 2; r++) {
FlowPanel row = new FlowPanel();
row.addStyleName("chirow");
for (int c = 0; c < getSc().columns + 2; c++) {
cell[r][c] = new ChiSquareCellW(getSc(), r, c);
cell[r][c].getInputField().addKeyPressHandler(this);
cell[r][c].getInputField().addFocusHandler(this);
if (getStatCalc().getSelectedProcedure() == Procedure.GOF_TEST) {
//cell[r][c].setColumns(10);
}
row.add(cell[r][c].getWrappedPanel());
}
pnlCount.add(row);
}
// upper-right corner cell
cell[0][0].setMarginCell(true);
//column headers and margins
for (int c = 1; c < getSc().columns + 2; c++) {
cell[0][c].setHeaderCell(true);
cell[getSc().rows + 1][c].setMarginCell(true);
}
// row headers adn margins
for (int r = 0; r < getSc().rows + 1; r++) {
cell[r][0].setHeaderCell(true);
cell[r][getSc().columns + 1].setMarginCell(true);
}
//set input cells
for (int r = 1; r < getSc().rows + 1; r++) {
for (int c = 1; c < getSc().columns + 1; c++) {
cell[r][c].setInputCell(true);
}
}
//clear other corners
cell[getSc().rows + 1][0].hideAll();
cell[0][getSc().columns + 1].hideAll();
if (getStatCalc().getSelectedProcedure() == Procedure.GOF_TEST) {
cell[0][1].setMarginCell(true);
cell[0][2].setMarginCell(true);
}
}
// ==========================================
// Event handlers
// ==========================================
public void updateGUI() {
if (getStatCalc().getSelectedProcedure() == Procedure.CHISQ_TEST) {
cbColumns.setVisible(true);
lblColumns.setVisible(true);
ckRowPercent.setVisible(true);
ckExpected.setVisible(true);
ckChiDiff.setVisible(true);
} else if (getStatCalc().getSelectedProcedure() == Procedure.GOF_TEST) {
cbColumns.setVisible(false);
lblColumns.setVisible(false);
ckRowPercent.setVisible(false);
ckExpected.setVisible(false);
ckChiDiff.setVisible(false);
cbColumns.setSelectedIndex(0);
}
getSc().setChiSqData(Integer.parseInt(cbRows.getValue(cbRows.getSelectedIndex())),
Integer.parseInt(cbColumns.getValue(cbColumns.getSelectedIndex())));
createCountPanel();
setLabels();
}
private void updateVisibility() {
for (int i = 1; i < getSc().rows + 1; i++) {
for (int j = 1; j < getSc().columns + 1; j++) {
cell[i][j].setLabelVisible(1, ckExpected.getValue());
cell[i][j].setLabelVisible(2, ckChiDiff.getValue());
cell[i][j].setLabelVisible(3, ckRowPercent.getValue());
cell[i][j].setLabelVisible(4, ckColPercent.getValue());
}
}
// column percent for bottom margin
for (int r = 0; r < getSc().rows; r++) {
cell[r + 1][getSc().columns + 1].setLabelVisible(3,
ckColPercent.getValue());
}
// row percent for right margin
for (int c = 0; c < getSc().columns; c++) {
cell[getSc().rows + 1][c + 1].setLabelVisible(4,
ckRowPercent.getValue());
}
updateCellContent();
}
private void updateCellContent() {
getStatProcessor().doCalculate();
for (int r = 0; r < getSc().rows; r++) {
for (int c = 0; c < getSc().columns; c++) {
if (ckExpected.getValue()) {
cell[r + 1][c + 1].setLabelText(1,
getStatCalc().format(getSc().expected[r][c]));
}
if (ckChiDiff.getValue()) {
cell[r + 1][c + 1].setLabelText(2,
getStatCalc().format(getSc().diff[r][c]));
}
if (ckRowPercent.getValue()) {
cell[r + 1][c + 1].setLabelText(
3,
getStatCalc().format(100 * getSc().observed[r][c]
/ getSc().rowSum[r]));
}
if (ckColPercent.getValue()) {
cell[r + 1][c + 1].setLabelText(
4,
getStatCalc().format(100 * getSc().observed[r][c]
/ getSc().columnSum[c]));
}
}
}
// column margin
if (showColumnMargin) {
for (int r = 0; r < getSc().rows; r++) {
cell[r + 1][getSc().columns + 1].setLabelText(0,
getStatCalc().format(getSc().rowSum[r]));
if (ckRowPercent.getValue()) {
cell[r + 1][getSc().columns + 1].setLabelText(3,
getStatCalc().format(100 * getSc().rowSum[r] / getSc().total));
}
}
}
// bottom margin
for (int c = 0; c < getSc().columns; c++) {
cell[getSc().rows + 1][c + 1].setLabelText(0,
getStatCalc().format(getSc().columnSum[c]));
if (ckColPercent.getValue()) {
cell[getSc().rows + 1][c + 1].setLabelText(4,
getStatCalc().format(100 * getSc().columnSum[c] / getSc().total));
}
}
// bottom right corner
if (showColumnMargin) {
cell[getSc().rows + 1][getSc().columns + 1].setLabelText(0,
getStatCalc().format(getSc().total));
}
}
/**
* Update translation
*/
public void setLabels() {
lblRows.setText(getMenu("Rows"));
lblColumns.setText(getMenu("Columns"));
ckExpected.setText(getMenu("ExpectedCount"));
ckChiDiff.setText(getMenu("ChiSquaredContribution"));
ckRowPercent.setText(getMenu("RowPercent"));
ckColPercent.setText(getMenu("ColumnPercent"));
if (getStatCalc().getSelectedProcedure() == Procedure.GOF_TEST) {
cell[0][1].setLabelText(0, getMenu("ObservedCount"));
cell[0][2].setLabelText(0, getMenu("ExpectedCount"));
}
}
private void createGUIElements() {
lblRows = new Label();
lblColumns = new Label();
ckExpected = new CheckBox();
ckChiDiff = new CheckBox();
ckRowPercent = new CheckBox();
ckColPercent = new CheckBox();
ckExpected.addValueChangeHandler(this);
ckChiDiff.addValueChangeHandler(this);
ckRowPercent.addValueChangeHandler(this);
ckColPercent.addValueChangeHandler(this);
// drop down menu for rows/columns 2-12
String[] num = new String[11];
for (int i = 0; i < num.length; i++) {
num[i] = "" + (i + 2);
}
cbRows = new ListBox();
cbColumns = new ListBox();
for (int i = 0; i < num.length; i++) {
cbRows.addItem(num[i]);
cbColumns.addItem(num[i]);
}
Log.debug(getSc().rows + " :: " + getSc().columns);
cbRows.setSelectedIndex(ListBoxApi.getIndexOf(String.valueOf(getSc().rows), cbRows));
cbRows.addChangeHandler(this);
cbColumns.setSelectedIndex(ListBoxApi.getIndexOf(String.valueOf(getSc().columns -1), cbColumns));
cbColumns.addChangeHandler(this);
}
//@Override
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
Object source = event.getSource();
if (source == ckExpected || source == ckChiDiff
|| source == ckRowPercent || source == ckColPercent) {
updateVisibility();
}
}
//@Override
@Override
public void onChange(ChangeEvent event) {
updateGUI();
}
public class ChiSquareCellW extends ChiSquareCell implements FocusHandler,
KeyUpHandler {
private FlowPanel wrappedPanel;
private AutoCompleteTextFieldW fldInput;
private Label[] label;
private Boolean isInputCell = false;
/**
* Construct ChiSquareCell with given row, column
*/
public ChiSquareCellW(StatisticsCollection sc, int row, int column) {
this(sc);
init(row, column);
}
/**
* Construct ChiSquareCell
*/
public ChiSquareCellW(StatisticsCollection sc) {
super(sc);
this.wrappedPanel = new FlowPanel();
this.wrappedPanel.addStyleName("ChiSquarePanelW");
fldInput = new AutoCompleteTextFieldW(statCalc.getApp());
fldInput.addKeyUpHandler(this);
fldInput.addFocusHandler(this);
wrappedPanel.add(fldInput);
label = new Label[5];
for (int i = 0; i < label.length; i++) {
label[i] = new Label();
wrappedPanel.add(label[i]);
}
setColumns(4);
setVisualStyle();
hideAllLabels();
}
public void setColumns(int columns) {
//fldInput.setColumns(columns); no good for layout
// force a minimum width for margin cells
wrappedPanel.add(fldInput);
}
/**
* hide all labels
*/
public void hideAllLabels() {
for (int i = 0; i < label.length; i++) {
label[i].setVisible(false);
}
}
/**
* hide all
*/
public void hideAll() {
hideAllLabels();
fldInput.setVisible(false);
}
/**
* @return input field
*/
public AutoCompleteTextFieldW getInputField() {
return fldInput;
}
/**
* @return label array
*/
public Label[] getLabel() {
return label;
}
public void setLabelText(int index, String s) {
label[index].setText(s);
}
public void setLabelVisible(int index, boolean isVisible) {
label[index].setVisible(isVisible);
}
public void setInputCell(boolean isInputCell) {
this.isInputCell = isInputCell;
setVisualStyle();
}
@Override
protected void setVisualStyle() {
fldInput.setVisible(false);
if (isMarginCell()) {
setLabelVisible(0, true);
} else if (isHeaderCell()) {
fldInput.setVisible(true);
wrappedPanel.addStyleName("headercell");
//TODO CSSfldInput.setBackground(geogebra.awt.GColorD
//.getAwtColor(GeoGebraColorConstants.TABLE_BACKGROUND_COLOR_HEADER));
} else if (isInputCell) {
fldInput.setVisible(true);
wrappedPanel.addStyleName("inputcell");
} else {
fldInput.setVisible(true);
wrappedPanel.removeStyleName("headercell");
//TODO csswrappedPanel.setBorder(BorderFactory.createLineBorder(Color.GRAY, 1));
//TODO cssfldInput.setBackground(geogebra.awt.GColorD
//.getAwtColor(GeoGebraColorConstants.WHITE));
}
}
private void updateCellData() {
updateCellData(fldInput.getText());
}
// TODO attach the listener
public void focusLost(FocusEvent e) {
updateCellData();
getStatCalc().updateResult();
}
public FlowPanel getWrappedPanel() {
return wrappedPanel;
}
@Override
public void onKeyUp(KeyUpEvent e) {
updateCellData();
getStatCalc().updateResult();
updateCellContent();
}
@Override
public void onFocus(FocusEvent event) {
if (event.getSource() instanceof TextBox) {
((TextBox) event.getSource()).selectAll();
}
}
}
@Override
public void onFocus(FocusEvent event) {
if (event.getSource() instanceof TextBox) {
((TextBox) event.getSource()).selectAll();
}
}
@Override
public void onKeyPress(KeyPressEvent event) {
Object source = event.getSource();
if (source instanceof TextBox) {
doTextFieldActionPerformed();
}
}
private void doTextFieldActionPerformed() {
updateCellContent();
}
/**
* @return the wrapped panel
*/
public FlowPanel getWrappedPanel() {
return wrappedPanel;
}
}