/*
* File : Complete.java
* Created : 24-oct-2001 17:01
* By : fbusquets
*
* JClic - Authoring and playing system for educational activities
*
* Copyright (C) 2000 - 2005 Francesc Busquets & Departament
* d'Educacio de la Generalitat de Catalunya
*
* 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 2 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 (see the LICENSE file).
*/
package edu.xtec.jclic.activities.text;
import edu.xtec.jclic.*;
import edu.xtec.jclic.media.EventSounds;
import edu.xtec.jclic.project.JClicProject;
import edu.xtec.util.Actions;
import edu.xtec.util.StrUtils;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
/**
*
* @author Francesc Busquets (fbusquets@xtec.cat)
* @version 13.09.16
*/
public class Complete extends TextActivityBase {
Evaluator ev;
/** Creates new Complete */
public Complete(JClicProject project) {
super(project);
ev=new ComplexEvaluator(project);
hasCheckButton=true;
}
@Override
public org.jdom.Element getJDomElement(){
org.jdom.Element e=super.getJDomElement();
e.addContent(ev.getJDomElement());
return e;
}
@Override
public void setProperties(org.jdom.Element e, Object aux) throws Exception{
super.setProperties(e, aux);
ev=Evaluator.getEvaluator(e.getChild(Evaluator.ELEMENT_NAME), project);
}
@Override
public void setProperties(edu.xtec.jclic.clic3.Clic3Activity c3a) throws Exception{
super.setProperties(c3a);
((ComplexEvaluator)ev).setProperties(c3a);
hasCheckButton=true;
}
@Override
public boolean needsKeyboard(){
return true;
}
@Override
public Activity.Panel getActivityPanel(PlayStation ps) {
return new Panel(ps);
}
class Panel extends TextActivityBase.Panel {
TextActivityDocument playDoc=null;
boolean locked;
int nActions;
protected Panel(PlayStation ps){
super(ps);
locked=true;
nActions=0;
}
@Override
protected void initDocument() throws Exception{
nActions=0;
if(tad!=null){
playing=false;
playDoc=new TextActivityDocument(styleContext);
tad.cloneDoc(playDoc, true, false, false);
pane.setStyledDocument(playDoc);
playDoc.attachTo(pane, Complete.Panel.this);
pane.setEnabled(true);
if(playDoc.tmb.size()>0){
pane.setEditable(true);
pane.requestFocus();
pane.getCaret().setVisible(true);
locked=false;
}
else{
locked=true;
pane.setEditable(false);
pane.getCaret().setVisible(false);
}
}
}
@Override
protected TextActivityPane buildPane(){
//CompletePane cp=new CompletePane(this);
CompletePane cp=new CompletePane();
cp.setActions();
return cp;
}
class CompletePane extends TextActivityPane{
//public CompletePane(Complete act){
protected CompletePane(){
super(Complete.Panel.this);
}
@Override
public boolean processMouse(MouseEvent e){
if(super.processMouse(e) && e.getID()==MouseEvent.MOUSE_PRESSED && playing && !locked)
return true;
return false;
}
protected void invalidateSelection(){
int offset=getCaret().getDot();
if(getCaret().getMark()!=offset)
getCaret().setDot(offset);
}
@Override
protected void fireCaretUpdate(CaretEvent e){
invalidateSelection();
super.fireCaretUpdate(e);
}
@Override
public void replaceSelection(String content){
invalidateSelection();
if(content!=null && content.length()>0){
char ch=content.charAt(0);
int offset=getCaret().getDot();
if(ch>=0x20 && ch!=0x7F){
try{
playDoc.insertString(offset, new String(new char[]{ch}), playDoc.getTargetAttributeSet());
} catch(BadLocationException ex){
System.err.println("Text activity error:\n"+ex);
}
}
}
}
@Override
public void cut(){
invalidateSelection();
}
@Override
public void paste(){
invalidateSelection();
}
boolean readyForActions(){
return playing && !locked && isEditable() && isEnabled();
}
// Actions
Action kitDeletePrevCharAction=null;
AbstractAction deletePrevCharAction=new AbstractAction(DefaultEditorKit.deletePrevCharAction){
public void actionPerformed(ActionEvent e){
if(readyForActions() && kitDeletePrevCharAction!=null){
invalidateSelection();
int offset=getCaret().getDot()-1;
if(offset>0 && playDoc.checkBooleanAttribute(offset, TextActivityDocument.TARGET)==true){
kitDeletePrevCharAction.actionPerformed(e);
}
}
}
};
Action kitDeleteNextCharAction=null;
AbstractAction deleteNextCharAction=new AbstractAction(DefaultEditorKit.deleteNextCharAction){
public void actionPerformed(ActionEvent e){
if(readyForActions() && kitDeleteNextCharAction!=null){
invalidateSelection();
int offset=getCaret().getDot();
if(offset>=0 && offset<playDoc.getLength() && playDoc.checkBooleanAttribute(offset, TextActivityDocument.TARGET)==true){
kitDeleteNextCharAction.actionPerformed(e);
}
}
}
};
protected void setActions(){
kitDeleteNextCharAction=getActionMap().get(DefaultEditorKit.deleteNextCharAction);
kitDeletePrevCharAction=getActionMap().get(DefaultEditorKit.deletePrevCharAction);
java.util.Map<String, Object[]> actionKeys=Actions.getActionKeys(this);
ActionMap am=new ActionMap();
am.setParent(getActionMap());
setActionMap(am);
Actions.mapAction(this, actionKeys, deletePrevCharAction);
Actions.mapAction(this, actionKeys, deleteNextCharAction);
}
}
@Override
protected void doCheck(boolean fromButton){
if(playDoc==null || locked)
return;
String match;
String current;
try {
match = StrUtils.trimEnding(tad.getText(0, tad.getLength()));
current = StrUtils.trimEnding(playDoc.getText(0, playDoc.getLength()));
} catch (BadLocationException e) {
System.err.println("Error: unable to retrieve text:\n"+e);
return;
}
byte[] result=ev.evalText(current, match);
int score=0;
if(result!=null){
int l=result.length;
int i=0;
while(i<l){
while(i<l && !playDoc.checkBooleanAttribute(i, TextActivityDocument.TARGET))
i++;
if(i<l){
nActions++;
boolean actionOk=true;
int j=i;
while(i<l && playDoc.checkBooleanAttribute(i, TextActivityDocument.TARGET))
i++;
playDoc.setCharacterAttributes(j, i-j, styleContext.getStyle(TextActivityDocument.TARGET), true);
for(int k=j; k<i; k++){
if(result[k]!=Evaluator.FLAG_OK){
actionOk=false;
playDoc.setCharacterAttributes(k, 1, styleContext.getStyle(TextActivityDocument.TARGET_ERROR), false);
}
}
if(actionOk)
score++;
}
}
}
ps.setCounterValue(SCORE_COUNTER, score);
ps.setCounterValue(ACTIONS_COUNTER, nActions);
if(Evaluator.isOk(result))
finishActivity(true);
else
if(fromButton)
playEvent(EventSounds.FINISHED_ERROR);
}
@Override
public void finishActivity(boolean result){
pane.setEditable(false);
pane.setEnabled(false);
super.finishActivity(result);
}
}
}