package edu.sc.seis.gee.task;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import org.apache.log4j.Logger;
import edu.iris.Fissures.FissuresException;
import edu.iris.Fissures.seismogramDC.LocalSeismogramImpl;
import edu.sc.seis.fissuresUtil.display.SeismogramDisplay;
import edu.sc.seis.fissuresUtil.display.SeismogramInfoDisplay;
import edu.sc.seis.fissuresUtil.display.mouse.SDMouseAdapter;
import edu.sc.seis.fissuresUtil.display.mouse.SDMouseEvent;
import edu.sc.seis.fissuresUtil.exceptionHandler.GlobalExceptionHandler;
import edu.sc.seis.fissuresUtil.xml.DataSetSeismogram;
import edu.sc.seis.fissuresUtil.xml.SeisDataChangeEvent;
import edu.sc.seis.fissuresUtil.xml.SeisDataChangeListener;
import edu.sc.seis.fissuresUtil.xml.SeisDataErrorEvent;

public class SeismogramInfoTask  extends SDMouseAdapter implements GUITask {
    public void configure(Map params){
        configParams = params;
    }

    public JComponent getMoreOptionsGUI() { return null;  }

    public JComponent getGUI() throws Exception {
        if (infoDisplay == null) {
            LinkedList format = new LinkedList();
            if(configParams.containsKey("numPoints")){
                format.add("Number of Points");
            }
            if(configParams.containsKey("ID")){
                format.add("ID");
            }
            if(configParams.containsKey("sampling")){
                format.add("Sampling");
            }
            if(configParams.containsKey("channelID")){
                format.add("Channel ID");
            }
            if(configParams.containsKey("beginTime")){
                format.add("Begin Time");
            }
            if(configParams.containsKey("endTime")){
                format.add("End Time");
            }
            if(configParams.containsKey("minValue")){
                format.add("Minimum Value");
            }
            if(configParams.containsKey("maxValue")){
                format.add("Maximum Value");
            }
            if(configParams.containsKey("meanValue")){
                format.add("Mean Value");
            }
            if(configParams.containsKey("channel")){
                format.add("channel");
            }
            if(configParams.containsKey("instrumentation")){
                format.add("instrumentation");
            }
            infoDisplay = new SeismogramInfoDisplay(format);
            infoDisplay.setMinimumSize(new Dimension(200, 100));
        }
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        panel.add(infoDisplay, BorderLayout.CENTER);

        JButton clear = new JButton("Clear");
        clear.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        infoDisplay.clear();
                    }
                });
        panel.add(clear, BorderLayout.SOUTH);
        return panel;
    }

    public boolean hasMoreOptions() { return false; }

    public void invoke(){
        GlobalToolBar.setActive(this);
    }

    public void destroy(){}

    public SeismogramInfoDisplay getInfoDisplay(){ return infoDisplay; }

    public void mouseClicked(SDMouseEvent me) {
        logger.debug("Got a mouse click");

        SeismogramDisplay display = me.getDisplay();
        DataSetSeismogram[] seismograms = display.getSeismograms();
        logger.debug("Got a mouse click on a SD, there are "+
                         seismograms.length+" seismograms.");
        SeismogramInfoProcessor infoProcessor =
            new SeismogramInfoProcessor(seismograms, getInfoDisplay());
        for (int i=0; i<seismograms.length; i++) {
            getInfoDisplay().addSeismogram(seismograms[i]);
            seismograms[i].retrieveData(infoProcessor);
        }
    }

    private class SeismogramInfoProcessor implements  SeisDataChangeListener {
        SeismogramInfoProcessor(DataSetSeismogram[] seis,
                                SeismogramInfoDisplay infoDisplay) {
            this.seis = seis;
            this.infoDisplay = infoDisplay;
        }

        public void error(SeisDataErrorEvent sdce) {
            error = sdce;
            logger.warn("error for "+sdce.getSource().getName());
        }

        public void finished(SeisDataChangeEvent sdce) {
            logger.debug("finished "+sdce.getSource().getName());
        }

        public void pushData(SeisDataChangeEvent sdce) {
            if (sdce.getSeismograms().length != 0) {
                for (int i=0; i<sdce.getSeismograms().length; i++) {
                    try {
                        infoDisplay.addSeismogram(sdce.getSeismograms()[i]);
                    } catch (FissuresException e) {
                        GlobalExceptionHandler.handle(e);
                    }
                }
            } else {
                logger.info("pushData event has zero length localSeismogram array");
            }
        }

        private int getIndex(DataSetSeismogram s) {
            for (int i=0; i<seis.length; i++) {
                if (seis[i] == s) {
                    return i;
                }
            }
            throw new IllegalArgumentException("Can't find index for this seismogram");
        }

        DataSetSeismogram[] seis;

        SeismogramInfoDisplay infoDisplay;

        boolean[] finished;

        LocalSeismogramImpl[] localSeis;

        SeisDataErrorEvent error = null;

    }

    protected Map configParams;

    protected SeismogramInfoDisplay infoDisplay = null;

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