package com.craigc.progen;
import org.w3c.dom.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
/**
 * Play Domain with all Run-time variabilities, Phase I
 */
class PlayRT extends Frame implements ActionListener {
    Hashtable name2button = new Hashtable();// prop names to buttons
    Hashtable button2name = new Hashtable();// buttons to prop names
    Hashtable name2prop = new Hashtable();  // prop names to prop nodes
    Document doc; // the internal representation of the XML document
    
    public PlayRT(Document c) {
        super(DOM_Util.get(c, "title", "Play Example"));
        doc = c;
        setLayout(new FlowLayout());
        Node playNode = c.getDocumentElement();
        
        // initialize props and hash tables
        NodeList e = c.getElementsByTagName("prop");
        for (int j=0; j<e.getLength(); ++j) {
            Node bnode = e.item(j);
            String name = DOM_Util.getAttr(bnode, "name", "?");
            name2prop.put(name, bnode);
            Button b = new Button();
            setupProp(b, bnode);
            b.addActionListener(this);
            name2button.put(name, b);
            button2name.put(b, name);
        }
        setSize(DOM_Util.getIntAttr(playNode, "width", 500),
                DOM_Util.getIntAttr(playNode, "height", 250));
        enterNewScene(DOM_Util.getAttr(playNode, "start", "?"));
        show();
    }
    
    void enterNewScene(String sceneName) {
        removeAll();
        NodeList e = doc.getElementsByTagName("scene");
        for (int j=0; j<e.getLength(); ++j) {
            Element snode = (Element) e.item(j);
            String name = DOM_Util.getAttr(snode, "name", "");
            if (name.equals(sceneName)) {
                // found the right scene, now add the props
                setBackground(Color.decode(DOM_Util.getAttr(snode, 
                                                "color", "#ff0000")));
                NodeList e2 = snode.getElementsByTagName("addprop");
                for (int j2=0; j2<e2.getLength(); ++j2) {
                    Node pnode = e2.item(j2);
                    String pname = DOM_Util.getAttr(pnode, "name", "");
                    Button b = (Button) name2button.get(pname);
                    if (b!=null) {
                        add(b);
                    } else {
                        error("No prop named "+pname);
                    }
                }
                show();
                return;
            }
        }
    }
    
    /** perform action when button is clicked */
    public void actionPerformed(ActionEvent e) {
        String pname = (String) button2name.get(e.getSource());
        if (pname==null || pname.equals("")) {
            error("Invalid button prop");
            return;
        }
        Node bnode = (Node) name2prop.get(pname);
        if (bnode==null) {
            error("No prop named "+pname);
            return;
        }
        NodeList e2 = ((Element)bnode).getElementsByTagName("script");
        // there should only be one action script for a prop
        for (int j=0; j<e2.getLength(); ++j) {
            Node snode = e2.item(j);
            // in phase 1, all scripts are Action scripts
            setupProp((Button)name2button.get(pname), snode);
            String nextScene = DOM_Util.getAttr(snode, "goto", "");
            if (nextScene!=null && !nextScene.equals("")) {
                enterNewScene(nextScene);
            }
            return; // only execute first script
        }
    }
    
    void setupProp(Button b, Node bnode) {
        // can't use getElementsByTagName here since there are nested
        // trait elements in script elements that shouldn't be used.
        for (Node n = bnode.getFirstChild(); n!=null;
                                        n = n.getNextSibling()) {
            if (n instanceof Element) {
                if (n.getNodeName().equals("trait")
                  && DOM_Util.getAttr(n, "name", "?").equals("Label")) {
                    String pname = DOM_Util.getAttr(n, "prop", "");
                    if (pname!=null && !pname.equals("")) {
                        b = (Button) name2button.get(pname);
                    }
                    if (b!=null) {
                        b.setLabel(DOM_Util.getContent(n));
                    } else {
                        error("Configuration error");
                    }
                } // ignore all other traits since this is only Phase 1
            }
        }
        
    }
    
    static void error(String msg) {
        System.out.println("Error: "+msg);
    }
        
    public static void main(String args[]) {
        if (args.length>0) {
            try {
                // read XML file and start up display
                Document c = DOM_Util.readDocument(args[0]);
                new PlayRT(c);
            } catch (Exception e) {
                error("Invalid config file: "+args[0]);
            }
        } else {
            error("No config file specified");
        }
    }
}
 
 |