package edu.sc.seis.gee.task;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import org.apache.log4j.Category;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import edu.sc.seis.fissuresUtil.exceptionHandler.GlobalExceptionHandler;
import edu.sc.seis.gee.CommonAccess;
import edu.sc.seis.gee.configurator.AbstractHandler;
import edu.sc.seis.gee.configurator.ConfigurationException;

/**
 * LayoutTask.java
 *
 *
 * Created: Tue Oct  8 13:15:09 2002
 *
 * @author <a href="mailto:">Philip Crotwell</a>
 * @version
 */

public class LayoutTask extends JPanel implements SAXTask {
    public LayoutTask() {
        setLayout(new GridBagLayout());
    }

    public void configure(Map params) throws ConfigurationException {
        this.params = params;
    }

    public AbstractHandler getConfigureHandler(String name,
                                               org.xml.sax.XMLReader parser,
                                               AbstractHandler parent) {
        return new MyConfigHandler(name, parser, parent);
    }


    public void invoke() throws ConfigurationException {
        if (taskList == null) {
            taskList = new LinkedList();
            Iterator it = layoutParams.keySet().iterator();
            while (it.hasNext()) {
                String key = (String)it.next();
                if (key.startsWith("layout_")) {
                    Object value = layoutParams.get(key);
                    if (value instanceof GridBagConstraints) {
                        GridBagConstraints gbc = (GridBagConstraints)value;
                        addToLayout(key, gbc);
                    } else {
                        logger.warn("Can't layout if config value is not element");
                    }
                }
            }
        }
    }

    protected void addToLayout(String name, GridBagConstraints gbc) {
        String layoutTaskName = name.substring(7);
        TaskAction taskAction =
            CommonAccess.getCommonAccess().getTaskAction(layoutTaskName);

        taskList.add(taskAction);


        try{
            if (taskAction == null ||
                ! (taskAction.getTask() instanceof JComponent)) {
                logger.warn("Can't layout "+name+" if task is not available.");
                add(new JLabel(name), gbc);
            } else {
                Task task = taskAction.getTask();
                task.invoke();
                if (task instanceof JComponent) {
                    JPanel panel = new JPanel();
                    panel.setLayout(new BorderLayout());
                    panel.add((JComponent)task, BorderLayout.CENTER);
                    JToolBar toolbar = taskAction.getToolBar();
                    if ( toolbar != null) {
                        panel.add(toolbar, BorderLayout.NORTH);
                    }
                    add(panel, gbc);
                }
            }
        } catch(ConfigurationException e) {
            logger.warn("Can't add to layout "+name, e);
            add(new JLabel(name), gbc);
        } catch(Exception e) {
            logger.warn("Can't get task ",e);
            add(new JLabel(name), gbc);
        }

    }

    public void destroy(){
    }

    Map params;

    HashMap layoutParams = new HashMap();

    LinkedList taskList = null;

    static Category logger = Category.getInstance(LayoutTask.class.getName());

    class MyConfigHandler extends AbstractHandler {

        public MyConfigHandler(String name,
                             org.xml.sax.XMLReader parser,
                             AbstractHandler parent) {
            super(parser, parent);
            this.paramName = name;
        }

        public void startElement(String namespaceURI,
                                 String localName,
                                 String qName,
                                 Attributes atts) {
            if ( localName == "gridbag") {
                gbc = new GridBagConstraints();
            } // end of else
            currValue = "";
        }

        public void characters(char[] ch,
                               int start,
                               int length)
            throws SAXException {
            if (currValue == null) {
                currValue =  new String(ch, start, length);
            } else {
                currValue +=  new String(ch, start, length);
            } // end of else
        }

        public void endElement(java.lang.String namespaceURI,
                               java.lang.String localName,
                               java.lang.String qName)
            throws SAXException {
            if ( localName.equals("complexValue")) {
                // end of gridbag, so add to configuration and call super
                layoutParams.put(paramName, gbc);
                super.endElement(namespaceURI, localName, qName);
            } else {
                try {
                    Class gbcClass = GridBagConstraints.class;
                    if (localName.equals("gridx") ||
                        localName.equals("gridy") ||
                        localName.equals("gridwidth") ||
                        localName.equals("gridheight") ||
                        localName.equals("ipadx") ||
                        localName.equals("ipady") ||
                        localName.equals("insets")) {
                        java.lang.reflect.Field f =
                            gbcClass.getField(localName);
                        f.set(gbc, new Integer(currValue));
                    } else if (localName.equals("weightx") ||
                               localName.equals("weighty")) {
                        java.lang.reflect.Field f =
                            gbcClass.getField(localName);
                        f.set(gbc, new Double(currValue));
                    } else if (localName.equals("fill")) {
                        if (currValue.equals("NONE")) {
                            gbc.fill = gbc.NONE;
                        } else  if (currValue.equals("HORIZONTAL")) {
                            gbc.fill = gbc.HORIZONTAL;
                        } else  if (currValue.equals("VERTICAL")) {
                            gbc.fill = gbc.VERTICAL;
                        } else  if (currValue.equals("BOTH")) {
                            gbc.fill = gbc.BOTH;
                        }
                    } else if (localName.equals("anchor")) {
                        if (currValue.equals("CENTER")) {
                            gbc.anchor = gbc.CENTER;
                        } else if (currValue.equals("NORTHWEST")) {
                            gbc.anchor = gbc.NORTHWEST;
                        } else if (currValue.equals("NORTH")) {
                            gbc.anchor = gbc.NORTH;
                        } else if (currValue.equals("NORTHEAST")) {
                            gbc.anchor = gbc.NORTHEAST;
                        } else if (currValue.equals("EAST")) {
                            gbc.anchor = gbc.EAST;
                        } else if (currValue.equals("SOUTHEAST")) {
                            gbc.anchor = gbc.SOUTHEAST;
                        } else if (currValue.equals("SOUTH")) {
                            gbc.anchor = gbc.SOUTH;
                        } else if (currValue.equals("SOUTHWEST")) {
                            gbc.anchor = gbc.SOUTHWEST;
                        } else if (currValue.equals("WEST")) {
                            gbc.anchor = gbc.WEST;
                        }
                    }
                } catch (IllegalArgumentException e) {
                    GlobalExceptionHandler.handle("Bad reflection ",e);
                } catch (IllegalAccessException e) {
                    GlobalExceptionHandler.handle("Bad reflection ",e);
                } catch (NullPointerException e) {
                    GlobalExceptionHandler.handle("Bad reflection ",e);
                } catch (NoSuchFieldException e) {
                    GlobalExceptionHandler.handle("Bad reflection ",e);
                }

                currValue = "";
            } // end of else


        }

        String paramName = "";

        String currValue = "";

        GridBagConstraints gbc;
    }

}// LayoutTask
