/* 
 * Copyright (c)2009-2025 DemiVision, LLC. All Rights Reserved. The information 
 * herein is the CONFIDENTIAL and PROPRIETARY information of DemiVision, LLC. 
 */

using Syncfusion.Pdf;
using Syncfusion.Pdf.Graphics;

using DXLib.UI;

namespace iStatVball3;

/*
 * Creates a PDF document from a stats analysis report. The document includes a header, preamble lines, and then all
 * data cards from the report.
 */
public class PDFReport
{
    /* Constants */
    public const float Spacing = 2;
    public const float TitleSpacing = 6;
    public const float TitleHt = 60;

    private const string LogoFile = "logo_export";

    /* Fields */
    private PdfPage page;

    /* Methods */

    // Creates PDF document for specified report configuration
    public async Task<byte[]> Create( ExportConfig config )
    {
        // Orientation
        bool landscape = !config.IsCustom && config.Json.PDF.Landscape;

        // Configure page layout
        PdfPageSettings settings = new()
        {
            Orientation = landscape ? PdfPageOrientation.Landscape : PdfPageOrientation.Portrait,
            Margins = new PdfMargins
            {
                Left = 25,
                Right = 25,
                Top = 25,
                Bottom = 25
            }
        };

        // Create master document
        PdfDocument document = new()
        {
            PageSettings = settings
        };

        // Create first page
        page = document.Pages.Add();

        // Logo
        float y = await PDFUtils.DrawImage( page, LogoFile, 0, 0 );

        string title = config.Title.ToUpper();

        // Title
        await PDFUtils.DrawText( page, title, PDFUtils.BoldFont, 17, PDFUtils.GetColor( DXColors.Dark4 ), 135, 0 );

        // Preamble lines
        PDFPreamble preamble = new( config, page );

		y = await preamble.Draw( y + (Spacing * 2) );
		y += (Spacing * 4);

		// Report cards
		foreach ( ReportCard card in config.Cards )
		{
            y += (Spacing * 10);

            // Type specific drawing
            y = await DrawCard( document, card, y );
        }

		MemoryStream stream = new();

        // Write PDF data to stream
        document.Save( stream );
        document.Close( true );

        // Return as byte array
        return stream.ToArray();
    }

    // Draws report card of any supported type
    private static async Task<float> DrawCard( PdfDocument document, ReportCard card, float y )
    {
        float endY = y;

        switch ( card )
        {
            // Grid
            case GridCard gridCard:
            {
                PDFGrid grid = new();
                await grid.Init();

                endY = await grid.Draw( document, gridCard, y );
                break;
            }
            // Bar
            case BarCard barCard:
            {
                endY = await PDFBar.Draw( document, barCard, y );
                break;
            }
            // Shot
            case ShotCard shotCard:
            {
                PDFShot shot = new();

                endY = await shot.Draw( document, shotCard, y );
                break;
            }
            // Heat
            case HeatCard heatCard:
            {
                PDFHeat heat = new();

                endY = await heat.Draw( document, heatCard, y );
                break;
            }
            // Trend
            case TrendCard trendCard:
            {
                endY = await PDFTrend.Draw( document, trendCard, y );
                break;
            }
            // Momentum
            case MomentumCard momentumCard:
            {
                endY = await PDFMomentum.Draw( document, momentumCard, y );
                break;
            }
        }

        return endY;
    }
}

//
