tv.dyndns.kishibe.qmaclone.client.creation.WidgetProblemForm.java Source code

Java tutorial

Introduction

Here is the source code for tv.dyndns.kishibe.qmaclone.client.creation.WidgetProblemForm.java

Source

//The MIT License
//
//Copyright (c) 2009 nodchip
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
package tv.dyndns.kishibe.qmaclone.client.creation;

import static com.google.common.base.Strings.emptyToNull;
import static com.google.common.base.Strings.nullToEmpty;
import static tv.dyndns.kishibe.qmaclone.client.constant.Constant.MAX_NUMBER_OF_ANSWERS;
import static tv.dyndns.kishibe.qmaclone.client.constant.Constant.MAX_NUMBER_OF_CHOICES;
import static tv.dyndns.kishibe.qmaclone.client.constant.Constant.MAX_PLAYER_NAME_LENGTH;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import tv.dyndns.kishibe.qmaclone.client.PlusOne;
import tv.dyndns.kishibe.qmaclone.client.Service;
import tv.dyndns.kishibe.qmaclone.client.UserData;
import tv.dyndns.kishibe.qmaclone.client.Utility;
import tv.dyndns.kishibe.qmaclone.client.game.ProblemGenre;
import tv.dyndns.kishibe.qmaclone.client.game.ProblemType;
import tv.dyndns.kishibe.qmaclone.client.game.RandomFlag;
import tv.dyndns.kishibe.qmaclone.client.packet.PacketBbsResponse;
import tv.dyndns.kishibe.qmaclone.client.packet.PacketBbsThread;
import tv.dyndns.kishibe.qmaclone.client.packet.PacketProblem;
import tv.dyndns.kishibe.qmaclone.client.packet.ProblemIndicationEligibility;
import tv.dyndns.kishibe.qmaclone.client.util.StringUtils;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.gwt.core.client.JavaScriptException;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class WidgetProblemForm extends VerticalPanel implements ClickHandler, ChangeHandler {
    private static final Logger logger = Logger.getLogger(WidgetProblemForm.class.getName());
    private static final int MAX_PROBLEM_NOTE_LENGTH = 1024;
    private final Label labelProblemNumber = new Label("???");
    private final ListBox listBoxGenre = new ListBox();
    @VisibleForTesting
    final ListBox listBoxType = new ListBox();
    private final ListBox listBoxRandomFlag = new ListBox();
    private final TextArea textAreaSentence = new TextArea();
    @VisibleForTesting
    final TextBox[] textBoxAnswer = new TextBox[MAX_NUMBER_OF_ANSWERS];
    @VisibleForTesting
    final TextBox[] textBoxChoice = new TextBox[MAX_NUMBER_OF_CHOICES];
    private final RadioButton radioButtonNone = new RadioButton("external", "???");
    private final RadioButton radioButtonImage = new RadioButton("external", "?");
    private final RadioButton radioButtonYouTube = new RadioButton("external", "YouTube");
    private final ListBox listBoxNumberOfDisplayedChoices = new ListBox();
    private final TextBox textBoxExternalUrl = new TextBox();
    private final HorizontalPanel panelExternalUrl = new HorizontalPanel();
    private final TextBox textBoxCreator = new TextBox();
    private final TextArea textAreaNote = new TextArea();
    private final CreationUi creationUi;
    private final Label labelAnswerCounter = new Label("0/0");
    private final CheckBox checkBoxResetAnswerCount = new CheckBox("?");
    @VisibleForTesting
    final HTML htmlPlusOne = new HTML();
    private final Label labelGood = new Label("0");
    private final CheckBox checkBoxResetVote = new CheckBox("??");
    private final CheckBox checkBoxImageChoice = new CheckBox("??");
    private final CheckBox checkBoxImageAnswer = new CheckBox("?");
    private final CheckBox checkBoxRemovePlayerAnswers = new CheckBox("?");
    private int problemId = PacketProblem.CREATING_PROBLEM_ID;
    private final List<Button> buttonPolygonCreation = new ArrayList<Button>();
    private final VerticalPanel panelProblemFeedback = new VerticalPanel();
    private final Button buttonClearProblemFeedback = new Button("", this);
    private Date indication;
    private Date indicationResolved;
    private final Button buttonIndicate = new Button("????");
    @VisibleForTesting
    final CheckBox checkBoxUnindicate = new CheckBox(
            "? (????????)");
    private boolean reserveResetAnswerCount = false;

    public WidgetProblemForm(CreationUi creationUi) {
        this.creationUi = creationUi;

        // ??
        add(labelProblemNumber);

        Grid grid = new Grid(15, 2);
        grid.addStyleName("gridFrame");
        grid.addStyleName("gridFontNormal");

        int row = 0;

        // 
        for (ProblemGenre genre : ProblemGenre.values()) {
            String name = genre == ProblemGenre.Random ? "???????" : genre.toString();
            listBoxGenre.addItem(name, Integer.toString(genre.getIndex()));
        }
        listBoxGenre.setWidth("200px");
        grid.setText(row, 0, "");
        grid.setWidget(row++, 1, listBoxGenre);

        // ?
        for (ProblemType type : ProblemType.values()) {
            if (ProblemType.Random1.compareTo(type) <= 0) {
                break;
            }
            String item = type == ProblemType.Random ? "????????" : type.toString();
            listBoxType.addItem(item, type.name());
        }
        listBoxType.setWidth("200px");
        listBoxType.addChangeHandler(this);
        grid.setText(row, 0, "?");
        grid.setWidget(row++, 1, listBoxType);

        // 
        for (int i = 1; i <= 5; ++i) {
            String s = Integer.toString(i);
            listBoxRandomFlag.addItem(s, RandomFlag.values()[i].name());
        }
        listBoxRandomFlag.setSelectedIndex(4);
        listBoxRandomFlag.setWidth("100px");
        grid.setText(row, 0, "");
        grid.setWidget(row++, 1, listBoxRandomFlag);

        // ?
        textAreaSentence.setCharacterWidth(60);
        textAreaSentence.setVisibleLines(5);
        grid.setText(row, 0, "?");
        grid.setWidget(row++, 1, textAreaSentence);

        // ?
        VerticalPanel choicePanel = new VerticalPanel();
        choicePanel.setStyleName("gridNoFrame");
        choicePanel.addStyleName("gridFontNormal");
        for (int i = 0; i < MAX_NUMBER_OF_CHOICES; ++i) {
            textBoxChoice[i] = new TextBox();
            textBoxChoice[i].setWidth("400px");
            choicePanel.add(textBoxChoice[i]);
        }
        choicePanel.add(checkBoxImageChoice);
        grid.setText(row, 0, "?");
        grid.setWidget(row++, 1, choicePanel);

        // 
        VerticalPanel answerPanel = new VerticalPanel();
        answerPanel.setStyleName("gridNoFrame");
        answerPanel.addStyleName("gridFontNormal");
        for (int i = 0; i < MAX_NUMBER_OF_ANSWERS; ++i) {
            HorizontalPanel panel = new HorizontalPanel();
            panel.setVerticalAlignment(ALIGN_MIDDLE);
            answerPanel.add(panel);

            textBoxAnswer[i] = new TextBox();
            textBoxAnswer[i].setWidth("400px");
            panel.add(textBoxAnswer[i]);

            Button button = new Button("?", this);
            panel.add(button);
            buttonPolygonCreation.add(button);
        }
        answerPanel.add(checkBoxImageAnswer);
        grid.setText(row, 0, "");
        grid.setWidget(row++, 1, answerPanel);

        // ???
        grid.setText(row, 0, "???");
        grid.setWidget(row++, 1, listBoxNumberOfDisplayedChoices);
        listBoxNumberOfDisplayedChoices.setWidth("50px");
        listBoxNumberOfDisplayedChoices.addItem("3");
        listBoxNumberOfDisplayedChoices.addItem("4");
        listBoxNumberOfDisplayedChoices.setSelectedIndex(1);

        // 
        grid.setText(row, 0, "");
        {
            VerticalPanel panel = new VerticalPanel();
            panel.setStyleName("gridNoFrame");
            panel.addStyleName("gridFontNormal");
            {
                radioButtonNone.setValue(true);
                radioButtonNone.addClickHandler(this);
                radioButtonImage.addClickHandler(this);
                radioButtonYouTube.addClickHandler(this);

                HorizontalPanel panel2 = new HorizontalPanel();
                panel2.add(radioButtonNone);
                panel2.add(radioButtonImage);
                panel2.add(radioButtonYouTube);
                panel.add(panel2);
            }
            {
                textBoxExternalUrl.setWidth("400px");

                panelExternalUrl.add(new Label("URL"));
                panelExternalUrl.add(textBoxExternalUrl);
                panel.add(panelExternalUrl);
            }
            grid.setWidget(row++, 1, panel);
        }

        // ?
        textBoxCreator.setWidth("200px");
        textBoxCreator.setMaxLength(MAX_PLAYER_NAME_LENGTH);
        textBoxCreator.setText(UserData.get().getPlayerName());
        grid.setText(row, 0, "??");
        grid.setWidget(row++, 1, textBoxCreator);

        // 
        grid.setText(row, 0, "");
        HorizontalPanel panelAnswerCount = new HorizontalPanel();
        panelAnswerCount.add(labelAnswerCounter);
        panelAnswerCount.add(checkBoxResetAnswerCount);
        panelAnswerCount.add(checkBoxRemovePlayerAnswers);
        checkBoxResetAnswerCount.setVisible(false);
        checkBoxRemovePlayerAnswers.setVisible(false);
        grid.setWidget(row++, 1, panelAnswerCount);

        // 
        grid.setText(row, 0, "+1");
        HorizontalPanel panelVoteCount = new HorizontalPanel();
        panelVoteCount.add(htmlPlusOne);
        grid.setWidget(row++, 1, panelVoteCount);

        // 
        grid.setText(row, 0, "?");
        HorizontalPanel panelGood = new HorizontalPanel();
        panelGood.add(labelGood);
        panelGood.add(checkBoxResetVote);
        checkBoxResetVote.setVisible(false);
        grid.setWidget(row++, 1, panelGood);

        // 
        grid.setText(row, 0, "");
        HorizontalPanel panelIndicate = new HorizontalPanel();
        buttonIndicate.setVisible(false);
        checkBoxUnindicate.setVisible(false);
        panelIndicate.add(buttonIndicate);
        panelIndicate.add(checkBoxUnindicate);
        grid.setWidget(row++, 1, panelIndicate);
        buttonIndicate.addClickHandler(this);

        // ?
        grid.setText(row, 0, "?");
        textAreaNote.setCharacterWidth(60);
        textAreaNote.setVisibleLines(5);
        grid.setWidget(row++, 1, textAreaNote);

        // ?
        grid.setText(row, 0, "?");
        grid.setWidget(row++, 1, panelProblemFeedback);

        add(grid);

        updateForm();
    }

    /**
     * ??
     * 
     * @param problem
     *          ?
     */
    public void setProblem(PacketProblem problem) {
        // TODO ??????????Java???????
        listBoxGenre.setSelectedIndex(problem.genre.getIndex());
        listBoxType.setSelectedIndex(problem.type.getIndex());
        listBoxRandomFlag.setSelectedIndex(problem.randomFlag.getIndex() - 1);
        textAreaSentence.setText(problem.getProblemCreationSentence());

        if (problem.answers != null) {
            for (int i = 0; i < problem.answers.length; ++i) {
                String answer = nullToEmpty(problem.answers[i]);
                textBoxAnswer[i].setText(answer);
            }
        }

        if (problem.choices != null) {
            for (int i = 0; i < problem.choices.length; ++i) {
                String choice = nullToEmpty(problem.choices[i]);
                textBoxChoice[i].setText(choice);
            }
        }

        if (problem.type.isNumberOfDisplayedChoicesChangeable()) {
            listBoxNumberOfDisplayedChoices.setSelectedIndex(problem.numberOfDisplayedChoices - 3);
        } else {
            listBoxNumberOfDisplayedChoices.setSelectedIndex(1);
        }

        if (problem.creator != null) {
            textBoxCreator.setText(problem.creator);
        }

        labelAnswerCounter.setText(problem.good + "/" + problem.bad);

        if (problem.isCopiedProblem()) {
            htmlPlusOne.setHTML("");
        } else {
            htmlPlusOne.setHTML(PlusOne.getButton(problem.id, true));
            try {
                PlusOne.render();
            } catch (JavaScriptException e) {
                logger.warning("+1??????");
            }
        }

        textAreaNote.setText(problem.note.trim());
        checkBoxImageAnswer.setValue(problem.imageAnswer);
        checkBoxImageChoice.setValue(problem.imageChoice);

        problemId = problem.id;

        if (problemId == PacketProblem.CREATING_PROBLEM_ID) {
            labelProblemNumber.setText("??");
            checkBoxRemovePlayerAnswers.setVisible(false);
        } else {
            labelProblemNumber.setText("??" + problemId + "??");
            checkBoxRemovePlayerAnswers.setVisible(true);
        }
        checkBoxResetAnswerCount.setValue(problem.needsResetAnswerCount);
        checkBoxResetVote.setValue(problem.needsResetVote);
        checkBoxRemovePlayerAnswers.setValue(problem.needsRemovePlayerAnswers);
        checkBoxResetAnswerCount.setVisible(!problem.isCopiedProblem());
        checkBoxRemovePlayerAnswers.setVisible(!problem.isCopiedProblem());
        checkBoxResetVote.setVisible(!problem.isCopiedProblem());

        if (problem.imageUrl != null) {
            textBoxExternalUrl.setText(problem.imageUrl);
            radioButtonImage.setValue(true);

        } else if (problem.movieUrl != null) {
            textBoxExternalUrl.setText(problem.movieUrl);
            radioButtonYouTube.setValue(true);

        } else {
            radioButtonNone.setValue(true);
        }

        // ?
        labelGood.setText(String.valueOf(problem.voteGood));

        // 
        // BugTrack-QMAClone/595 - QMAClone wiki
        // http://kishibe.dyndns.tv/qmaclone/wiki/wiki.cgi?page=BugTrack%2DQMAClone%2F595
        if (problem.isCopiedProblem()) {
            // ???????
            indication = null;
            indicationResolved = null;
        } else {
            if (problem.indication == null) {
                indication = null;
                indicationResolved = problem.indicationResolved;
                buttonIndicate.setVisible(true);
                checkBoxUnindicate.setVisible(false);
            } else {
                indication = problem.indication;
                indicationResolved = null;
                buttonIndicate.setVisible(false);
                checkBoxUnindicate.setVisible(true);
            }
        }

        checkBoxImageAnswer.setValue(false);

        // ?
        panelProblemFeedback.clear();
        if (problemId != PacketProblem.CREATING_PROBLEM_ID) {
            Service.Util.getInstance().getProblemFeedback(problemId, callbackGetProblemFeedback);
        }

        updateForm();
    }

    private final AsyncCallback<List<String>> callbackGetProblemFeedback = new AsyncCallback<List<String>>() {
        public void onSuccess(List<String> result) {
            panelProblemFeedback.add(
                    new HTML(new SafeHtmlBuilder().appendEscapedLines(Joiner.on('\n').join(result)).toSafeHtml()));

            if (!result.isEmpty()) {
                panelProblemFeedback.add(buttonClearProblemFeedback);
            }
        }

        public void onFailure(Throwable caught) {
            logger.log(Level.WARNING, "?????????", caught);
        }
    };

    private void updateForm() {
        ProblemType type = getSelectedType();

        creationUi.setTypeDescription(type.getDescription());

        for (TextBox textBox : textBoxChoice) {
            textBox.setEnabled(false);
            textBox.setVisible(false);
        }
        for (TextBox textBox : textBoxAnswer) {
            textBox.setEnabled(false);
            textBox.setVisible(false);
        }

        for (int i = 0; i < type.getNumberOfAnswers(); ++i) {
            textBoxAnswer[i].setEnabled(true);
            textBoxAnswer[i].setVisible(true);
        }
        for (int i = type.getNumberOfAnswers(); i < MAX_NUMBER_OF_ANSWERS; ++i) {
            textBoxAnswer[i].setText("");
        }

        for (int i = 0; i < type.getNumberOfChoices(); ++i) {
            textBoxChoice[i].setEnabled(true);
            textBoxChoice[i].setVisible(true);
        }
        for (int i = type.getNumberOfChoices(); i < MAX_NUMBER_OF_CHOICES; ++i) {
            textBoxChoice[i].setText("");
        }

        checkBoxImageAnswer.setVisible(type.isImageAnswer());
        checkBoxImageChoice.setVisible(type.isImageChoice());

        for (Button button : buttonPolygonCreation) {
            button.setVisible(type.isPolygonCreation());
        }

        if (radioButtonNone.getValue()) {
            textBoxExternalUrl.setText("");
            panelExternalUrl.setVisible(false);
        } else {
            panelExternalUrl.setVisible(true);
        }

        listBoxNumberOfDisplayedChoices.setVisible(type.isNumberOfDisplayedChoicesChangeable());
    }

    public void setEnable(boolean enabled) {
        List<FocusWidget> focusWidgets = Lists.newArrayList(listBoxGenre, listBoxType, listBoxRandomFlag,
                textAreaSentence, textBoxAnswer[0], textBoxAnswer[1], textBoxAnswer[2], textBoxAnswer[3],
                textBoxChoice[0], textBoxChoice[1], textBoxChoice[2], textBoxChoice[3], radioButtonNone,
                radioButtonImage, radioButtonYouTube, textBoxExternalUrl, textBoxCreator, textAreaNote,
                checkBoxResetAnswerCount, checkBoxImageChoice, checkBoxImageAnswer, checkBoxRemovePlayerAnswers,
                buttonClearProblemFeedback, checkBoxResetVote);
        focusWidgets.addAll(buttonPolygonCreation);

        for (FocusWidget focusWidget : focusWidgets) {
            focusWidget.setEnabled(enabled);
        }
    }

    /**
     * ???
     * 
     * @return ?
     */
    public PacketProblem getProblem() {
        PacketProblem problem = new PacketProblem();

        // ??
        problem.id = problemId;

        // ?
        problem.genre = ProblemGenre.values()[Integer
                .parseInt(listBoxGenre.getValue(listBoxGenre.getSelectedIndex()))];
        problem.type = getSelectedType();
        problem.randomFlag = RandomFlag.values()[listBoxRandomFlag.getSelectedIndex() + 1];

        // ?
        problem.setSentence(textAreaSentence.getText());

        // ?
        problem.answers = new String[MAX_NUMBER_OF_ANSWERS];
        for (int i = 0; i < MAX_NUMBER_OF_ANSWERS; ++i) {
            problem.answers[i] = emptyToNull(textBoxAnswer[i].getText().replaceAll("&", ""));

            if (problem.type == ProblemType.Typing || problem.type == ProblemType.Effect
                    || problem.type == ProblemType.Flash) {
                problem.answers[i] = StringUtils.toFullWidth(problem.answers[i]);
            }
        }

        // ?
        problem.choices = new String[MAX_NUMBER_OF_CHOICES];
        for (int i = 0; i < MAX_NUMBER_OF_CHOICES; ++i) {
            problem.choices[i] = emptyToNull(textBoxChoice[i].getText().replaceAll("&", ""));
        }

        if (problem.type == ProblemType.YonTaku || problem.type == ProblemType.Rensou) {
            problem.answers = new String[MAX_NUMBER_OF_ANSWERS];
            problem.answers[0] = problem.choices[0];
        }

        if (radioButtonImage.getValue()) {
            problem.imageUrl = textBoxExternalUrl.getText();
        } else if (radioButtonYouTube.getValue()) {
            problem.movieUrl = textBoxExternalUrl.getText();
        }

        // ???
        if (problem.type.isNumberOfDisplayedChoicesChangeable()) {
            problem.numberOfDisplayedChoices = Integer.valueOf(listBoxNumberOfDisplayedChoices
                    .getItemText(listBoxNumberOfDisplayedChoices.getSelectedIndex()));
        } else {
            problem.numberOfDisplayedChoices = 4;
        }

        // ?
        problem.creator = textBoxCreator.getText();

        // 
        String answerCount[] = labelAnswerCounter.getText().split("/");
        problem.good = Integer.parseInt(answerCount[0]);
        problem.bad = Integer.parseInt(answerCount[1]);
        problem.needsResetAnswerCount = checkBoxResetAnswerCount.getValue();
        problem.needsRemovePlayerAnswers = checkBoxRemovePlayerAnswers.getValue();

        // 
        problem.voteGood = Integer.valueOf(labelGood.getText());
        problem.needsResetVote = checkBoxResetVote.getValue();

        // 
        if (indication != null) {
            if (!checkBoxUnindicate.getValue()) {
                problem.indication = indication;
                problem.indicationResolved = null;
            } else {
                // ???
                problem.indication = null;
                problem.indicationResolved = new Date();
            }
        } else {
            problem.indication = null;
            problem.indicationResolved = indicationResolved;
        }

        // ?
        problem.note = textAreaNote.getText().trim();
        if (problem.note.length() > MAX_PROBLEM_NOTE_LENGTH) {
            problem.note = problem.note.substring(0, MAX_PROBLEM_NOTE_LENGTH);
        }

        problem.imageAnswer = isImageAnswer();
        problem.imageChoice = isImageChoice();

        return problem;
    }

    private ProblemType getSelectedType() {
        int selectedIndex = listBoxType.getSelectedIndex();
        String value = listBoxType.getValue(selectedIndex);
        return ProblemType.valueOf(value);
    }

    private void clearProblemFeedback() {
        if (problemId == PacketProblem.CREATING_PROBLEM_ID) {
            return;
        }

        panelProblemFeedback.clear();
        Service.Util.getInstance().clearProblemFeedback(problemId, callbackClearProblemFeedback);
    }

    private final AsyncCallback<Void> callbackClearProblemFeedback = new AsyncCallback<Void>() {
        @Override
        public void onSuccess(Void result) {
        }

        @Override
        public void onFailure(Throwable caught) {
            logger.log(Level.WARNING, "????????", caught);
        }
    };

    private boolean isImageAnswer() {
        ProblemType type = getSelectedType();
        return type.isImageAnswer() && checkBoxImageAnswer.getValue();
    }

    private boolean isImageChoice() {
        ProblemType type = getSelectedType();
        return type.isImageChoice() && checkBoxImageChoice.getValue();
    }

    @Override
    public void onClick(ClickEvent event) {
        Widget sender = (Widget) event.getSource();

        if (buttonPolygonCreation.contains(sender)) {
            final int answerIndex = buttonPolygonCreation.indexOf(sender);
            final DialogBoxPolygonCreation polygonCreation = new DialogBoxPolygonCreation(
                    textBoxChoice[0].getText(), textBoxAnswer[answerIndex].getText());
            polygonCreation.setPopupPosition(Window.getScrollLeft() + 10, Window.getScrollTop() + 10);
            polygonCreation.addDialogBoxPolygonCreationListener(new DialogBoxPolygonCreationListener() {
                public void onOk() {
                    textBoxAnswer[answerIndex].setText(polygonCreation.getPolygonDescription());
                }

                public void onCancel() {
                }
            });
            polygonCreation.show();
        } else if (sender == buttonClearProblemFeedback) {
            clearProblemFeedback();
        } else if (sender == radioButtonNone) {
            updateForm();
        } else if (sender == radioButtonImage) {
            updateForm();
        } else if (sender == radioButtonYouTube) {
            updateForm();
        } else if (sender == buttonIndicate) {
            onButtonIndicate();
        }
    }

    public void onButtonIndicate() {
        Service.Util.getInstance().getProblemIndicationEligibility(UserData.get().getUserCode(),
                callbackGetProblemIndicationEligibility);
    }

    private final AsyncCallback<ProblemIndicationEligibility> callbackGetProblemIndicationEligibility = new AsyncCallback<ProblemIndicationEligibility>() {
        @Override
        public void onSuccess(ProblemIndicationEligibility result) {
            switch (result) {
            case OK:
                indicate();
                break;

            case PLAYER_NAME_UNCHANGED:
                Window.alert("?????????????\n"
                        + "?????????????");
                break;

            case REACHED_MAX_NUMBER_OF_REQUESTS_PER_UNIT_TIME:
                Window.alert("?????????\n"
                        + "???????????");
                break;

            default:
                break;
            }
        }

        @Override
        public void onFailure(Throwable caught) {
            logger.log(Level.WARNING, "");
        }
    };

    private void indicate() {
        String prompt = Window.prompt("????????",
                "(????????)");
        if (prompt == null) {
            return;
        }

        final String message = prompt.trim();
        if (Strings.isNullOrEmpty(message)) {
            return;
        }

        if (indicationResolved != null
                && System.currentTimeMillis() < indicationResolved.getTime() + 7L * 24 * 60 * 60 * 1000) {
            // ???7??
            AsyncCallback<List<PacketBbsThread>> callbackGetBbsThreads = new AsyncCallback<List<PacketBbsThread>>() {
                @Override
                public void onSuccess(List<PacketBbsThread> result) {
                    if (result == null || result.isEmpty()) {
                        logger.log(Level.WARNING, "???????");
                        return;
                    }

                    PacketBbsThread thread = result.get(0);
                    PacketBbsResponse response = new PacketBbsResponse();
                    response.threadId = thread.id;
                    response.name = UserData.get().getPlayerName();
                    response.userCode = UserData.get().getUserCode();
                    response.dispInfo = 2;
                    response.postTime = System.currentTimeMillis();
                    response.body = message;

                    Service.Util.getInstance().writeToBbs(response, true, callbackBuildBbsThread);
                }

                @Override
                public void onFailure(Throwable caught) {
                }
            };
            Service.Util.getInstance().getBbsThreads(problemId, 0, 1, callbackGetBbsThreads);
        } else {
            // ????????????7????
            PacketBbsThread thread = new PacketBbsThread();
            thread.title = "??????? (" + Utility.toDateFormat(new Date()) + ")";
            PacketBbsResponse response = new PacketBbsResponse();
            response.body = message;
            response.dispInfo = 2; // ?
            response.name = UserData.get().getPlayerName();
            response.userCode = UserData.get().getUserCode();

            Service.Util.getInstance().buildBbsThread(problemId, thread, response, callbackBuildBbsThread);
        }
    }

    private final AsyncCallback<Void> callbackBuildBbsThread = new AsyncCallback<Void>() {
        @Override
        public void onSuccess(Void result) {
            creationUi.reloadBbs();
            indication = new Date();
            Service.Util.getInstance().indicateProblem(problemId, UserData.get().getUserCode(),
                    callbackPointOutInProblem);
        }

        @Override
        public void onFailure(Throwable caught) {
            logger.log(Level.WARNING, "BBS??????", caught);
        }
    };
    private final AsyncCallback<Void> callbackPointOutInProblem = new AsyncCallback<Void>() {
        @Override
        public void onSuccess(Void result) {
            indication = new Date();
            checkBoxUnindicate.setValue(false);
            setProblem(getProblem());

            if (UserData.get().isRegisterIndicatedProblem()) {
                Service.Util.getInstance().addProblemIdsToReport(UserData.get().getUserCode(),
                        ImmutableList.of(problemId), callbackAddProblemIdsToReport);
            }

            Window.alert("???????????");
        }

        @Override
        public void onFailure(Throwable caught) {
            logger.log(Level.WARNING, "??????", caught);
        }
    };
    private final AsyncCallback<Void> callbackAddProblemIdsToReport = new AsyncCallback<Void>() {
        @Override
        public void onSuccess(Void result) {
        }

        @Override
        public void onFailure(Throwable caught) {
            logger.log(Level.WARNING, "????????", caught);
        }
    };

    @Override
    public void onChange(ChangeEvent event) {
        Widget sender = (Widget) event.getSource();
        if (sender == listBoxType) {
            updateForm();
        }
    }

    public boolean isReserveResetAnswerCount() {
        return reserveResetAnswerCount;
    }
}