package org.geogebra.web.web.gui.util;
import org.geogebra.common.gui.inputfield.AltKeys;
import org.geogebra.common.main.Feature;
import org.geogebra.common.main.GWTKeycodes;
import org.geogebra.web.html5.Browser;
import org.geogebra.web.html5.gui.HasKeyboardTF;
import org.geogebra.web.html5.gui.inputfield.FieldHandler;
import org.geogebra.web.html5.main.AppW;
import org.geogebra.web.html5.main.GlobalKeyDispatcherW;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
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.user.client.ui.TextArea;
/** Class for future syntax highlighting, line numbering and so on. */
public class ScriptArea extends TextArea
implements KeyPressHandler,
KeyDownHandler, KeyUpHandler, HasKeyboardTF {
private boolean dummyCursor = false;
/**
* Creates new script area
*/
public ScriptArea() {
setStyleName("scriptArea");
addKeyPressHandler(this);
addKeyDownHandler(this);
addKeyUpHandler(this);
}
@Override
public void onKeyUp(KeyUpEvent e) {
if (e.isAltKeyDown() && !e.isControlKeyDown()) {
String s = AltKeys.getAltSymbols((char) e.getNativeKeyCode(),
e.isShiftKeyDown(), true);
if (s != null) {
insertString(s);
}
}
}
private void setText(int start, int end, String text) {
// clear selection if there is one
if (start != end) {
String oldText = getText();
StringBuilder sb = new StringBuilder();
sb.append(oldText.substring(0, start));
sb.append(oldText.substring(end));
setText(sb.toString());
setCursorPos(start);
}
int pos = getCursorPos();
String oldText = getText();
StringBuilder sb = new StringBuilder();
sb.append(oldText.substring(0, pos));
sb.append(text);
sb.append(oldText.substring(pos));
setText(sb.toString());
// setCaretPosition(pos + text.length());
final int newPos = pos + text.length();
setCursorPos(newPos, false);
}
private int getSelectionEnd() {
return getSelectionStart() + getSelectionLength();
}
private int getSelectionStart() {
return getText().indexOf(getSelectedText());
}
/**
* @param caretPos
* caret position
* @param moveDummyCursor
* whether dummy cursor needs to be moved
*/
public void setCursorPos(int caretPos, boolean moveDummyCursor) {
if (dummyCursor && moveDummyCursor) {
if (caretPos == this.getText().length()) {
return;
}
removeDummyCursor();
addDummyCursor(caretPos);
} else {
setSelectionRange(caretPos, 0);
}
}
@Override
public void setCursorPos(int pos){
setCursorPos(pos, true);
}
/**
* @param text
* inserted text
*/
public void insertString(String text) {
int start = getSelectionStart();
int end = getSelectionEnd();
setText(start, end, text);
// if (insertHandler != null) {
// insertHandler.onInsert(text);
// }
}
@Override
public void onKeyDown(KeyDownEvent e) {
if (GlobalKeyDispatcherW.isBadKeyEvent(e)
|| e.getNativeKeyCode() == GWTKeycodes.KEY_F1) {
e.preventDefault();
}
}
@Override
public void onKeyPress(KeyPressEvent e) {
if (GlobalKeyDispatcherW.isBadKeyEvent(e)) {
e.preventDefault();
e.stopPropagation();
return;
}
}
@Override
public void startOnscreenKeyboardEditing() {
if (Browser.isAndroid()) {
addDummyCursor();
}
}
@Override
public void endOnscreenKeyboardEditing() {
if (Browser.isAndroid()) {
removeDummyCursor();
}
}
@Override
public void addDummyCursor() {
if (dummyCursor) {
return;
}
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
@Override
public void execute() {
int caretPos = getCursorPos();
addDummyCursor(caretPos);
}
});
}
@Override
public int removeDummyCursor() {
if (!dummyCursor) {
return -1;
}
String text = getText();
int cpos = getCursorPos();
text = text.substring(0, cpos) + text.substring(cpos + 1);
setValue(text);
dummyCursor = false;
return cpos;
}
/**
* @param caretPos
* caret position
*/
public void addDummyCursor(int caretPos) {
if (dummyCursor) {
return;
}
String text = getText();
text = text.substring(0, caretPos) + '|' + text.substring(caretPos);
setValue(text);
setCursorPos(caretPos);
dummyCursor = true;
}
@Override
public void setFocus(boolean focus, boolean scheduled) {
// TODO Auto-generated method stub
}
@Override
public void ensureEditing() {
// TODO Auto-generated method stub
}
@Override
public void onEnter(boolean b) {
// TODO Auto-generated method stub
}
@Override
public boolean needsAutofocus() {
// TODO Auto-generated method stub
return false;
}
/**
* @param app
* application
*/
public void enableGGBKeyboard(final AppW app) {
if (!app.has(Feature.KEYBOARD_BEHAVIOUR)) {
return;
}
if (Browser.isTabletBrowser()) {
// avoid native keyboard opening
setReadOnly(true);
}
addFocusHandler(new FocusHandler() {
@Override
public void onFocus(FocusEvent event) {
FieldHandler.focusGained(ScriptArea.this, app);
}
});
addBlurHandler(new BlurHandler() {
@Override
public void onBlur(BlurEvent event) {
FieldHandler.focusLost(ScriptArea.this, app);
}
});
}
}