// Module    : $RCSfile: GUIModelFactory.java,v $
// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 13.05.2012 $
// Project   : JavaInteractionParser
// Creation  : 2012 by patrick
// Copyright : Patrick Harms, 2012

package de.ugoe.cs.quest.plugin.jfc.guimodel;

import java.util.logging.Logger;

import de.ugoe.cs.quest.eventcore.guimodel.AbstractDefaultGUIElementFactory;
import de.ugoe.cs.quest.eventcore.guimodel.IGUIElement;
import de.ugoe.cs.quest.eventcore.guimodel.GUIModelConfigurationException;
import de.ugoe.cs.quest.eventcore.guimodel.IGUIElementSpec;

/**
 * TODO comment
 * 
 * @version $Revision: $ $Date: 13.05.2012$
 * @author 2012, last modified by $Author: patrick$
 */
public class JFCGUIElementFactory extends AbstractDefaultGUIElementFactory {
    
    /** */
    private static JFCGUIElementFactory instance = new JFCGUIElementFactory();

    /**
     * TODO: comment
     * 
     */
    private JFCGUIElementFactory() {
        super();
    }

    /**
     * TODO: comment
     * 
     * @return
     */
    public static synchronized JFCGUIElementFactory getInstance() {
        return instance;
    }

    /* (non-Javadoc)
     * @see de.ugoe.cs.quest.eventcore.guimodel.IGUIElementFactory#instantiateGUIElement(IGUIElementSpec)
     */
    @Override
    public IGUIElement instantiateGUIElement(IGUIElementSpec specification) {
        if (!(specification instanceof JFCGUIElementSpec)) {
            throw new IllegalArgumentException
                ("can only process gui element specifications of type JFCHGUIElementSpec");
        }
        
        JFCGUIElementSpec jfcGuiElemSpec = (JFCGUIElementSpec) specification;
        
        return createNewGUIElementInternal(jfcGuiElemSpec);
    }

    /**
     * TODO: comment
     * 
     * @param name
     * @param type
     * @param icon
     * @param index
     * @param hash
     * @return
     */
    private synchronized JFCGUIElement createNewGUIElementInternal(JFCGUIElementSpec specification)
    {
        JFCGUIElement retVal = null;

        IGUIElement guiElement = null;
        try {
            guiElement = super.instantiateGUIElementFromConfiguredMappings(specification);
        }
        catch (GUIModelConfigurationException e) {
            throw new IllegalArgumentException
                ("detected a configuration error in the GUI element mapping", e);
        }

        if ((guiElement != null) && (!(guiElement instanceof JFCGUIElement))) {
            Logger.getLogger(this.getClass().getName()).warning
                ("configured GUI element representing class " +
                 guiElement.getClass().getName() + " is no valid GUIElement derivate.");
        }
        else {
            retVal = (JFCGUIElement) guiElement;
        }

        String type = specification.getType();

        if (retVal == null) {
            if ("javax.swing.JPanel".equals(type)) {
                retVal = new JFCPanel(specification);
            }
            else if ("javax.swing.JRootPane".equals(type)) {
                retVal = new JFCPanel(specification);
            }
            else if ("javax.swing.JLayeredPane".equals(type)) {
                retVal = new JFCPanel(specification);
            }
            else if ("javax.swing.JTabbedPane".equals(type)) {
                retVal = new JFCTabbedPane(specification);
            }
            else if ("javax.swing.JScrollPane".equals(type)) {
                retVal = new JFCScrollPane(specification);
            }
            else if ("javax.swing.JViewport".equals(type)) {
                retVal = new JFCPanel(specification);
            }
            else if ("javax.swing.JScrollPane$ScrollBar".equals(type)) {
                retVal = new JFCScrollBar(specification);
            }
            else if ("javax.swing.JMenu".equals(type)) {
                retVal = new JFCMenu(specification);
            }
            else if ("javax.swing.JMenu$1".equals(type)) {
                retVal = new JFCMenu(specification);
            }
            else if ("javax.swing.JDialog".equals(type)) {
                retVal = new JFCDialog(specification);
            }
            else if ("javax.swing.JFileChooser".equals(type)) {
                retVal = new JFCDialog(specification);
            }
            else if ("javax.swing.plaf.metal.MetalFileChooserUI$3".equals(type)) {
                retVal = new JFCPanel(specification);
            }
            else {
                throw new IllegalArgumentException
                    ("could not find a GUIElement representation for type specification " + type);
            }
        }

        return retVal;
    }

}
