/*
* Copyright (C) 2011 Alasdair C. Hamilton
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package ketUI.responder;
import geom.Position;
import ket.Message;
import ket.Selection;
import ket.math.Argument;
import ket.math.Token;
import ket.math.purpose.Word;
import ket.math.purpose.Text;
import ketUI.MouseButton;
import ketUI.MouseEventHandler;
import ketUI.chord.Chord;
import ketUI.chord.KeyboardEventHandler;
import ketUI.chord.Macros;
import ketUI.modes.DocumentState;
import ketUI.modes.Modes;
import ket.math.Equation;
/**
* Various message types can be displayed within ket and this class delegates chord events to the various classes.
*/
public class EchoResponder extends Responder {
final Modes modes;
Presentation presentation;
public EchoResponder(Modes modes) {
this.modes = modes;
Presentation presentation = null;
}
@Override
public void prepareToRespond() {
// Do nothing.
if (modes.getDocumentState()==DocumentState.INTERACT) {
presentation = new Presentation();
presentation.start();
}
}
@Override
public void cleanAfterRespond() {
getMessage().cancelAndClear();
if (presentation!=null) {
presentation.done();
presentation = null;
}
}
@Override
public void respondToChordEvent(Chord chord, Macros macros, KeyboardEventHandler keyboardEventHandler) {
// Messages are displayed until cleared with a key press.
switch (modes.getDocumentState()) {
case ECHO_ERROR:
// TODO: Is this the appropriate place to do this?
chord.setError(true);
chord.setComplete(true);
break;
case ECHO_FEEDBACK:
chord.setComplete(true);
break;
case INTERACT:
//- Selection s = modes.getSelection();
//- s.replace(new Token(new Text("random: " + Math.random())));
presentation.poke();
break;
}
}
@Override
public void respondToMouseClick(MouseButton mouseButton, boolean singleClick, Position p) {
switch (modes.getDocumentState()) {
case ECHO_ERROR:
modes.setDocumentState(DocumentState.NORMAL);
break;
case ECHO_FEEDBACK:
modes.setDocumentState(DocumentState.NORMAL);
break;
case ECHO_VIEW:
// Stay in view until modes.setDocumentState() is called.
break;
case INTERACT:
System.out.println(getSelection().getCurrent()); //?
break;
}
}
class Presentation extends Thread {
Argument target;
Argument argument;
String[] titles = new String[] { //ish
"Welcome!",
"This is an short presentation",
"How to integrate: ln(x).",
"Use the chain rule",
"Differentiate, simplify and integrate"};
String[] acts = new String[] { //ish
"integral(ln(x),x)",
"integral(x'x*ln(x),x)",
"x*ln(x)-integral(x*ln(x)'x,x)",
"x*ln(x)-integral(x/x,x)",
"x*ln(x)-x"};
int i;
boolean loop;
public Presentation() {
i = 0;
loop = true;
target = new Token(new Text("goal:"));
argument = parse("integral(ln:x, x)");
getSelection().getCurrent().getEquation().addBefore(new Equation(target));
getSelection().getCurrent().getEquation().addBefore(new Equation(argument));
}
public Argument parse(String s) {
return modes.getDocument().parseArgument(s);
}
@Override
public void run() {
try {
while (loop) {
update();
System.out.print(".");
synchronized (this) {
wait(1000);
}
}
} catch (InterruptedException ie) {
System.out.println("[Presentation thread interupted]");
}
}
public synchronized void update() {
// BUG: What if you've selected this?
if (getSelection().getCurrent()==target || getSelection().getCurrent()==argument) {
getSelection().appendEquation(new Equation());
}
synchronized (getSelection()) {
synchronized (target) {
Argument u = new Token(new Text((titles[i])));
target.replace(u);
target = u;
}
synchronized (argument) {
Argument v = parse(acts[i]);
argument.replace(v);
argument = v;
}
getSelection().replace(new Token(Math.random()));
modes.getDocument().updateAndRepaint();
}
}
public void poke() { //?
i = (i+1) % acts.length;
synchronized (this) {
notify();
}
}
public void done() {
loop = false;
}
}
public Selection getSelection() {
return modes.getSelection();
}
@Override
public void respondToMouseDrag(MouseButton mouseButton, Position initial, Position release) {
// Do nothing.
}
private Message getMessage() {
return modes.getMessage();
}
}