/**
 * NetworkAddTask.java
 * 
 * @author Created by Omnicore CodeGuide
 */
package edu.sc.seis.gee.task;

import java.awt.BorderLayout;
import java.util.List;
import java.util.Map;

import javax.swing.DefaultListModel;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.apache.log4j.Logger;

import edu.iris.Fissures.network.NetworkAttrImpl;
import edu.sc.seis.fissuresUtil.cache.AbstractJob;
import edu.sc.seis.fissuresUtil.cache.JobTracker;
import edu.sc.seis.fissuresUtil.cache.WorkerThreadPool;
import edu.sc.seis.fissuresUtil.chooser.ChannelChooserException;
import edu.sc.seis.fissuresUtil.chooser.ChannelChooserSource;
import edu.sc.seis.fissuresUtil.chooser.NameListCellRenderer;
import edu.sc.seis.fissuresUtil.chooser.NetworkFromSource;
import edu.sc.seis.fissuresUtil.exceptionHandler.GlobalExceptionHandler;
import edu.sc.seis.gee.CommonAccess;
import edu.sc.seis.gee.NoNetworkException;
import edu.sc.seis.gee.configurator.ConfigurationException;

public class NetworkAddTask implements GUITask {

    /**
     * Method getMoreOptionsGUI
     * 
     * @return a JComponent
     */
    public JComponent getMoreOptionsGUI() {
        // TODO
        return null;
    }

    /**
     * Method configure
     * 
     * @param params
     *            a Map
     * @exception ConfigurationException
     */
    public void configure(Map params) throws ConfigurationException {
        logger.debug("configure");
        this.params = params;
        String chanChooserId = (String)params.get("channelChooserTask");
        TaskAction chanChooserAction = CommonAccess.getCommonAccess()
                .getTaskAction(chanChooserId);
        channelChooserTask = (ChannelChooserTask)chanChooserAction.getTask();
    }

    /**
     * Method destroy
     */
    public void destroy() {
    // logger.debug("destroy");
    }

    /**
     * Method hasMoreOptions
     * 
     * @return a boolean
     */
    public boolean hasMoreOptions() {
        // TODO
        return false;
    }

    /**
     * Method getGUI
     * 
     * @return a JComponent
     * @exception Exception
     */
    public JComponent getGUI() throws Exception {
        if(panel == null) {
            logger.debug("Panel is null, initPanel");
            panel = initPanel();
        }
        return panel;
    }

    /**
     * Method invoke
     * 
     * @exception Exception
     */
    public void invoke() throws Exception {
    // TODO
    }

    protected JPanel initPanel() throws ConfigurationException {
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        networks = new DefaultListModel();
        networkList = new JList(networks);
        networkList.setCellRenderer(new NameListCellRenderer(true, true, true));
        networkList.addListSelectionListener(new ListSelectionListener() {

            public void valueChanged(ListSelectionEvent e) {
                if(e.getValueIsAdjusting()) {
                    return;
                }
                int first = e.getFirstIndex();
                int last = e.getLastIndex();
                ListSelectionModel selections = networkList.getSelectionModel();
                for(int i = first; i <= last; i++) {
                    NetworkFromSource net = (NetworkFromSource)networks.get(i);
                    if(selections.isSelectedIndex(i)) {
                        NetworkFromSource selectedNet = (NetworkFromSource)networks.get(i);
                        try {
                            channelChooserTask.getChannelChooser()
                                    .appendNetwork(selectedNet);
                        } catch(NoNetworkException ex) {
                            // this should never happen as we have gotten the
                            // networks over
                            // the wire in order for the list to be populated
                            GlobalExceptionHandler.handle("Caught no network, ignoring user selection "
                                                                  + i,
                                                          ex);
                        }
                    } else {
                        // unselected?
                    }
                }
            }
        });
        List<ChannelChooserSource> netDC = channelChooserTask.getConfiguredNetworkSources();
        LoadNetworks loader = new LoadNetworks(netDC);
        JobTracker.getTracker().add(loader);
        WorkerThreadPool.getDefaultPool().invokeLater(loader);
        panel.add(new JScrollPane(networkList), BorderLayout.CENTER);
        // panel.add(new JButton("ADD"), BorderLayout.SOUTH);
        return panel;
    }

    class LoadNetworks extends AbstractJob {

        LoadNetworks(List<ChannelChooserSource> netDCs) {
            super("Network List Loader");
            this.netDCs = netDCs;
        }

        public void runJob() {
            for (ChannelChooserSource source : netDCs) {
                setStatus("Getting networks from net datacenter " +source.toString());
                List<NetworkAttrImpl> all;
                try {
                    all = source.getNetworks();
                    for (NetworkAttrImpl networkAttrImpl : all) {
                        final NetworkFromSource na = new NetworkFromSource(networkAttrImpl, source);
                        SwingUtilities.invokeLater(new Runnable() {
                            
                            public void run() {
                                networks.addElement(na);
                                networkList.repaint();
                            }
                        });
                    }
                } catch(ChannelChooserException e) {
                    GlobalExceptionHandler.handle("Unable to get networks from "+source.toString(), e);
                }
            }
            setFinished();
            networkList.repaint();
        }

        List<ChannelChooserSource> netDCs;
    }

    JPanel panel = null;

    JList networkList;

    DefaultListModel networks;

    ChannelChooserTask channelChooserTask;

    Map params;

    private static Logger logger = Logger.getLogger(NetworkAddTask.class);
}
