/* 
 * 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;
using DXLib.Utils;

using SizeF = Syncfusion.Drawing.SizeF;

namespace iStatVball3;

/*
 * Creates a PDF document from a Play-by-Play log. The document includes a header, preamble lines, and then a line for
 * each stat in the log.
 */
public class LogExport
{
    /* Constants */
    private const float Spacing = 2;
    private const float StatHt = 10;

    // Header logo
    private const string LogoFile = "Images/logo_export.png";

    /* Fields */
    private PdfPage page;

    // Stat output
    private RecordHistory history;
    private Set set;

    /* Methods */

    // Creates PDF document for specified configuration
    public async Task<byte[]> Create( ExportConfig config )
    {
        // Always set scope
        set = config.DataConfig.ScopeObject as Set;

        // Configure page layout
        PdfPageSettings settings = new()
        {
            Orientation = PdfPageOrientation.Portrait,
            Margins = new PdfMargins
            {
                Left = 50,
                Right = 50,
                Top = 15,
                Bottom = 30
            }
        };

        // 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 += (Spacing * 2);
        y = await preamble.Draw( y );
        y += (Spacing * 10);

        List<Stat> stats = config.Stats;

        // Stat count
        y = await DrawCount( stats, y );

        // All stat lines
        await DrawStats( document, stats, y );

        MemoryStream stream = new();

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

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

    // Draws stat count header
    private async Task<float> DrawCount( List<Stat> stats, float y )
    {
        // '321 Events'
        string text = $"{stats.Count} {DXString.GetUpper( "log.events" )}";

        PdfColor color = PDFUtils.GetColor( DXColors.Dark1 );

        // Draw
        return await PDFUtils.DrawText( page, text, PDFUtils.BoldFont, StatHt, color, 0, y );
    }

    // Draws line for each stat in log
    private async Task DrawStats( PdfDocument document, List<Stat> stats, float y )
    {
        // Prep line creator
        history = new RecordHistory
        {
            ShowTeams = true,
            ShowScores = true,
            ShowRatings = true,
            ShowErrors = true,

            ShowModifiers = true,
            ShowFaults = true,
            ShowMultiBlock = true,
            ActionMode = RecordHistory.ActionModes.ActionSelector,

            AbbreviateTeams = true,
            AbbreviateNames = false,
            AbbreviateResults = false,

            MaxNameLength = 32
        };

        history.Init( set.Match );

        float statY = y;

        // Output each stat
        foreach ( Stat stat in stats )
        {
            statY += (Spacing * 4);
            statY = await DrawStat( document, stat, statY );
        }
    }

    // Draws individual stat line into PDF document
    private async Task<float> DrawStat( PdfDocument document, Stat stat, float y )
    {
        // Time offset
        string offset = LogView.GetOffset( stat, 0 );

        // Stat line
        string line = history.CreateLine( stat );

        // '0:00    FOO John Doe Attack Attempt'
        string text = $"{offset}\t\t{line}";

        // Color coded by action
        PdfColor color = PDFUtils.GetColor( LogView.GetColor( stat, DXColors.Dark1 ) );

        // Some actions bold
        string font = (stat.IsPoint || stat.IsEnd) ? PDFUtils.BoldFont : PDFUtils.RegularFont;

        // Draw
        float statY = await PDFUtils.DrawText( page, text, font, StatHt, color, 0, y );

        SizeF size = page.GetClientSize();

        // Start new page if will not fit
        if ( (statY + StatHt) > size.Height )
        {
            page = document.Pages.Add();
            statY = 0;
        }

        // Listen for pagination
        document.Pages.PageAdded += OnPageAdded;

        return statY;
    }

    /* Event Callbacks */

    // Required for correct pagination
    private void OnPageAdded( object sender, PageAddedEventArgs args )
    {
        page = args.Page;
    }
}

//
