package edu.sc.seis.gee.task;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import edu.iris.Fissures.IfEvent.EventAccessOperations;
import edu.sc.seis.fissuresUtil.cache.BulletproofVestFactory;
import edu.sc.seis.fissuresUtil.cache.CacheEvent;
import edu.sc.seis.fissuresUtil.cache.EventUtil;
import edu.sc.seis.fissuresUtil.cache.ProxyEventAccessOperations;
import edu.sc.seis.fissuresUtil.dataset.EarthquakeStationIterator;
import edu.sc.seis.fissuresUtil.display.SeismogramDisplay;
import edu.sc.seis.fissuresUtil.xml.DataSetSeismogram;
import edu.sc.seis.fissuresUtil.xml.StdAuxillaryDataNames;
import edu.sc.seis.gee.CommonAccess;
import edu.sc.seis.gee.FrameManager;
import edu.sc.seis.gee.configurator.ConfigurationException;

/**
 * @author oliverpa Created on Feb 15, 2005
 */
public class SeismogramApprovalTask implements GUITask {

    /**
     *
     */
    public void configure(Map params) throws ConfigurationException {
        this.params = params;
        if(params.containsKey("seisDisplay")) {
            String displayId = (String)params.get("seisDisplay");
            dispAction = CommonAccess.getCommonAccess()
                    .getTaskAction(displayId);
            colSeis = (ColumnSeismogramTask)dispAction.getTask();
        } else {
            throw new ConfigurationException("seisDisplay parameter must defined");
        } // end of else
        if(params.containsKey("approvalExport")) {
            String displayId = (String)params.get("approvalExport");
            exportAction = CommonAccess.getCommonAccess()
                    .getTaskAction(displayId);
        } else {
            throw new ConfigurationException("seisDisplay parameter must defined");
        } // end of else
    }

    /**
     *
     */
    public void invoke() throws Exception {
        colSeis.getDisplay().clear();
        CommonAccess commonAccess = CommonAccess.getCommonAccess();
        eqStaIt = new EarthquakeStationIterator(commonAccess.getDataSetRoot());
        if(!queueUpSeismograms()) {
            JOptionPane.showMessageDialog(FrameManager.getManager()
                                                  .getCurrentFrame(),
                                          "There are no seismograms in the dataset!",
                                          "No seismograms!",
                                          JOptionPane.INFORMATION_MESSAGE);
            hide();
        }
    }

    /**
     *
     */
    public JComponent getGUI() throws Exception {
        if(vBox == null) {
            vBox = Box.createVerticalBox();
            vBox.add(Box.createVerticalGlue());
            Box singleBox = Box.createHorizontalBox();
            singleBox.setBorder(BorderFactory.createTitledBorder("Current Seismograms"));
            ButtonGroup singleButtons = new ButtonGroup();
            JButton singleApproveButton = new JButton("Approve");
            singleApproveButton.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent ae) {
                    approveSeismograms(true);
                }
            });
            singleButtons.add(singleApproveButton);
            JButton singleDisapproveButton = new JButton("Disapprove");
            singleDisapproveButton.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent ae) {
                    approveSeismograms(false);
                }
            });
            singleButtons.add(singleDisapproveButton);
            singleButtons.setSelected(singleApproveButton.getModel(), true);
            singleBox.add(Box.createHorizontalGlue());
            singleBox.add(singleApproveButton);
            singleBox.add(Box.createHorizontalGlue());
            singleBox.add(singleDisapproveButton);
            singleBox.add(Box.createHorizontalGlue());
            vBox.add(singleBox);
            vBox.add(Box.createVerticalGlue());
            Box batchBox = Box.createHorizontalBox();
            batchBox.setBorder(BorderFactory.createTitledBorder("Remaining Seismograms for Event"));
            ButtonGroup batchButtons = new ButtonGroup();
            JButton batchApproveButton = new JButton("Approve");
            batchApproveButton.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    approveRemainingSeismograms(currentEvent, true);
                }
            });
            batchButtons.add(batchApproveButton);
            batchButtons.setSelected(batchApproveButton.getModel(), true);
            JButton batchDisapproveButton = new JButton("Disapprove");
            batchDisapproveButton.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    approveRemainingSeismograms(currentEvent, false);
                }
            });
            batchButtons.add(batchDisapproveButton);
            batchBox.add(Box.createHorizontalGlue());
            batchBox.add(batchApproveButton);
            batchBox.add(Box.createHorizontalGlue());
            batchBox.add(batchDisapproveButton);
            batchBox.add(Box.createHorizontalGlue());
            vBox.add(batchBox);
            vBox.add(Box.createVerticalGlue());
            Box evInfoBox = Box.createHorizontalBox();
            evInfoBox.setBorder(BorderFactory.createTitledBorder("Event Info"));
            evInfoBox.add(Box.createHorizontalGlue());
            eventInfo.setEditable(false);
            evInfoBox.add(eventInfo);
            evInfoBox.add(Box.createHorizontalGlue());
            vBox.add(evInfoBox);
            vBox.add(Box.createVerticalGlue());
//            panel = new JPanel();
//            panel.setLayout(new BorderLayout());
//            panel.add(vBox, BorderLayout.CENTER);
        }
        return vBox;
    }

    /**
     *
     */
    public boolean hasMoreOptions() {
        // TODO Auto-generated method stub
        return false;
    }

    /**
     *
     */
    public JComponent getMoreOptionsGUI() {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     *
     */
    public void destroy() {
    // TODO Auto-generated method stub
    }

    private void approveRemainingSeismograms(EventAccessOperations event,
                                             boolean approve) {
        while(event.equals(currentEvent)) {
            approveSeismograms(approve);
        }
    }

    private void approveSeismograms(boolean approve) {
        SeismogramDisplay display = colSeis.getDisplay();
        DataSetSeismogram[] seismos = display.getSeismograms();
        for(int i = 0; i < seismos.length; i++) {
            if(approve) {
                seismos[i].addAuxillaryData(StdAuxillaryDataNames.APPROVED,
                                            "true");
            } else {
                seismos[i].addAuxillaryData(StdAuxillaryDataNames.APPROVED,
                                            "false");
            }
        }
        colSeis.getDisplay().clear();
        if(!queueUpSeismograms()) {
            JOptionPane.showMessageDialog(FrameManager.getManager()
                                          .getCurrentFrame(),
                                  "You've finished this quality control session.  Now it's time to export!",
                                  "Finished!",
                                  JOptionPane.INFORMATION_MESSAGE);
            hide();
            exportAction.invoke(false);
        }
    }

    private boolean queueUpSeismograms() {
        if(eqStaIt.hasNext()) {
            currentSeismograms = (List)eqStaIt.next();
            DataSetSeismogram[] dsSeismos = (DataSetSeismogram[])currentSeismograms.toArray(new DataSetSeismogram[0]);
            currentEvent = BulletproofVestFactory.vestEventAccess(dsSeismos[0].getDataSet()
                    .getEvent());
            eventInfo.setText(EventUtil.getEventInfo(currentEvent, "LOC\nTIME\nMag: MAG\nDepth: DEPTH DEPTH_UNIT\nLat: LAT\nLon: LON"));
            colSeis.setDisplay();
            for(int i = 0; i < dsSeismos.length; i++) {
                colSeis.addSeismogram(dsSeismos[i]);
            }
            return true;
        }
        currentEvent = null;
        return false;
    }

    private void hide() {
        TaskAction thisAction = CommonAccess.getCommonAccess()
                .getTaskAction(this);
        thisAction.getJFrame().hide();
    }
    
    private JTextArea eventInfo = new JTextArea();

    private ProxyEventAccessOperations currentEvent;

    private List currentSeismograms;

    private EarthquakeStationIterator eqStaIt;

    private Map params;

    private TaskAction dispAction, exportAction;

    private ColumnSeismogramTask colSeis;
    
    private Box vBox;

    private JPanel panel;
}