/*
 * SendHtmlMain.java
 *
 * Created on 22 de Fevereiro de 2002, 00:03
 */

package lenApp;

/**
 *
 * @author  oribeiro
 * @version 
 */
public class SendHtmlMail 
{
    //Arquivo a ser enviado por e-mail
    protected java.io.File htmlFile = null;
    //Servidor SMTP que será utilizado
    protected String smtpServer = null;
    protected int smtpPorta = 0;
    //Informações para o envio do e-mail
    protected String subject = null, to[] = null, from = null;
    //Barra de porcentagem
    protected javax.swing.JProgressBar barra = null;
    
    //Conjunto com todos os nossos listeners
    java.util.Vector listeners = new java.util.Vector();
    
    //Classe com as informações sobre cada imagem que deve ser anexada ao
    //sistema
    protected class ImagemAnexada
    {
        //Arquivo que aponta para o conteudo da imagem
        protected java.io.File arquivoImagem;
        
        public ImagemAnexada()
        {
        }
        
        public void setImagem(java.io.File pArquivoImagem)
        {
            arquivoImagem = pArquivoImagem;
        }
        
        public String getName()
        {
            return arquivoImagem.getName();
        }
        
        public String getContentType()
        {
            String contentType=null;
            if(arquivoImagem.getName().indexOf("gif") > 0)
            {
                contentType =  "image/gif";
            }
            else if(arquivoImagem.getName().indexOf("jpg") > 0)
            {
                contentType =  "image/jpeg";
            }
            
            return contentType;
        }
        
        public String getBase64() throws java.io.FileNotFoundException, java.io.IOException
        {
            //Codifica e retorna a imagem
            String[] base64 = {"A","B","C","D","E","F","G","H","I","J","K","L",
                            "M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
                            "a","b","c","d","e","f","g","h","i","j","k","l",
                            "m","n","o","p","q","r","s","t","u","v","w","x","y","z",
                            "0","1","2","3","4","5","6","7","8","9","+","/","="};


            java.io.FileInputStream stream = new java.io.FileInputStream(arquivoImagem);
            byte[] conteudo = new byte[(int)arquivoImagem.length()];
            stream.read(conteudo);
            
            String strBase64="";
            int index = 0;
            
            char thisCar;

            int j = 0;
            for(int i = 0; i < conteudo.length; i+=3)
            {
                if(j >= 75)
                {
                    j=0;
                    strBase64 += "\r\n";
                }
                //Pega os 6 bits da frente
                index = (conteudo[i] & 0xfc)>>2;
                strBase64 += base64[index];

                index = ((conteudo[i]&0x3)<<4) | ((conteudo[i+1]&0xf0)>>4);
                strBase64 += base64[(int)index];
                
                index = ((conteudo[i+1]&0xf)<<2) | ((conteudo[i+2]&0xc0)>>6);
                strBase64 += base64[(int)index];
                
                index = ((conteudo[i+2]&0x3f));
                strBase64 += base64[(int)index];
                j+=4;
            }
            return strBase64;
        }
        
        public String getContentId()
        {
            return arquivoImagem.getName();
        }
    };
    
    //Conjunto com todas as imagens que deverão ser anexadas
    java.util.Vector imagens = new java.util.Vector();

    /** Creates new SendHtmlMain */
    public SendHtmlMail() 
    {
    }
    
    public java.io.File getHtmlFile()
    {
        return htmlFile;
    }
    
    public void setHtmlFile(java.io.File pHtmlFile)
    {
        htmlFile = pHtmlFile;
    }
    
    public String getSmtpServer()
    {
        return smtpServer;
    }
    
    public int getSmtpPorta()
    {
        return smtpPorta;
    }
    
    public void setSmtpPorta(int pPorta)
    {
        smtpPorta = pPorta;
    }

    public void setSmtpServer(String pSmtpServer)
    {
        smtpServer = pSmtpServer;
    }
    
    public void setProgressBar(javax.swing.JProgressBar pBarra)
    {
        barra = pBarra;
    }
    
    public void setMainInfo(String pSubject, String[] pTo, String pFrom)
    {
        subject = pSubject;
        to = pTo;
        from = pFrom;
    }
    
    public String loadAttachments(String pHtmlContent)
    {
        String htmlContent = pHtmlContent;
        
        String path = htmlFile.getAbsolutePath();
        int separatorPos = path.lastIndexOf(java.io.File.separatorChar);
        path = path.substring(0,separatorPos+1);

        
        //Verifica e anexa todos os arquivos do e-mail
        int pos = htmlContent.indexOf("src=");
        
        while(pos != -1)
        {
            int pos1 = htmlContent.indexOf("\"",pos);
            int pos2 = htmlContent.indexOf("\"",pos1+1);
            
            //pega o nome do arquivo
            String nomeArquivo = htmlContent.substring(pos1+1,pos2);
            nomeArquivo.replace('/',java.io.File.separatorChar);
            
            java.io.File thisFile = new java.io.File(nomeArquivo);
            
            if(!thisFile.exists())
            {
                thisFile = new java.io.File(path+nomeArquivo);
            }
            
            if(thisFile.exists())
            {
                htmlContent = htmlContent.substring(0,pos1+1) + "cid:"+htmlContent.substring(pos1+1);
                
                ImagemAnexada estaImagem = new ImagemAnexada();
                estaImagem.setImagem(thisFile);
                imagens.add(estaImagem);
            }
            
            pos = htmlContent.indexOf("src=",pos+1);
        }
        
        return htmlContent;
        
    }
    
    public String getBoundary()
    {
        //Pega o divisor do corpo do e-mail e das imagens a serem transmitidas
        String boundary = "OOtavioeumcaralegal,muitolegal!!!";
        
        return boundary;
    }
    
    public void sendData(java.net.Socket sock) throws java.io.IOException
    {
        java.io.InputStream input;
        java.io.OutputStream output;

        //Pega os streams de envio e recebimento das informações
        input = sock.getInputStream();
        output = sock.getOutputStream();
        
        String out;
        byte[] in = new byte[255];
        
        out = "DATA\r\n";
        output.write(out.getBytes());
        
        this.fireCommandSend(out);
        
        int len = input.read(in);
        out = new String(in,0,len);
        
        this.fireResponseReceived(out);
        
        if(out.substring(0,3).compareTo("354")==0)
        {
            //Vamos enviar o corpo da nossa mensagem
            
            //Envia o subject da mensagem
            out = "subject: " + this.subject + "\r\n";
            output.write(out.getBytes());
            
            out = "MIME-Version: 1.0\r\n";
            output.write(out.getBytes());
            out = "Content-Type: multipart/related;\r\n\ttype=\"text/html\";\r\n\tboundary=\""+ this.getBoundary()+"\"\r\n";
            output.write(out.getBytes());
            out = "X-Mailer: Otávio Mailer 1.0\r\n";
            output.write(out.getBytes());
            
            //Le o conteudo do arquivo
            java.io.FileReader reader = new java.io.FileReader(this.htmlFile);
            char[] conteudo = new char[(int)(htmlFile.length()+1)];
            reader.read(conteudo);
            
            
            out = "\r\n--" + this.getBoundary()+"\r\n";
            output.write(out.getBytes());
            out = "Content-Type: text/html;\r\n\tcharset=\"iso-8859-1\"\r\n";
            output.write(out.getBytes());
            out = "Content-Transfer-Encoding: 8bit\r\n\r\n";
            output.write(out.getBytes());
            out = "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN'>\r\n";
            output.write(out.getBytes());
            
            //Carrega as imagens do disco
            String strConteudo = this.loadAttachments(new String(conteudo));
            
            //Envia o conteudo para o servidor
            output.write(strConteudo.getBytes());
            
            for(java.util.Enumeration enum = imagens.elements(); enum.hasMoreElements();)
            {
                ImagemAnexada imagem = (ImagemAnexada)enum.nextElement();
                
                out = "\r\n--" + this.getBoundary()+"\r\n";
                output.write(out.getBytes());

                out = "Content-Type: "+imagem.getContentType()+";\r\n\tnome=\""+imagem.getName()+"\"\r\n";
                output.write(out.getBytes());

                out = "Content-Transfer-Encoding: base64\r\n";
                output.write(out.getBytes());

                out = "Content-ID:<"+imagem.getContentId()+">\r\n\r\n";
                output.write(out.getBytes());

                output.write(imagem.getBase64().getBytes());
            }

            out = "\r\n\r\n--" + this.getBoundary()+"--\r\n";
            output.write(out.getBytes());
            
            //Termina o envio da mensagem
            out = "\r\n.\r\n";
            output.write(out.getBytes());
            this.fireCommandSend(out);

            len = input.read(in);
            out = new String(in,0,len);
            this.fireResponseReceived(out);
        }
    }
    
    public boolean sendMail() throws SendHtmlMailException, java.net.UnknownHostException, java.io.IOException
    {
        //Envia o e-mail para o destino selecionado
        if(this.htmlFile == null)
        {
            throw(new SendHtmlMailException("Arquivo HTML não selecionado"));
        }
        
        if(this.smtpServer == null)
        {
            throw(new SendHtmlMailException("Servidor SMTP não configurado"));
        }
        
        if(this.subject == null || this.from == null || this.to==null)
        {
            throw(new SendHtmlMailException("Falta informações"));
        }
        
        //Tenta realizar a conexão no servidor já que está tudo ok
        java.net.Socket sock = new java.net.Socket(this.smtpServer,this.smtpPorta);
        
        //Canal de comunicação com o servidor
        java.io.InputStream input = sock.getInputStream();
        java.io.OutputStream output = sock.getOutputStream();
        
        String out;
        byte[] in = new byte[255];
        
        int len = input.read(in);
        out = new String(in,0,len);
        
        //Entra no sistema de e-mail
        out = "helo\r\n";
        output.write(out.getBytes());
        
        this.fireCommandSend(out);
                
        len = input.read(in);
        out = new String(in,0,len);
        
        this.fireResponseReceived(out);
        
        boolean start = true;
        
        int i;
        for(i = 0; i < this.to.length; i++)
        {
            this.barra.setValue(i);
            if(start == true)
            {
                //Configura de quem é o e-mail
                out = "mail from: " + this.from + "\r\n";
                output.write(out.getBytes());
                
                this.fireCommandSend(out);

                len = input.read(in);
                out = new String(in,0,len);
                
                this.fireResponseReceived(out);

                if(out.substring(0,3).compareTo("250")!=0)
                {
                    throw(new SendHtmlMailException(out));
                }
                
                start = false;
            }        
            
            out = "rcpt to: " + this.to[i] + "\r\n";
            output.write(out.getBytes());
            
            this.fireCommandSend(out);
            
            len = input.read(in);
            out = new String(in,0,len);
            
            this.fireResponseReceived(out);
            
            if(out.substring(0,3).compareTo("250")!=0)
            {
                //Precisamos começar de novo que o servidor não
                //suporta mais destinatarios
                
                //Envia o corpor do e-mail
                this.sendData(sock);
                
                //Marca para iniciar novamente
                start = true;
            }
            //faz para cada cliente
        }
        
        //Apenas envia o corpo
        this.sendData(sock);

        this.barra.setValue(i+1);
        //A conecão foi efetuada corretamente, precisamos iniciar o envio do e-mail
        
        return true;
    }
    
    public void addCommandListener(SendMailListener listener)
    {
        listeners.add(listener);
    }
    
    public void removeCommandListener(SendMailListener listener)
    {
        listeners.remove(listener);
    }
    
    public void fireCommandSend(String message)
    {
        for(java.util.Enumeration enum = listeners.elements();enum.hasMoreElements();)
        {
            SendMailListener listener = (SendMailListener)enum.nextElement();
            
            listener.commandSend(new SendMailEvent(this,message));
        }
    }

    public void fireResponseReceived(String message)
    {
        for(java.util.Enumeration enum = listeners.elements();enum.hasMoreElements();)
        {
            SendMailListener listener = (SendMailListener)enum.nextElement();
            
            listener.responseReceived(new SendMailEvent(this,message));
        }
    }
}

