/*
 $Id$

 Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.

 Redistribution and use of this software and associated documentation
 ("Software"), with or without modification, are permitted provided
 that the following conditions are met:

 1. Redistributions of source code must retain copyright
    statements and notices.  Redistributions must also contain a
    copy of this document.

 2. Redistributions in binary form must reproduce the
    above copyright notice, this list of conditions and the
    following disclaimer in the documentation and/or other
    materials provided with the distribution.

 3. The name "groovy" must not be used to endorse or promote
    products derived from this Software without prior written
    permission of The Codehaus.  For written permission,
    please contact info@codehaus.org.

 4. Products derived from this Software may not be called "groovy"
    nor may "groovy" appear in their names without prior written
    permission of The Codehaus. "groovy" is a registered
    trademark of The Codehaus.

 5. Due credit should be given to The Codehaus -
    http://groovy.codehaus.org/

 THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
 ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 OF THE POSSIBILITY OF SUCH DAMAGE.

 */
package groovy.swing;

import groovy.lang.Closure;
import groovy.lang.MissingMethodException;

import groovy.model.DefaultTableModel;
import groovy.model.ValueHolder;
import groovy.model.ValueModel;

import groovy.swing.impl.ComponentFacade;
import groovy.swing.impl.ContainerFacade;
import groovy.swing.impl.DefaultAction;
import groovy.swing.impl.Factory;
import groovy.swing.impl.Startable;
import groovy.swing.impl.TableLayout;
import groovy.swing.impl.TableLayoutCell;
import groovy.swing.impl.TableLayoutRow;

import groovy.util.BuilderSupport;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Dialog;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.LayoutManager;
import java.awt.Window;

import java.text.Format;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.DefaultBoundedRangeModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JPopupMenu;
import javax.swing.JProgressBar;
import javax.swing.JRadioButton;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.JToolTip;
import javax.swing.JTree;
import javax.swing.JViewport;
import javax.swing.JWindow;
import javax.swing.KeyStroke;
import javax.swing.OverlayLayout;
import javax.swing.RootPaneContainer;
import javax.swing.SpinnerDateModel;
import javax.swing.SpinnerListModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.SpringLayout;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;

import org.codehaus.groovy.runtime.InvokerHelper;

/**
 * A helper class for creating Swing widgets using GroovyMarkup
 * 
 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
 * @version $Revision$
 */
public class SwingBuilder extends BuilderSupport {

    private Logger log = Logger.getLogger(getClass().getName());
    private Map factories = new HashMap();
    private Object constraints;
    private Map passThroughNodes = new HashMap();
    private Map widgets = new HashMap();
    // tracks all containing windows, for auto-owned dialogs
    private LinkedList containingWindows = new LinkedList();

    public SwingBuilder() {
        registerWidgets();
    }

    public Object getProperty(String name) {
        Object widget = widgets.get(name);
        if (widget == null) {
            return super.getProperty(name);
        }
        return widget;
    }

    protected void setParent(Object parent, Object child) {
        if (child instanceof Action) {
            Action action = (Action) child;
            try {
                InvokerHelper.setProperty(parent, "action", action);
            } catch (RuntimeException re) {
                // must not have an action property...
                // so we ignore it and go on
            }
            Object keyStroke = action.getValue("KeyStroke");
            //System.out.println("keystroke: " + keyStroke + " for: " + action);
            if (parent instanceof JComponent) {
                JComponent component = (JComponent) parent;
                KeyStroke stroke = null;
                if (keyStroke instanceof String) {
                    stroke = KeyStroke.getKeyStroke((String) keyStroke);
                }
                else if (keyStroke instanceof KeyStroke) {
                    stroke = (KeyStroke) keyStroke;
                }
                if (stroke != null) {
                    String key = action.toString();
                    component.getInputMap().put(stroke, key);
                    component.getActionMap().put(key, action);
                }
            }
        }
        else if (child instanceof LayoutManager) {
            if (parent instanceof RootPaneContainer) {
                RootPaneContainer rpc = (RootPaneContainer) parent;
                parent = rpc.getContentPane();
            }
            InvokerHelper.setProperty(parent, "layout", child);
        }
        else if (child instanceof JToolTip && parent instanceof JComponent) {
            ((JToolTip)child).setComponent((JComponent)parent);
        }
        else if (parent instanceof JTable && child instanceof TableColumn) {
            JTable table = (JTable) parent;
            TableColumn column = (TableColumn) child;
            table.addColumn(column);
        }
        else if (parent instanceof JTabbedPane && child instanceof Component) {
            JTabbedPane tabbedPane = (JTabbedPane) parent;
            tabbedPane.add((Component)child);
        } 
        else if (child instanceof Window) {
            // do nothing.  owner of window is set elsewhere, and this 
            // shouldn't get added to any parent as a child 
            // if it is a top level component anyway
        }
        else { 
            Component component = null;
            if (child instanceof Component) {
                component = (Component) child;
            }
            else if (child instanceof ComponentFacade) {
                ComponentFacade facade = (ComponentFacade) child;
                component = facade.getComponent();
            }
            if (component != null) {
                if (parent instanceof JFrame && component instanceof JMenuBar) {
                    JFrame frame = (JFrame) parent;
                    frame.setJMenuBar((JMenuBar) component);
                }
                else if (parent instanceof RootPaneContainer) {
                    RootPaneContainer rpc = (RootPaneContainer) parent;
                    if (constraints != null) {
                    	rpc.getContentPane().add(component, constraints);
                    } else {
                    	rpc.getContentPane().add(component);
                    }
                }
                else if (parent instanceof JScrollPane) {
                    JScrollPane scrollPane = (JScrollPane) parent;
                    if (child instanceof JViewport) {
                        scrollPane.setViewport((JViewport)component);
                    } 
                    else {
                        scrollPane.setViewportView(component);
                    }
                }
                else if (parent instanceof JSplitPane) {
                    JSplitPane splitPane = (JSplitPane) parent;
                    if (splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
                        if (splitPane.getTopComponent() == null) {
                            splitPane.setTopComponent(component);
                        }
                        else {
                            splitPane.setBottomComponent(component);
                        }
                    }
                    else {
                        if (splitPane.getLeftComponent() == null) {
                            splitPane.setLeftComponent(component);
                        }
                        else {
                            splitPane.setRightComponent(component);
                        }
                    }
                }
                else if (parent instanceof JMenuBar && component instanceof JMenu) {
                    JMenuBar menuBar = (JMenuBar) parent;
                    menuBar.add((JMenu) component);
                }
                else if (parent instanceof Container) {
                    Container container = (Container) parent;
                    if (constraints != null) {
                        container.add(component, constraints);
                    }
                    else {
                        container.add(component);
                    }
                }
                else if (parent instanceof ContainerFacade) {
                    ContainerFacade facade = (ContainerFacade) parent;
                    facade.addComponent(component);
                }
            }
        }
    }

    protected void nodeCompleted(Object parent, Object node) {
        // set models after the node has been completed
        if (node instanceof TableModel && parent instanceof JTable) {
            JTable table = (JTable) parent;
            TableModel model = (TableModel) node;
            table.setModel(model);
        }
        if (node instanceof Startable) {
            Startable startable = (Startable) node;
            startable.start();
        }
        if (node instanceof Window) {
            if (!containingWindows.isEmpty() && containingWindows.getLast() == node) {
                containingWindows.removeLast();
            }
        }
    }

    protected Object createNode(Object name) {
        return createNode(name, Collections.EMPTY_MAP);
    }

    protected Object createNode(Object name, Object value) {
        if (passThroughNodes.containsKey(name) && (value != null) && ((Class)passThroughNodes.get(name)).isAssignableFrom(value.getClass())) {
            // value may need to go into containing windows list
            if (value instanceof Window) {
                containingWindows.add(value);
            }
            return value;
        }
        else if (value instanceof String) {
            Object widget = createNode(name);
            if (widget != null) {
                InvokerHelper.invokeMethod(widget, "setText", value);
            }
            return widget;
        }
        else {
        	throw new MissingMethodException((String) name, getClass(), new Object[] {value}, false);
        }
    }

    protected Object createNode(Object name, Map attributes, Object value) {
        if (passThroughNodes.containsKey(name) && (value != null) && ((Class)passThroughNodes.get(name)).isAssignableFrom(value.getClass())) {
            // value may need to go into containing windows list
            if (value instanceof Window) {
                containingWindows.add(value);
            }
            handleWidgetAttributes(value, attributes);
            return value;
        }
        else { 
            Object widget = createNode(name, attributes);
            if (widget != null) {
                InvokerHelper.invokeMethod(widget, "setText", value.toString());
            }
            return widget;
        }
    }
    
    protected Object createNode(Object name, Map attributes) {
        String widgetName = (String) attributes.remove("id");
        constraints = attributes.remove("constraints");
        Object widget = null;
        if (passThroughNodes.containsKey(name)) {
            widget = attributes.get(name);
            if ((widget != null) && ((Class)passThroughNodes.get(name)).isAssignableFrom(widget.getClass())) {
                // value may need to go into containing windows list
                if (widget instanceof Window) {
                    containingWindows.add(widget);
                }
                attributes.remove(name);
            }
            else {
                widget = null;
            }
        }
        if (widget == null) {
            Factory factory = (Factory) factories.get(name);
            if (factory != null) {
                try {
                    widget = factory.newInstance(attributes);
                    if (widgetName != null) {
                        widgets.put(widgetName, widget);
                    }
                    if (widget == null) {
                        log.log(Level.WARNING, "Factory for name: " + name + " returned null");
                    }
                    else {
                        if (log.isLoggable(Level.FINE)) {
                            log.fine("For name: " + name + " created widget: " + widget);
                        }
                    }
                }
                catch (Exception e) {
                    throw new RuntimeException("Failed to create component for" + name + " reason: " + e, e);
                }
            }
            else {
                log.log(Level.WARNING, "Could not find match for name: " + name);
            }
        }
        handleWidgetAttributes(widget, attributes);
        return widget;
    }

    protected void handleWidgetAttributes(Object widget, Map attributes) {
        if (widget != null) {
            if (widget instanceof Action) {
                /** @todo we could move this custom logic into the MetaClass for Action */
                Action action = (Action) widget;

                Closure closure = (Closure) attributes.remove("closure");
                if (closure != null && action instanceof DefaultAction) {
                    DefaultAction defaultAction = (DefaultAction) action;
                    defaultAction.setClosure(closure);
                }

                Object accel = attributes.remove("accelerator");
                KeyStroke stroke = null;
                if (accel instanceof KeyStroke) {
                    stroke = (KeyStroke) accel;
                } else if (accel != null) {
                    stroke = KeyStroke.getKeyStroke(accel.toString());
                }
                action.putValue(Action.ACCELERATOR_KEY, stroke);

                Object mnemonic = attributes.remove("mnemonic");
                if ((mnemonic != null) && !(mnemonic instanceof Number)) {
                    mnemonic = new Integer(mnemonic.toString().charAt(0));
                }
                action.putValue(Action.MNEMONIC_KEY, mnemonic);

                for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
                    Map.Entry entry = (Map.Entry) iter.next();
                    String actionName = (String) entry.getKey();    // todo dk: misleading naming. this can be any property name

                    // typically standard Action names start with upper case, so lets upper case it            
                    actionName = capitalize(actionName);            // todo dk: in general, this shouldn't be capitalized
                    Object value = entry.getValue();

                    action.putValue(actionName, value);
                }

            }
            else {
                // some special cases...
                if (attributes.containsKey("buttonGroup")) {
                    Object o = attributes.get("buttonGroup");
                    if ((o instanceof ButtonGroup) && (widget instanceof AbstractButton)) {
                        ((AbstractButton)widget).getModel().setGroup((ButtonGroup)o);
                        attributes.remove("buttonGroup");
                    }
                }

                // this next statement nd if/else is a workaround until GROOVY-305 is fixed
                Object mnemonic = attributes.remove("mnemonic");
                if ((mnemonic != null) && (mnemonic instanceof Number)) {
                    InvokerHelper.setProperty(widget, "mnemonic", new Character((char)((Number)mnemonic).intValue()));
                } 
                else if (mnemonic != null) {
                    InvokerHelper.setProperty(widget, "mnemonic", new Character(mnemonic.toString().charAt(0)));
                } 

                // set the properties
                for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
                    Map.Entry entry = (Map.Entry) iter.next();
                    String property = entry.getKey().toString();
                    Object value = entry.getValue();
                    InvokerHelper.setProperty(widget, property, value);
                }
            }
        }
    }

    protected String capitalize(String text) {
        char ch = text.charAt(0);
        if (Character.isUpperCase(ch)) {
            return text;
        }
        StringBuffer buffer = new StringBuffer(text.length());
        buffer.append(Character.toUpperCase(ch));
        buffer.append(text.substring(1));
        return buffer.toString();
    }

    protected void registerWidgets() {
        //
        // non-widget support classes
        //
        registerBeanFactory("action", DefaultAction.class);
        passThroughNodes.put("action", javax.swing.Action.class);
        registerBeanFactory("buttonGroup", ButtonGroup.class);
        registerFactory("map", new Factory() {      // todo dk: is that still needed?
            public Object newInstance(Map properties)
                throws InstantiationException, InstantiationException, IllegalAccessException {
                return properties;
            }
        });
        // ulimate pass through type
        passThroughNodes.put("widget", java.awt.Component.class);

        //
        // standalone window classes
        //
        registerFactory("dialog", new Factory() {
            public Object newInstance(Map properties)
                throws InstantiationException, InstantiationException, IllegalAccessException {
                return createDialog(properties);
            }
        });
        registerFactory("frame", new Factory() {
            public Object newInstance(Map properties)
                throws InstantiationException, InstantiationException, IllegalAccessException {
                return createFrame(properties);
            }
        });
        registerBeanFactory("fileChooser", JFileChooser.class);
        registerFactory("frame", new Factory() {        // todo dk: frame registered twice ???
            public Object newInstance(Map properties)
                throws InstantiationException, InstantiationException, IllegalAccessException {
                return createFrame(properties);
            }
        });
        registerBeanFactory("optionPane", JOptionPane.class);
        registerFactory("window", new Factory() {
            public Object newInstance(Map properties)
                throws InstantiationException, InstantiationException, IllegalAccessException {
                return createWindow(properties);
            }
        });
        
        //
        // widgets
        //
        registerBeanFactory("button", JButton.class);
        registerBeanFactory("checkBox", JCheckBox.class);
        registerBeanFactory("checkBoxMenuItem", JCheckBoxMenuItem.class);
        registerBeanFactory("colorChooser", JColorChooser.class);
        registerFactory("comboBox", new Factory() {
            public Object newInstance(Map properties)
                throws InstantiationException, InstantiationException, IllegalAccessException {
                return createComboBox(properties);
            }
        });
        registerBeanFactory("desktopPane", JDesktopPane.class);
        registerBeanFactory("editorPane", JEditorPane.class);
        registerFactory("formattedTextField", new Factory() {
            public Object newInstance(Map properties)
                throws InstantiationException, InstantiationException, IllegalAccessException {
                return createFormattedTextField(properties);
            }
        });
        registerBeanFactory("internalFrame", JInternalFrame.class);
        registerBeanFactory("label", JLabel.class);
        registerBeanFactory("layeredPane", JLayeredPane.class);
        registerBeanFactory("list", JList.class);
        registerBeanFactory("menu", JMenu.class);
        registerBeanFactory("menuBar", JMenuBar.class);
        registerBeanFactory("menuItem", JMenuItem.class);
        registerBeanFactory("panel", JPanel.class);
        registerBeanFactory("passwordField", JPasswordField.class);
        registerBeanFactory("popupMenu", JPopupMenu.class);
        registerBeanFactory("progressBar", JProgressBar.class);
        registerBeanFactory("radioButton", JRadioButton.class);
        registerBeanFactory("radioButtonMenuItem", JRadioButtonMenuItem.class);
        registerBeanFactory("scrollBar", JScrollBar.class);
        registerBeanFactory("scrollPane", JScrollPane.class);
        registerBeanFactory("separator", JSeparator.class);
        registerBeanFactory("slider", JSlider.class);
        registerBeanFactory("spinner", JSpinner.class);
        registerFactory("splitPane", new Factory() {
            public Object newInstance(Map properties) {
                JSplitPane answer = new JSplitPane();
                answer.setLeftComponent(null);
                answer.setRightComponent(null);
                answer.setTopComponent(null);
                answer.setBottomComponent(null);
                return answer;
            }
        });
        registerBeanFactory("tabbedPane", JTabbedPane.class);
        registerBeanFactory("table", JTable.class);
        registerBeanFactory("textArea", JTextArea.class);
        registerBeanFactory("textPane", JTextPane.class);
        registerBeanFactory("textField", JTextField.class);
        registerBeanFactory("toggleButton", JToggleButton.class);
        registerBeanFactory("toolBar", JToolBar.class);
        //registerBeanFactory("tooltip", JToolTip.class); // doens't work, user toolTipText property
        registerBeanFactory("tree", JTree.class);
        registerBeanFactory("viewport", JViewport.class); // sub class?

        //
        // MVC models   
        //
        registerBeanFactory("boundedRangeModel", DefaultBoundedRangeModel.class);

        // spinner models
	registerBeanFactory("spinnerDateModel", SpinnerDateModel.class);
        registerBeanFactory("spinnerListModel", SpinnerListModel.class);
        registerBeanFactory("spinnerNumberModel", SpinnerNumberModel.class);

	// table models
        registerFactory("tableModel", new Factory() {
            public Object newInstance(Map properties) {
                ValueModel model = (ValueModel) properties.remove("model");
                if (model == null) {
                    Object list = properties.remove("list");
                    if (list == null) {
                        list = new ArrayList();
                    }
                    model = new ValueHolder(list);
                }
                return new DefaultTableModel(model);
            }
        });
        passThroughNodes.put("tableModel", javax.swing.table.TableModel.class);

        registerFactory("propertyColumn", new Factory() {
            public Object newInstance(Map properties) {
                Object current = getCurrent();
                if (current instanceof DefaultTableModel) {
                    DefaultTableModel model = (DefaultTableModel) current;
                    Object header = properties.remove("header");
                    if (header == null) {
                        header = "";
                    }
                    String property = (String) properties.remove("propertyName");
                    if (property == null) {
                        throw new IllegalArgumentException("Must specify a property for a propertyColumn");
                    }
                    Class type = (Class) properties.remove("type");
                    if (type == null) {
                        type = Object.class;
                    }
                    return model.addPropertyColumn(header, property, type);
                }
                else {
                    throw new RuntimeException("propertyColumn must be a child of a tableModel");
                }
            }
        });

        registerFactory("closureColumn", new Factory() {
            public Object newInstance(Map properties) {
                Object current = getCurrent();
                if (current instanceof DefaultTableModel) {
                    DefaultTableModel model = (DefaultTableModel) current;
                    Object header = properties.remove("header");
                    if (header == null) {
                        header = "";
                    }
                    Closure readClosure = (Closure) properties.remove("read");
                    if (readClosure == null) {
                        throw new IllegalArgumentException("Must specify 'read' Closure property for a closureColumn");
                    }
                    Closure writeClosure = (Closure) properties.remove("write");
                    Class type = (Class) properties.remove("type");
                    if (type == null) {
                        type = Object.class;
                    }
                    return model.addClosureColumn(header, readClosure, writeClosure, type);
                }
                else {
                    throw new RuntimeException("propertyColumn must be a child of a tableModel");
                }
            }
        });


        //Standard Layouts
        registerBeanFactory("borderLayout", BorderLayout.class);
        registerBeanFactory("cardLayout", CardLayout.class);
        registerBeanFactory("flowLayout", FlowLayout.class);
        registerBeanFactory("gridBagLayout", GridBagLayout.class);
        registerBeanFactory("gridLayout", GridLayout.class);
        registerBeanFactory("overlayLayout", OverlayLayout.class);
        registerBeanFactory("springLayout", SpringLayout.class);
        registerBeanFactory("gridBagConstraints", GridBagConstraints.class);
        registerBeanFactory("gbc", GridBagConstraints.class); // shortcut name

        // box layout
        registerFactory("boxLayout", new Factory() {
            public Object newInstance(Map properties)
                throws InstantiationException, InstantiationException, IllegalAccessException {
                return createBoxLayout(properties);
            }
        });

        // Box related layout components
        registerFactory("hbox", new Factory() {
            public Object newInstance(Map properties) {
                return Box.createHorizontalBox();
            }
        });
        registerFactory("hglue", new Factory() {
            public Object newInstance(Map properties) {
                return Box.createHorizontalGlue();
            }
        });
        registerFactory("hstrut", new Factory() {
            public Object newInstance(Map properties) {
                try {
                Object num = properties.remove("width");
                if (num instanceof Number) {
                    return Box.createHorizontalStrut(((Number)num).intValue());
                } else {
                    return Box.createHorizontalStrut(6);
                }
                } catch (RuntimeException re) {
                    re.printStackTrace(System.out);
                    throw re;
                }
            }
        });
        registerFactory("vbox", new Factory() {
            public Object newInstance(Map properties) {
                return Box.createVerticalBox();
            }
        });
        registerFactory("vglue", new Factory() {
            public Object newInstance(Map properties) {
                return Box.createVerticalGlue();
            }
        });
        registerFactory("vstrut", new Factory() {
            public Object newInstance(Map properties) {
                Object num = properties.remove("height");
                if (num instanceof Number) {
                    return Box.createVerticalStrut(((Number)num).intValue());
                } else {
                    return Box.createVerticalStrut(6);
                }
            }
        });
        registerFactory("glue", new Factory() {
            public Object newInstance(Map properties) {
                return Box.createGlue();
            }
        });
        registerFactory("rigidArea", new Factory() {
            public Object newInstance(Map properties) {
                Dimension dim;
                Object o = properties.remove("size");
                if (o instanceof Dimension) {
                    dim = (Dimension) o;
                } else {
                    int w, h;
                    o = properties.remove("width");
                    w = ((o instanceof Number)) ? ((Number)o).intValue() : 6;
                    o = properties.remove("height");
                    h = ((o instanceof Number)) ? ((Number)o).intValue() : 6;
                    dim = new Dimension(w, h);
                }
                return Box.createRigidArea(dim);
            }
        });
        
        // table layout
        registerBeanFactory("tableLayout", TableLayout.class);
        registerFactory("tr", new Factory() {
            public Object newInstance(Map properties) {
                Object parent = getCurrent();
                if (parent instanceof TableLayout) {
                    return new TableLayoutRow((TableLayout) parent);
                }
                else {
                    throw new RuntimeException("'tr' must be within a 'tableLayout'");
                }
            }
        });
        registerFactory("td", new Factory() {
            public Object newInstance(Map properties) {
                Object parent = getCurrent();
                if (parent instanceof TableLayoutRow) {
                    return new TableLayoutCell((TableLayoutRow) parent);
                }
                else {
                    throw new RuntimeException("'td' must be within a 'tr'");
                }
            }
        });
    }

    protected Object createBoxLayout(Map properties) {
        Object parent = getCurrent();
        if (parent instanceof Container) {
            Object axisObject = properties.remove("axis");
            int axis = BoxLayout.X_AXIS;
            if (axisObject != null) {
                Integer i = (Integer) axisObject;
                axis = i.intValue();
            }
            
            Container target = (Container) parent;
            if (target instanceof RootPaneContainer) {
            	target = ((RootPaneContainer) target).getContentPane();
            }
            BoxLayout answer = new BoxLayout(target, axis);
            
            // now lets try set the layout property
            InvokerHelper.setProperty(parent, "layout", answer);
            return answer;
        }
        else {
            throw new RuntimeException("Must be nested inside a Container");
        }
    }

    protected Object createDialog(Map properties) {
        JDialog dialog;
        Object owner = properties.remove("owner");
        // if owner not explicit, use the last window type in the list
        if ((owner == null) && !containingWindows.isEmpty()) {
            owner = containingWindows.getLast();
        }
        if (owner instanceof Frame) {
            dialog = new JDialog((Frame) owner);
        }
        else if (owner instanceof Dialog) {
            dialog = new JDialog((Dialog) owner);
        }
        else {
            dialog = new JDialog();
        }
        containingWindows.add(dialog);
        return dialog;
    }
    
    /**
     * Uses 'format," or "value,"  (in order)
     *
     */
    protected Object createFormattedTextField(Map properties) {
        JFormattedTextField ftf;
        if (properties.containsKey("format")) {
            ftf = new JFormattedTextField((Format) properties.remove("format"));
        }
        else if (properties.containsKey("value")) {
            ftf = new JFormattedTextField(properties.remove("value"));
        }
        else {
            ftf = new JFormattedTextField();
        }
        return ftf;
    }

    protected Object createFrame(Map properties) {
        JFrame frame = new JFrame();
        containingWindows.add(frame);
        return frame;
    }
    
    protected Object createWindow(Map properties) {
        JWindow window;
        Object owner = properties.remove("owner");
        // if owner not explicit, use the last window type in the list
        if ((owner == null) && !containingWindows.isEmpty()) {
            owner = containingWindows.getLast();
        }
        if (owner instanceof Frame) {
            window = new JWindow((Frame) owner);
        }
        else if (owner instanceof Window) {
            window = new JWindow((Window) owner);
        }
        else {
            window = new JWindow();
        }
        containingWindows.add(window);
        return window;
    }

    protected Object createComboBox(Map properties) {
        Object items = properties.remove("items");
        if (items instanceof Vector) {
            return new JComboBox((Vector) items);
        }
        else if (items instanceof List) {
            List list = (List) items;
            return new JComboBox(list.toArray());
        }
        else if (items instanceof Object[]) {
            return new JComboBox((Object[]) items);
        }
        else {
            return new JComboBox();
        }
    }

    protected void registerBeanFactory(String name, final Class beanClass) {
        registerFactory(name, new Factory() {
            public Object newInstance(Map properties) throws InstantiationException, IllegalAccessException {
                return beanClass.newInstance();
            }
        });

    }

    protected void registerFactory(String name, Factory factory) {
        factories.put(name, factory);
    }
}
