/*
 * $Id:  $
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package groovy.swing

import java.awt.*
import java.awt.event.InputEvent
import java.awt.event.KeyEvent
import java.text.SimpleDateFormat
import javax.swing.*
import javax.swing.JPopupMenu.Separator as JPopupMenu_Separator
import javax.swing.JToolBar.Separator as JToolBar_Separator
import javax.swing.text.DateFormatter
import javax.swing.text.NumberFormatter
import javax.swing.plaf.metal.MetalLookAndFeel
import javax.swing.border.TitledBorder
import groovy.ui.Console

class SwingBuilderTest extends GroovyTestCase {

    private Boolean isHeadless

    private Boolean isHeadless() {
        if (isHeadless != null)
          return isHeadless;

        try {
            new JFrame("testing")
            isHeadless = false
        } catch (java.awt.HeadlessException he) {
            isHeadless = true
        }
        return isHeadless
    }

    void testNamedWidgetCreation() {
        if (isHeadless()) return

        def topLevelWidgets = [
            frame: [JFrame.class, true],
            dialog: [JDialog.class, true],
            window: [JWindow.class, false],
            fileChooser: [JFileChooser.class, false],
            optionPane: [JOptionPane.class, false]
        ]
        def swing = new SwingBuilder()
        topLevelWidgets.each{ name, widgetInfo ->
            if (widgetInfo[1])
                swing."$name"(id:"${name}Id".toString(), title:"This is my $name")
            else
                swing."$name"(id:"${name}Id".toString())
            def widget = swing."${name}Id"
            assert widget.class == widgetInfo[0]
            if (widgetInfo[1]) assert widget.title == "This is my $name"
        }
    }

    void testLayoutCreation() {
        if (isHeadless()) return

        def layouts = [
            borderLayout: BorderLayout.class,
            cardLayout: CardLayout.class,
            flowLayout: FlowLayout.class,
            gridBagLayout: GridBagLayout.class,
            gridLayout: GridLayout.class,
//            overlayLayout: OverlayLayout.class,
            springLayout: SpringLayout.class,
//            boxLayout: BoxLayout.class
        ]
        def swing = new SwingBuilder()
        layouts.each{ name, expectedLayoutClass ->
            def frame = swing.frame(){
               "$name"()
            }
            assert frame.contentPane.layout.class == expectedLayoutClass
        }
    }

    void testWidgetCreation() {
        if (isHeadless()) return

        def widgets = [
            button: JButton.class,
            checkBox: JCheckBox.class,
            checkBoxMenuItem: JCheckBoxMenuItem.class,
            colorChooser: JColorChooser.class,
            comboBox: JComboBox.class,
            desktopPane: JDesktopPane.class,
            editorPane: JEditorPane.class,
            formattedTextField: JFormattedTextField.class,
            internalFrame: JInternalFrame.class,
            label: JLabel.class,
            layeredPane: JLayeredPane.class,
            list: JList.class,
            menu: JMenu.class,
            menuBar: JMenuBar.class,
            menuItem: JMenuItem.class,
            panel: JPanel.class,
            passwordField: JPasswordField.class,
            popupMenu: JPopupMenu.class,
            progressBar: JProgressBar.class,
            radioButton: JRadioButton.class,
            radioButtonMenuItem: JRadioButtonMenuItem.class,
            scrollBar: JScrollBar.class,
            scrollPane: JScrollPane.class,
            separator: JSeparator.class,
            slider: JSlider.class,
            spinner: JSpinner.class,
            splitPane: JSplitPane.class,
            tabbedPane: JTabbedPane.class,
            table: JTable.class,
            textArea: JTextArea.class,
            textPane: JTextPane.class,
            textField: JTextField.class,
            toggleButton: JToggleButton.class,
            toolBar: JToolBar.class,
            tree: JTree.class,
            viewport: JViewport.class,
        ]
        def swing = new SwingBuilder()
        widgets.each{ name, expectedLayoutClass ->
            def frame = swing.frame(){
               "$name"(id:"${name}Id".toString())
            }
            assert swing."${name}Id".class == expectedLayoutClass
        }
    }

    void testButtonGroupOnlyForButtons() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        def buttonGroup = swing.buttonGroup()
        shouldFail(MissingPropertyException) {
            swing.label(buttonGroup:buttonGroup)
        }
    }

    void testWidget() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        def label = swing.label("By Value:")
        def widgetByValue = swing.widget(label)
        assert widgetByValue != null
        def widgetByLabel = swing.widget(widget: label)
        assert widgetByLabel != null
    }

    void testTableColumn() {
        if (isHeadless()) return

        // TODO is this required?
        def swing = new SwingBuilder()
        swing.table{
            tableColumn()
        }
    }

    void testSplitPane() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        def buttonGroup = swing.buttonGroup()
        def frame = swing.frame(){
            splitPane(id:'hsplit', orientation: JSplitPane.HORIZONTAL_SPLIT) {
                button(id:'left', buttonGroup:buttonGroup)
                button(id:'right', buttonGroup:buttonGroup)
            }
            splitPane(id:'vsplit', orientation: JSplitPane.VERTICAL_SPLIT) {
                button(id:'top')
                button(id:'bottom')
            }
        }
        assert swing.hsplit.leftComponent == swing.left
        assert swing.hsplit.rightComponent == swing.right
        assert swing.vsplit.topComponent == swing.top
        assert swing.vsplit.bottomComponent == swing.bottom
    }

    void testNestedWindows() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        swing.window (id:'root') {
            window(id:'child1')
            frame(id:'child2') {
                window(id:'child2_1')
            }
        }
        swing.window (id:'root2')

        //assert swing.root.owner == null;
        assert swing.child1.owner == swing.root
        assert swing.child2.owner == null // it's a frame, frames have no owners
        assert swing.child2_1.owner == swing.child2

        assert swing.root2.owner != swing.root
        assert swing.root2.owner != swing.child1
        assert swing.root2.owner != swing.child2
        assert swing.root2.owner != swing.child2_1

        swing.panel {
            swing.frame()
            swing.window()
            swing.dialog()
        }
    }

    void testFrames() {
        if (isHeadless()) return
        def swing = new SwingBuilder()

        swing.frame(id:'frame') {
            button('test', id:'button', defaultButton:true)
        }
        assert swing.frame.rootPane.defaultButton == swing.button
        assert swing.button.defaultButton
    }

    void testDialogs() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        swing.dialog(id:'d1')
        swing.frame(id:'f') { dialog(id:'fd') }
        swing.dialog(id:'d') { dialog(id:'dd') }
        swing.dialog(id:'d2')

        //assert swing.d1.owner == null
        assert swing.fd.owner == swing.f
        assert swing.dd.owner == swing.d

        assert swing.d2.owner != swing.dd
        assert swing.d2.owner != swing.fd
        assert swing.d2.owner != swing.d
        assert swing.d2.owner != swing.f
        assert swing.d2.owner != swing.d1
    }

    void testWindows() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        swing.window()
        swing.frame{ window() }
        swing.dialog{ window() }
    }

    void testNodeCreation() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        def frame = swing.frame(){
            // 4 valid parameter combinations
            button()
            button('Text')
            button(label:'Label')
            button(label:'Label', 'Text')
        }
        shouldFail(){
            frame = swing.frame(){
                // invalid parameter
                button(new Date())
            }
        }
    }

    void testSetMnemonic() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        swing.panel(layout:new BorderLayout()) {
            label(id:'label0', text:'Name0', mnemonic:48)
            label(id:'label1', text:'Name1', mnemonic:'N')
        }
        int expected0 = '0'
        int expected1 = 'N'
        assert swing.label0.displayedMnemonic == expected0
        assert swing.label1.displayedMnemonic == expected1
        swing.menuBar{
            menu{
                menuItem {
                    action(id:'actionId', name:'About', mnemonic:'A')
                }
            }
        }
        int expected2 = 'A'
        int actual = swing.actionId.getValue(Action.MNEMONIC_KEY)
        assert  actual == expected2
    }

    void testBuilderProperties() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        assert swing.class.name == 'groovy.swing.SwingBuilder'
    }

    void testFormattedTextField() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        def dummy = new Date()
        def field = swing.formattedTextField(value:dummy)
        assert field.value == dummy
        assert field.formatter.class == DateFormatter.class
        def dummyFormatter = new SimpleDateFormat()
        field = swing.formattedTextField(format:dummyFormatter)
        assert field.formatter.class == DateFormatter.class
        field = swing.formattedTextField()
        field.value = 3
        assert field.formatter.class == NumberFormatter.class
    }

    void testTabbedPane() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        swing.tabbedPane(id:'tp') {
            panel(id:'p1', name:'Title 1')
            panel(id:'p2')
            panel(id:'p3', title:'Title 3')
            panel(id:'p4', title:'Title 4', name:'Name 4')
            panel(id:'p5', title:'Title 5', tabIcon: imageIcon(Console.ICON_PATH, id:'i5'))
            panel(id:'p6', title:'Title 6', tabDisabledIcon: imageIcon(Console.ICON_PATH, id:'i6'))
            panel(id:'p7', title:'Title 7', tabToolTip:'tip 7')
            panel(id:'p8', title:'Title 8', tabBackground:Color.GREEN)
            panel(id:'p9', title:'Title 9', tabForeground:Color.GREEN)
            panel(id:'pA', title:'Title A', tabEnabled:false)
            panel(id:'pB', title:'Title B', tabMnemonic: 'T');
            panel(id:'pC', title:'Title C', tabDisplayedMnemonicIndex: 2);
        }

        assert swing.tp.tabCount == 12 
        assert swing.tp.indexOfComponent(swing.p1) == 0
        assert swing.tp.indexOfComponent(swing.p2) == 1
        assert swing.tp.indexOfComponent(swing.p3) == 2
        assert swing.tp.indexOfComponent(swing.p4) == 3
        assert swing.tp.indexOfTab('Title 1') == 0
        assert swing.tp.indexOfTab('Title 3') == 2
        assert swing.tp.indexOfTab('Title 4') == 3
        assert swing.tp.getIconAt(4) == swing.i5
        assert swing.tp.getDisabledIconAt(5) == swing.i6
        assert swing.tp.getToolTipTextAt(6) == 'tip 7'
        assert swing.tp.getBackgroundAt(7) == Color.GREEN
        assert swing.tp.getForegroundAt(8) == Color.GREEN
        assert swing.tp.isEnabledAt(9) == false
        assert swing.tp.getMnemonicAt(10) == 0x54
        assert swing.tp.getDisplayedMnemonicIndexAt(11) == 2

        swing.tabbedPane(id:'tp', selectedComponent:swing.p2) {
            panel(p1, name:'Title 1')
            panel(p2)
            panel(p3)
        }
        assert swing.tp.selectedIndex == 1
        assert swing.tp.selectedComponent == swing.p2

        swing.tabbedPane(id:'tp', selectedIndex:1) {
            panel(p1, name:'Title 1')
            panel(p2)
            panel(p3)
        }
        assert swing.tp.selectedIndex == 1
        assert swing.tp.selectedComponent == swing.p2

    }

    void testComboBox() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        Object[] objects = ['a','b']
        def list = ['c', 'd', 'e']
        def vector = new Vector(['f', 'g', 'h', 'i'])
        assert swing.comboBox(items:objects).itemCount == 2
        assert swing.comboBox(items:list).itemCount == 3
        assert swing.comboBox(items:vector).itemCount == 4
    }

    void testMisplacedActionsAreIgnored() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        // labels don't support actions; should be ignored
        swing.label{
            action(id:'actionId', Name:'about', mnemonic:'A', closure:{x->x})
            map()
        }
        swing.panel{
            borderLayout{
                // layouts don't support actions, will be ignored
                action(id:'actionId')
            }
        }
    }

    void testBoxLayout() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        def message = shouldFail{
            swing.boxLayout()
        }
        assert message.contains('Must be nested inside a Container')
        // default is X_AXIS
        swing.panel(id:'panel'){
            boxLayout(id:'layout1')
        }
        // can also set explicit axis
        swing.frame(id:'frame'){
            boxLayout(id:'layout2', axis:BoxLayout.Y_AXIS)
        }
    }

    void testKeystrokesWithinActions() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        swing.panel{
            button(id:'buttonId'){
                action(id:'action1', keyStroke:'ctrl W')
                action(id:'action2',
                    keyStroke:KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.ALT_MASK))
            }
        }
        def component = swing.buttonId
        def expected1 = swing.action1.toString()
        def expected2 = swing.action2.toString()
        def keys = component.actionMap.allKeys().toList()
        assert keys.contains(expected1)
        assert keys.contains(expected2)
        def inputMap = component.inputMap
        def values = inputMap.allKeys().toList().collect{ inputMap.get(it) }
        assert values.contains(expected1)
        assert values.contains(expected2)
    }

    void testSetAccelerator() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        def help = swing.action(accelerator:'F1')
        def about = swing.action(accelerator:KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.CTRL_MASK))
        assert help.getValue(Action.ACCELERATOR_KEY).toString()
                             .indexOf(KeyEvent.getKeyText(KeyEvent.VK_F1)) > -1
        def aboutKeyStroke = about.getValue(Action.ACCELERATOR_KEY)
        assert aboutKeyStroke.keyCode == KeyEvent.VK_SPACE
        assert(aboutKeyStroke.modifiers & InputEvent.CTRL_MASK) != 0
    }

    Action verifyAccel(Action action, int mustHave = 0) {
        int mods = action.getValue(Action.ACCELERATOR_KEY).modifiers
        assert mods != 0
        assert (mods & mustHave) == mustHave
        // don't assert (modd % musthave) != 0 because mustHave may be the platform shortcut modifer
        return action
    }

    void testSetAcceleratorShortcuts() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        char q = 'Q'
        swing.actions {
            verifyAccel(action(accelerator: shortcut(q)))
            verifyAccel(action(accelerator: shortcut(q, InputEvent.SHIFT_DOWN_MASK)), InputEvent.SHIFT_DOWN_MASK)
            verifyAccel(action(accelerator: shortcut(KeyEvent.VK_NUMPAD5)))
            verifyAccel(action(accelerator: shortcut(KeyEvent.VK_NUMPAD5, InputEvent.SHIFT_DOWN_MASK)), InputEvent.SHIFT_DOWN_MASK)
            verifyAccel(action(accelerator: shortcut('DELETE')))
            verifyAccel(action(accelerator: shortcut('DELETE', InputEvent.SHIFT_DOWN_MASK)), InputEvent.SHIFT_DOWN_MASK)
        }
    }

    void testBorderLayoutConstraints() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        swing.internalFrame(id:'frameId',
                border:BorderFactory.createTitledBorder(BorderFactory.createLoweredBevelBorder())) {
            swing.frameId.contentPane.layout = new BorderLayout()
            vbox(id:'vboxId', constraints:BorderLayout.NORTH)
            hbox(id:'hboxId', constraints:BorderLayout.WEST)
            rigidArea(id:'area1', constraints:BorderLayout.EAST, size:[3,4] as Dimension)
            rigidArea(id:'area2', constraints:BorderLayout.SOUTH, width:30, height:40)
            scrollPane(id:'scrollId', constraints:BorderLayout.CENTER,
                border:BorderFactory.createRaisedBevelBorder()) {
                glue()
                vglue()
                hglue()
                vstrut()
                vstrut(height:8)
                hstrut()
                hstrut(width:8)
                rigidArea(id:'area3')
                viewport()
            }
        }
        assert swing.vboxId.parent == swing.frameId.contentPane
        assert swing.hboxId.parent == swing.frameId.contentPane
        assert swing.scrollId.parent == swing.frameId.contentPane
    }

    void testPropertyColumn() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        def msg = shouldFail{
            swing.propertyColumn()
        }
        assert msg.contains('propertyColumn must be a child of a tableModel')
        msg = shouldFail{
            swing.table{
                tableModel(){
                    propertyColumn()
                }
            }
        }
        assert msg.contains("Must specify a property for a propertyColumn"): \
            "Instead found message: " + msg
        swing.table{
            tableModel(id: 'model'){
                propertyColumn(propertyName:'p')
                propertyColumn(propertyName:'ph', header: 'header')
                propertyColumn(propertyName:'pt', type: String)
                propertyColumn(propertyName:'pth', type: String, header: 'header')
                propertyColumn(propertyName:'pe', editable:false)
                propertyColumn(propertyName:'peh', editable:false, header: 'header')
                propertyColumn(propertyName:'pet', editable:false, type: String, )
                propertyColumn(propertyName:'peth', editable:false, type: String, header: 'header')
            }
        }
        swing.model.columnList.each { col ->
            def propName = col.valueModel.property
            assert (col.headerValue == 'header') ^ !propName.contains('h')
            assert (col.type == String) ^ !propName.contains('t')
            assert col.valueModel.editable ^ propName.contains('e')
        }
    }

    void testClosureColumn() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        def msg = shouldFail{
            swing.closureColumn()
        }
        assert msg.contains('closureColumn must be a child of a tableModel')
        msg = shouldFail{
            swing.table{
                tableModel(){
                    closureColumn()
                }
            }
        }
        assert msg.contains("Must specify 'read' Closure property for a closureColumn"): \
            "Instead found message: " + msg
        def closure = { x -> x }
        def table = swing.table {
            tableModel(){
                closureColumn(read:closure, write:closure, header:'header')
            }
            tableModel(model:new groovy.model.ValueHolder('foo')){
                closureColumn(read:closure, type:String.class)
            }
            tableModel(list:['a','b']){
                closureColumn(read:closure, type:String.class)
            }
        }

        assert table.columnModel.class.name == 'groovy.model.DefaultTableModel$MyTableColumnModel'
    }

    void testTableModelChange() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        def table = swing.table {
            tableModel {
                propertyColumn(propertyName:'p')
                propertyColumn(propertyName:'ph', header: 'header')
                propertyColumn(propertyName:'pt', type: String)
            }
        }

        def sorter = new groovy.inspect.swingui.TableSorter(table.model)
        table.model = sorter

        //GROOVY-2111 - resetting the model w/ a pass-through cleared the columns
        assert table.columnModel.columnCount == 3
    }

    void testTableModelValues() {
        if (isHeadless()) return

        def squares  = [
            [ val: 1, square:  1 ],
            [ val: 2, square:  4 ],
            [ val: 3, square:  9 ],
            [ val: 4, square: 16 ]
        ]

        def swing = new SwingBuilder()
        def frame = swing.frame(title: 'Tabelle',
                        windowClosing: { System.exit(0) } ) {
            scrollPane {
                table(id:'table') {
                    tableModel(list: squares) {
                        propertyColumn(header: "Wert", propertyName: "val")
                        closureColumn(header: "Quadrat", read: { it.square })
                    }
                }
            }
        }

        squares.eachWithIndex {it, i ->
            assert swing.table.getValueAt(i, 0) == it.val
            assert swing.table.getValueAt(i, 1) == it.square
        }
    }

    void testSetConstraints() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        swing.panel(layout:new BorderLayout()) {
            label(text:'Name', constraints:BorderLayout.CENTER)
        }
    }

    void testSetToolTipText() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        swing.panel(layout:new BorderLayout()) {
            label(id:'labelId', text:'Name', toolTipText:'This is the name field')
        }

    }

    void testTableLayout() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        def msg = shouldFail(RuntimeException){
            def frame = swing.frame(){
                tr()
            }
        }
        assert msg == "'tr' must be within a 'tableLayout'"
        msg = shouldFail(RuntimeException){
            def frame = swing.frame(){
                tableLayout(){
                    td()
                }
            }
        }
        assert msg == "'td' must be within a 'tr'"
        swing.frame(id:'frame'){
            tableLayout(){
                tr {
                    td {
                        label(id:'label')
                    }
                }
            }
        }

        assert swing.label.parent
        assert swing.label.parent.parent
        assert swing.label.parent.parent.parent
        assert swing.label.parent.parent.parent.parent
        assert swing.frame == swing.label.parent.parent.parent.parent.parent
    }

    void testAttributeOrdering() {
        if (isHeadless()) return

        def swing = new SwingBuilder()

        def frame = swing.frame(
            size:[500,500],
            locationRelativeTo:null
        )
        def locationFirst = frame.location

        frame = swing.frame(
            locationRelativeTo:null,
            size:[500,500]
        )
        def locationLast = frame.location

        // setLocationReativeTo(null) places the component in the center of
        // the screen, relative to it's size, so centering it after sizing it
        // should result in a 250,250 offset from centering it before sizing it
        assert locationFirst != locationLast
    }

    void testWidgetPassthroughConstraints() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        def foo = swing.button('North')
        def frame = swing.frame {
            borderLayout()
            widget(foo, constraints: BorderLayout.NORTH)
            // a failed test throws MissingPropertyException by now
        }
    }

    void testGROOVY1837ReuseAction() {
        if (isHeadless()) return

        def swing = new SwingBuilder()

        def testAction = swing.action(name:'test', mnemonic:'A', accelerator:'ctrl R')
        assert testAction.getValue(Action.MNEMONIC_KEY) != null
        assert testAction.getValue(Action.ACCELERATOR_KEY) != null

        swing.action(testAction)
        assert testAction.getValue(Action.MNEMONIC_KEY) != null
        assert testAction.getValue(Action.ACCELERATOR_KEY) != null
    }

    void testSeparators() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        swing.frame {
            menu("test") {
                separator(id:"menuSep")
            }
            toolBar {
                separator(id:"tbSep")
            }
            separator(id:"sep")
        }
        assert swing.menuSep instanceof JPopupMenu_Separator
        assert swing.tbSep instanceof JToolBar_Separator
        assert swing.sep instanceof JSeparator
    }

    void testCollectionNodes() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        def collection = swing.actions {
            action(id:'test')
        }
        assert collection.contains(swing.test)
    }

    void testFactoryCornerCases() {
        if (isHeadless()) return

        def swing = new SwingBuilder()
        assert swing.bogusWidget() == null

        swing.registerFactory("nullWidget",
            [newInstance:{builder, name, value, props -> null}] as AbstractFactory)
        assert swing.nullWidget() == null
    }

    void testFactoryLogging() {
        def logger = java.util.logging.Logger.getLogger(SwingBuilder.class.name)
        def oldLevel = logger.getLevel()
        logger.setLevel(java.util.logging.Level.FINE)
        def swing = new SwingBuilder()
        swing.label()
        logger.setLevel(oldLevel)
    }

    void testEnhancedValueArguments() {
        if (isHeadless()) return

        def swing = new SwingBuilder()

        def anAction = swing.action(name:"test action")
        def icon = new javax.swing.plaf.metal.MetalComboBoxIcon()
        def richActionItems = [
            'button',
            'checkBox',
            'radioButton',
            'toggleButton',
            'menuItem',
            'checkBoxMenuItem',
            'radioButtonMenuItem'
        ]

        richActionItems.each {name ->
            swing."$name"(anAction, id:"${name}Action".toString())
            swing."$name"(icon, id:"${name}Icon".toString())
            swing."$name"("string", id:"${name}String".toString())
            swing."$name"(swing."${name}Action", id:"${name}Self".toString())

            assert swing."${name}Action"
            assert swing."${name}Icon"
            assert swing."${name}String".text == 'string'
            assert swing."${name}Self" == swing."${name}Action"
            shouldFail {
                swing."$name"(['bad'])
            }
        }

        // elements that take no value argument
        def noValueItems = [
            "actions",
            "boxLayout",
            "comboBox",
            "formattedTextField",
            "glue",
            "hbox",
            "hglue",
            "hstrut",
            "map",
            "rigidArea",
            "separator",
            "vbox",
            "vglue",
            "vstrut",
        ]

        noValueItems.each {name ->
            //println name
            shouldFail {
                swing.frame {
                    "$name"(swing."$name"(), id:"${name}Self".toString())
                }
	    }
        }

         // elements that only take their own type as a value argument
        def selfItems = [
            "action",
            "borderLayout",
            "boundedRangeModel",
            "box",
            "buttonGroup",
            "cardLayout",
            //"closureColumn",
            "colorChooser",
            //"container",
            "desktopPane",
            "dialog",
            "fileChooser",
            "flowLayout",
            "frame",
            "gbc",
            "gridBagConstraints",
            "gridBagLayout",
            "gridLayout",
            "internalFrame",
            "layeredPane",
            "list",
            "menu",
            "menuBar",
            "optionPane",
            //"overlayLayout",
            "panel",
            "popupMenu",
            "progressBar",
            //"propertyColumn",
            "scrollBar",
            "scrollPane",
            "slider",
            "spinner",
            "spinnerDateModel",
            "spinnerListModel",
            "spinnerNumberModel",
            "splitPane",
            "springLayout",
            "tabbedPane",
            "table",
            "tableColumn",
            "tableLayout",
            "tableModel",
            //"td",
            "toolBar",
            //"tr",
            "tree",
            "viewport",
            //"widget",
            "window",
        ]
        selfItems.each {name ->
            //println name
            swing.frame {
                "$name"(swing."$name"(), id:"${name}Self".toString())
            }

            shouldFail {
                swing.frame {
                    swing."$name"(icon)
                }
	    }
        }

         // elements take their own type as a value argument or a stringa s a text property
        def textItems = [
            "editorPane",
            "label",
            "passwordField",
            "textArea",
            "textField",
            "textPane",
        ]
        textItems.each {name ->
            //println name
            swing.frame {
                "$name"(swing."$name"(), id:"${name}Self".toString())
                "$name"('text', id:"${name}Text".toString())
            }
            assert swing."${name}Text".text == 'text'

            shouldFail {
                swing.frame {
                    swing."$name"(icon)
                }
	    }
        }

        // leftovers...
        swing.frame {
            action(action:anAction)
            box(axis:BoxLayout.Y_AXIS)
            hstrut(5)
            vstrut(5)
            tableModel(tableModel:tableModel())
            container(panel()) {
                widget(label("label"))
                bean("anything")
            }
            container(container:panel()) {
                widget(widget:label("label"))
                bean(bean:"anything")
            }
        }
        shouldFail {
            swing.actions(property:'fails')
        }
        shouldFail {
            swing.widget()
        }
        shouldFail {
            swing.widget(label('label')) {
                label('No Content For You!')
            }
        }
        shouldFail {
            swing.container()
        }
        shouldFail {
            swing.bean()
        }
        shouldFail {
            swing.bean("anything") {
                label('Nothing')
            }
        }
    }

    boolean instancePass

    public void markPassed() {
        instancePass = true
    }

    public void testEDT() {
        if (isHeadless()) return
        def swing = new SwingBuilder()

        boolean pass = false
        swing.edt { pass = SwingUtilities.isEventDispatchThread() }
        assert pass

        pass = false
        swing.edt { swing.edt { pass = SwingUtilities.isEventDispatchThread() } }
        assert pass

        instancePass = false
        swing.edt this.&markPassed
        assert instancePass
    }

    public void testDoLater() {
        if (isHeadless()) return
        def swing = new SwingBuilder()

        boolean pass = false
        swing.doLater {sleep 100; pass = true }
        assert !pass
        sleep 200
        assert pass

        // doLater in the EDT is still a do later
        pass = false
        swing.edt { swing.doLater {sleep 100; pass = true } }
        assert !pass
        sleep 200
        assert pass

        instancePass = false
        swing.doLater this.&markPassed
        sleep 50
        assert instancePass
    }

    public void testDoOutside() {
        if (isHeadless()) return
        def swing = new SwingBuilder()

        boolean pass = false
        swing.doOutside {sleep 100; pass = true }
        assert !pass
        sleep 200
        assert pass

        pass = false
        swing.edt {
            swing.doOutside {sleep 100; pass = true }
            assert !pass
            sleep 200
            assert pass
        }

        instancePass = false
        swing.doOutside this.&markPassed
        sleep 50
        assert instancePass
    }

    public void testDispose() {
        if (isHeadless()) return
        def swing = new SwingBuilder()

        swing.frame(id:'frame').pack()
        swing.dialog(id:'dialog').pack()
        swing.window(id:'window').pack()

        //TODO check bind and model
        assert swing.frame.isDisplayable()
        assert swing.dialog.isDisplayable()
        assert swing.window.isDisplayable()
        swing.dispose()

        //TODO check bind and model
        assert !swing.frame.isDisplayable()
        assert !swing.dialog.isDisplayable()
        assert !swing.window.isDisplayable()

    }

    public void testPackAndShow() {
        if (isHeadless()) return
        def swing = new SwingBuilder()

        swing.frame(id:'frame', pack:true)
        swing.dialog(id:'dialog', pack:true)
        swing.window(id:'window', pack:true)

        assert swing.frame.isDisplayable()
        assert swing.dialog.isDisplayable()
        assert swing.window.isDisplayable()
        swing.dispose()

        swing.frame(id:'frame', show:true)
        swing.dialog(id:'dialog', show:true)
        swing.window(id:'window', show:true)

        assert swing.frame.visible
        assert swing.dialog.visible
        assert swing.window.visible
        swing.dispose()

        swing.frame(id:'frame', pack:true, show:true)
        swing.dialog(id:'dialog', pack:true, show:true)
        swing.window(id:'window', pack:true, show:true)

        assert swing.frame.visible
        assert swing.dialog.visible
        assert swing.window.visible
        swing.dispose()
    }

    public void testContainment() {
        if (isHeadless()) return
        def swing = new SwingBuilder()

        def topLevel = [
            "window",
            "frame",
            "dialog",
            "internalFrame",
        ]

        def containers = [
            "hbox",
            "box",
            "desktopPane",
            "layeredPane",
            "panel",
            "popupMenu",
            //"scrollPane",
            "splitPane",
            "tabbedPane",
            "toolBar",
            "viewport",
        ]

        def components = [
            "comboBox",
            "formattedTextField",
            "glue",
            "hbox",
            "hglue",
            "hstrut",
            "rigidArea",
            "separator",
            "vbox",
            "vglue",
            "vstrut",
            "box",
            "colorChooser",
            "desktopPane",
            "fileChooser",
            "internalFrame",
            "layeredPane",
            "list",
            "menu",
            //"menuBar",
            "optionPane",
            "panel",
            //"popupMenu",
            "progressBar",
            "scrollBar",
            "scrollPane",
            "slider",
            "spinner",
            "splitPane",
            "tabbedPane",
            "table",
            "toolBar",
            "tree",
            "viewport",
            "editorPane",
            "label",
            "passwordField",
            "textArea",
            "textField",
            "textPane",
        ]


        topLevel.each {parentWidget ->
            components.each { childWidget ->
                //println "$parentWidget / $childWidget"
                def child
                def parent = swing."$parentWidget" { child = "$childWidget"() }
                assert parent.contentPane == child.parent
            }
        }

        containers.each {parentWidget ->
            components.each { childWidget ->
                //println "$parentWidget / $childWidget"
                def child
                def parent = swing."$parentWidget" { child = "$childWidget"() }
                assert parent == child.parent
            }
        }

        components.each { childWidget ->
            //println "scrollPane / $childWidget"

            def child
            def parent = swing.scrollPane { child = "$childWidget"() }
            if (childWidget == 'viewport') {
                assert parent.viewport == child
            } else {
                assert parent.viewport == child.parent
            }
        }
    }

    public void testMenus() {
        if (isHeadless()) return
        def swing = new SwingBuilder()

        def frame = swing.frame {
            menuBar(id:'bar') {
                menu('menu', id:'menu') {
                    menuItem('item', id:'item')
                    checkBoxMenuItem('check', id:'check')
                    radioButtonMenuItem('radio', id:'radio')
                    separator(id:'sep')
                    menu('subMenu', id:'subMenu') {
                        menuItem('item', id:'subitem')
                        checkBoxMenuItem('check', id:'subcheck')
                        radioButtonMenuItem('radio', id:'subradio')
                        separator(id:'subsep')
                        menu('subSubMenu', id:'subSubMenu')
                    }
                }
            }
        }

        assert frame.JMenuBar == swing.bar
        assert swing.bar.menuCount == 1
        assert swing.bar.getMenu(0) == swing.menu

        assert swing.menu.itemCount == 5
        assert swing.menu.getItem(0) == swing.item
        assert swing.menu.getItem(1) == swing.check
        assert swing.menu.getItem(2) == swing.radio
        assert swing.menu.getItem(3) == null // not a menu item
        assert swing.menu.getMenuComponent(3) == swing.sep
        assert swing.menu.getItem(4) == swing.subMenu
        shouldFail { swing.menu.getItem(5) }

        assert swing.subMenu.itemCount == 5
        assert swing.subMenu.getItem(0) == swing.subitem
        assert swing.subMenu.getItem(1) == swing.subcheck
        assert swing.subMenu.getItem(2) == swing.subradio
        assert swing.subMenu.getItem(3) == null // not a menu item
        assert swing.subMenu.getMenuComponent(3) == swing.subsep
        assert swing.subMenu.getItem(4) == swing.subSubMenu
    }

    public void testLookAndFeel() {
        if (isHeadless()) return
        def swing = new SwingBuilder()

        def oldLAF = UIManager.getLookAndFeel();
        try {
            // test LAFs guaranteed to be everywhere
            swing.lookAndFeel('metal')
            swing.lookAndFeel('system')
            swing.lookAndFeel('crossPlatform')

            // test alternate invocations...
            swing.lookAndFeel(new javax.swing.plaf.metal.MetalLookAndFeel())
            shouldFail() {
                swing.lookAndFeel(this)
            }
            swing.lookAndFeel('javax.swing.plaf.metal.MetalLookAndFeel')
            shouldFail() {
                swing.lookAndFeel('BogusLookAndFeel')
            }

            // test Metal Themeing and aux attributes
            swing.lookAndFeel('metal', theme: 'steel', boldFonts: false)
            shouldFail {
                swing.lookAndFeel('metal', theme: 'steel', boldFonts: false, bogusAttribute: 'bad bad bad')
            }

            // test setup via attribute alone
            swing.lookAndFeel(lookAndFeel:'metal', theme: 'steel', boldFonts: false)

            // test Look and Feel Closure
            swing.lookAndFeel('metal') { laf ->
                assert laf instanceof MetalLookAndFeel
            }
            swing.lookAndFeel('metal', boldFonts: true) { laf ->
                assert laf instanceof MetalLookAndFeel
            }
            swing.lookAndFeel(lookAndFeel:'metal', boldFonts: true) { laf ->
                assert laf instanceof MetalLookAndFeel
            }
            shouldFail {
                swing.lookAndFeel() {laf ->
                    println "shouldn't get here"
                }
            }

        } finally {
            UIManager.setLookAndFeel(oldLAF)
        }
   }

    public void testBorders() {
        if (isHeadless()) return
        def swing = new SwingBuilder()

        // classic smoke test, try every valid combination and look for smoke...
        swing.frame {
            lineBorder(color:Color.BLACK, parent:true)
            lineBorder(color:Color.BLACK, thickness:4, parent:true)
            lineBorder(color:Color.BLACK, roundedCorners:true, parent:true)
            lineBorder(color:Color.BLACK, thickness:4, roundedCorners:true, parent:true)
            raisedBevelBorder(parent:true)
            raisedBevelBorder(highlight:Color.GREEN, shadow:Color.PINK, parent:true)
            raisedBevelBorder(highlightOuter:Color.GREEN, highlightInner:Color.RED, shadowOuter:Color.PINK, shadowInner:Color.BLUE, parent:true)
            loweredBevelBorder(parent:true)
            loweredBevelBorder(highlight:Color.GREEN, shadow:Color.PINK, parent:true)
            loweredBevelBorder(highlightOuter:Color.GREEN, highlightInner:Color.RED, shadowOuter:Color.PINK, shadowInner:Color.BLUE, parent:true)
            etchedBorder(parent:true)
            etchedBorder(highlight:Color.GREEN, shadow:Color.PINK, parent:true)
            loweredEtchedBorder(parent:true)
            loweredEtchedBorder(highlight:Color.GREEN, shadow:Color.PINK, parent:true)
            raisedEtchedBorder(parent:true)
            raisedEtchedBorder(highlight:Color.GREEN, shadow:Color.PINK, parent:true)
            titledBorder("Title 1", parent:true)
            titledBorder(title:"Title 2", parent:true)
            titledBorder("Title 3", position:'bottom', parent:true)
            titledBorder(title:"Title 4", position:'aboveBottom', parent:true)
            titledBorder("Title 5", position:TitledBorder.ABOVE_TOP, parent:true)
            titledBorder(title:"Title 6", position:TitledBorder.BOTTOM, parent:true)
            titledBorder("Title 7", justification:'right', parent:true)
            titledBorder(title:"Title 8", justification:'acenter', parent:true)
            titledBorder("Title 9", justification:TitledBorder.TRAILING, parent:true)
            titledBorder(title:"Title A", justification:TitledBorder.LEADING, parent:true)
            titledBorder("Title B", border:lineBorder(color:Color.RED, thickness:6), parent:true)
            titledBorder(title:"Title C", border:lineBorder(color:Color.BLUE, thickness:6), parent:true)
            titledBorder("Title D", color:Color.CYAN, parent:true)
            titledBorder(title:"Title E", border:lineBorder(color:Color.BLUE, thickness:6), parent:true)
            emptyBorder(6, parent:true)
            emptyBorder([3,5,6,9], parent:true)
            emptyBorder(top:6, left:5, bottom:6, right:9, parent:true)
            compoundBorder([titledBorder("single")], parent:true)
            compoundBorder([titledBorder("outer"), titledBorder("inner")], parent:true)
            compoundBorder(outer:titledBorder("outer"), inner:titledBorder("inner"), parent:true)
            compoundBorder([titledBorder("outer"), titledBorder("middle"), titledBorder("inner")], parent:true)
            matteBorder(Color.MAGENTA, size:7, parent:true)
            matteBorder(7, color:Color.MAGENTA, parent:true)
            matteBorder(javax.swing.plaf.metal.MetalIconFactory.getCheckBoxIcon(), size:9, parent:true)
            matteBorder(9, icon:javax.swing.plaf.metal.MetalIconFactory.getCheckBoxIcon(), parent:true)

            lineBorder(color:Color.BLACK)
            lineBorder(color:Color.BLACK, thickness:4)
            lineBorder(color:Color.BLACK, roundedCorners:true)
            lineBorder(color:Color.BLACK, thickness:4, roundedCorners:true)
            raisedBevelBorder()
            raisedBevelBorder(highlight:Color.GREEN, shadow:Color.PINK)
            raisedBevelBorder(highlightOuter:Color.GREEN, highlightInner:Color.RED, shadowOuter:Color.PINK, shadowInner:Color.BLUE)
            loweredBevelBorder()
            loweredBevelBorder(highlight:Color.GREEN, shadow:Color.PINK)
            loweredBevelBorder(highlightOuter:Color.GREEN, highlightInner:Color.RED, shadowOuter:Color.PINK, shadowInner:Color.BLUE)
            etchedBorder()
            etchedBorder(highlight:Color.GREEN, shadow:Color.PINK)
            loweredEtchedBorder()
            loweredEtchedBorder(highlight:Color.GREEN, shadow:Color.PINK)
            raisedEtchedBorder()
            raisedEtchedBorder(highlight:Color.GREEN, shadow:Color.PINK)
            titledBorder("Title 1")
            titledBorder(title:"Title 2")
            titledBorder("Title 3", position:'bottom')
            titledBorder(title:"Title 4", position:'aboveBottom')
            titledBorder("Title 5", position:TitledBorder.ABOVE_TOP)
            titledBorder(title:"Title 6", position:TitledBorder.BOTTOM)
            titledBorder("Title 7", justification:'right')
            titledBorder(title:"Title 8", justification:'acenter')
            titledBorder("Title 9", justification:TitledBorder.TRAILING)
            titledBorder(title:"Title A", justification:TitledBorder.LEADING)
            titledBorder("Title B", border:lineBorder(color:Color.RED, thickness:6))
            titledBorder(title:"Title C", border:lineBorder(color:Color.BLUE, thickness:6))
            titledBorder("Title D", color:Color.CYAN)
            titledBorder(title:"Title E", border:lineBorder(color:Color.BLUE, thickness:6))
            emptyBorder(6)
            emptyBorder([3,5,6,9])
            emptyBorder(top:6, left:5, bottom:6, right:9)
            compoundBorder([titledBorder("single")])
            compoundBorder([titledBorder("outer"), titledBorder("inner")])
            compoundBorder(outer:titledBorder("outer"), inner:titledBorder("inner"))
            compoundBorder([titledBorder("outer"), titledBorder("middle"), titledBorder("inner")])
            matteBorder(Color.MAGENTA, size:7)
            matteBorder(7, color:Color.MAGENTA)
            matteBorder(javax.swing.plaf.metal.MetalIconFactory.getCheckBoxIcon(), size:9)
            matteBorder(9, icon:javax.swing.plaf.metal.MetalIconFactory.getCheckBoxIcon())
        }
    }

    public void testBorderAttachment() {
        if (isHeadless()) return
        def swing = new SwingBuilder()

        swing.frame(id:'frame') {
           raisedBevelBorder()
        }
        assert swing.frame.contentPane.border == null

        swing.frame(id:'frame') {
           raisedBevelBorder(parent:true)
        }
        assert swing.frame.contentPane.border != null

        swing.panel(id:'panel') {
           raisedBevelBorder()
        }
        assert swing.panel.border == null

        swing.panel(id:'panel') {
           raisedBevelBorder(parent:true)
        }
        assert swing.panel.border != null
    }

    public void testImageIcon() {
        if (isHeadless()) return
        def swing = new SwingBuilder()

        String baseDir = new File("src/main").absolutePath

        String resource = Console.ICON_PATH
        String path = baseDir + resource
        File file = new File(path)
        String relativeResource = file.name
        URL url = file.toURL()

        swing.imageIcon(path, id:'ii')
        assert swing.ii != null

        swing.imageIcon(file:path, id:'ii')
        assert swing.ii != null

        swing.imageIcon(path, description:'<none>', id:'ii')
        assert swing.ii != null
        assert swing.ii.description == '<none>'

        swing.imageIcon(file:path, description:'<none>', id:'ii')
        assert swing.ii != null
        assert swing.ii.description == '<none>'


        swing.imageIcon(url, id:'ii')
        assert swing.ii != null

        swing.imageIcon(url:url, id:'ii')
        assert swing.ii != null

        swing.imageIcon(url, description:'<none>', id:'ii')
        assert swing.ii != null
        assert swing.ii.description == '<none>'

        swing.imageIcon(url:url, description:'<none>', id:'ii')
        assert swing.ii != null
        assert swing.ii.description == '<none>'


        swing.imageIcon(resource, id:'ii')
        assert swing.ii != null

        swing.imageIcon(resource:resource, id:'ii')
        assert swing.ii != null

        swing.imageIcon(resource, description:'<none>', id:'ii')
        assert swing.ii != null
        assert swing.ii.description == '<none>'

        swing.imageIcon(file:resource, description:'<none>', id:'ii')
        assert swing.ii != null
        assert swing.ii.description == '<none>'


        swing.imageIcon(resource, class:Console, id:'ii')
        assert swing.ii != null

        swing.imageIcon(resource:resource, class:Console, id:'ii')
        assert swing.ii != null

        swing.imageIcon(resource, description:'<none>', class:Console, id:'ii')
        assert swing.ii != null
        assert swing.ii.description == '<none>'

        swing.imageIcon(file:resource, description:'<none>', class:Console, id:'ii')
        assert swing.ii != null
        assert swing.ii.description == '<none>'


        swing.imageIcon(relativeResource, class:Console, id:'ii')
        assert swing.ii != null

        swing.imageIcon(resource:relativeResource, class:Console, id:'ii')
        assert swing.ii != null

        swing.imageIcon(relativeResource, description:'<none>', class:Console, id:'ii')
        assert swing.ii != null
        assert swing.ii.description == '<none>'

        swing.imageIcon(file:relativeResource, description:'<none>', class:Console, id:'ii')
        assert swing.ii != null
        assert swing.ii.description == '<none>'

    }
}