//----------------------------------------------------------------------------
//
// Module:      DefaultDocumentHandler.java      
//
// Description: Containts default and utility routines for XML processing
//
// 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.*;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;


public class DefaultDocumentHandler implements DocumentHandler {

    protected boolean trace;
    protected GuiContext guiContext;

    public DefaultDocumentHandler(GuiContext gc, boolean trace) {
        super();
        this.trace = trace;
        this.guiContext = gc;
    }
    
     // Receive notification of character data. 
     public void characters(char[] ch, int start, int length) throws SAXException {
         if (trace) System.out.println("CHARACTERS: [[" + new String(ch) + "]]");
         throw new SAXException("Unexpected CHARACTERS in document");
     }
      
     // Receive notification of the end of a document. 
     public void endDocument() throws SAXException {
         if (trace) System.out.println("END_DOCUMENT");
         throw new SAXException("Unexpected END_DOCUMENT in document");
     }
      
      
     // Receive notification of the end of an element. 
     public void endElement(java.lang.String name) throws SAXException {
         if (trace) System.out.println("END_ELEMENT: </" + name + ">");
         throw new SAXException("Unexpected END_ELEMENT in document");
     }
      
     // Receive notification of ignorable whitespace in element content. 
     public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
         if (trace) System.out.println("IGNORABLE_WHITESPACE: " + length);
     }
      
     // Receive notification of a processing instruction. 
     public void processingInstruction(java.lang.String target, java.lang.String data) throws SAXException {
         if (trace) System.out.println("PROCESSING_INSTRUCTIONS: '" + data + "'");
         throw new SAXException("Unexpected PROCESSING_INSTRUCTIONS in document");
     }
      
      
     // Receive an object for locating the origin of SAX document events. 
     public void setDocumentLocator(Locator locator) {
         if (trace) System.out.println("SET_DOCUMENT_LOCATOR: " + locator);
     }
      
     // Receive notification of the beginning of a document. 
     public void startDocument() throws SAXException {
         if (trace) System.out.println("START_DOCUMENT");
         throw new SAXException("Unexpected START_DOCUMENT in document");
     }
      
     // Receive notification of the beginning of an element.
     public void startElement(java.lang.String name, AttributeList atts) throws SAXException {
         if (trace) System.out.println("START_ELEMENT: <" + name + ">, " + 
                                         atts.getLength() + " attribute(s)");
         throw new SAXException("Unexpected START_ELEMENT ignored");
     }
     
     // To process the end of the enclosing block
     public void processEnd(String name) throws SAXException {
         throw new SAXException("Unexpected PROCESS END in document");
     }
     
     // Utility routines
     String getAttribute(String name,  AttributeList atts) {
         for (int i = 0; i < atts.getLength(); i++) {
             if (name.equals(atts.getName(i))) {
                 return atts.getValue(i);
             }
          } // for
          return null;
      }   

    protected  void processComponentAttributes(Component cp, AttributeList atts) throws SAXException {
        processBG(cp, atts);
        processFG(cp, atts);
        processFONTs(cp, atts);
        processSIZE(cp, atts);
        processLOCATION(cp, atts);
        processToolTipText(cp, atts);
        processPopupId(cp, atts);
    }

    protected void processJComponentAttributes(JComponent jl, AttributeList atts) throws SAXException {
         processOPAQUE(jl, atts);
         processMINIMUMSIZE(jl, atts);
         processMAXIMUMSIZE(jl, atts);
         processPREFERREDSIZE(jl, atts);
         processBOUNDS(jl, atts);
    }
        
    protected  void processPopupId(Component cp, AttributeList atts) throws SAXException {
        String popupId = getAttribute("popupId", atts);
        if (popupId != null) {
            Component pm = (Component) guiContext.getById(popupId);
            if (pm == null) {
                throw new SAXException("Popup id="+popupId+" not found");
            } else if (pm instanceof JPopupMenu) {
                final JPopupMenu popupMenu = (JPopupMenu) pm;
                cp.addMouseListener (new MouseListener() {
                    public void mouseClicked(MouseEvent ev) {
                        if (ev.isPopupTrigger()) {
                            popupMenu.show(ev.getComponent(),
                                    ev.getX(), ev.getY());
                        }
                    }
                    public void mouseEntered(MouseEvent ev) {}
                    public void mouseExited(MouseEvent ev) {}
                    public void mousePressed(MouseEvent ev) {
                        if (ev.isPopupTrigger()) {
                            popupMenu.show(ev.getComponent(),
                                    ev.getX(), ev.getY());
                        }
                    }
                    public void mouseReleased(MouseEvent ev) {
                        if (ev.isPopupTrigger()) {
                            popupMenu.show(ev.getComponent(),
                                    ev.getX(), ev.getY());
                        }
                    }
                });
            } else {
                throw new SAXException("Element id "+ popupId + " is not a JPopupMenu");
            }
        }
    } 
    
    protected  void processToolTipText(Component cp, AttributeList atts) {
         String ttt = getAttribute("toolTipText", atts);
         if (ttt!=null && cp instanceof JComponent) {
             if (trace) System.out.println("  TOOLTIPTEXT=" + ttt);
             ((JComponent) cp).setToolTipText(ttt);
         }
     }
    
    protected  void processOptionalId(Component cp, AttributeList atts) {
         String id = getAttribute("id", atts);
         if (id!=null) {
             if (trace) System.out.println("  ID=" + id);
             guiContext.putId(id, cp);
         }
     }

    
     protected Dimension processSIZE(Component cp, AttributeList atts) throws SAXException {
         String sizeString = getAttribute("size", atts);
         if (sizeString != null) {
             int width, height;
             if (sizeString.charAt(0) != '(') {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);
             }
             int comma = sizeString.indexOf(",");
             if (comma<1) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);
             }
             String widthString = sizeString.substring(1,comma);
             int paren = sizeString.indexOf(")", comma);
             if (paren<1) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);
             }
             String heightString = sizeString.substring(comma+1,paren);             
             try {
                 width = Integer.parseInt(widthString);
             } catch (NumberFormatException ignore) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);                 
             }
             try {
                 height = Integer.parseInt(heightString);
             } catch (NumberFormatException ignore) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);                 
             }
             if (trace) System.out.println("  SIZE: (" + width+ "," + height+")");         
             cp.setSize(width, height);
             return new Dimension(width, height);
         }
         return null;
     }
     
     protected Point processLOCATION(Component cp, AttributeList atts) throws SAXException {
         String locationString = getAttribute("location", atts);
         if (locationString != null) {
             int x,y;
             if (locationString.charAt(0) != '(') {
                 throw new SAXException("Location format is (x,y), not: " + locationString);
             }
             int comma = locationString.indexOf(",");
             if (comma<1) {
                 throw new SAXException("Location format is (x,y), not: " + locationString);
             }
             String xString = locationString.substring(1,comma);
             int paren = locationString.indexOf(")", comma);
             if (paren<1) {
                 throw new SAXException("Location format is (x,y), not: " + locationString);
             }
             String yString = locationString.substring(comma+1,paren);             
             try {
                 x = Integer.parseInt(xString);
             } catch (NumberFormatException ignore) {
                 throw new SAXException("Location format is (x,y), not: " + locationString);                 
             }
             try {
                 y = Integer.parseInt(yString);
             } catch (NumberFormatException ignore) {
                 throw new SAXException("Location format is (x,y), not: " + locationString);                 
             }
             if (trace) System.out.println("  LOCATION: (" + x+ "," + y+")");         
             cp.setLocation(x, y);
             return new Point(x, y);
         }
         return null;
     }
     
     protected Color processBG(Component cp, AttributeList atts) throws SAXException {
         String bg = getAttribute("bg", atts);
         Color color = null;
         if (bg!=null) {
             color = colorByName(bg);
             if (trace) System.out.println("  BG: " + bg);         
             if (color!= null) cp.setBackground(color);
         }
         return color;
     }
     
     
     protected Color processFG(Component cp, AttributeList atts) throws SAXException {
         String fg = getAttribute("fg", atts);
         Color color = null;
         if (fg != null) {
             color = colorByName(fg);
             if (trace) System.out.println("  FG: " + fg);         
             if (color != null) cp.setForeground(color);
         }
         return color;
     }

     protected Font processFONTs(Component cp, AttributeList atts) throws SAXException {
         Font font = null;
         String fontFace = getAttribute("fontFace",  atts);
         String fontSize = getAttribute("fontSize", atts);
         String fontStyle = getAttribute("fontStyle", atts);
         boolean anySpecified = false;
         if (fontFace != null) {
             anySpecified = true;
         } else {
             fontFace = "Serif"; // Should get system default
         }
         if (fontSize != null) {
             anySpecified = true;
         }
         if (fontStyle != null) {
             anySpecified = true;
         }
         int size = 10;
         if (fontSize != null) {
             try {
                 size = Integer.parseInt(fontSize);
             } catch (NumberFormatException ignore) {
                 throw new SAXException("Bad font size: " + fontSize);
             }
         }
         int style = Font.PLAIN;
         if (fontStyle!=null) {
             style = styleByName(fontStyle);
         }
         if (anySpecified) {
             if (trace) System.out.println("  FONT: "+fontFace+", "+style+", " +size);
             font = new Font(fontFace, style, size);
             cp.setFont(font);
         }
         return font;
     }
      

     protected Icon processAbstractButtonICON(AbstractButton jb, AttributeList atts) {
         int halign = JTextField.LEFT;
         Icon icon = null;
         String iconString = getAttribute("icon",atts);
         if (iconString != null) {
             icon = new ImageIcon(iconString);
             if (trace) System.out.println("  ICON: "+iconString);
             jb.setIcon(icon);
         }
         return icon;
     }


    protected char processMNEMONIC(AbstractButton cp, AttributeList atts) throws SAXException {
         String s = getAttribute("mnemonic", atts);
         char c = '\0';
         if (s != null && s.length()>0) {
             c = s.charAt(0);
             if (trace) System.out.println("  MNEMONIC: " + c);         
             cp.setMnemonic(c);
         }
         return c;
    }

     protected Icon processDISABLEDICON(AbstractButton jb, AttributeList atts) {
         int halign = JTextField.LEFT;
         Icon icon = null;
         String iconString = getAttribute("disabledIcon", atts);
         if (iconString != null) {
             icon = new ImageIcon(iconString);
             if (trace) System.out.println("  DISABLEDICON: "+iconString);
             jb.setDisabledIcon(icon);
         }
         return icon;
     }


     protected boolean processSELECTED(AbstractButton jb, AttributeList atts) throws SAXException {
         boolean selected = false;
         String tf = getAttribute("selected", atts);
         if (tf != null) {
             tf = tf.toLowerCase();
             if (trace) System.out.println("  SELECTED: " + tf);
             if (tf.equals("true")) {
                 selected = true;
             } else if (!tf.equals("false")) {
                 throw new SAXException("Bad true/false value for selected: " + tf);
             }
             jb.setSelected(selected);
         }
         return selected;
     }

     protected boolean processBORDERPAINTED(AbstractButton jb, AttributeList atts) throws SAXException {
         boolean tf = false;
         String tfString = getAttribute("borderPainted", atts);
         if (tfString != null) {
             tfString = tfString.toLowerCase();
             if (trace) System.out.println("  BORDERPAINTED: " + tf);
             if (tfString.equals("true")) {
                 tf = true;
             } else if (!tfString.equals("false")) {
                 throw new SAXException("Bad true/false value for selected: " + tf);
             }
             jb.setBorderPainted(tf);
         }
         return tf;
     }

      protected boolean processFOCUSPAINTED(AbstractButton jb, AttributeList atts) throws SAXException {
         boolean tf = false;
         String tfString = getAttribute("focusPainted", atts);
         if (tfString != null) {
             tfString = tfString.toLowerCase();
             if (trace) System.out.println("  FOCUSPAINTED: " + tf);
             if (tfString.equals("true")) {
                 tf = true;
             } else if (!tfString.equals("false")) {
                 throw new SAXException("Bad true/false value for selected: " + tf);
             }
             jb.setFocusPainted(tf);
         }
         return tf;
     }

     protected boolean processENABLED(AbstractButton jb, AttributeList atts) throws SAXException {
         boolean tf = false;
         String tfString = getAttribute("enabled", atts);
         if (tfString != null) {
             tfString = tfString.toLowerCase();
             if (trace) System.out.println("  ENABLED: " + tf);
             if (tfString.equals("true")) {
                 tf = true;
             } else if (!tfString.equals("false")) {
                 throw new SAXException("Bad true/false value for selected: " + tf);
             }
             jb.setEnabled(tf);
         }
         return tf;
     }

   
     protected Dimension processMINIMUMSIZE(JComponent cp, AttributeList atts) throws SAXException {
         String sizeString = getAttribute("minimumSize", atts);
         if (sizeString != null) {
             int width, height;
             if (sizeString.charAt(0) != '(') {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);
             }
             int comma = sizeString.indexOf(",");
             if (comma<1) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);
             }
             String widthString = sizeString.substring(1,comma);
             int paren = sizeString.indexOf(")", comma);
             if (paren<1) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);
             }
             String heightString = sizeString.substring(comma+1,paren);             
             try {
                 width = Integer.parseInt(widthString);
             } catch (NumberFormatException ignore) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);                 
             }
             try {
                 height = Integer.parseInt(heightString);
             } catch (NumberFormatException ignore) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);                 
             }
             if (trace) System.out.println("  MINIMUMSIZE: (" + width+ "," + height+")");         
             Dimension d = new Dimension(width, height);
             cp.setMinimumSize(d);
             return d;
         }
         return null;
     }
     

    
     protected Dimension processMAXIMUMSIZE(JComponent cp, AttributeList atts) throws SAXException {
         String sizeString = getAttribute("maximumSize", atts);
         if (sizeString != null) {
             int width, height;
             if (sizeString.charAt(0) != '(') {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);
             }
             int comma = sizeString.indexOf(",");
             if (comma<1) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);
             }
             String widthString = sizeString.substring(1,comma);
             int paren = sizeString.indexOf(")", comma);
             if (paren<1) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);
             }
             String heightString = sizeString.substring(comma+1,paren);             
             try {
                 width = Integer.parseInt(widthString);
             } catch (NumberFormatException ignore) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);                 
             }
             try {
                 height = Integer.parseInt(heightString);
             } catch (NumberFormatException ignore) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);                 
             }
             if (trace) System.out.println("  MAXIMUMSIZE: (" + width+ "," + height+")");         
             Dimension d = new Dimension(width, height);
             cp.setMaximumSize(d);
             return d;
         }
         return null;
     }
     
    
     protected Dimension processPREFERREDSIZE(JComponent cp, AttributeList atts) throws SAXException {
         String sizeString = getAttribute("preferredSize", atts);
         if (sizeString != null) {
             int width, height;
             if (sizeString.charAt(0) != '(') {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);
             }
             int comma = sizeString.indexOf(",");
             if (comma<1) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);
             }
             String widthString = sizeString.substring(1,comma);
             int paren = sizeString.indexOf(")", comma);
             if (paren<1) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);
             }
             String heightString = sizeString.substring(comma+1,paren);             
             try {
                 width = Integer.parseInt(widthString);
             } catch (NumberFormatException ignore) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);                 
             }
             try {
                 height = Integer.parseInt(heightString);
             } catch (NumberFormatException ignore) {
                 throw new SAXException("Size format is (x,y), not: " + sizeString);                 
             }
             if (trace) System.out.println("  PREFERREDSIZE: (" + width+ "," + height+")");         
             Dimension d = new Dimension(width, height);
             cp.setPreferredSize(d);
             return d;
         }
         return null;
     }
     
    
     protected Rectangle processBOUNDS(JComponent cp, AttributeList atts) throws SAXException {
         String sizeString = getAttribute("bounds", atts);
         if (sizeString != null) {
             int x, y, width, height;
             if (sizeString.charAt(0) != '(') {
                 throw new SAXException("Bounds format is (x,y,height,width), not: " + sizeString);
             }
             int comma = sizeString.indexOf(",");
             if (comma<1) {
                 throw new SAXException("Bounds format is (x,y,height,width), not: " + sizeString);
             }
             String xString = sizeString.substring(1,comma);
             int prevComma = comma+1;
             comma = sizeString.indexOf(",",prevComma);
             if (comma<1) {
                 throw new SAXException("Bounds format is (x,y,height,width), not: " + sizeString);
             }
             String yString = sizeString.substring(prevComma,comma);
             prevComma = comma+1;
             comma = sizeString.indexOf(",",prevComma);
             if (comma<1) {
                 throw new SAXException("Bounds format is (x,y,height,width), not: " + sizeString);
             }
             String widthString = sizeString.substring(prevComma,comma);
             prevComma = comma+1;
             int paren = sizeString.indexOf(")", prevComma);
             if (paren<1) {
                 throw new SAXException("Bounds format is (x,y,height,width), not: " + sizeString);
             }
             String heightString = sizeString.substring(prevComma,paren);             
             try {
                 x = Integer.parseInt(xString);
             } catch (NumberFormatException ignore) {
                 throw new SAXException("Bad x, bounds format is (x,y,height,width), not: " + sizeString);
             }
             try {
                 y = Integer.parseInt(yString);
             } catch (NumberFormatException ignore) {
                 throw new SAXException("Bad y, bounds format is (x,y,height,width), not: " + sizeString);
             }
             try {
                 width = Integer.parseInt(widthString);
             } catch (NumberFormatException ignore) {
                 throw new SAXException("Bad width, bounds format is (x,y,height,width), not: " + sizeString);
             }
             try {
                 height = Integer.parseInt(heightString);
             } catch (NumberFormatException ignore) {
                 throw new SAXException("Bad  height, bounds format is (x,y,height,width), not: " + sizeString);
             }
             if (trace) System.out.println("  BOUNDS: (" + width+ "," + height+")");         
             Rectangle r = new Rectangle(x, y, width, height);
             cp.setBounds(r);
             return r;
         }
         return null;
    }


     protected boolean processOPAQUE(JComponent jb, AttributeList atts) throws SAXException {
         boolean opaque = false;
         String tf = getAttribute("opaque", atts);
         if (tf != null) {
             tf = tf.toLowerCase();
             if (trace) System.out.println("  OPAQUE: " + tf);
             if (tf.equals("true")) {
                 opaque = true;
             } else if (!tf.equals("false")) {
                 throw new SAXException("Bad true/false value for opaque: " + tf);
             }
             jb.setOpaque(opaque);
         }
         return opaque;
     }



     protected void processAbstractButtonAttributes(AbstractButton ab, AttributeList atts) throws SAXException {
         processTEXTab(ab, atts);
         processAbstractButtonICON(ab, atts);
         processDISABLEDICON(ab, atts);
         processSELECTED(ab, atts);
         processENABLED(ab, atts);
         processMNEMONIC(ab, atts);
         processBORDERPAINTED(ab, atts);
         processFOCUSPAINTED(ab, atts);
    }

    
    protected String processTEXTab(AbstractButton jb, AttributeList atts) {
         String label = getAttribute("text", atts);
         if (label != null ) {
             if (trace) System.out.println("  TEXT: "+label);
             jb.setText(label);
         }
         return label;
     }

      
      
     protected void processLAYOUT(Container ct, AttributeList atts) throws SAXException {
         String layout = getAttribute("layout",atts);
         if (layout != null ) {
             if (trace) System.out.println("  LAYOUT: " + layout);
         } else {
             layout = "FlowLayout()";
         }
         if (layout.equals("null")) {
             ct.setLayout(null);
         } else if (layout.startsWith("BorderLayout(")) {
             Vector params = parseParams(layout,13);
             if (params.size() == 2) {
                 int p1=0, p2=0;
                 try {
                     p1 = Integer.parseInt((String) params.elementAt(0));
                 } catch (NumberFormatException ignore) {
                 }
                 try {
                     p2 = Integer.parseInt((String) params.elementAt(1));
                 } catch (NumberFormatException ignore) {
                 }
                 ct.setLayout(new BorderLayout(p1, p2));
             } else {
                 ct.setLayout(new BorderLayout());
             }
         } else if (layout.startsWith("FlowLayout(")) {
             Vector params = parseParams(layout,11);
             if (params.size() == 1) {
                 int p1=0;
                 try {
                     p1 = Integer.parseInt((String) params.elementAt(0));
                 } catch (NumberFormatException ignore) {
                 }
                 ct.setLayout(new FlowLayout(p1));
             } else if (params.size() == 1) {
                 int p1=0, p2=0, p3=0;
                 try {
                     p1 = Integer.parseInt((String) params.elementAt(0));
                 } catch (NumberFormatException ignore) {
                 }
                 try {
                     p2 = Integer.parseInt((String) params.elementAt(1));
                 } catch (NumberFormatException ignore) {
                 }
                 try {
                     p3 = Integer.parseInt((String) params.elementAt(2));
                 } catch (NumberFormatException ignore) {
                 }
                 ct.setLayout(new FlowLayout(p1,p2,p3));
             } else {
                 ct.setLayout(new FlowLayout());
             }
         } else if (layout.startsWith("GridLayout(")) {
             Vector params = parseParams(layout,11);
             if (params.size() == 2) {
                 int p1=0, p2=0;
                 try {
                     p1 = Integer.parseInt((String) params.elementAt(0));
                 } catch (NumberFormatException ignore) {
                 }
                 try {
                     p2 = Integer.parseInt((String) params.elementAt(1));
                 } catch (NumberFormatException ignore) {
                 }
                 ct.setLayout(new GridLayout(p1,p2));
             } else if (params.size() == 4) {
                 int p1=0, p2=0, p3=0, p4=0;
                 try {
                     p1 = Integer.parseInt((String) params.elementAt(0));
                 } catch (NumberFormatException ignore) {
                 }
                 try {
                     p2 = Integer.parseInt((String) params.elementAt(1));
                 } catch (NumberFormatException ignore) {
                 }
                 try {
                     p3 = Integer.parseInt((String) params.elementAt(2));
                 } catch (NumberFormatException ignore) {
                 }
                 try {
                     p4 = Integer.parseInt((String) params.elementAt(3));
                 } catch (NumberFormatException ignore) {
                 }
                 ct.setLayout(new GridLayout(p1,p2,p3,p4));
             } else {
                 ct.setLayout(new GridLayout());
             }
         } else if (layout.startsWith("GridBagLayout(")) {
             // Vector params = parseParams(layout,14);
             ct.setLayout(new GridBagLayout());
         } else if (layout.startsWith("BoxLayout(")) {
             Vector params = parseParams(layout,10);
             int axis = BoxLayout.Y_AXIS;
             if (params.size()!=1) {
                 throw new SAXException("Missing parameter for BoxLayout manager '" + layout + "'");
             } else {
                 String a = ((String) params.elementAt(0)).toUpperCase();
                 if (a.equals("X_AXIS")) {
                 } else if (!a.equals("Y_AXIS")) {
                     throw new SAXException("Bad parameter for BoxLayout manager '" + layout + "'");
                 }
             }
             ct.setLayout(new BoxLayout(ct,axis));
         } else {
             throw new SAXException("Cannot created layout manager '" + layout + "'");
         }
     }
     
         
     
     protected void addConstrained(Container ct, Component cp, AttributeList atts) {
         String constraint = getAttribute("constraint", atts);
         if (constraint == null) {
             ct.add(cp);
         } else {
             ct.add(cp, constraint);
         }
     }

     protected void addConstrained(Container ct, Component cp, String constraint) {
         if (constraint == null) {
             ct.add(cp);
         } else {
             ct.add(cp, constraint);
         }
     }


    protected Vector parseParams(String str, int start) {
        Vector v = new Vector();
        int next = str.indexOf(",",start);
        while(next != -1) {
            String p = str.substring(start,next);
            //System.out.println("PPP:"+p);
            v.addElement(p);
            start = next+1;
            next = str.indexOf(",",start);
        }
        next = str.indexOf(")",start);
        if (next != -1) {
            String p = str.substring(start,next);
            //System.out.println("PPP:"+p);
            v.addElement(p);
        }
        return v;
    }
 
     protected String saveScript(Component cp, AttributeList atts) {
         String script = getAttribute("script", atts);
         if (script != null) {
             if (trace) System.out.println("  SCRIPT: " + script);
         }
         return script;
     }


     protected void processScript(Component cp, String script) throws SAXException {
         if (script != null) {
             if (trace) System.out.println("  Processing SCRIPT");
             try {
                 JSObject o = guiContext.global.makeObjectWrapper(cp);
                 o.eval(script); 
             } catch (JSException ex) {
                 throw new SAXException("Cannot evaluate script: " + ex.getMessage(), ex);
             }
         }
         return;
     }
      
     float componentAlignmentByName(String alignString) throws SAXException{
         String as = alignString.toLowerCase();
         if (as.equals("bottom")) { 
             return Component.BOTTOM_ALIGNMENT;
         } else if (as.equals("center")) {
             return Component.CENTER_ALIGNMENT;
         } else if (as.equals("left")) {
             return Component.LEFT_ALIGNMENT;
         } else if (as.equals("rigth")) {
             return Component.RIGHT_ALIGNMENT;
         } else if (as.equals("top")) {
             return Component.TOP_ALIGNMENT;
         }
         throw new SAXException("Unrecognized alignment: " + alignString);
     }

     int jTextFieldAlignmentByName(String alignString) throws SAXException {
         String as = alignString.toLowerCase();
         if (as.equals("left")) { 
             return JTextField.LEFT;
         } else if (as.equals("center")) {
             return JTextField.CENTER;
         } else if (as.equals("right")) {
             return JTextField.RIGHT;
         }
         throw new SAXException("Unrecognized alignment: " + alignString);
     }
     
     int styleByName(String styleName)  throws SAXException {
         String cbn = styleName.toLowerCase();
         if (cbn.equals("bold")) {
             return Font.BOLD;
         } else if (cbn.equals("italic")) { 
             return Font.ITALIC;
         } else if (cbn.equals("plain")) {
             return Font.PLAIN;
         } 
         throw new SAXException("Urecognized style: " + styleName);
     }
     
     Color colorByName(String colorName) throws SAXException {
         String cbn = colorName.toLowerCase();
         if (cbn.equals("black")) {
             return Color.black;
         } else if (cbn.equals("blue")) { 
             return Color.blue;
         } else if (cbn.equals("cyan")) {
             return Color.cyan;
         } else if (cbn.equals("darkgray")) {
             return Color.darkGray;
         } else if (cbn.equals("gray")) {
             return Color.gray;
         } else if (cbn.equals("green")) {
             return Color.green;
         } else if (cbn.equals("lightgray")) {
             return Color.lightGray;
         } else if (cbn.equals("magenta")) {
             return Color.magenta;
         } else if (cbn.equals("orange")) {
             return Color.orange;
         } else if (cbn.equals("pink")) {
             return Color.pink;
         } else if (cbn.equals("red")) {
             return Color.red;
         } else if (cbn.equals("white")) { 
             return Color.white;
         } else if (cbn.equals("yellow")) {
             return Color.yellow;
         }
         throw new SAXException("Unrecognized color: " + colorName);
     }     


    /**
     * Create a component either using the class or using a user provided script
     */
    Component createComponent(Class componentClass, AttributeList atts) throws SAXException {
        Component c;
        String creationScript = getAttribute("creationScript", atts);
        if (creationScript == null) {
            Object o;
            try {
                o=componentClass.newInstance();
            } catch (IllegalAccessException ex) {
                throw new SAXException("Not allowed to create a "+ componentClass, ex);
            } catch (InstantiationException ex) {
                throw new SAXException("Not allowed to create a "+ componentClass, ex);
            }
            if (! (componentClass.isInstance(o))) {
                throw new SAXException(componentClass + " is not a Component");
            }
            c = (Component)o;
        } else {
            Object o;
            try {
                 o = guiContext.global.evalAsFunction(creationScript); 
            } catch (JSException ex) {
                 throw new SAXException("Cannot evaluate CreationScript: " + ex.getMessage(), ex);
            }
            if (! (componentClass.isInstance(o))) {
                throw new SAXException("creationScript did not return a " + componentClass);
            }
            c = (Component)o;
        }
        return c;
    }
    
}