using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using Word=Microsoft.Office.Interop.Word;
using System.Reflection;
using System.Drawing;
using System.IO;

public class Export : System.Web.UI.Page
{
    private int font_size=12;
    private String ordem = "";
    private String process_name="";
    private String process_folder = @"c:\";
    private String font_type;

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected int getSelectedProcessId()
    {
        int process_id = 0;
        try
        {
            process_id = Convert.ToInt32(Request.QueryString["id"]);
        }
        catch (Exception ex)
        {
        }
        return process_id;
    }

    protected void Load_Settings()
    {
        font_size = Config.getInstance().getTamanhoLetra();
        font_type = Config.getInstance().getTipoLetra();
    }

    protected void Escreve_Seccao(SECCAO seccao,Word._Document oDoc)
    {
        object end_of_doc = "\\endofdoc";

        // Titulo da secção
        Word.Paragraph para_titulo_seccao;
        object range_titulo_seccao = oDoc.Bookmarks.get_Item(ref end_of_doc).Range;
        para_titulo_seccao = oDoc.Content.Paragraphs.Add(ref range_titulo_seccao);
        para_titulo_seccao.Range.Font.Bold = 1;
        para_titulo_seccao.Range.Font.Size = font_size;
        para_titulo_seccao.Range.Font.Name = font_type;
        para_titulo_seccao.Range.Text = ordem + seccao.TITULO;

        if (seccao.ID_SECCAO_PAI == null)
        {
            para_titulo_seccao.LeftIndent = 0;
        }
        else
        {
            int num_idents = ordem.Length * 2;
            para_titulo_seccao.LeftIndent = num_idents;
        }
        para_titulo_seccao.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft;
        para_titulo_seccao.Format.SpaceAfter = 6;
        para_titulo_seccao.Range.InsertParagraphAfter();

        // Texto da secção
        Word.Paragraph para_desc_seccao;
        object range_desc_seccao = oDoc.Bookmarks.get_Item(ref end_of_doc).Range;
        para_desc_seccao = oDoc.Content.Paragraphs.Add(ref range_desc_seccao);
        para_desc_seccao.Range.Font.Bold = 0;
        para_desc_seccao.Range.Font.Size = font_size;
        para_desc_seccao.Range.Font.Name = font_type;
        para_desc_seccao.Range.Text = seccao.DESCRICAO;
        if (seccao.ID_SECCAO_PAI == null)
        {
            para_desc_seccao.LeftIndent = 10;
        }
        else
        {
            int num_idents = ordem.Length * 4;
            para_desc_seccao.LeftIndent = num_idents;
        }
        para_desc_seccao.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphJustify;
        para_desc_seccao.Format.SpaceAfter = 8;
        para_desc_seccao.Range.InsertParagraphAfter();

        Word.Paragraph para_titulo_notas_seccao;
        object range_titulo_notas_seccao = oDoc.Bookmarks.get_Item(ref end_of_doc).Range;
        para_titulo_notas_seccao = oDoc.Content.Paragraphs.Add(ref range_titulo_notas_seccao);
        para_titulo_notas_seccao.Range.Font.Bold = 1;
        para_titulo_notas_seccao.Range.Font.Size = font_size;
        para_titulo_notas_seccao.Range.Font.Name = font_type;
        para_titulo_notas_seccao.Range.Text = "Notas:";
        if (seccao.ID_SECCAO_PAI == null)
        {
            para_titulo_notas_seccao.LeftIndent = 10;
        }
        else
        {
            int num_idents = ordem.Length * 4;
            para_titulo_notas_seccao.LeftIndent = num_idents;
        }
        para_titulo_notas_seccao.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphJustify;
        para_titulo_notas_seccao.Format.SpaceAfter = 6;
        para_titulo_notas_seccao.Range.InsertParagraphAfter();

        // Texto das notas
        Word.Paragraph para_notas_seccao;
        object range_notas_seccao = oDoc.Bookmarks.get_Item(ref end_of_doc).Range;
        para_notas_seccao = oDoc.Content.Paragraphs.Add(ref range_notas_seccao);
        para_notas_seccao.Range.Font.Bold = 0;
        para_notas_seccao.Range.Font.Size = font_size;
        para_notas_seccao.Range.Font.Name = font_type;
        para_notas_seccao.Range.Text = seccao.NOTAS;
        if (seccao.ID_SECCAO_PAI == null)
        {
            para_notas_seccao.LeftIndent = 10;
        }
        else
        {
            int num_idents = ordem.Length * 4;
            para_notas_seccao.LeftIndent = num_idents;
        }
        para_notas_seccao.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphJustify;
        para_notas_seccao.Format.SpaceAfter = 16;
        para_notas_seccao.Range.InsertParagraphAfter();
    }

    protected void Escreve_Sub_Seccoes(DataClassesDataContext db, SECCAO seccao_pai,Word._Document oDoc)
    {
        var sub_seccoes = from sub in db.SECCAOs where sub.ID_SECCAO_PAI == seccao_pai.ID_SECCAO orderby sub.ORDEM ascending select sub;
        String ordem_aux = ordem;
        foreach (SECCAO sub_seccao in sub_seccoes)
        {
            ordem += sub_seccao.ORDEM + ". ";
            Escreve_Seccao(sub_seccao,oDoc);
            Escreve_Sub_Seccoes(db,sub_seccao,oDoc);
            ordem = ordem_aux;
        }
    }

    protected void Insere_Imagem(IMAGEM bd_img, Word._Document oDoc)
    {
        object end_of_doc = "\\endofdoc";
        object missing = System.Reflection.Missing.Value;
        // Imagem
        Word.Paragraph para_img;
        object range_img = oDoc.Bookmarks.get_Item(ref end_of_doc).Range;
        para_img = oDoc.Content.Paragraphs.Add(ref range_img);
        para_img.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
        para_img.Format.SpaceAfter = 8;
        para_img.Range.InlineShapes.AddPicture(bd_img.NOME_FICHEIRO, ref missing, ref missing, ref missing);

        // Insere legenda
        Word.Paragraph para_leg_img;
        object range_leg_img = oDoc.Bookmarks.get_Item(ref end_of_doc).Range;
        para_leg_img = oDoc.Content.Paragraphs.Add(ref range_leg_img);
        para_leg_img.Range.Font.Size = 10;
        para_leg_img.Range.Font.Name = font_type;
        para_leg_img.Range.Text = bd_img.LEGENDA;
        para_leg_img.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
        para_leg_img.Format.SpaceAfter = 24;
        para_leg_img.Range.InsertParagraphAfter();
    }

    public void Export_To_Doc(int process_id)
    {
        Load_Settings();
        object missing = System.Reflection.Missing.Value;
        object end_of_doc = "\\endofdoc"; /* \endofdoc is a predefined bookmark */

        // Cria um documento do word
        Word._Application word_app;
        Word._Document word_doc;
        word_app = new Word.Application();
        word_app.Visible = true;
        word_doc = word_app.Documents.Add(ref missing, ref missing, ref missing, ref missing);


        // Titulo "Relatório de Averiguação"
        Word.Paragraph para_1;
        para_1 = word_doc.Content.Paragraphs.Add(ref missing);
        para_1.Range.Font.Size = 20;
        para_1.Range.Font.Name = font_type;
        para_1.Range.Text = "Relatório de Averiguação";
        para_1.Range.Font.Bold = 1;
        para_1.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
        para_1.Format.SpaceAfter = 36;
        para_1.Range.InsertParagraphAfter();

        DataClassesDataContext db = new DataClassesDataContext();
        PROCESSO processo = db.PROCESSOs.Single(p => p.ID_PROCESSO == process_id);

        // Número do processo
        Word.Paragraph para_2;
        object range_para_2 = word_doc.Bookmarks.get_Item(ref end_of_doc).Range;
        para_2 = word_doc.Content.Paragraphs.Add(ref range_para_2);
        para_2.Range.Font.Bold = 1;
        para_2.Range.Font.Size = font_size;
        para_2.Range.Font.Name = font_type;
        para_2.Range.Text = "Processo Nº. " + processo.NUMERO_PROCESSO;
        setPocessName(processo.NUMERO_PROCESSO);
        process_folder = Server.MapPath("../Upload/processos/"+processo.ID_PROCESSO + @"/");
        para_2.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft;
        para_2.Format.SpaceAfter = 18;
        para_2.Range.InsertParagraphAfter();

        var seccoes = from s in db.SECCAOs where s.ID_PROCESSO == process_id && s.ID_SECCAO_PAI == null orderby s.ORDEM ascending select s;

        foreach (SECCAO seccao in seccoes)
        {
            ordem = seccao.ORDEM + ". ";
            Escreve_Seccao(seccao, word_doc);
            Escreve_Sub_Seccoes(db, seccao, word_doc);
        }

        // Passa para a página seguinte
        Word.Range range = word_doc.Bookmarks.get_Item(ref end_of_doc).Range;
        object collapse_end = Word.WdCollapseDirection.wdCollapseEnd;
        object page_break = Word.WdBreakType.wdPageBreak;
        range.Collapse(ref collapse_end);
        range.InsertBreak(ref page_break);
        range.Collapse(ref collapse_end);
        range.InsertParagraphAfter();

        // Titulo "Anexos"
        Word.Paragraph para_3;
        object range_para_3 = word_doc.Bookmarks.get_Item(ref end_of_doc).Range;
        para_3 = word_doc.Content.Paragraphs.Add(ref range_para_3);
        para_3.Range.Font.Bold = 1;
        para_3.Range.Font.Size = 16;
        para_3.Range.Font.Name = font_type;
        para_3.Range.Text = "Anexos";
        para_3.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
        para_3.Format.SpaceAfter = 18;
        para_3.Range.InsertParagraphAfter();

        // Inserir imagens
        var imagens = from i in db.IMAGEMs where i.ID_PROCESSO == process_id orderby i.ORDEM ascending select i;

        foreach (IMAGEM img in imagens)
        {
            Insere_Imagem(img, word_doc);
        }

        object obj = new object();
        String path = process_folder + getProcessName() + ".doc";
        obj = (object)path;
        try
        {
            word_doc.SaveAs(ref obj, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
            object f = new object();
            f = (bool)false;
            word_app.Quit(ref f, ref missing, ref missing);
        }
        catch (Exception e)
        {
        }
    }

    public void Export_To_HTML(int process_id)
    {
        Load_Settings();
        object missing = System.Reflection.Missing.Value;
        object end_of_doc = "\\endofdoc"; /* \endofdoc is a predefined bookmark */

        // Cria um documento do word
        Word._Application word_app;
        Word._Document word_doc;
        word_app = new Word.Application();
        word_app.Visible = false;
        word_doc = word_app.Documents.Add(ref missing, ref missing, ref missing, ref missing);


        // Titulo "Relatório de Averiguação"
        Word.Paragraph para_1;
        para_1 = word_doc.Content.Paragraphs.Add(ref missing);
        para_1.Range.Font.Size = 20;
        para_1.Range.Font.Name = font_type;
        para_1.Range.Text = "Relatório de Averiguação";
        para_1.Range.Font.Bold = 1;
        para_1.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
        para_1.Format.SpaceAfter = 36;
        para_1.Range.InsertParagraphAfter();

        DataClassesDataContext db = new DataClassesDataContext();
        PROCESSO processo = db.PROCESSOs.Single(p => p.ID_PROCESSO == process_id);

        // Número do processo
        Word.Paragraph para_2;
        object range_para_2 = word_doc.Bookmarks.get_Item(ref end_of_doc).Range;
        para_2 = word_doc.Content.Paragraphs.Add(ref range_para_2);
        para_2.Range.Font.Bold = 1;
        para_2.Range.Font.Size = font_size;
        para_2.Range.Font.Name = font_type;
        para_2.Range.Text = "Processo Nº. " + processo.NUMERO_PROCESSO;
        setPocessName(processo.NUMERO_PROCESSO);
        process_folder = Server.MapPath("../Upload/processos/" + processo.ID_PROCESSO + @"/");
        para_2.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft;
        para_2.Format.SpaceAfter = 18;
        para_2.Range.InsertParagraphAfter();

        var seccoes = from s in db.SECCAOs where s.ID_PROCESSO == process_id && s.ID_SECCAO_PAI == null orderby s.ORDEM ascending select s;

        foreach (SECCAO seccao in seccoes)
        {
            ordem = seccao.ORDEM + ". ";
            Escreve_Seccao(seccao, word_doc);
            Escreve_Sub_Seccoes(db, seccao, word_doc);
        }

        // Passa para a página seguinte
        Word.Range range = word_doc.Bookmarks.get_Item(ref end_of_doc).Range;
        object collapse_end = Word.WdCollapseDirection.wdCollapseEnd;
        object page_break = Word.WdBreakType.wdPageBreak;
        range.Collapse(ref collapse_end);
        range.InsertBreak(ref page_break);
        range.Collapse(ref collapse_end);
        range.InsertParagraphAfter();

        // Titulo "Anexos"
        Word.Paragraph para_3;
        object range_para_3 = word_doc.Bookmarks.get_Item(ref end_of_doc).Range;
        para_3 = word_doc.Content.Paragraphs.Add(ref range_para_3);
        para_3.Range.Font.Bold = 1;
        para_3.Range.Font.Size = 16;
        para_3.Range.Font.Name = font_type;
        para_3.Range.Text = "Anexos";
        para_3.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
        para_3.Format.SpaceAfter = 18;
        para_3.Range.InsertParagraphAfter();

        // Inserir imagens
        var imagens = from i in db.IMAGEMs where i.ID_PROCESSO == process_id orderby i.ORDEM ascending select i;

        foreach (IMAGEM img in imagens)
        {
            Insere_Imagem(img, word_doc);
        }

        object obj = new object();
        String path = process_folder + getProcessName() + ".doc";
        obj = (object)path;
        try
        {

            object f = new object();
            f = (bool)false;
            word_doc.SaveAs(ref obj, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
            word_app.Quit(ref f, ref missing, ref missing);
            word_to_html(process_folder + getProcessName() + ".doc", process_folder + getProcessName() + ".html");
        }
        catch (Exception e)
        {
        }
    }

    public void Export_To_PDF(int process_id)
    {
        Load_Settings();
        object missing = System.Reflection.Missing.Value;
        object end_of_doc = "\\endofdoc"; /* \endofdoc is a predefined bookmark */

        // Cria um documento do word
        Word._Application word_app;
        Word._Document word_doc;
        word_app = new Word.Application();
        word_app.Visible = true;
        word_doc = word_app.Documents.Add(ref missing, ref missing, ref missing, ref missing);
        

        // Titulo "Relatório de Averiguação"
        Word.Paragraph para_1;
        para_1 = word_doc.Content.Paragraphs.Add(ref missing);
        para_1.Range.Font.Size = 20;
        para_1.Range.Font.Name = font_type;
        para_1.Range.Text = "Relatório de Averiguação";
        para_1.Range.Font.Bold = 1;
        para_1.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
        para_1.Format.SpaceAfter = 36;
        para_1.Range.InsertParagraphAfter();

        DataClassesDataContext db = new DataClassesDataContext();
        PROCESSO processo = db.PROCESSOs.Single(p => p.ID_PROCESSO == process_id);

        // Número do processo
        Word.Paragraph para_2;
        object range_para_2 = word_doc.Bookmarks.get_Item(ref end_of_doc).Range;
        para_2 = word_doc.Content.Paragraphs.Add(ref range_para_2);
        para_2.Range.Font.Bold = 1;
        para_2.Range.Font.Size = font_size;
        para_2.Range.Font.Name = font_type;
        para_2.Range.Text = "Processo Nº. " + processo.NUMERO_PROCESSO;
        setPocessName(processo.NUMERO_PROCESSO);
        process_folder = Server.MapPath("../Upload/processos/" + processo.ID_PROCESSO + @"/");
        para_2.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft;
        para_2.Format.SpaceAfter = 18;
        para_2.Range.InsertParagraphAfter();

        var seccoes = from s in db.SECCAOs where s.ID_PROCESSO==process_id && s.ID_SECCAO_PAI==null orderby s.ORDEM ascending select s;

        foreach (SECCAO seccao in seccoes)
        {
            ordem = seccao.ORDEM + ". ";
            Escreve_Seccao(seccao, word_doc);
            Escreve_Sub_Seccoes(db, seccao, word_doc);
        }

        // Passa para a página seguinte
        Word.Range range = word_doc.Bookmarks.get_Item(ref end_of_doc).Range;
        object collapse_end = Word.WdCollapseDirection.wdCollapseEnd;
        object page_break = Word.WdBreakType.wdPageBreak;
        range.Collapse(ref collapse_end);
        range.InsertBreak(ref page_break);
        range.Collapse(ref collapse_end);
        range.InsertParagraphAfter();

        // Titulo "Anexos"
        Word.Paragraph para_3;
        object range_para_3 = word_doc.Bookmarks.get_Item(ref end_of_doc).Range;
        para_3 = word_doc.Content.Paragraphs.Add(ref range_para_3);
        para_3.Range.Font.Bold = 1;
        para_3.Range.Font.Size = 16;
        para_3.Range.Font.Name = font_type;
        para_3.Range.Text = "Anexos";
        para_3.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
        para_3.Format.SpaceAfter = 18;
        para_3.Range.InsertParagraphAfter();

        // Inserir imagens
        var imagens = from i in db.IMAGEMs where i.ID_PROCESSO == process_id orderby i.ORDEM ascending select i;

        foreach (IMAGEM img in imagens)
        {
            Insere_Imagem(img, word_doc);
        }

        object obj = new object();
        String path = process_folder + getProcessName() + ".doc";
        obj=(object)path;
        try
        {
            object f = new object();
            f = (bool)false;

            word_doc.SaveAs(ref obj, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
            word_app.Quit(ref f, ref missing, ref missing);
        }
        catch (Exception e)
        {
        }
        word_to_pdf(process_folder + getProcessName(),process_folder + getProcessName() + ".doc", process_folder + getProcessName() + ".pdf");
    }

    private void word_to_html(object source, object target)
    {             
        Word.ApplicationClass ms_doc = new Word.ApplicationClass();

        object missing = System.Reflection.Missing.Value;

        try
        {
            ms_doc.Visible = false;
            ms_doc.Documents.Open(ref source, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
            ms_doc.Application.Visible = false;
            ms_doc.WindowState = Word.WdWindowState.wdWindowStateMinimize;

            object format = Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatHTML;

            ms_doc.ActiveDocument.SaveAs(ref target, ref format, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
        }
        catch (Exception e)
        {
        }
        finally
        {
            if (ms_doc != null)
            {
                ms_doc.Documents.Close(ref missing, ref missing, ref missing);
                //WordDoc.Application.Quit(ref Unknown, ref Unknown, ref Unknown);
            }
            // for closing the application
            ms_doc.Quit(ref missing, ref missing, ref missing);
        }
    }

    private void word_to_pdf(object nome_sem_extensao, object source, object target)
    {            
        Word.ApplicationClass ms_doc = new Word.ApplicationClass();

        object missing = System.Reflection.Missing.Value;

        try
        {
            ms_doc.Visible = false;
            ms_doc.Documents.Open(ref source, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
            ms_doc.Application.Visible = false;
            ms_doc.WindowState = Word.WdWindowState.wdWindowStateMinimize;

            object format = Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatRTF;
            object nome_rtf = (String)nome_sem_extensao + ".rtf";

            ms_doc.ActiveDocument.SaveAs(ref nome_rtf, ref format, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
        }
        catch (Exception e)
        {
        }
        finally
        {
            if (ms_doc != null)
            {
                ms_doc.Documents.Close(ref missing, ref missing, ref missing);
                //WordDoc.Application.Quit(ref Unknown, ref Unknown, ref Unknown);
            }
            // for closing the application
            ms_doc.Quit(ref missing, ref missing, ref missing);
        }
        SautinSoft.PdfMetamorphosis p = new SautinSoft.PdfMetamorphosis();
        String src = (String)nome_sem_extensao + ".rtf";
        String tgt = (String)target;
        p.RtfToPdfConvertFile(src, tgt);
        File.Delete(src);
    }

    protected String getProcessName()
    {
        return process_name;
    }

    protected void setPocessName(String processo)
    {
        this.process_name = processo;
    }    
}
