/*
 * Created on Jan 15, 2004
 */
package org.lucci.madhoc.gui;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;

import org.lucci.madhoc.simulation.Monitor;
import org.lucci.madhoc.simulation.projection.Projection;

public class ProjectionComponent extends JPanel implements TreeSelectionListener, SimulationRuntimeListener
{
    private JPanel viewsPane;
    private Projection projection;
    private MonitorTree tree;
    // this will instantiated at the first invocation of getViews()
    private Map<Class, MonitorView> monitorViews = new HashMap<Class, MonitorView>();

    
    public Projection getProjection()
    {
        return projection;
    }

    public void setProjection(Projection projection)
        throws Throwable
    {
        if (projection == null)
            throw new IllegalArgumentException();

        this.projection = projection;
        setName(projection.getName());

        for (Monitor monitor : projection.getSourceNetwork().getMonitorMap().values())
        {
            for (Class clazz : monitor.getMonitorViewClasses())
            {
                MonitorView view = (MonitorView) clazz.newInstance();
                view.setProjectionComponent(this);
                view.setMonitor(monitor);
                view.configure();
                monitorViews.put(view.getClass(), view);
            }
        }

        tree = new MonitorTree();
        tree.setProjectionFrame(this);
        tree.addTreeSelectionListener(this);

        for (int i = 0; i < tree.getRowCount(); ++i)
        {
            tree.expandRow(i);
        }

        JPanel leftPanel = new JPanel(new BorderLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.insets = new Insets(10, 10, 10, 10);
        leftPanel.add(new JScrollPane(tree), BorderLayout.CENTER);

        viewsPane = new JPanel();
        
        JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        sp.setLeftComponent(leftPanel);
        sp.setRightComponent(viewsPane);
        
        setLayout(new GridLayout(1, 1));
        add(sp);
    }

    public void valueChanged(TreeSelectionEvent event)
    {
        // removes all views
        for (int j = 0; j < viewsPane.getComponentCount(); ++j)
        {
            MonitorView simulationApplicationView = (MonitorView) viewsPane.getComponent(j);
            simulationApplicationView.setActive(false);
        }

        viewsPane.removeAll();

        // add selected views
        {
            viewsPane.setLayout(new GridBagLayout());
            TreePath[] selection = tree.getSelectionPaths();

            for (int j = 0; selection != null && j < selection.length; ++j)
            {
                Object object = ((DefaultMutableTreeNode) selection[j].getLastPathComponent()).getUserObject();

                if (object instanceof MonitorView)
                {
                    MonitorView simulationApplicationView = (MonitorView) object;
                    GridBagConstraints c = new GridBagConstraints();
                    c.gridx = 0;
                    c.gridy = j;
                    viewsPane.add(simulationApplicationView, c);
                    simulationApplicationView.setActive(true);
                    simulationApplicationView.updateViewContent();
                }
            }
        }

        viewsPane.doLayout();
        viewsPane.validate();
        viewsPane.getParent().repaint(0);
        viewsPane.repaint(0);
    }
    
    
    public void stateChanged()
    {
    }

    /* (non-Javadoc)
     * @see org.lucci.madhoc.gui.SimulationRuntimeListener#iterationPerformed()
     */
    public void iterationPerformed()
    {
        for (int j = 0; j < viewsPane.getComponentCount(); ++j)
        {
            MonitorView simulationApplicationView = (MonitorView) viewsPane.getComponent(j);

            if (simulationApplicationView.isActive())
            {
                simulationApplicationView.updateViewContent();
            }
        }
    }

    public Map<Class, MonitorView> getMonitorViews()
    {
        return monitorViews;
    }
}