package edu.sc.seis.gee.task;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.border.EmptyBorder;
import edu.sc.seis.fissuresUtil.chooser.FileNameFilter;
import edu.sc.seis.fissuresUtil.display.SeismogramDisplay;
import edu.sc.seis.fissuresUtil.display.SeismogramPDFBuilder;
import edu.sc.seis.fissuresUtil.display.VerticalSeismogramDisplay;
import edu.sc.seis.gee.CommonAccess;
import edu.sc.seis.gee.configurator.ConfigurationException;

public class PrintTask implements Task {

    public void configure(Map params) throws ConfigurationException {
        if(params.containsKey("printTarget")) {
            String printTargetId = (String)params.get("printTarget");
            CommonAccess ca = CommonAccess.getCommonAccess();
            TaskAction ta = ca.getTaskAction(printTargetId);
            colSeis = (ColumnSeismogramTask)ta.getTask();
        } else {
            throw new ConfigurationException("A PrintTask requires a columnSeismogramTask in its config in the key printTarget!");
        }
    }

    public void invoke() {
        getImagesPerPage(getNumOfDisp());
    }

    private int getNumOfDisp() {
        SeismogramDisplay disp = colSeis.getDisplay();
        if(disp instanceof VerticalSeismogramDisplay) {
            return ((VerticalSeismogramDisplay)disp).getDisplays().size();
        } else
            return 1;
    }

    private void print(int numPerPage) {
        String tmp = chooseOutputFile("pdf");
        if(tmp != null) {
            try {
                pdfBuilder.setDispPerPage(numPerPage);
                pdfBuilder.createPDF(colSeis.getDisplay(), new File(tmp));
            } catch(IOException e) {
                int choice = JOptionPane.showConfirmDialog(null,
                                                           "Unable to create file "
                                                                   + tmp
                                                                   + ".  Would you like to try another location?",
                                                           "Unable to create file",
                                                           JOptionPane.WARNING_MESSAGE);
                if(choice == JOptionPane.YES_OPTION)
                    print(numPerPage);
            }
        }
    }

    private void getImagesPerPage(int numSeis) {
        final JDialog dialog = new JDialog();
        dialog.getContentPane().setLayout(new GridBagLayout());
        dialog.setTitle("Printing Options");
        dialog.setModal(true);
        JLabel information = new JLabel("Seismograms per page:  ");
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets = new Insets(5, 5, 5, 5);
        dialog.getContentPane().add(information, gbc);
        Integer[] numbers = new Integer[3];// to initialize the combo box with
        // correct values
        for(int i = 0; i < 3; i++)
            numbers[i] = new Integer(i + 1);
        final JComboBox options = new JComboBox(numbers);
        gbc.gridx++;
        gbc.ipadx = 10;
        dialog.getContentPane().add(options, gbc);
        JButton next = new JButton("Next");
        next.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                int currentNumber = ((Integer)options.getSelectedItem()).intValue();
                print(currentNumber);
                dialog.dispose();
            }
        });
        gbc.gridy++;
        gbc.ipadx = 0;
        dialog.getContentPane().add(next, gbc);
        JButton cancel = new JButton("Cancel");
        cancel.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                dialog.dispose();
            }
        });
        gbc.gridx--;
        dialog.getContentPane().add(cancel, gbc);
        dialog.pack();
        Toolkit tk = Toolkit.getDefaultToolkit();
        dialog.setLocation((tk.getScreenSize().width - dialog.getWidth()) / 2,
                           (tk.getScreenSize().height - dialog.getHeight()) / 2);
        dialog.show();
    }

    private String chooseOutputFile(String extension) {
        final JFileChooser fc;
        if(lastSaveLocation != null) {
            fc = new JFileChooser(lastSaveLocation);
        } else {
            fc = new JFileChooser();
        }
        String extensions[] = new String[1];
        extensions[0] = extension;
        fc.setFileFilter(new FileNameFilter(extensions));
        fc.setDialogTitle("Save to File");
        fc.setSelectedFile(new File("output." + extension));
        int returnVal = fc.showSaveDialog(null);
        if(returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            lastSaveLocation = file.getParentFile();
            String newExtension = file.getName().substring(file.getName()
                    .lastIndexOf(".") + 1);
            if(!newExtension.equalsIgnoreCase(extension)) {
                // add extension to end
                file = new File(file.getAbsolutePath() + "." + extension);
            }
            if(file.exists()) {
                String[] options = {"Yes", "No", "Choose again"};
                int n = JOptionPane.showOptionDialog(null,
                                                     "File "
                                                             + file.getName()
                                                             + " exists, replace?",
                                                     "File Exists",
                                                     JOptionPane.YES_NO_CANCEL_OPTION,
                                                     JOptionPane.QUESTION_MESSAGE,
                                                     null,
                                                     options,
                                                     options[0]);
                if(n == JOptionPane.NO_OPTION) {
                    return null;
                } else if(n == JOptionPane.CANCEL_OPTION) {
                    return chooseOutputFile(extension);
                }
                // ok to replace...
            }
            return file.getAbsolutePath();
        }
        return null;
    }

    private static EmptyBorder EMPTY_BORDER = new EmptyBorder(5, 5, 5, 5);

    private File lastSaveLocation = null;

    private SeismogramPDFBuilder pdfBuilder = new SeismogramPDFBuilder(false,
                                                                       1,
                                                                       true);

    public void destroy() {}

    private ColumnSeismogramTask colSeis;
}// PrintTask
