package tv.dyndns.kishibe.qmaclone.client.game.input;
import java.util.Set;
import tv.dyndns.kishibe.qmaclone.client.GlobalKeyEventHandler;
import tv.dyndns.kishibe.qmaclone.client.game.AnswerView;
import tv.dyndns.kishibe.qmaclone.client.game.LetterType;
import tv.dyndns.kishibe.qmaclone.client.game.SessionData;
import tv.dyndns.kishibe.qmaclone.client.game.panel.QuestionPanel;
import tv.dyndns.kishibe.qmaclone.client.packet.PacketProblem;
import tv.dyndns.kishibe.qmaclone.client.util.StringUtils;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Sets;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
public class InputWidgetTypingQwerty extends InputWidget implements ClickHandler {
private static final String STYLE_NAME_LETTER = "gwt-Button-typing";
private static final String STYLE_NAME_CONTROL = "gwt-Button-typingControl";
private static final String[] LETTERS = { "1234567890-", "QWERTYUIOP", "ASDFGHJKL", "ZXCVBNM" };
private static final String ACCEPTED_KEYS = "1234567890-QWERTYUIOPASDFGHJKLZXCVBNM";
private final LetterType letterType;
private final Set<Button> buttons = Sets.newHashSet();
private final Button buttonDelete = new Button("消す", this);
private final Button buttonOk = new Button("OK", this);
private HandlerRegistration globalKeyHandlerRegistration;
public InputWidgetTypingQwerty(PacketProblem problem, AnswerView answerView,
QuestionPanel questionPanel, LetterType letterType, SessionData sessionData) {
super(problem, answerView, questionPanel, sessionData);
this.letterType = letterType;
setHorizontalAlignment(ALIGN_LEFT);
for (int row = 0; row < LETTERS.length; ++row) {
HorizontalPanel panel = new HorizontalPanel();
HTML space = new HTML();
space.setPixelSize(row * 20, 1);
panel.add(space);
String letters = LETTERS[row];
for (int column = 0; column < letters.length(); ++column) {
Button button = new Button(letters.substring(column, column + 1), this);
button.setStyleName(STYLE_NAME_LETTER);
panel.add(button);
buttons.add(button);
}
if (row + 1 == LETTERS.length) {
panel.add(buttonDelete);
panel.add(buttonOk);
buttonDelete.setStyleName(STYLE_NAME_CONTROL);
buttonOk.setStyleName(STYLE_NAME_CONTROL);
}
add(panel);
}
}
@Override
public void enable(boolean b) {
for (Button button : buttons) {
button.setEnabled(b);
}
buttonDelete.setEnabled(b);
buttonOk.setEnabled(b);
}
@Override
public void onClick(ClickEvent event) {
Button source = (Button) event.getSource();
if (buttons.contains(source)) {
// 文字ボタン
String letter = source.getText();
addLetterToAnswer(letter);
} else if (source == buttonDelete) {
// 消すボタン
onErase();
} else if (source == buttonOk) {
// OKボタン
onOk();
} else {
throw new AssertionError();
}
}
private void onKey(char ch) {
if (!buttonOk.isEnabled()) {
return;
}
System.out.println("key='" + ch + "' (" + (int) ch + ")");
System.out.println("enter=(" + (int) '\n' + ")");
System.out.println("bs=(" + (int) '\b' + ")");
// Enter == OKボタン
if (ch == '\n' || ch == '\r') {
// 1問につき複数回解答が送信できてしまうバグへの対処
if (buttonOk.isEnabled()) {
onOk();
}
return;
}
// Back Space == 消すボタン
if (ch == '\b') {
onErase();
return;
}
String letter = "" + ch;
letter = letter.toUpperCase();
if (!ACCEPTED_KEYS.contains(letter)) {
return;
}
letter = StringUtils.toFullWidth(letter);
addLetterToAnswer(letter);
}
private void onErase() {
String answer = answerView.get();
answer = StringUtils.removeLast(answer);
answerView.set(answer, true);
}
private void onOk() {
enable(false);
String answer = answerView.get();
if (letterType != LetterType.Alphabet) {
answer = StringUtils.convertLastAlphabetToKanaBeforeSendAnswer(answer,
letterType == LetterType.Hiragana ? LetterType.Hiragana : LetterType.Katakana);
}
answerView.set(answer, true);
sendAnswer(answer);
}
@VisibleForTesting
void addLetterToAnswer(String letter) {
String answer = answerView.getRaw();
answer += letter;
switch (letterType) {
case Alphabet:
break;
case Hiragana:
answer = StringUtils.convertLastAlphabetToKana(answer, LetterType.Hiragana);
break;
case Katakana:
answer = StringUtils.convertLastAlphabetToKana(answer, LetterType.Katakana);
break;
}
answerView.set(answer, true);
}
@Override
protected void onLoad() {
super.onLoad();
globalKeyHandlerRegistration = Event.addNativePreviewHandler(new GlobalKeyEventHandler() {
@Override
protected void onKeyPress(char ch) {
onKey(ch);
}
});
}
@Override
protected void onUnload() {
if (globalKeyHandlerRegistration != null) {
globalKeyHandlerRegistration.removeHandler();
globalKeyHandlerRegistration = null;
}
super.onUnload();
}
}