AiGetTable.cs
//
// This code is part of Document Solutions for PDF demos.
// Copyright (c) MESCIUS inc. All rights reserved.
//
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Pdf.AI;
using GrapeCity.Documents.Layout;
using GrapeCity.Documents.Drawing;
using DsPdfWeb.Demos.Common;
using System.Threading.Tasks;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;

namespace DsPdfWeb.Demos
{
    // This sample uses the PDF AI Assistant (DsPdfAI) to extract data from a specified table in a PDF.
    // The extracted data is then inserted into the first page using TableRenderer,
    // following the approach demonstrated in the PlainTable sample.
    //
    // To run this sample locally, set your OpenAI credentials
    // using Util.OpenAIToken.

    public class AiGetTable
    {
        public int CreatePDF(Stream stream, int paramsIdx = 0)
        {
            return CreatePDF(stream, GetSampleParamsList()[paramsIdx]);
        }

        public int CreatePDF(Stream stream, string[] sampleParams)
        {
            var doc = new GcPdfDocument();
            using var fs = File.OpenRead(Path.Combine("Resources", "PDFs", sampleParams[3]));
            doc.Load(fs);
            try
            {
                var a = new OpenAIDocumentAssistant(Util.OpenAIToken);
                var task = a.GetTable(doc, sampleParams[4]);
                task.Wait();

                var page = doc.Pages.Insert(0);
                var rc = Util.AddNote("Table data extracted using DsPdf AI Assistant", page);
                DrawTable(task.Result, page.Graphics, rc.X, rc.Bottom + 18, page.Size.Width, page.Size.Height);
            }
            catch (Exception ex)
            {
                // Make sure you have assigned your OpenAI API key to Util.OpenAIToken:
                Util.CreatePdfError(doc, ex.Message);
            }
            doc.Save(stream);
            return doc.Pages.Count;
        }

        static void DrawTable(Table table, GcGraphics g, float x, float y, float pageWidth, float pageHeight)
        {
            var host = new LayoutHost();
            var view = host.CreateView(pageWidth, pageHeight);

            var rt = view.CreateRect();
            rt.AnchorTopLeft(null, y, x);

            var ta = new TableRenderer(g,
                rt, FixedTableSides.TopLeft,
                rowCount: table.Rows.Count,
                columnCount: table.Cols.Count,
                gridLineColor: Color.DarkGray,
                gridLineWidth: 1,
                rowMinHeight: 10);

            ta.DefaultCellStyle = new CellStyle
            {
                MaxWidth = pageWidth / table.Cols.Count, // A guess assuming that some columns will be narrow
                TextAlignment = TextAlignment.Leading,
                PaddingTopBottom = 3,
                PaddingLeftRight = 4,
                FixedWidth = false,
                TextFormat = new TextFormat
                {
                    Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "NotoSans-Regular.ttf")),
                    FontSize = 16,
                    FontSizeInGraphicUnits = true
                }
            };

            for (int i = 0; i < table.Rows.Count; ++i)
            {
                for (int j = 0; j < table.Cols.Count; ++j)
                {
                    ta.AddCell(i, j, table.Rows[i].Cells[j].Text);
                }
            }

            ta.ApplyCellConstraints();
            ta.Render();
        }

        public static List<string[]> GetSampleParamsList()
        {
            // Items are: name, description, info, PDF name, AI request:
            return
            [
                new string[] { "@ai-table/Invoice Items", "Get items data from a table in an invoice document", "",
                    "zugferd-invoice.pdf", "Get rows 1 to 5 from the table in the document." },
                new string[] { "@ai-table/Projected Payments", "Get 'Projected Payments' table from a loan closure document", "",
                    "LoanClosure.pdf", "Get the 'Projected Payments' table from the document." },
                new string[] { "@ai-table/Expenses (Top 3 Rows)", "Get the first three rows of a table in an expenses report", "",
                    "ExpenseReport.pdf", "Get the first three rows of 'Expenses' table from the document." },
            ];
        }
    }
}