package com.rmiguel.mail;

import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;

import com.tertulia.excecao.Excecao;

import java.sql.*;

/**
 * Envia um email em formato HTML com algum arquivo anexado. Qualquer CSS
 * utilizado no HTML não deveria ser incluido em anexo e sim incorporado
 * ao fonte HTML.
 *
 *
 * @author Rodrigo Miguel
 */
public class EmailHTMLArquivo {

	//remetente
	private String from = "";
	private String cc = null;
	private String bcc = null;
	private String userName = "";
	private String password = "";
	//servidor smtp
	private String mailhost = "";
	//porta de comunicacao
	private int porta = 25;
	//caminho completo do arquivo que será anexado
	private ArrayList arquivos;
	private static String mailer = "EmailHTMLArquivo por Rodrigo Miguel";

	/**
	* Construtor que já inicializa quem será o remetente das mensagens.
	* Deveria ser construído sempre por aqui.
	*
	* @param Deve ser um endereço de email válido.
	*/
	public EmailHTMLArquivo(String remetente) {
		this.from = remetente;
		this.arquivos = new ArrayList();
	}

	/**
	* Construtor que inicializa a instância com o remetente padrão:
	* rodrigomiguel@email.com.
	*/
	public EmailHTMLArquivo() {
		this.from = "rodrigomiguel@email.com";
		this.arquivos = new ArrayList();
	}

	/**
	* Seta o arquivo que será anexado ao email.
	*
	* @param Deve ser um objeto java.util.File apontando para
	* o arquivo.
	*/
	public void addArquivo(File arquivo) {
		this.arquivos.add(arquivo);
	}

	/**
	* Envia o email se a busca por um servidor smtp teve sucesso. O corpo
	* do email é dividido em duas partes, uma para o HTML e outra para o
	* arquivo que será anexado.
	*
	* @param Deve receber como parâmetros o endereço do destinatário, o corpo
	* da mensagem em formato HTML e o assunto do email.
	*
	* @exception Lança uma exception caso o email não possa ser enviado.
	*/
	public void enviaMail(Address[] addresses, String corpo, String assunto) throws Excecao {
		// seta algumas propriedades
		Properties props = System.getProperties();
		props.put("mail.smtp.host", this.mailhost);

		//se o servidor requer autenticação
		if (!userName.equals("") && !password.equals(""))
			props.put("mail.smtp.auth", "true");

		props.put("mail.smtp.port", String.valueOf(porta));

		//instancia uma sessão de email passando as propriedades setadas
		Session session = Session.getDefaultInstance(props);

		// constrói a mensagem
		Message msg = new MimeMessage(session);

		try {
			msg.setFrom(new InternetAddress(from));

			msg.setRecipients(Message.RecipientType.TO, addresses);

			if (cc != null)
				msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc, false));
			if (bcc != null)
				msg.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(bcc, false));

			msg.setSubject(assunto);

			// cria a primeira parte da mensagem (HTML)
			MimeBodyPart mbp1 = new MimeBodyPart();

			// cria o corpo do email em formato HTML.
			mbp1.setDataHandler(new DataHandler(new ByteArrayDataSource(corpo, "text/html")));

			// cria o Multipart e as partes dele
			Multipart mp = new MimeMultipart("related");

			mp.addBodyPart(mbp1);

			Iterator i = this.arquivos.iterator();
			MimeBodyPart mbp2;
			FileDataSource fds;
			while (i.hasNext()) {
				// cria a segunda parte da mensagem (arquivo anexo)
				mbp2 = new MimeBodyPart();

				// anexa o arquivo à mensagem
				fds = new FileDataSource((File) i.next());
				mbp2.setDataHandler(new DataHandler(fds));
				mbp2.setFileName(fds.getName());
				mbp2.setHeader("Content-ID", fds.getName());
				mp.addBodyPart(mbp2);
			}

			// adiciona o Multipart à mensagem
			msg.setContent(mp);

			// seta a data de envio
			msg.setSentDate(new java.util.Date());

			// instancia o objeto que vai fazer o envio da mensagem,
			// setando o protocolo utilizado
			Transport transport = session.getTransport("smtp");
			transport.connect(mailhost, porta, userName, password); //faz a conexao com o host
			msg.saveChanges(); //salva as mudanças na mensagem
			transport.sendMessage(msg, msg.getAllRecipients()); //envia a mensagem
			transport.close(); //fecha a conexao com o host

		} catch (Exception ex) {
			ex.printStackTrace();
			//SendMailFailedException biex = new SendMailFailedException(ex);
			//biex.setAcao("enviar email");
			//biex.setLocal(this.getClass(), "enviaMail(String, String, String)");
			//throw biex;
		}
	}

	/**
	 * Returns the arquivos.
	 * @return ArrayList
	 */
	public ArrayList getArquivos() {
		return arquivos;
	}

	/**
	 * Returns the bcc.
	 * @return String
	 */
	public String getBcc() {
		return bcc;
	}

	/**
	 * Returns the cc.
	 * @return String
	 */
	public String getCc() {
		return cc;
	}

	/**
	 * Returns the from.
	 * @return String
	 */
	public String getFrom() {
		return from;
	}

	/**
	 * Returns the mailhost.
	 * @return String
	 */
	public String getMailhost() {
		return mailhost;
	}

	/**
	 * Returns the password.
	 * @return String
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * Returns the porta.
	 * @return int
	 */
	public int getPorta() {
		return porta;
	}

	/**
	 * Returns the userName.
	 * @return String
	 */
	public String getUserName() {
		return userName;
	}

	/**
	 * Sets the arquivos.
	 * @param arquivos The arquivos to set
	 */
	public void setArquivos(ArrayList arquivos) {
		this.arquivos = arquivos;
	}

	/**
	 * Sets the bcc.
	 * @param bcc The bcc to set
	 */
	public void setBcc(String bcc) {
		this.bcc = bcc;
	}

	/**
	 * Sets the cc.
	 * @param cc The cc to set
	 */
	public void setCc(String cc) {
		this.cc = cc;
	}

	/**
	 * Sets the from.
	 * @param from The from to set
	 */
	public void setFrom(String from) {
		this.from = from;
	}

	/**
	 * Sets the mailhost.
	 * @param mailhost The mailhost to set
	 */
	public void setMailhost(String mailhost) {
		this.mailhost = mailhost;
	}

	/**
	 * Sets the password.
	 * @param password The password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * Sets the porta.
	 * @param porta The porta to set
	 */
	public void setPorta(int porta) {
		this.porta = porta;
	}

	/**
	 * Sets the userName.
	 * @param userName The userName to set
	 */
	public void setUserName(String userName) {
		this.userName = userName;
	}

}

