//----------------------------------------------------------------------------
//
// Module:      GuiDocumentHandler.java      
//
// Description: Handle top level document
//
// FESI Copyright (c) Jean-Marc Lugrin, 2000
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser 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
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//----------------------------------------------------------------------------
package FesiForm;

import org.xml.sax.*;

import FESI.jslib.*;

public class GuiDocumentHandler extends DefaultDocumentHandler {

    private boolean inScript = false;
    private boolean startScriptSeen = false;
    private boolean endScriptSeen = false;
    private boolean endSeen = false;
    private StringBuffer currentScript = null;
    private String containedName = null;
    
    public GuiDocumentHandler(GuiContext guiContext, boolean trace) {
        super(guiContext, trace);
    }

     // Receive notification of the beginning of a document. 
    public void startDocument() throws SAXException {
        if (trace) System.out.println("GUI START_DOCUMENT");
    }
      
    // Receive notification of the beginning of an element.
    public void startElement(String name, AttributeList atts) throws SAXException {
        if (trace) System.out.println("GUI START_ELEMENT: <" + name + ">, " + 
                                         atts.getLength() + " attribute(s)");
                                         
        if (name.equals("script")) {
             
            if (endSeen || endScriptSeen) {
                throw new SAXException("SCRIPT after end ignored");
            } else {
                currentScript = null;
                inScript = true;
                if (startScriptSeen) {
                    endScriptSeen = true;
                } else {
                    startScriptSeen = true;
                }
            }
             
        } else if (name.equals("JFrame")) {
             
            if (endScriptSeen) {
                throw new SAXException("JFRAME after end or end script ignored");
            } else {
                containedName = name;
                DocumentHandler dh = new JFrameDocumentHandler("JFrame", this, guiContext, trace);
                guiContext.parser.setDocumentHandler(dh);
                dh.startElement(name, atts);
            }
             
        } else if (name.equals("JDialog")) {
             
            if (endScriptSeen) {
                throw new SAXException("JDIALOG after end or end script ignored");
            } else {
                containedName = name;
                DocumentHandler dh = new JDialogDocumentHandler("JDialog", this, guiContext, trace);
                guiContext.parser.setDocumentHandler(dh);
                dh.startElement(name, atts);
            }
             
        } else if (name.equals("JPopupMenu")) {
             
            if (endScriptSeen) {
                throw new SAXException("JPOPUPMENU after end or end script ignored");
            } else {
                containedName = name;
                DocumentHandler dh = new JPopupMenuDocumentHandler("JPopupMenu", this, guiContext, trace);
                guiContext.parser.setDocumentHandler(dh);
                dh.startElement(name, atts);
            }
             
        } else if (name.equals("gui")) {
            
            // <!ELEMENT gui (frame|script)*>
            // <!ATTLIST gui
            //    lf    (native|crossPlaform) "crossPlatform"
            // >
            String lf = getAttribute("lf", atts);
            if (lf!=null && lf.equalsIgnoreCase("native")) {
                guiContext.useNative = true;
            }
             
        } else {
            throw new SAXException("Unexpected GUI ELEMENT: " + name);
        }
    }

    public void characters(char[] ch, int start, int length) throws SAXException {
        if (trace) System.out.println("GUI CHARACTERS: [[" + new String(ch) + "]]");
        if (inScript) {
            if (currentScript == null) {
                currentScript = new StringBuffer(length);
            }
            currentScript.append(ch, start, length);
        } else {
            throw new SAXException("Unexpected GUI CHARACTERS ignored");
        }
    }
      
      
    // Receive notification of the end of an element. 
    public void endElement(String name) throws SAXException {
        if (trace) System.out.println("GUI END_ELEMENT: </" + name + ">");
        if (name.equals("script")) {
            if (currentScript != null) {
                String script = currentScript.toString();
                currentScript = null;
                inScript = false;
                if (trace) System.out.println("  SCRIPT: " + script);
                try {
                    JSObject o = guiContext.global.makeObjectWrapper(guiContext);
                    o.eval(script.toString()); 
                } catch (JSException ex) {
                    throw new SAXException("Cannot evaluate script: " + ex.getMessage(), ex);
                }
            }
        } else if (name.equals("gui")) {
            endScriptSeen = true; // Even if none at all, so just this one to test
            endSeen = true;
        } else if (name.equals(containedName)) {
                containedName = null;
                guiContext.parser.setDocumentHandler(this);
        } else {
            throw new SAXException("Unexpected GUI ELEMENT end: " + name);
        }
        
    }


    // Receive notification of the end of a document. 
    public void endDocument() {
        if (trace) System.out.println("GUI END_DOCUMENT");
    }
            
}
         