Logo Search packages:      
Sourcecode: jclic version File versions  Download package

Activity.java

/*
 * File    : Activity.java
 * Created : 16-aug-2001 1:05
 * 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;

import edu.xtec.jclic.automation.AutoContentProvider;
import edu.xtec.jclic.bags.MediaBagElement;
import edu.xtec.jclic.boxes.ActiveBagContent;
import edu.xtec.jclic.boxes.ActiveBoxBag;
import edu.xtec.jclic.boxes.ActiveBoxContent;
import edu.xtec.jclic.boxes.BoxBase;
import edu.xtec.jclic.boxes.BoxConnector;
import edu.xtec.jclic.boxes.TextGridContent;
import edu.xtec.jclic.clic3.Clic3Activity;
import edu.xtec.jclic.edit.Editable;
import edu.xtec.jclic.edit.Editor;
import edu.xtec.jclic.media.EventSounds;
import edu.xtec.jclic.misc.Gradient;
import edu.xtec.jclic.project.JClicProject;
import edu.xtec.jclic.skins.Skin;
import edu.xtec.util.Domable;
import edu.xtec.util.Html;
import edu.xtec.util.JDomUtility;
import edu.xtec.util.ResourceBridge;
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Iterator;
import java.util.StringTokenizer;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;


/**
 * <CODE>Activity</CODE> is the abstract base class for JClic activities. It
 * defines also the inner class {@link edu.xtec.jclic.Activity.Panel}, wich is
 * responsible of the user interaction with the activity content.
 * Activities should extend both <CODE>Activity</CODE> and
 * <CODE>Activity.Panel</CODE> classes in order to become fully operative.
 * JClic stores activities in memory as {@link org.JDom.Element} objects. So,
 * all non-transient data must be stored to and retrieved from JDom elements.
 * @author Francesc Busquets (fbusquets@xtec.net)
 * @version 1.0
 */

00075 public abstract class Activity extends Object implements Constants, Editable, Domable {
    
    /**
     * The {@link JClicProject} this activity belongs to.
     */
00080     protected JClicProject project;
    
    // public fields
    /**
     * The activity name
     */
00086     public String name=DEFAULT_NAME;
    
    /**
     * Code used in reports to filter queries. Default is <I>null</I>.
     */
00091     public String code;
    
    /**
     * Description of the activity.
     */
00096     public String description;
    
    /**
     * Space, measured in pixels, between the activity components.
     */
00101     public int margin=DEFAULT_MARGIN;
    
    /**
     * Background color of the activity panel.
     */
00106     public Color bgColor=DEFAULT_BG_COLOR;
    
    /**
     * Gradient used to draw the background of the activity panel.
     */
00111     public Gradient bgGradient;
    
    /**
     * Whether the bgImage (if any) has to be tiled across the panel background.
     */
00116     public boolean tiledBgImg;
    
    /**
     * Filename of the image painted in the panel background. Default is <I>null</I>.
     */
00121     public String bgImageFile;
    
    /**
     * Whether to draw a border around the activity panel.
     */
00126     public boolean border=true;
    
    /**
     * Whether to place the activity panel at the point specified by {@link
     * absolutePosition}, or leave it centered in the main window of the player.
     */
00132     public boolean absolutePositioned;
    
    /** Position of the activity panel into the {@link ActivityContainer}.
     */
00136     public Point absolutePosition;
    
    /**
     * Whether to generate usage reports.
     */
00141     public boolean includeInReports=true;
    
    /**
     * Whether to send action events to the {@link Reporter}.
     */
00146     public boolean reportActions;
    
    
    /**
     * Whether to have a help window or not.
     */
00152     public boolean helpWindow;
    
    /**
     * Whether to show the solution on the help window.
     */
00157     public boolean showSolution;
    
    /**
     * Message to show in the help window when {@link showSolution} is <CODE>false</CODE>.
     */
00162     public String helpMsg;
    
    /**
     * Specific set of {@link EventSounds} used in the activity. The default is <CODE>null</CODE>,
     * meaning to use the {@link ActivityContainer} sounds.
     */
00168     public EventSounds eventSounds=new EventSounds(null);
    
    /**
     * Wheter the activity must be solved in a specific order. The default is <CODE>false</CODE>.
     */
00173     public boolean useOrder;
    
    /**
     * Wheter the cells of the activity will be dragged across the screen. When <CODE>false</CODE>,
     * a line will be painted to link elements.
     */
00179     public boolean dragCells;
    
    /**
     * File name of the Skin used by the activity. The default value is null, meaning
     * that the activity will use the skin specified for the project.
     */
00185     public String skinFileName;
    /**
     * Maximum amount of time (seconds) to solve the activity. The default value is <CODE>0</CODE>,
     * meaning unlimited time.
     */
00190     public int maxTime;
    /**
     * Whether the time counter should display a countdown when {@link maxTime} > 0.
     */
00194     public boolean countDownTime;
    /**
     * Maximum number of actions allowed to solve the activity. The default value is <CODE>0</CODE>,
     * meaning unlimited actions.
     */
00199     public int maxActions;
    /**
     * Whether the actions counter should display a countdown when {@link maxActions} > 0.
     */
00203     public boolean countDownActions;
    /**
     * String with the URL to be displayed when the user clicks on the <I>info</I> button.
     * Default is <CODE>null</CODE>.
     */
00208     public String infoUrl;
    /**
     * System command to be executed when the user clicks the <I>info</I> button. Default is
     * <CODE>null</CODE>. Applets have this function disabled.
     */
00213     public String infoCmd;
    
    // protected fields
    /**
     * String labels corresponding to the four identifiers of JClic messages:
     * PREVIOUS, MAIN, END and END_ERROR.
     */
00220     public static final String[] MSG_TYPE={"previous", "initial", "final", "finalError"};
    
    /**
     * Identifier of the message displayed before the activity starts. Used only in
     * certain types of activities.
     */
00226     public static final int PREVIOUS = 0;
    
    /**
     * Identifier of the main message, displayed as long as the activity is playing.
     */
00231     public static final int MAIN = 1;
    
    /**
     * Identifier of the message displayed when the user successfully ends the
     * activity.
     */
00237     public static final int END = 2;
    
    /**
     * Identifier of the message displayed when the user exceeds the maximum amount of time
     * or actions allowed.
     * @see maxTime
     * @see maxActions
     */
00245     public static final int END_ERROR = 3;
    
    /**
     * Number of message types.
     */
00250     public static final int     NUM_MSG=4;
    
    protected ActiveBoxContent[] messages=new ActiveBoxContent[NUM_MSG];
    protected Dimension windowSize=new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    protected boolean transparentBg;
    protected Color activityBgColor=DEFAULT_BG_COLOR;
    protected Gradient activityBgGradient;
    protected boolean bTimeCounter=true;
    protected boolean bScoreCounter=true;
    protected boolean bActionsCounter=true;
    protected int shuffles=DEFAULT_SHUFFLES;
    protected AutoContentProvider acp;
    
    // fields used only by certain activity types
    public ActiveBagContent[] abc;
    public TextGridContent tgc;
    public int boxGridPos;
    public boolean[] scramble=new boolean[2];
    public boolean invAss;
    
    // static fields
    
    // layout constants
    public static final int AB=0, BA=1, AUB=2, BUA=3;
    public static final String[] LAYOUT_NAMES={"AB", "BA", "AUB", "BUA"};
    
    public static final int DEFAULT_WIDTH=400;
    public static final int DEFAULT_HEIGHT=300;
    public static final int MINIMUM_WIDTH=40;
    public static final int MINIMUM_HEIGHT=40;
    public static final String DEFAULT_NAME="---";
    public static final int DEFAULT_MARGIN=8;
    public static final int DEFAULT_SHUFFLES=31;
    public static final int DEFAULT_GRID_ELEMENT_SIZE=20;
    public static final Color DEFAULT_BG_COLOR=Color.lightGray;
    
    
    // Constants for actions
    public static final String ACTION_MATCH="MATCH", ACTION_PLACE="PLACE", 
    ACTION_WRITE="WRITE", ACTION_SELECT="SELECT", ACTION_HELP="HELP";
    
    // Constants for XML fields
    public static final String ELEMENT_NAME="activity", NAME="name";
    public static final String BASE_CLASS="edu.xtec.jclic.activities.", BASE_CLASS_TAG="@";
00294     public static final String ID="id", CODE="code", DESCRIPTION="description",
    MESSAGES="messages", TYPE="type",
    //PREVIOUS="previous", INITIAL="initial", FINAL="final", FINAL_ERROR="finalError",
    SETTINGS="settings", LAYOUT="layout", MARGIN="margin",
    CONTAINER="container", BGCOLOR="bgColor", IMAGE="image", TILED="tiled",
    COUNTERS="counters", TIME="time", ACTIONS="actions", SCORE="score",
    WINDOW="window", TRANSPARENT="transparent", BORDER="border",
    POSITION="position", X="x", Y="y", SIZE="size", WIDTH="width", HEIGHT="height",
    PRIMARY="primary", SECONDARY="secondary",
    SOLVED_PRIMARY="solvedPrimary", SOLVED_SECONDARY="solved_secondary",
    GRID="grid", ROW="row", CLUES="clues", CLUE="clue", RANDOM_CHARS="random_chars",
    SCRAMBLE="scramble", TIMES="times", REPORT="report", REPORT_ACTIONS="reportActions",
    HELP_WINDOW="helpWindow", HELP_SHOW_SOLUTION="showSolution", USE_ORDER="useOrder",
00307     DRAG_CELLS="dragCells", SKIN="skin", FILE="file",
    MAX_TIME="maxTime", COUNT_DOWN_TIME="countDownTime",
    MAX_ACTIONS="maxActions", COUNT_DOWN_ACTIONS="countDownActions",
    INFO_URL="infoUrl", INFO_CMD="infoCmd";
    
    public static final String[][] COMPATIBLE_ACTIVITIES = new String[][]{
        new String[]{
            "@puzzles.DoublePuzzle",
            "@puzzles.ExchangePuzzle",
            "@puzzles.HolePuzzle",
            "@memory.MemoryGame",
            "@associations.SimpleAssociation",
            "@associations.ComplexAssociation",
            "@panels.Explore",
            "@panels.Identify",
            "@panels.InformationScreen",
            "@text.WrittenAnswer"
        },
        new String[]{
            "@text.FillInBlanks",
            "@text.Identify",
            "@text.Order",
            "@text.Complete",
        }
    };
    
    
    /** Creates new edu.xtec.jclicActivity */
00335     public Activity(JClicProject project) {
        this.project=project;
    }
    
    public void initNew(){
        name=project.getBridge().getMsg("UNNAMED");
    }
    
    public String getPublicName(){
        return name;
    }
    
    public JClicProject getProject(){
        return project;
    }
    
00351     public Editor getEditor(Editor parent){
        Editor result=null;
        String s=getClass().getName()+"Editor";
        try{
            Class.forName(s);
        } catch(ClassNotFoundException ex){
            s="edu.xtec.jclic.ActivityEditor";
        }
        return Editor.createEditor(s, this, parent);
    }
    
    public String getShortClassName(){
        String s=getClass().getName();
        if(s.startsWith(BASE_CLASS))
            s=BASE_CLASS_TAG+s.substring(BASE_CLASS.length());
        return s;
    }
    
    public String[] getSimilarActivityClasses(){
        String[] result=null;
        String cl=getShortClassName();
        for(int i=0; i<COMPATIBLE_ACTIVITIES.length; i++){
            String[] classGroup=COMPATIBLE_ACTIVITIES[i];
            for(int j=0; j<classGroup.length; j++){
                if(cl.equals(classGroup[j])){
                    result=classGroup;
                    break;
                }
            }
        }
        if(result==null){
            result=new String[]{cl};
        }
        return result;
    }
    
    public org.jdom.Element getJDomElement(){
        org.jdom.Element child, child2, child3;
        org.jdom.Element e=new org.jdom.Element(ELEMENT_NAME);
        
        e.setAttribute(JDomUtility.CLASS, getShortClassName());
        e.setAttribute(NAME, name);
        if(code!=null) e.setAttribute(CODE, code);
        if(description!=null) JDomUtility.addParagraphs(e, DESCRIPTION, description);
        
        child=new org.jdom.Element(MESSAGES);
        for(int i=0; i<NUM_MSG; i++)
            if(messages[i]!=null)
                child.addContent(messages[i].getJDomElement().setAttribute(TYPE, MSG_TYPE[i]));
        e.addContent(child);
        
        child=new org.jdom.Element(SETTINGS);
        
        child.setAttribute(MARGIN, Integer.toString(margin));
        
        if(infoUrl!=null && infoUrl.length()>0)
            child.setAttribute(INFO_URL, infoUrl);
        else if(infoCmd!=null && infoCmd.length()>0)
            child.setAttribute(INFO_CMD, infoCmd);
        
        if(useOrder)
            child.setAttribute(USE_ORDER, JDomUtility.boolString(useOrder));
        if(dragCells)
            child.setAttribute(DRAG_CELLS, JDomUtility.boolString(dragCells));
        if(maxTime>0){
            child.setAttribute(MAX_TIME, Integer.toString(maxTime));
            child.setAttribute(COUNT_DOWN_TIME, JDomUtility.boolString(countDownTime));
        }
        if(maxActions>0){
            child.setAttribute(MAX_ACTIONS, Integer.toString(maxActions));
            child.setAttribute(COUNT_DOWN_ACTIONS, JDomUtility.boolString(countDownActions));
        }
        child.setAttribute(REPORT, JDomUtility.boolString(includeInReports));
        if(includeInReports)
            child.setAttribute(REPORT_ACTIONS, JDomUtility.boolString(reportActions));
        if(helpWindow){
            child2=new org.jdom.Element(HELP_WINDOW);
            boolean hsa=helpSolutionAllowed();
            if(hsa)
                child2.setAttribute(HELP_SHOW_SOLUTION, JDomUtility.boolString(showSolution));
            if(helpMsg!=null && (!hsa || !showSolution))
                JDomUtility.setParagraphs(child2, helpMsg);
            child.addContent(child2);
        }
        child2=new org.jdom.Element(CONTAINER);
        child2.setAttribute(BGCOLOR, JDomUtility.colorToString(bgColor));
        if(bgGradient!=null)
            child2.addContent(bgGradient.getJDomElement());
        
        if(bgImageFile!=null && bgImageFile.length()>0){
            child3=new org.jdom.Element(IMAGE);
            child3.setAttribute(NAME, bgImageFile);
            child3.setAttribute(TILED, JDomUtility.boolString(tiledBgImg));
            child2.addContent(child3);
        }
        
        child3=new org.jdom.Element(COUNTERS);
        child3.setAttribute(TIME, JDomUtility.boolString(bTimeCounter));
        child3.setAttribute(ACTIONS, JDomUtility.boolString(bActionsCounter));
        child3.setAttribute(SCORE, JDomUtility.boolString(bScoreCounter));
        child2.addContent(child3);
        
        child.addContent(child2);
        
        child2=new org.jdom.Element(WINDOW);
        child2.setAttribute(BGCOLOR, JDomUtility.colorToString(activityBgColor));
        if(activityBgGradient!=null)
            child2.addContent(activityBgGradient.getJDomElement());
        if(transparentBg) child2.setAttribute(TRANSPARENT, JDomUtility.boolString(transparentBg));
        child2.setAttribute(BORDER, JDomUtility.boolString(border));
        
        if(absolutePositioned && absolutePosition!=null){
            child3=new org.jdom.Element(POSITION);
            child3.setAttribute(X, Integer.toString(absolutePosition.x));
            child3.setAttribute(Y, Integer.toString(absolutePosition.y));
            child2.addContent(child3);
        }
        
        if(windowSize.width!=DEFAULT_WIDTH || windowSize.height!=DEFAULT_HEIGHT){
            child3=new org.jdom.Element(SIZE);
            child3.setAttribute(WIDTH, Integer.toString(windowSize.width));
            child3.setAttribute(HEIGHT, Integer.toString(windowSize.height));
            child2.addContent(child3);
        }
        child.addContent(child2);
        
        if((child2=eventSounds.getJDomElement())!=null)
            child.addContent(child2);
        
        if(skinFileName!=null){
            child2=new org.jdom.Element(SKIN);
            child2.setAttribute(FILE, skinFileName);
            //if(skin!=null && skin.name!=null && skin.name.length()>0)
            //    child2.setAttribute(NAME, skin.name);
            child.addContent(child2);
        }
        
        e.addContent(child);
        
        if(acp!=null)
            e.addContent(acp.getJDomElement());
        
        return e;
    }
    
    public static Activity getActivity(Object o, JClicProject project) throws Exception{
        Activity act=null;
        org.jdom.Element e=null;
        Clic3Activity c3a=null;
        String className;
        String s;
        
        //if(o.getClass()==org.jdom.Element.class){
        if(o instanceof org.jdom.Element){
            e=(org.jdom.Element)o;
            JDomUtility.checkName(e, ELEMENT_NAME);
            className=JDomUtility.getClassName(e);
        }
        //else if(o.getClass()==Clic3Activity.class){
        else if(o instanceof Clic3Activity){
            c3a=(Clic3Activity)o;
            className=c3a.className;
        }
        else if(o instanceof String){
            className=(String)o;
        }
        else
            throw new Exception("unknown data!!");
        
        Class activityClass;
        Constructor con;
        Class[] cparams={JClicProject.class};
        Object[] initArgs={project};
        if(className.startsWith(BASE_CLASS_TAG))
            className=BASE_CLASS+className.substring(1);
        activityClass=Class.forName(className);
        con=activityClass.getConstructor(cparams);
        act=(Activity)con.newInstance(initArgs);
        if(e!=null)
            act.setProperties(e, null);
        else if(c3a!=null)
            act.setProperties(c3a);
        else
            act.initNew();
        return act;
    }
    
    public Activity duplicate() throws Exception{
        return Activity.getActivity(getJDomElement(), project);
    }
    
    public void setProperties(org.jdom.Element e, Object aux) throws Exception{
        org.jdom.Element child, child2, child3;
        
        JDomUtility.checkName(e, ELEMENT_NAME);
        
        name=JDomUtility.getStringAttr(e, NAME, name, false);
        code=JDomUtility.getStringAttr(e, CODE, code, false);
        
        if((child=e.getChild(DESCRIPTION))!=null)
            description=JDomUtility.getParagraphs(child);
        
        if((child=e.getChild(MESSAGES))!=null){
            Iterator itr = child.getChildren(ActiveBoxContent.ELEMENT_NAME).iterator();
            while (itr.hasNext()){
                child2=((org.jdom.Element)itr.next());
                int i=JDomUtility.getStrIndexAttr(child2, TYPE, MSG_TYPE, -1);
                if(i>=0)
                    messages[i]=ActiveBoxContent.getActiveBoxContent(child2, project.mediaBag);
            }
        }
        
        if((child=e.getChild(SETTINGS))!=null){
            margin=JDomUtility.getIntAttr(child, MARGIN, margin);
            infoUrl=JDomUtility.getStringAttr(child, INFO_URL, infoUrl, false);
            if(infoUrl==null)
                infoCmd=JDomUtility.getStringAttr(child, INFO_CMD, infoCmd, false);
            useOrder=JDomUtility.getBoolAttr(child, USE_ORDER, useOrder);
            dragCells=JDomUtility.getBoolAttr(child, DRAG_CELLS, dragCells);
            maxTime=JDomUtility.getIntAttr(child, MAX_TIME, maxTime);
            if(maxTime>0)
                countDownTime=JDomUtility.getBoolAttr(child, COUNT_DOWN_TIME, countDownTime);
            maxActions=JDomUtility.getIntAttr(child, MAX_ACTIONS, maxActions);
            if(maxActions>0)
                countDownActions=JDomUtility.getBoolAttr(child, COUNT_DOWN_ACTIONS, countDownActions);
            includeInReports=JDomUtility.getBoolAttr(child, REPORT, includeInReports);
            if(includeInReports)
                reportActions=JDomUtility.getBoolAttr(child, REPORT_ACTIONS, reportActions);
            else reportActions=false;
            if((child2=child.getChild(HELP_WINDOW))!=null){
                if(helpSolutionAllowed()){
                    showSolution=JDomUtility.getBoolAttr(child2, HELP_SHOW_SOLUTION, showSolution);
                }
                if(!showSolution)
                    helpMsg=JDomUtility.getParagraphs(child2);
                helpWindow = helpMsg!=null || showSolution;
            }
            if((child2=child.getChild(CONTAINER))!=null){
                bgColor=JDomUtility.getColorAttr(child2, BGCOLOR, bgColor);
                if((child3=child2.getChild(Gradient.ELEMENT_NAME))!=null)
                    bgGradient=Gradient.getGradient(child3);
                if((child3=child2.getChild(IMAGE))!=null){
                    bgImageFile=child3.getAttributeValue(NAME);
                    tiledBgImg=JDomUtility.getBoolAttr(child3, TILED, tiledBgImg);
                }
                if((child3=child2.getChild(COUNTERS))!=null){
                    bTimeCounter=JDomUtility.getBoolAttr(child3, TIME, bTimeCounter);
                    bActionsCounter=JDomUtility.getBoolAttr(child3, ACTIONS, bActionsCounter);
                    bScoreCounter=JDomUtility.getBoolAttr(child3, SCORE, bScoreCounter);
                    // Check for old version bug
                    //String v=rb.getOptions().getString(CURRENT_PROJECT_VERSION);
                    String v=project.version;
                    if(v!=null && v.compareTo("0.1.1")<=0){
                        boolean b=bScoreCounter;
                        bScoreCounter=bTimeCounter;
                        bTimeCounter=bActionsCounter;
                        bActionsCounter=b;
                    }
                }
            }
            if((child2=child.getChild(WINDOW))!=null){
                activityBgColor=JDomUtility.getColorAttr(child2, BGCOLOR, activityBgColor);
                if((child3=child2.getChild(Gradient.ELEMENT_NAME))!=null)
                    activityBgGradient=Gradient.getGradient(child3);
                transparentBg=JDomUtility.getBoolAttr(child2, TRANSPARENT, transparentBg);
                border=JDomUtility.getBoolAttr(child2, BORDER, border);
                if((child3=child2.getChild(POSITION))!=null){
                    absolutePositioned=true;
                    absolutePosition=JDomUtility.getPointAttr(child3, X, Y, absolutePosition);
                }
                if((child3=child2.getChild(SIZE))!=null){
                    windowSize=JDomUtility.getDimensionAttr(child3, WIDTH, HEIGHT, windowSize);
                }
            }
            if((child2=child.getChild(EventSounds.ELEMENT_NAME))!=null)
                eventSounds=EventSounds.getEventSounds(child2);
            
            if((child2=child.getChild(SKIN))!=null){
                skinFileName=JDomUtility.getStringAttr(child2, FILE, skinFileName, false);
                
                /*
                if(skinFileName!=null && skinFileName.length()>0){
                    if(project.getBridge() instanceof PlayStation)
                        skin=project.mediaBag.getSkinElement(skinFileName, (PlayStation)project.getBridge());
                }
                else
                    skinFileName=null;
                 */
            }
        }
        
        if((child=e.getChild(AutoContentProvider.ELEMENT_NAME))!=null){
            acp=AutoContentProvider.getAutoContentProvider(child);
        }
    }
    
    public void setProperties(Clic3Activity c3a) throws Exception{
        name=c3a.fileName;
        if(c3a.fileDesc.length()>0)
            description=c3a.fileDesc;
        BoxBase bbMessage=c3a.getBoxBase(2);
        for(int i=MAIN; i<END_ERROR; i++){
            messages[i]=new ActiveBoxContent();
            messages[i].setBoxBase(bbMessage);
            c3a.setActiveBoxTextContent(messages[i], i==MAIN ? c3a.initMess : c3a.endMess);
            if(messages[i].mediaContent!=null)
                messages[i].mediaContent.level=2;
        }
        
        /*
        messages[MAIN]=new ActiveBoxContent();
        messages[MAIN].setBoxBase(bbMessage);
        c3a.setActiveBoxTextContent(messages[MAIN], c3a.initMess);
        if(messages[MAIN].mediaContent!=null)
            messages[MAIN].mediaContent.level=2;
         
        messages[END]=new ActiveBoxContent();
        messages[END].setBoxBase(bbMessage);
        c3a.setActiveBoxTextContent(messages[END], c3a.endMess);
        if(messages[END].mediaContent!=null)
            messages[END].mediaContent.level=2;
         */
        
        absolutePositioned=c3a.pwrp;
        absolutePosition=new Point(c3a.pwrx, c3a.pwry);
        transparentBg=c3a.pwTransp;
        //activityBgPattern=c3a.tramaFons[1];
        activityBgColor=c3a.colorFons[1];
        border=c3a.marcs;
        //bgPattern=c3a.tramaFons[0];
        bgImageFile=c3a.bmpFons;
        if(bgImageFile!=null && bgImageFile.length()>0)
            project.mediaBag.getImageElement(bgImageFile);
        tiledBgImg=c3a.tileBmp;
        bgColor=c3a.colorFons[0];
        
        bTimeCounter=c3a.comptadors[0];
        bScoreCounter=c3a.comptadors[1];
        bActionsCounter=c3a.comptadors[2];
        
        includeInReports=!c3a.noAv;
        
        if(c3a.custHlp==true && c3a.custHelpFile!=null && c3a.custHelpFile.length()>0){
            StringBuffer sb=new StringBuffer();
            sb.append(c3a.custHelpFile);
            if(c3a.hlpTopic!=null && c3a.hlpTopic.length()>0)
                sb.append(" ").append(c3a.hlpTopic);
            String s=sb.substring(0);
            if(s.indexOf(".htm")>0){
                StringTokenizer st=new StringTokenizer(s, " ");
                while(st.hasMoreTokens()){
                    String r=st.nextToken();
                    if(r.indexOf(".htm")>0){
                        infoUrl=r;
                        break;
                    }
                }
            }
            else{
                if(c3a.custHelpFile.toLowerCase().indexOf(".hlp")>0)
                    infoCmd="winhelp.exe "+c3a.custHelpFile;
                else
                    infoCmd=s;
            }
        }
        
        if(helpSolutionAllowed())
            showSolution=c3a.shHelp;
        if(showSolution)
            helpWindow=true;
        
        if(c3a.useDLL){
            if(c3a.rgDLL.equalsIgnoreCase("arith2.dll")){
                org.jdom.Element e=new org.jdom.Element(AutoContentProvider.ELEMENT_NAME);
                e.setAttribute(JDomUtility.CLASS, "edu.xtec.jclic.automation.arith.Arith");
                try{
                    acp=AutoContentProvider.getAutoContentProvider(e);
                    if(acp!=null) acp.setClic3Properties(c3a.dllOptions);
                }catch(Exception ex){
                    System.err.println("Unable to start arith2:\n"+ex);
                }
            }
        }
    }
    
    public static void listReferences(org.jdom.Element e, HashMap map){
        org.jdom.Element child, child2, child3;
        
        if((child=e.getChild(MESSAGES))!=null){
            Iterator itr = child.getChildren(ActiveBoxContent.ELEMENT_NAME).iterator();
            while(itr.hasNext())
                ActiveBoxContent.listReferences((org.jdom.Element)itr.next(), map);
        }
        
        if((child=e.getChild(SETTINGS))!=null){
            if((child2=child.getChild(CONTAINER))!=null){
                if((child3=child2.getChild(IMAGE))!=null){
                    map.put(child3.getAttributeValue(NAME), Constants.MEDIA_OBJECT);
                }
            }
            if((child2=child.getChild(EventSounds.ELEMENT_NAME))!=null)
                EventSounds.listReferences(child2, map);
            
            if((child2=child.getChild(SKIN))!=null){
                String skfn=JDomUtility.getStringAttr(child2, FILE, null, false);
                if(skfn!=null && !skfn.startsWith(Skin.INTERNAL_SKIN_PREFIX))
                    map.put(skfn, Constants.SKIN_OBJECT);
                // check skin dependences...
            }
        }
        
        Iterator itr = e.getChildren(ActiveBagContent.ELEMENT_NAME).iterator();
        while(itr.hasNext())
            ActiveBagContent.listReferences((org.jdom.Element)itr.next(), map);
        
        if((child=e.getChild("document"))!=null){
            //if((child=e.getChild(TextActivityDocument.ELEMENT_NAME))!=null){
            //TextActivityDocument.listReferences(child, map);
            innerListReferences(child, map);
        }
        
        if((child=e.getChild(AutoContentProvider.ELEMENT_NAME))!=null){
            try{
                AutoContentProvider.listReferences(child, map);
            } catch(Exception ex){
                System.err.println("Error checking AutoContentProvider: "+ex);
            }
        }        
        
    }
    
    
    public static void innerListReferences(org.jdom.Element e, HashMap map){
        Iterator it=e.getChildren(ActiveBoxContent.ELEMENT_NAME).iterator();
        while(it.hasNext())
            ActiveBoxContent.listReferences((org.jdom.Element)it.next(), map);
        
        it=e.getChildren().iterator();
        while(it.hasNext()){
            org.jdom.Element child=(org.jdom.Element)it.next();
            if(!ActiveBoxContent.ELEMENT_NAME.equals(child.getName()))
                innerListReferences(child, map);
        }
    }
    
    public ActiveBoxContent[] getMessages(){
        return messages;
    }
    
    public String toHtmlString(ResourceBridge rb){
        Html html=new Html(1000);
        
        html.doubleCell(rb.getMsg("about_window_lb_activity"), true, name, true);
        
        if(description!=null)
            html.doubleCell(rb.getMsg("about_window_lb_description"), true, description, false);
        
        return Html.table(html.toString(), null, 1, 5, -1, null, false);
    }
    
    // 02-oct-2006: Param "ResourceBridge" removed (can be obtained from "project"),
    // Changed the call to "init"
    public void initAutoContentProvider(){
        if(acp!=null)
            acp.init(project.getBridge(), project.getFileSystem());
    }
    
    public boolean prepareMedia(PlayStation ps){
        if(eventSounds!=null) eventSounds.realize(ps.getOptions(), project.mediaBag);
        for(int i=0; i<NUM_MSG; i++)
            if(messages[i]!=null)
                messages[i].prepareMedia(ps);
        if(abc!=null)
            for(int i=0; i<abc.length; i++)
                if(abc[i]!=null)
                    abc[i].prepareMedia(ps);
        return true;
    }
    
    protected Activity getActivity(){return this;}
    
    public abstract Activity.Panel getActivityPanel(PlayStation ps);
    
    public boolean helpSolutionAllowed(){
        return false;
    }
    
    public boolean helpWindowAllowed(){
        return helpWindow && ((helpSolutionAllowed() && showSolution) || helpMsg!=null);
    }
    
    public abstract int getMinNumActions();
    public boolean mustPauseSequence(){
        return getMinNumActions()!=0;
    }
    
    public boolean canReinit(){
        return true;
    }
    
    public boolean hasInfo(){
        return
        ((infoUrl!=null && infoUrl.length()>0)
        || (infoCmd!=null && infoCmd.length()>0));
    }
    
    public boolean hasRandom(){
        return false;
    }
    
    public boolean shuffleAlways(){
        return false;
    }
    
    public void end(){
        if(eventSounds!=null){
            eventSounds.close();
            eventSounds=null;
        }
        clear();
    }
    
    public void clear(){
    }
    
    public void finalize() throws Throwable{
        end();
        super.finalize();
    }
    
    /** Getter for property windowSize.
     * @return Value of property windowSize.
     */
00884     public Dimension getWindowSize() {
        return new Dimension(windowSize);
    }
    
    /** Setter for property windowSize.
     * @param windowSize New value of property windowSize.
     */
00891     public void setWindowSize(Dimension windowSize) {
        this.windowSize = new Dimension(windowSize);
    }
    
    public abstract class Panel extends JPanel {
        
        //public Activity act;
        //public ActivityContainer ac;
        
        public Skin skin=null;
        public boolean solved=false;
        public Image bgImage=null;
        protected boolean playing=false;
        protected boolean firstRun=true;
        protected int currentItem=0;
        protected BoxConnector bc=null;
        public PlayStation ps;
        
        /** Creates new ActivityPanel */
        protected Panel(PlayStation ps) {
            super();
            //this.act=act;
            //ac=act.ac;
            this.ps=ps;
            setMinimumSize(new Dimension(100, 100));
            setPreferredSize(new Dimension(500, 400));
            enableEvents(AWTEvent.MOUSE_EVENT_MASK
            | AWTEvent.MOUSE_MOTION_EVENT_MASK
            | AWTEvent.KEY_EVENT_MASK);
            //setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
            
            // 02-oct-2006: Added a call to initAutoContentProvider
            initAutoContentProvider();
        }
        
        public Activity getActivity(){
            return Activity.this;
        }
        
        public PlayStation getPs(){
            return ps;
        }
        
        public void buildVisualComponents() throws Exception {
            playing=false;
            
            skin=null;
            if(skinFileName!=null && skinFileName.length()>0)
                skin=project.mediaBag.getSkinElement(skinFileName, ps);
            
            bgImage=null;
            if(bgImageFile!=null && bgImageFile.length()>0){
                MediaBagElement mbe=project.mediaBag.getImageElement(bgImageFile);
                bgImage=mbe.getImage();
                //bgImageFile=mbe.getFileName();
                bgImageFile=mbe.getName();
            }
            //ac.setBackgroundSettings(bgColor, image, tiledBgImg);
            setBackground(activityBgColor);
            if(transparentBg){
                setOpaque(false);
            }
            setBorder(border
            ? BorderFactory.createBevelBorder(BevelBorder.RAISED)
            : BorderFactory.createEmptyBorder());
            
            invalidate();
        }
        
        protected void playEvent(int event){
            if(eventSounds!=null)
                eventSounds.play(event);
        }
        
        public void initActivity() throws Exception{
            if(playing){
                playing=false;
                ps.reportEndActivity(Activity.this, solved);
            }
            solved=false;
            ps.reportNewActivity(Activity.this, 0);
            enableCounters();
            //playEvent(EventSounds.START);
        }
        
        public void startActivity() throws Exception{
            // do nothing
        }
        
        public void showHelp(){}
        public abstract void render(Graphics2D g2, Rectangle dirtyRegion);
        public abstract Dimension setDimension(Dimension maxSize);
        
        public void processMouse(MouseEvent e){}
        public void processKey(KeyEvent e){}
        public boolean isPlaying(){
            return playing;
        }
        
        public final void fitTo(Rectangle proposed, Rectangle bounds){
            Point origin=new Point(0,0);
            if(absolutePositioned && absolutePosition!=null){
                //origin=new Point(absolutePosition);
                //origin.translate(fx, fy);
                origin.x=Math.max(0, absolutePosition.x+proposed.x);
                origin.y=Math.max(0, absolutePosition.y+proposed.y);
                proposed.width-=absolutePosition.x;
                proposed.height-=absolutePosition.y;
            }
            Dimension d=setDimension(new Dimension(
            Math.max(2*margin+Activity.MINIMUM_WIDTH, proposed.width),
            Math.max(2*margin+Activity.MINIMUM_HEIGHT, proposed.height)));
            if(!absolutePositioned){
                origin.setLocation(
                Math.max(0, proposed.x+(proposed.width-d.width)/2),
                Math.max(0, proposed.y+(proposed.height-d.height)/2));
            }
            if(origin.x+d.width>bounds.width)
                origin.x=Math.max(0, bounds.width-d.width);
            if(origin.y+d.height>bounds.height)
                origin.y=Math.max(0, bounds.height-d.height);
            setBounds(origin.x, origin.y, d.width, d.height);
        }
        
        public void paintComponent(Graphics g){
            Graphics2D g2=(Graphics2D)g;
            RenderingHints rh=g2.getRenderingHints();
            g2.setRenderingHints(DEFAULT_RENDERING_HINTS);
            //RenderingHints rh=ac.setScreenRenderingHints(g2);
            if(!transparentBg){
                if(activityBgGradient==null || activityBgGradient.hasTransparency())
                    super.paintComponent(g2);
                if(activityBgGradient!=null)
                    activityBgGradient.paint(g2, new Rectangle(0, 0, getWidth(), getHeight()));
            }
            while(true){
                BoxBase.flagFontReduced=false;
                render(g2, g2.getClipBounds());
                if(!BoxBase.flagFontReduced) break;
            }
            g2.setRenderingHints(rh);
        }
        
        public void forceFinishActivity(){
        }
        
        public void finishActivity(boolean result){
            playing=false;
            solved=result;
            
            if(bc!=null)
                bc.end();
            
            if(result){
                setAndPlayMsg(END, EventSounds.FINISHED_OK);
                //if(messages[END]==null || messages[END].mediaContent==null)
                //    playEvent(EventSounds.FINISHED_OK);
                //ps.setMsg(messages[END]);
            }
            else{
                setAndPlayMsg(END_ERROR, EventSounds.FINISHED_ERROR);
                //if(messages[END_ERROR]==null || messages[END_ERROR].mediaContent==null)
                //    playEvent(EventSounds.FINISHED_ERROR);
                //ps.setMsg(messages[END_ERROR]);
            }
            //ps.playMsg();
            ps.activityFinished(solved);
            ps.reportEndActivity(Activity.this, solved);
        }
        
        protected void setAndPlayMsg(int msgCode, int eventSoundsCode){
            ps.setMsg(messages[msgCode]);
            if(messages[msgCode]==null || messages[msgCode].mediaContent==null)
                playEvent(eventSoundsCode);
            else
                ps.playMsg();
        }
        
        public void end(){
            forceFinishActivity();
            if(playing){
                if(bc!=null)
                    bc.end();
                ps.reportEndActivity(Activity.this, solved);
                playing=false;
                solved=false;
            }
            clear();
        }
        
        public abstract void clear();
        
        public void finalize() throws Throwable{
            end();
        }
        
        protected void enableCounters(){
            enableCounters(bTimeCounter, bScoreCounter, bActionsCounter);
        }
        
        protected void enableCounters(boolean eTime, boolean eScore, boolean eActions){
            ps.setCounterEnabled(TIME_COUNTER, eTime);
            if(countDownTime)
                ps.setCountDown(TIME_COUNTER, maxTime);
            ps.setCounterEnabled(SCORE_COUNTER, eScore);
            ps.setCounterEnabled(ACTIONS_COUNTER, eActions);
            if(countDownActions)
                ps.setCountDown(ACTIONS_COUNTER, maxActions);
        }
        
        public void doLayout(){
        }
        
        
        protected void shuffle(ActiveBoxBag[] bg, boolean visible, boolean fitInArea){
            //int steps=3;
            int steps=shuffles;
            
            //if(visible) ac.getComponent().paint(ac.getComponent().getGraphics());
            int i=shuffles;
            while(i>0){
                int k=i>steps ? steps:i;
                for(int j=0; j<bg.length; j++)
                    if(bg[j]!=null)
                        bg[j].scrambleCells(k, fitInArea);
                //if(visible) ac.getComponent().paint(ac.getComponent().getGraphics());
                i-=steps;
            }
        }
        
        protected void processEvent(AWTEvent e){
            if(playing && e instanceof MouseEvent){
                if(e.getID()==MouseEvent.MOUSE_PRESSED && !hasFocus())
                    requestFocus();
                if(playing)
                    processMouse((MouseEvent)e);
            }
            else if(playing && e instanceof KeyEvent)
                processKey((KeyEvent)e);
            
            super.processEvent(e);
        }
        
    }
    
}

Generated by  Doxygen 1.6.0   Back to index