package com.mycompany.email;

import java.lang.reflect.*;
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
import javax.mail.event.*;
import javax.mail.search.*;
import com.sun.activation.registries.*;
import com.sun.activation.viewers.*;
import com.sun.mail.*;
import com.sun.mail.handlers.*;
import com.sun.mail.iap.*;
import com.sun.mail.imap.*;
import com.sun.mail.imap.protocol.*;
import com.sun.mail.smtp.*;
import com.sun.mail.util.*;


/**
 * SendEmail is a JavaBean designed to be exposed as a COM
 * object on Windows platforms. It allows email to be sent from
 * any application that can instantiate and use Windows COM objects.
 * JavaReg.exe from the Microsoft Java SDK MAY be used to
 * register this bean as a COM object.
 * You can also use sun.beans.ole.Packager
 *
 * i.e.
 * javareg
 * /codebase:c:\visualcafe\projects\email\SendEmail.jar
 * /class:com.mortgagefamily.email.SendEmail /register
 * /progid:SendEmail.Bean /control
 * /typelib:c:\visualcafe\projects\email\SendEmail.tlb
 * 
 * @author Dean W. Parker
 * @version 1 01/10/2000
 */ 
public class SendEmail
{
    
	public SendEmail()
	{
	    super();
	}
    
    
    /** 
    * function that get's the email data,
    * sets up the MimeMessage
    * and transmits the email(s).<p>
    * @returns Empty String if successful, Exception text otherwise
    *
    */
	public String send()
	{
	    return this.sendEmail(this);
    }    
	    
    /**
     * addurl method is called once per email address that will receive an attachment<BR><BR>
     * can call muliple times to build large list
     * 
     * @param String, Path name followed by separator character
     * @param String, File name without path
     * @return void
     */
    public void addfileattachment(String path, String name)
    {
        if (path == null || name == null)
            return;
        
        if (fileattachments == null) fileattachments = new Vector();
        
        FileDataSource fds = new FileDataSource(new File(path,name));
        fileattachments.addElement(fds);
        if(debug)
        {
            System.out.print("fileattachment added: ");
            System.out.println(fileattachments.elementAt(fileattachments.size() - 1).toString());
        }
    }

    
    /**
     * addCC method is called once per email address that will receive a cc mail<BR><BR>
     * can call muliple times to build large list
     * 
     * @param String, adds CC email address.
     * @return void
     */
    public  void addCC(String data)
    {
        if (data == null || data.length() == 0)
            return;
        if (cc == null) cc = new StringBuffer("");
            
        if (cc.length() > 0)
        {
            cc.append(",");
            cc.append(data);
        }
        else
        {
            if(data != null)
                cc.append(data);
        }
        if(debug)
        {
            System.out.print("cc added: ");
            System.out.println(cc.toString());
        }
    }

    /**
     * addBCC method is called once per email address that will receive a BlindCC mail
     * <BR><BR>
     * 
     * @param String, adds BCC email address.
     * @return void
     */
    public  void addBCC(String data)
    {
        if (data == null || data.length() == 0)
            return;
        if (bcc == null) bcc = new StringBuffer("");
            
        if (bcc.length() > 0)
        {
            bcc.append(",");
            bcc.append(data);
        }
        else
        {
            if(data != null)
                bcc.append(data);
        }
        
        if(debug)
        {
            System.out.print("bcc added: ");
            System.out.println(bcc.toString());
        }
    }

    /**
     * addBCC method is called once per email address that will receive the email<BR><BR>
     * Call as many times as emails addresses are required.
     * 
     * @param String, adds TO email address.
     * @return void
     */
	public  void addTo(String data)
    {
        if (data == null || data.length() == 0)        
            return;
            
        if (to != null)
        {
            to.append(",");
            to.append(data);
        }
        else
        {
           if(data != null)
               to = new StringBuffer(data);
        }
        
        if(debug)
        {
            System.out.print("to added: ");
            System.out.println(to.toString());
        }

    }


    /**
     * Set the replyTo of this email.  Use this value, instead of from, so when the counselor get the email, they can modify the email, a
     * and hit send.
     * 
     * @param String, adds ReplyTo email address.
     * @return void
     */
    public  void setReplyTo(String data)
    {
        if (data == null || data.length() == 0)        
            return;
            
        replyTo = new StringBuffer(data);
        if(debug)
        {
            System.out.print("replyTo added: ");
            System.out.println(replyTo.toString());
        }
    }

    
    /** 
	* Set the subject of this email
	* @param String, sets subject address.
	* @return void
	*/
    public  void setSubject(String data)
    {
        if (data == null || data.length() == 0)        
            return;
            
        subject = new StringBuffer(data);
        if(debug)
        {
            System.out.print("subject added: ");
            System.out.println(subject.toString());
        }
    }
    
    
    /** 
	* Set the sender id of this email.
	* <BR><BR>
	* Normally, this will be set to the same email, butcan vary from brand to brand.
	* We normally use <code>"internet@mortgagefamily.com" </code>
	* @param String, sets FROM address.
	* @return void
	*/
    public  void setFrom(String data)
    {
        if (data == null || data.length() == 0)        
            return;
            
        from = new StringBuffer(data);
        if(debug)
        {
            System.out.print("from added: ");
            System.out.println(from.toString());
        }
    }

    /** 
	* setBody method is called once per email address<BR><BR>
	* @param String, sets Message Text of email
	* @return void
	*/
    public void setBody(String data)
    {
        if (data == null || data.length() == 0)        
            return;
            
        if (body != null)
        {
            body.append(data);
        }
        else
        {
            body = new StringBuffer(data);
        }

        if(debug)
        {
            System.out.print("body added: ");
            System.out.println(body.toString());
        }

    }
    
    public String getFrom()
    {
        if(from != null)
            return from.toString();
        else
            return null;
    }

    public String getTo()
    {
        if(to != null)
            return to.toString();
        else
            return null;

    }

    public String getCC()
    {
        if(cc != null)
            return cc.toString();
        else
            return null;
    }
    
    public Vector getfileattachments()
    {
        return fileattachments;
    }
    

    public String getBCC()
    {
        if(bcc != null)
            return bcc.toString();
        else
            return null;
    }

    public String getReplyTo()
    {
        if(replyTo != null)
            return replyTo.toString();
        else
            return null;
    }

    public String getBody()
    {
        if(body != null)
            return body.toString();
        else
            return null;
    }

    public String getSubject()
    {
        if(subject != null)
            return subject.toString();
        else
            return null;
    }
    
       
	/**
	 * Validate that all required message properties are set.
	 * 
	 * @param holder    The message string.
	 * @return 0 if good, -1 if bad
	 */
    public int checkCoreData(String holder)
    {
        holder = "";
        boolean failure = false;
        if (from == null)
        {
            failure = true;
            holder += "Missing From, ";   
        }

        if (to == null)
        {
            failure = true;
            holder += "Missing To, ";
        }
            
        if (subject == null)
        {
            failure = true;
            holder += "Missing Subject, ";            
        }

        if (body == null)
        {
            failure = true;
            holder += "Missing Body";  
        }
        return (failure==false ? 0 : -1);
    }
    
    /**
     * Set the SMTPSERVER of this email.
     * 
     * @param String, sets SMTPSERVER.
     * @return void
     */
    public  void setSMTPSERVER(String data)
    {
        if (data == null || data.length() == 0)        
            return;
            
        SMTPSERVER = data;
        if(debug)
        {
            System.out.print("SMTPSERVER CHANGED: ");
            System.out.println(data);
        }
    }

    /**
     * Get the current SMTPSERVER.
     * @return SMTPSERVER
     */
    public String getSMTPSERVER()
    {
        return SMTPSERVER;
    }
    
    /** 
    * function that get's the email data,
    * sets up the MimeMessage
    * and transmits the email(s).<p>
    * @param EmailData    
    * @exception Exception
    * @returns Empty String if successful, Exception text otherwise
    *
    */
    private String sendEmail(SendEmail emailData ) 
    {
        String holder = "";
        String eol = "\n\r";
        StringBuffer sb = new StringBuffer("");
        MimeBodyPart mbp = new MimeBodyPart();
        Multipart mmp = new MimeMultipart();
        DataHandler dh;
        
        if (emailData.checkCoreData(holder) > 0)
        {
            throw new IllegalArgumentException(holder);
        }
        
        if(debug == true)
        {
            System.out.println("Debugging is on");
            sb.append("Debugging is on" + eol);
            emailData.setDebug(true);
        }

           
	    // create some properties and get the default Session
	    Properties props = new Properties();
	    props.put("mail.smtp.host", SMTPSERVER);
	    //props.put("mail.transport.protocol","smtp");
	    //props.put("mail.store.protocol","imap");
	    
	    if (debug)
	    {
	        System.out.println(props);
            sb.append(props + eol);
	        props.put("mail.debug", "true");
	    }

	    Session session = Session.getDefaultInstance(props, null);
	    if (debug)
	    {
            session.setDebug(debug);
            System.out.println(session);
            sb.append(session + eol);
	    }

	    try 
	    {
	        // create a message
	        Message msg = new MimeMessage(session);
	        try
	        {
	            // this is set so when we forward the email 
	            // to the counselor, they only have to hit SEND 
	            // for it to be sent to the customer!
	            
	            if (emailData.getReplyTo() != null)
	            {
	                InternetAddress[] address = {new InternetAddress(emailData.getReplyTo())};
                    msg.setReplyTo(address);
                }
               
	            msg.setFrom(new InternetAddress(emailData.getFrom()));
	            
	            if (emailData.getTo() != null)
	            {
                    InternetAddress[] address = InternetAddress.parse(emailData.getTo());
                    msg.setRecipients(Message.RecipientType.TO, address);
                }
                
                if (emailData.getCC() != null)
	            {
	                InternetAddress[] CCaddress = InternetAddress.parse(emailData.getCC());
	                msg.setRecipients(Message.RecipientType.CC, CCaddress);
	            }
	            if (emailData.getBCC() != null)
	            {
	                InternetAddress[] BCCaddress = InternetAddress.parse(emailData.getBCC());
	                msg.setRecipients(Message.RecipientType.BCC, BCCaddress);
	            }
                if (emailData.getfileattachments().size() > 0)
	            {
	                try
	                {
	                    
	                    //java.net.URL url = new java.net.URL("file:///" + file);
	                    for ( int i = 0;i < fileattachments.size();i++)
	                    {
	                        FileDataSource f = (FileDataSource)fileattachments.elementAt(i);
                            dh = new DataHandler(f);
	                        System.out.println(dh.getName());
   	                        System.out.println("Content Type:" + dh.getContentType());
   	                        //mbp = new MimeBodyPart(f.getInputStream());
   	                        mbp = new MimeBodyPart();
	                        mbp.setDataHandler(dh);
	                        mmp.addBodyPart(mbp);
	                        System.out.println(dh);
	                    }    
	                    System.out.println(msg);
	                }catch(Exception e)
	                {
	                    e.printStackTrace();
	                    System.out.println(e);
                        sb.append(e + eol);
        	            
	                    return sb.toString();
	                }
	            }
	        }
	        catch(ParseException e)
	        {
	            e.printStackTrace();
	            System.out.println(e);
                sb.append(e + eol);
	            
	            //return -1;
	            return sb.toString();
	        }
	        
	        msg.setFlags(new Flags(Flags.Flag.DRAFT), true);

        
	        msg.setSentDate(new Date());
	        // If the desired charset is known, you can use
	        // setText(text, charset)
            String bodyText = emailData.getBody();
            if (bodyText != null && bodyText.length() > 0)
            {
                if (emailData.getfileattachments().size() == 0)
                {
                    msg.setText(bodyText);
                }    
                else
                {
   	                mbp = new MimeBodyPart();
	                mbp.setContent(bodyText,"text/plain");
                    System.out.println("Content Type:" + mbp.getContentType());
    	            
	                mmp.addBodyPart(mbp);           
                    msg.setContent(mmp);
                }
            }    
	        
	        try
	        {
	            msg.setSubject(emailData.getSubject());
	        }
	        catch(MessagingException e)
	        {
	            System.out.println(e);
                sb.append(e.toString()  + eol);
	            
	            return sb.toString();
	            //return -1;
	        }
    	    if (debug)
    	    {
	            System.out.println(msg);
                sb.append(msg + eol);

                System.out.println("List of Providers:" + eol);
                sb.append("List of Providers:" + eol);
                Provider[] p;
                p = session.getProviders();
			    for (int q = 0; q < p.length; q++) 
			    {
			        System.out.println(p[q].getProtocol());
			        System.out.println(p[q].getVendor());
			        System.out.println(p[q].getVersion());
			        
			        sb.append(p[q].getProtocol() + eol);
			        sb.append(p[q].getVendor() + eol);
			        sb.append(p[q].getVersion() + eol);
			    }    
                
            }    
	        
	        Transport.send(msg);
    	}
	        
	    catch (MessagingException mex) 
	    {
	        System.out.println("\n--Exception handling");
            sb.append("Exception Handling" + eol);
            sb.append(mex.toString() + eol);

	        mex.printStackTrace();
	        Exception ex = mex;
	        do 
	        {
		        if (ex instanceof SendFailedException) 
		        {
		            SendFailedException sfex = (SendFailedException)ex;
		            Address[] invalid = sfex.getInvalidAddresses();
		            if (invalid != null) 
		            {
			            System.out.println("    ** Invalid Addresses");
                        sb.append("    ** Invalid Addresses" + eol);
			            
			            if (invalid != null) 
			            {
			                for (int i = 0; i < invalid.length; i++) 
			                {
			                    System.out.println("         " + invalid[i]);
			                    sb.append("         " + invalid[i] + eol);
			                }    
			            }
		            }
		            Address[] validUnsent = sfex.getValidUnsentAddresses();
		            if (validUnsent != null) 
		            {
			            System.out.println("    ** ValidUnsent Addresses");
                        sb.append("    ** ValidUnsent Addresses" + eol);
			            if (validUnsent != null) 
			            {
			                for (int i = 0; i < validUnsent.length; i++) 
			                {
			                    System.out.println("         "+validUnsent[i]);
			                    sb.append("         "+validUnsent[i] + eol);
			                }    
			            }
		            }
		            Address[] validSent = sfex.getValidSentAddresses();
		            if (validSent != null) 
		            {
			            System.out.println("    ** ValidSent Addresses");
                        sb.append("    ** ValidSent Addresses" + eol);
			            
			            if (validSent != null) 
			            {
			                for (int i = 0; i < validSent.length; i++)
			                {
			                    System.out.println("         "+validSent[i]);
                                sb.append("         "+validSent[i] + eol);
                            }    
			            }
		            }
		        }
		        System.out.println();
	        } while ((ex = ((MessagingException)ex).getNextException()) != null);
	        
	        return sb.toString();
	    }
	    
	    return "";
    }
    
    
    
	/**
	 * Set debugging for this session
	 * 
	 * @param data, boolean used to turn debugging off
	 */
    public void setDebug(boolean data)
    {
        debug = data;
    }
	
    public static void main(String[] args)
    {

        try
        {
            
            SendEmail e = new SendEmail();
            e.setDebug(true);
            
            e.addTo(args[0]);
            e.setFrom(args[1]);
            e.setSubject(args[2]);
            e.setBody(args[3]);
            e.addfileattachment(args[4], args[5]);
            e.send();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
	
    protected StringBuffer to;
    protected StringBuffer cc;
    protected StringBuffer bcc;
	protected StringBuffer from;	
	protected StringBuffer replyTo; // for emails sent to a third party before final send!
	protected StringBuffer subject;
	protected StringBuffer body;
	protected Vector fileattachments = new Vector();
    protected boolean debug;
    protected String SMTPSERVER = "mbs-mymailserver";
}