Imports SelectPdf
Imports System.Drawing
Imports System.Web

Namespace Controllers
    Public Class TableOfContentsController
        Inherits Controller

        ' number of items in the table of contents (TOC)
        Private TOC_Items As Integer = 13

        ' CSS class for TOC items (titles and targets)
        Private TOC_Class As String = "toc"

        ' font size for page numbers in the table of contents
        Private TOC_Page_Font_Size As Integer = 12

        ' CSS class for PDF bookmarks
        Private Bookmarks_Class As String = "bookmark"

        ' Each TOC item is represented by a title with ID TOC_Title{0}
        ' and a target (internal link) with ID TOC_Target{0}
        ' Both TOC titles and targets must have the same CSS Class ("toc" in our sample)


        ' GET: TableOfContents
        Public Function Index() As ActionResult
            Dim url As String = VirtualPathUtility.ToAbsolute("~/files/document2.html")
            ViewData.Add("ViewTxtUrl", (New Uri(Request.Url, url)).AbsoluteUri)
            Return View()
        End Function

        <HttpPost>
        Public Function SubmitAction(fields As FormCollection) As ActionResult
            Dim renderingEngine As RenderingEngine = CType([Enum].Parse(GetType(RenderingEngine), Request("DdlRenderingEngine"), True), RenderingEngine)
            ' instantiate a html to pdf converter object
            Dim converter As New HtmlToPdf()
            converter.Options.RenderingEngine = renderingEngine
            converter.Options.CefEnginePath = Server.MapPath(ConfigurationManager.AppSettings("CefEnginePath"))
            converter.Options.MarginTop = 20
            converter.Options.MarginRight = 20
            converter.Options.MarginBottom = 20
            converter.Options.MarginLeft = 20

            ' set the css selectors for the automatic bookmarks 
            ' (elements with CSS class "bookmark")
            converter.Options.PdfBookmarkOptions.CssSelectors =
                New String() {Convert.ToString("*.") & Bookmarks_Class}

            ' set the css selectors for the TOC related elements
            ' (elements with CSS class "toc")
            ' (alternatively, full list of IDs can be specified)
            converter.Options.WebElementsMappingOptions.CssSelectors =
                New String() {Convert.ToString("*.") & TOC_Class}

            ' display the bookmarks when the document is opened in a viewer
            converter.Options.ViewerPreferences.PageMode = PdfViewerPageMode.UseOutlines

            ' footer settings
            converter.Options.DisplayFooter = True
            converter.Footer.Height = 30

            ' page numbers can be added using a PdfTextSection object
            Dim text As New PdfTextSection(0, 10, "Page: {page_number} of {total_pages}  ",
                                           New System.Drawing.Font("Verdana", 10))
            text.HorizontalAlign = PdfTextHorizontalAlign.Right
            converter.Footer.Add(text)


            ' create a new pdf document converting an url
            Dim doc As PdfDocument = converter.ConvertUrl(fields("TxtUrl"))

            ' create font for page numbers
            Dim pageNumberFont As PdfFont = doc.Fonts.Add(
                New Font("Arial", TOC_Page_Font_Size,
                         FontStyle.Regular, GraphicsUnit.Point), True)

            ' get the right coordinate of the table of contents 
            ' to position the page numbers
            Dim tocRight As Single = doc.Pages(0).ClientRectangle.Width - 50

            ' add page numbers for the table of contents items
            For tocItem As Integer = 1 To TOC_Items
                Dim tocTitleID As String = [String].Format("TOC_Title{0}", tocItem)
                Dim tocTargetID As String = [String].Format("TOC_Target{0}", tocItem)

                Dim tocTitle As WebElement = converter.Options.WebElementsMappingOptions _
                    .Result.GetElementByHtmlId(tocTitleID)
                Dim tocTarget As WebElement = converter.Options.WebElementsMappingOptions _
                    .Result.GetElementByHtmlId(tocTargetID)

                If tocTitle Is Nothing OrElse tocTarget Is Nothing Then
                    ' TOC items not found
                    Continue For
                End If

                ' get the TOC title page and rendering rectangle
                Dim tocPage As PdfPage = doc.Pages(tocTitle.PdfRectangles(0).PageIndex)
                Dim tocTitleRectangle As RectangleF = tocTitle.PdfRectangles(0).Rectangle

                ' get the page number of target where the TOC entry points
                Dim tocTargetPageNumber As Integer =
                    tocTarget.PdfRectangles(0).PageIndex + 1

                ' add dashed line from TOC title to the page number
                Dim dashedLine As New PdfLineElement(tocTitleRectangle.Right + 5,
                            tocTitleRectangle.Y + tocTitleRectangle.Height - 4,
                            tocRight,
                            tocTitleRectangle.Y + tocTitleRectangle.Height - 4)
                dashedLine.LineStyle.LineWidth = 1
                dashedLine.LineStyle.LineDashStyle = PdfLineDashStyle.Dash
                dashedLine.ForeColor = Color.Black
                tocPage.Add(dashedLine)

                ' create the page number text element to the right of the TOC title
                Dim pageNumberTextElement As New PdfTextElement(tocRight + 5,
                                                    tocTitleRectangle.Y, -1,
                                                    tocTitleRectangle.Height,
                                                    tocTargetPageNumber.ToString(),
                                                    pageNumberFont)
                pageNumberTextElement.HorizontalAlign = PdfTextHorizontalAlign.Left
                pageNumberTextElement.VerticalAlign = PdfTextVerticalAlign.Middle
                pageNumberTextElement.ForeColor = Color.Black

                ' add the page number to the right of the TOC entry
                tocPage.Add(pageNumberTextElement)
            Next

            ' save pdf document
            Dim pdf As Byte() = doc.Save()

            ' close pdf document
            doc.Close()

            ' return resulted pdf document
            Dim fileResult As FileResult = New FileContentResult(pdf, "application/pdf")
            fileResult.FileDownloadName = "Document.pdf"
            Return fileResult
        End Function
    End Class
End Namespace