package usda.weru.weps;



import java.awt.Dimension;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import de.schlichtherle.io.File;
import de.schlichtherle.io.FileOutputStream;
import java.util.List;
import java.util.Vector;
import java.util.zip.ZipOutputStream;
import javax.help.CSH;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import org.apache.log4j.Logger;
import org.jdesktop.jdic.desktop.Message;


import usda.weru.util.*;


/**
 * This class/object is used to send emails with bug reports attached or interface mis behaviour
 * messages to the WEPS support team from within the interface. Project folders and run files with
 * particular test case could be used as information.
 */
public class Email extends usda.weru.weps.gui.Email_n implements PropertyChangeListener {
    private static final Logger LOGGER = Logger.getLogger(Email.class);
    
    private String c_mailHost = "";
    private boolean c_useSmtp = true;    
    private String c_toComments = "";
    private String c_toBugs = "";
    private boolean c_error = false;    
    private boolean outlookFlg = false;
    
    private String c_projectsPath;
    private String c_runPath;
    
//    private String dirPath = "";
    
    /**
     * Default constructor for the email object/class tbat calls the parent GUI object and adds help
     * material for the GUI.
     */
    public Email() {
        super();
        addHelp();
        setTitle("WEPS Email");
        //setIconImage(wepsbIcon.getImage());

        super.setIconImage(About.getWeruIconImage());
        
        if (c_configData != null){
            c_configData.addPropertyChangeListener(this);
            c_configData.fireAll(this);            
        }
    }
    
    

    
    public Email(String to, String subject, String body, String attachment, boolean error, boolean allowAttach, boolean autoSend){
        this();
        c_error = error;
        
        if (to == null || to.length() == 0){
            if (error){
                to = c_toBugs;
            }
            else{
                to = c_toComments;
            }
        }
        if (subject == null) subject = "";
        if (body == null) body = "";
        
        JTF_subject.setText(subject);
        JTF_attachment.setText(attachment);
        JTF_to.setText(to);
        JTA_text.setText(body);
        
        
        autoSend = autoSend || (c_error && !c_useSmtp) || (!allowAttach && !c_useSmtp);
        
        if(autoSend){
            if (c_useSmtp){
                JB_send.doClick();
            }
            else{
                JB_client.doClick();
            }
            dispose();
            return;
        }
        else{            
            JB_Run.setVisible(allowAttach);
            JB_Project.setVisible(allowAttach);
            JTF_attachment.setEnabled(allowAttach);
            
            setVisible(true);
        }
    }
    
    public static void blank(){
        comment(null, null, null);
    }
    
    public static void comment(String subject, String body, String attachment){
       boolean allowAttach = attachment == null || attachment.length() == 0;
       new Email(null, subject, body, attachment, false, allowAttach, false);
    }
    
    public static void error(String subject, String body, String attachment){
        boolean allowAttach = attachment == null || attachment.length() == 0;
        new Email(null, subject, body, attachment, true, allowAttach, false);
    }
    
    
    
    /**
     * help stuff
     */
    
    private void addHelp() {
        
        CSH.setHelpIDString(JL_to, "emailTo_html");
        CSH.setHelpIDString(JTF_to, "emailTo_html");
        CSH.setHelpIDString(JL_from, "emailFrom_html");
        CSH.setHelpIDString(JTF_from, "emailFrom_html");
        CSH.setHelpIDString(JL_subject, "emailSubject_html");
        CSH.setHelpIDString(JTF_subject, "emailSubject_html");
        CSH.setHelpIDString(JL_attachment, "emailAttachment_html");
        CSH.setHelpIDString(JTF_attachment, "emailAttachment_html");
        
        CSH.setHelpIDString(JSP_text, "emailComments_html");
        CSH.setHelpIDString(JP_buttons, "emailButtons_html");
        CSH.setHelpIDString(this, "emailScreen_html");
        
        
        /*CSH.setHelpIDString(JB_send, "emailSendButton");
        CSH.setHelpIDString(JB_cancel, "emailCancelButton");
        CSH.setHelpIDString(JB_Run, "emailAttachRunButton");
        CSH.setHelpIDString(JB_Project, "emailAttachProjButton");*/
        
    }
    

    
    /**
     * This method notifies when the window or frame is resized and the components need to be re-arranged
     * so they are evenly spaced relative to each other.
     * @param args Command line arguments passed that are needed if it were a stand alone application.
     */
    static public void main(String args[]) {
        //TODO: basic starter
    }
    
    
    @SuppressWarnings("unchecked")
    public void JBSend_actionPerformed(java.awt.event.ActionEvent event) {
        String sendTo = JTF_to.getText();
        if (sendTo.length() == 0) {
            JOptionPane.showMessageDialog(this,
                "Recipient not specified.\nAborting send",
                "Error (E-002)",
                JOptionPane.WARNING_MESSAGE);
            return;
        }
        String sentFrom = JTF_from.getText();
        if (sentFrom.length() == 0) {
            JOptionPane.showMessageDialog(this,
                "Sender not specified.\nAborting send",
                "Error (E-003)",
                JOptionPane.WARNING_MESSAGE);
            return;
        }
        
        String subject = JTF_subject.getText();
        if (subject.length() == 0) {
            subject = JTF_attachment.getText();
        }
        
        String messageText = JTA_text.getText();
        if (messageText.length() == 0) {
            messageText = "no message";
        }
        
        java.io.File attachment = null;
        Vector attachments = new Vector();
        String attachPath = JTF_attachment.getText().trim();
        if (attachPath == null) {} else if (attachPath.trim().length() == 0) {} else if (!(new File(attachPath).exists())) {
            JOptionPane.showMessageDialog(this,
                "Attachment file not found\nAborting send",
                "Error (E-001)",
                JOptionPane.WARNING_MESSAGE);
            return;
        } else {
            attachment = makeZipFile(attachPath);
            attachments.add(attachment);
        }
        
        try {
            Mailer.sendMail(c_mailHost,
                sentFrom, sendTo, subject, messageText,
                attachments);
        } catch (java.io.IOException e) {
            JOptionPane.showMessageDialog(this, e,
                "Error -- Mail not sent",
                JOptionPane.WARNING_MESSAGE);
            return;
        } catch (javax.mail.internet.AddressException f) {
            JOptionPane.showMessageDialog(this, f,
                "Error -- Mail not sent",
                JOptionPane.WARNING_MESSAGE);
            return;
        } catch (javax.mail.MessagingException g) {
            JOptionPane.showMessageDialog(this, g,
                "Error -- Mail not sent",
                JOptionPane.WARNING_MESSAGE);
        }
        finally{
            if (attachment != null){
                attachment.deleteOnExit();
            }
        }
        
        try {
            this.dispose();
        } catch (java.lang.Exception e) {
        }
    }
    
    protected void JB_client_actionPerformed(java.awt.event.ActionEvent evt) {        
        List <String> recipients = new Vector <String> ();
        List <String> attachments = new Vector <String> ();
        
        //Recipients
        String to = JTF_to.getText();
        if (outlookFlg) {
            if (!to.startsWith("smtp:")) {
                to = "smtp:" + to;
            }
        }
        recipients.add(to);
        
        //Attachments
        String attachPath = JTF_attachment.getText().trim();
        if (attachPath == null) {} else if (attachPath.trim().length() == 0) {} else if (!(new File(attachPath).exists())) {
            JOptionPane.showMessageDialog(this,
                "Attachment file not found",
                "Error (E-001)",
                JOptionPane.WARNING_MESSAGE);
            return;
        } else {
            attachments.add(makeZipFile(attachPath).getAbsolutePath());
        }
        
        
        
        try{
            Message msg = new Message();                
            msg.setToAddrs(recipients);
            msg.setAttachments(attachments);    
            msg.setSubject(JTF_subject.getText());            
            
            //TODO: Figure out how to set the mime-type to html so the body is displayed correctly
            //msg.setBody(JTA_text.getText());            
            
            org.jdesktop.jdic.desktop.Desktop.mail(msg);
        }        
        catch (UnsatisfiedLinkError ule){
            LOGGER.error("The required system JDIC stub is missing from the java class path.", ule);
            JOptionPane.showMessageDialog(this, "The required system JDIC stub is missing from the java class path.", "Error -- Unable to open default mail client", JOptionPane.WARNING_MESSAGE);
            return;
        }
        catch (NoClassDefFoundError ncdfe){
            LOGGER.error("The required system JDIC stub is missing from the java class path.", ncdfe);
            JOptionPane.showMessageDialog(this, "The required system JDIC stub is missing from the java class path.", "Error -- Unable to open default mail client", JOptionPane.WARNING_MESSAGE);
            return;
        }
        catch(Exception e){
            LOGGER.error("Unable to open default mail client", e);
            JOptionPane.showMessageDialog(this, e, "Error -- Unable to open default mail client", JOptionPane.WARNING_MESSAGE);
            return;
        }
                
        try {
            dispose();
        } catch (java.lang.Exception e) {
        }
    }
        
    
    public java.io.File makeZipFile(String pathName) {
        java.io.File zipFile = null;
        try {
            java.io.File tempDir = java.io.File.createTempFile("WEPS", null).getParentFile();
            
            java.io.File input = new java.io.File(pathName);
            String filename = input.getName();

            

            if (!c_error) {
                zipFile = new File(tempDir, filename + ".zip");
            }else{
                zipFile = new File(tempDir, filename + "_crash.zip");
            }
        
        
            
            FileOutputStream os = new FileOutputStream(zipFile);
            ZipOutputStream zip_os = new ZipOutputStream(os);                                  
            File logFile = About.getLog();
                       
           
            
            if (logFile != null && logFile.exists()){
                Util.writeFileToZip(zip_os, logFile, filename);
            }
            Util.writeFileToZip(zip_os, new File("cfg", "weps.cfg"), filename);
            if(input.isDirectory()){
                Util.writeDirToZip(zip_os, input, filename);
            }
            else{
                Util.writeFileToZip(zip_os, input, filename);
            }
            zip_os.close();            
            
        } catch (Exception e) {
            LOGGER.error("Unable to make zip file", e);
        }
        return zipFile;
    }
    
    public void JBCancel_actionPerformed(java.awt.event.ActionEvent event) {
        // to do: code goes here.
        try {
            this.dispose();
        } catch (java.lang.Exception e) {
        }
        
    }
    
    public void JBRun_actionPerformed(java.awt.event.ActionEvent event) {
        WepsFileChooser wpc = new WepsFileChooser(WepsFileChooser.RUN,c_runPath,
            WepsFileChooser.SELECT);
        wpc.setCurrentDirectory(new de.schlichtherle.io.File((new de.schlichtherle.io.File(c_runPath)).getPath()));
        //set the tooltip of "home" button to "Home" instead of "Desktop"
        wpc.homeToolTip(wpc);
        //remove the NewFolder button
        wpc.disableNewFolder(wpc);
        
        if (wpc.showDialog(this) == JFileChooser.APPROVE_OPTION) {
            JTF_attachment.setText(wpc.getSelectedFile().getPath());
        }
    }
    
    public void JBProject_actionPerformed(java.awt.event.ActionEvent event) {
        // to do: code goes here.
        WepsFileChooser wpc = new WepsFileChooser(WepsFileChooser.PROJECT,c_projectsPath,
            WepsFileChooser.SELECT);
        wpc.setCurrentDirectory(new de.schlichtherle.io.File((new de.schlichtherle.io.File(c_projectsPath)).getPath()));
        //set the tooltip of "home" button to "Home" instead of "Desktop"
        wpc.homeToolTip(wpc);
        //remove the NewFolder button
        wpc.disableNewFolder(wpc);
        
        if (wpc.showDialog(this) == JFileChooser.APPROVE_OPTION) {
            String attachedFile = null;
            attachedFile = wpc.getSelectedFile().getPath();
            JTF_attachment.setText(attachedFile);
        }
    }
    
    
    /**
     * The method that gets called when any changes to the registered property happen
     * whose new vales need to be propagaed and updated so as to reflect the most current data.
     * @param e The event that occurs on the property.
     */
    
    public void propertyChange(PropertyChangeEvent e) {
        String property = e.getPropertyName();
        String value = e.getNewValue().toString().trim();
        
        
        if (property.equals(ConfigData.EmailSender)) {
            JTF_from.setText(value);
        } else if (property.equals(ConfigData.MailHost)) {
            c_mailHost = value;
        } else if (property.equals(ConfigData.CommentAddr)) {
            c_toComments = value;
        } else if (property.equals(ConfigData.BugsAddr)) {
            c_toBugs = value;
        } else if (property.equals(ConfigData.UseDefaultMailClient)){
            c_useSmtp = !value.equals("1");
            updateDisplay();
        }else if (property.equals(ConfigData.ProjDir)){
            c_projectsPath = value;
        }
        else if (property.equals(ConfigData.CurrentProj)){
            c_runPath = Util.parse(value);
        }
        else if (property.equals(ConfigData.UseOutlookFlg)){
            outlookFlg = "1".equals(value);
        }
        
    }
    
    
    private void updateDisplay(){
        JL_from.setVisible(c_useSmtp);
        JTF_from.setVisible(c_useSmtp);
        
        JL_to.setVisible(c_useSmtp);
        JTF_to.setVisible(c_useSmtp);
        
        JL_subject.setVisible(c_useSmtp);
        JTF_subject.setVisible(c_useSmtp);
        
        JSP_text.setVisible(c_useSmtp);
        
        JL_clientNote.setVisible(!c_useSmtp);
        
        JB_send.setVisible(c_useSmtp);
        JB_client.setVisible(!c_useSmtp);
        
        Dimension size = JP_main.getPreferredSize();
        size.height += 50;
        setSize(size);
        
        
    }
    
    private static ConfigData c_configData;
    
    public static void listen(ConfigData cd){
        c_configData = cd;
    }
    
    protected void exit_form(java.awt.event.WindowEvent evt) {                          
        this.dispose();
        if (c_configData != null){
            c_configData.removePropertyChangeListener(this);
        }
    } 
}
