package edu.sc.seis.gee.task;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;
import javax.swing.border.EtchedBorder;
import edu.sc.seis.fissuresUtil.exceptionHandler.GlobalExceptionHandler;
import edu.sc.seis.gee.FrameManager;
import edu.sc.seis.gee.NetworkGateKeeper;
import edu.sc.seis.gee.configurator.Configuration;
import edu.sc.seis.gee.configurator.ConfigurationException;

/**
 * @author groves Created on Nov 29, 2004
 */
public class ChooseConfigTask extends ConfigSwitchTask implements GUITask {

    public void configure(Map params) throws ConfigurationException {
        configsFile = (String)params.get("configsFile");
        if(configsFile == null) { throw new ConfigurationException("ConfigSwitchTask must have a configsFile param"); }
        if(NetworkGateKeeper.accessAllowed()) {
            try {
                configs = Configuration.loadConfigs(configsFile);
            } catch(Exception e) {
                throw new ConfigurationException("unable to load the configurations from "
                        + configsFile);
            }
        }
        String resetTaskId = (String)params.get("resetTaskId");
        if(resetTaskId == null) { throw new ConfigurationException("ConfigSwitchTask must have a resetTaskId param"); }
        resetTask = AllTasks.getTaskAction(resetTaskId).getTask();
    }

    public void invoke() {}

    public JComponent getGUI() throws Exception {
        Box mainBox = new Box(BoxLayout.Y_AXIS);
        mainBox.add(Box.createVerticalStrut(10));
        mainBox.add(makeWebConfigGUI());
        mainBox.add(Box.createVerticalStrut(10));
        mainBox.add(makeLoadYourOwnConfigGUI());
        mainBox.add(Box.createVerticalStrut(10));
        return mainBox;
    }

    private Component makeLoadYourOwnConfigGUI() {
        Box horiz = new Box(BoxLayout.X_AXIS);
        horiz.add(Box.createHorizontalGlue());
        final JButton loadLocal = new JButton("Reconfigure GEE from a File");
        horiz.add(loadLocal);
        horiz.add(Box.createHorizontalStrut(20));
        loadLocal.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                if(jfc == null) {
                    jfc = new JFileChooser();
                }
                int returnVal = jfc.showOpenDialog(loadLocal);
                if(returnVal == JFileChooser.APPROVE_OPTION) {
                    try {
                        URL selected = jfc.getSelectedFile().toURL();
                        try {
                            switchConfig(selected.toString());
                        } catch(IOException e2) {
                            GlobalExceptionHandler.handle("Unable to read the given file",
                                                          e2);
                        } catch(ConfigurationException e2) {
                            GlobalExceptionHandler.handle("Trouble with the chosen config file",
                                                          e2);
                        }
                    } catch(MalformedURLException e1) {
                        GlobalExceptionHandler.handle("I wouldnt think this possible since I got the URL from a file chooser, but lookie!",
                                                      e1);
                    }
                }
            }

            private JFileChooser jfc;
        });
        final JButton loadRemote = new JButton("Reconfigure GEE from a URL");
        loadRemote.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                String value = (String)JOptionPane.showInputDialog(FrameManager.getManager()
                                                                           .getCurrentMainPanel(),
                                                                   "Enter the URL to reconfigure GEE",
                                                                   "Reconfigure from a URL",
                                                                   JOptionPane.QUESTION_MESSAGE,
                                                                   null,
                                                                   null,
                                                                   "http://");
                if(value != null) {//null indicates cancel was clicked
                    try {
                        new URL(value);//only create to throw
                        // MalformedURLException
                        // if the url is malformed
                        try {
                            switchConfig(value);
                        } catch(IOException e1) {
                            GlobalExceptionHandler.handle("Unable to read the given file",
                                                          e1);
                        } catch(ConfigurationException e1) {
                            GlobalExceptionHandler.handle("Trouble with the chosen config file",
                                                          e1);
                        }
                    } catch(MalformedURLException e2) {
                        JOptionPane.showMessageDialog(FrameManager.getManager()
                                                              .getCurrentMainPanel(),
                                                      value
                                                              + " doesn't appear to be a valid URL.  Try navigating to the config file in your browser, copying the location, and pasting it into the dialog",
                                                      "Invalid URL",
                                                      JOptionPane.WARNING_MESSAGE);
                    }
                }
            }
        });
        horiz.add(loadRemote);
        horiz.add(Box.createHorizontalStrut(20));
        JButton reset = new JButton("Return to GEE's Initial Screen");
        reset.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                try {
                    resetTask.invoke();
                } catch(Exception e1) {
                    GlobalExceptionHandler.handle(e1);
                }
            }
        });
        horiz.add(reset);
        horiz.add(Box.createHorizontalGlue());
        return horiz;
    }

    private JComponent makeWebConfigGUI() throws ConfigurationException {
        Box webConfigs;
        if(!NetworkGateKeeper.accessAllowed()) {
            webConfigs = new Box(BoxLayout.Y_AXIS);
            String title = "<h2> Internet Connection Required: </h2>";
            String message = "<p>This feature requires an Internet Connection. "
                    + "GEE is unable to connect to Internet right now.</p> <p>Check your internet connection"
                    + " and restart GEE. If it still doesn't work, please email <B>geebugs@seis.sc.edu</B> describing the problem. </p>";
            String labelText = "<html>" + title + message + "</html>";
            JLabel errorLabel = new JLabel(labelText, SwingConstants.LEFT);
            webConfigs.add(errorLabel);
            webConfigs.add(Box.createHorizontalStrut(5));
            webConfigs.setBorder(new EtchedBorder());
            return webConfigs;
        } else {
            webConfigs = new Box(BoxLayout.Y_AXIS);
            for(int i = 0; i < configs.length; i++) {
                webConfigs.add(makeConfigGUI(configs[i]));
            }
            JScrollPane scrollableWebConfigs = new JScrollPane(webConfigs);
            scrollableWebConfigs.setBorder(new BevelBorder(BevelBorder.RAISED));
            return scrollableWebConfigs;
        }
    }

    private Component makeConfigGUI(final Configuration configuration)
            throws ConfigurationException {
        Box configBox = new Box(BoxLayout.X_AXIS);
        configBox.add(Box.createHorizontalStrut(10));
        configBox.add(makeImageLabel(configuration));
        configBox.add(Box.createHorizontalStrut(20));
        configBox.add(makeDescAndButtons(configuration));
        configBox.setBorder(new EtchedBorder());
        return configBox;
    }

    private JComponent makeImageLabel(final Configuration configuration)
            throws ConfigurationException {
        String imgLoc = configuration.getImage();
        URL imageURL;
        if(imgLoc.startsWith("http:")) {
            try {
                imageURL = new URL(imgLoc);
            } catch(MalformedURLException e) {
                throw new ConfigurationException("Bad URL " + imgLoc
                        + " for configuration " + configuration.getName()
                        + " image", e);
            }
        } else {
            imageURL = getClass().getClassLoader().getResource(imgLoc);
        }
        JLabel imageLabel = new JLabel(new ImageIcon(imageURL));
        return imageLabel;
    }

    private JComponent makeDescAndButtons(Configuration config) {
        Box vertBox = new Box(BoxLayout.Y_AXIS);
        vertBox.add(Box.createVerticalGlue());
        vertBox.add(makeConfigDescription(config));
        vertBox.add(Box.createVerticalGlue());
        vertBox.add(makeSwitchers(config));
        vertBox.add(Box.createVerticalGlue());
        return vertBox;
    }

    private Component makeSwitchers(final Configuration config) {
        Box horizBox = new Box(BoxLayout.X_AXIS);
        for(int i = 0; i < config.getNumConfigs(); i++) {
            JButton switcher = new JButton(config.getName(i));
            horizBox.add(switcher);
            if(i != config.getNumConfigs() - 1) {
                horizBox.add(Box.createHorizontalStrut(10));
            }
            final int configIndex = i;
            switcher.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent arg0) {
                    try {
                        switchConfig(config.getConfig(configIndex));
                    } catch(Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        return horizBox;
    }

    private JComponent makeConfigDescription(Configuration config) {
        Box horiz = new Box(BoxLayout.X_AXIS);
        String name = "<h2>" + config.getName() + "</h2>";
        String desc = "<p>" + config.getDescription() + "</p>";
        String nameAndDesc = "<html>" + name + desc + "</html>";
        horiz.add(new JLabel(nameAndDesc, SwingConstants.LEFT));
        horiz.add(Box.createHorizontalGlue());
        return horiz;
    }

    public boolean hasMoreOptions() {
        return false;
    }

    public JComponent getMoreOptionsGUI() {
        return null;
    }

    private Task resetTask;

    private String configsFile;

    private Configuration currentConfig;

    private Configuration[] configs;
}