#-------------------------------------------------------------------------------
#  fddemo.pm:
#
#  Scripting Facility module to process the AFP spool input as given below
#  - Split each input page group as one PDF output
#  - Protects the output PDF with password
#  - Name the PDF output uniquely using the document index "Policy"
#  - Store each PDF output in a unique sub directory, which has been named with following syntax
#  -- <input file basename>/<YYYYMMDD>_<document id>/
# 
#  Example:
#  - Assuming the input filename is "samples/insure.afp" and current date is "17.04.2025"
#  - Outputs will be generated in a directory structure as given below
#    <output path>\
#                  insure.afp\
#                             20250417_000001\
#                                             324-1443255-11.pdf
#
#  Call:
#  On Windows: afp2web.exe -q -c -doc_cold -sp:fddemo.pm samples\insure.afp
#  On Unix:    ./afp2web   -q -c -doc_cold -sp:fddemo.pm samples/insure.afp
#
#  Author  : Fa. Maas
#  Date    : 2025-04-17
#
#  V100   2025-04-17    AFP-1243: FirstData UK (Fiserv): Initial Release
#
#-------------------------------------------------------------------------------

#-----------------------------------------------------------------------
# BEGIN block of module
#
# Extends PERL module search path array (@INC) with new element having
# this script modules path in order to have better module portability
#-----------------------------------------------------------------------
BEGIN {
    #---- Fetch script filename
    my $sScriptFilenameTmp = $0;

    #---- Extract script file path from script filename
    my $sScriptFilePathTmp = "";
    if ( $sScriptFilenameTmp =~ /(.*)\/.*\.pm/ ){
        $sScriptFilePathTmp = $1;
    }

    #printf STDERR ( "Script filename: " . $0 . " Script filepath: " . $sScriptFilePathTmp . "\n" );
    if ( $sScriptFilePathTmp eq "" ){
        $sScriptFilePathTmp = ".";
    }
    else {
        my $sScriptFileParentPathTmp = "";
        if ( $sScriptFilePathTmp =~ /(.*)\/sfsamples/ ){
            $sScriptFileParentPathTmp = $1;
        }

        #---- Add script file parent path to module search path
        if ( $sScriptFileParentPathTmp ne "" ){
            unshift( @INC, $sScriptFileParentPathTmp );
        }
    }

    #---- Add script file path to module search path
    unshift( @INC, $sScriptFilePathTmp );
}

use a2w::Config;
use a2w::Document;
use a2w::Font;
use a2w::Index;
use a2w::Kernel;
use a2w::Line;
use a2w::MediumMap;
use a2w::NOP;
use a2w::Overlay;
use a2w::Page;
use a2w::PSEG;
use a2w::Text;

use a2w::ConfigConstants;
use a2w::DocumentConstants;
use a2w::PageConstants;
use a2w::FontConstants;

#-----------------------------------------------------------------------
# Initialize once per process
#-----------------------------------------------------------------------
sub initialize(){

    #---- Get Parameter of initialize( Par: a2w::Config, a2w::Kernel )
    ( $a2wConfigPar, $a2wKernelPar ) = @_;

    #---- Define boolean values
    $TRUE  = 1;    # TRUE  boolean value
    $FALSE = 0;    # FALSE boolean value

    #---- Set/Reset Logging
    $bLog = $FALSE;
    if (index( lc($a2wConfigPar->getAttribute( $a2w::ConfigConstants::LOGGINGLEVEL )), "sf") >= 0 ){
        $bLog = $TRUE;
    }

    my $sScriptProcTmp = $a2wConfigPar->getAttribute( $a2w::ConfigConstants::SCRIPTPROCEDURE );
    my $sScriptArgsTmp = $a2wConfigPar->getAttribute( $a2w::ConfigConstants::SCRIPTARGUMENT );
    $sIndexFilePath    = $a2wConfigPar->getAttribute( $a2w::ConfigConstants::INDEXPATH );
    $sOutputFilePath   = $a2wConfigPar->getAttribute( $a2w::ConfigConstants::OUTPUTFILEPATH );
    $sSpoolFilename    = $a2wKernelPar->getSpoolFilename();

    if ( $bLog == $TRUE ){
        printf STDERR ( "Running $sScriptProcTmp...\n" );
        printf STDERR ( "initialize(): Processing $sSpoolFilename\n" );
        printf STDERR ( "initialize(): Args: $sScriptArgsTmp, IndexFilePath: $sIndexFilePath, OutputFilePath: $sOutputFilePath\n" );
    }

    #---- Page process flags
    $APPEND = 0;    # append page to Current Document
    $SKIP   = 1;    # skip page
    $NEWDOC = 2;    # new document

    #---- Set AutoSplit to true
    #INFO: If your AFP Spool contains Page Named Groups and Tag Logical 
    #INFO: Elements (TLEs) and if you want AFP2web to automatically split
    #INFO: the documents, set AutoSplit on, if not remove following line
    $a2wConfigPar->setAttribute( $a2w::ConfigConstants::AUTOSPLIT, "on" );

    #---- Protect the PDFs with password
    # owner password: firstdata
    # user password: fiserv
    $a2wConfigPar->setAttribute( $a2w::ConfigConstants::PDFSECURITY, "firstdata,fiserv" );

    #---- Get input file basename
    $sInputBasename = $sSpoolFilename;
    $sInputBasename =~ s/.*[\\\/](.*)$/$1/;

    return 0;
}

#-----------------------------------------------------------------------
# InitializeDoc for each document
#-----------------------------------------------------------------------
sub initializeDoc(){

    #---- Get Parameter of initializeDoc( Par: a2w::Document )
    ($a2wDocumentPar) = @_;

    if ( $bLog == $TRUE ){ printf STDERR ( "initializeDoc(): DocId " . $a2wDocumentPar->getId() . "\n" ); }

    return 0;
}

#-----------------------------------------------------------------------
# InitializePage for each page
#-----------------------------------------------------------------------
sub initializePage(){

    #---- Get Parameter of initializePage( Par: a2w::Page )
    ($a2wPagePar) = @_;

    if ( $bLog == $TRUE ){ printf STDERR ( "initializePage()\n" ); }

    return 0;
}

#-----------------------------------------------------------------------
# Main entry method
# Return values:
#        < 0:    error
#         0:    append page to Current Document
#         1:    skip page
#         2:    first page / new document
#-----------------------------------------------------------------------
sub afp2web(){

    if ( $bLog == $TRUE ){ printf STDERR ( "afp2web(): PageId " . $a2wPagePar->getParseId() . "\n" ); }

    #---- Set default return value
    my $iRetTmp = $APPEND; # append page to Current Document

    return $iRetTmp;
}

#-----------------------------------------------------------------------
# FinalizePage for each page
#-----------------------------------------------------------------------
sub finalizePage(){

    if ( $bLog == $TRUE ){ printf STDERR ( "finalizePage()\n" ); }
    return 0;
}

#-----------------------------------------------------------------------
# FinalizeDoc for each document
#-----------------------------------------------------------------------
sub finalizeDoc(){

    if ( $bLog == $TRUE ){ printf STDERR ( "finalizeDoc()\n" ); }

    #---- Get the document name
    my $sDocNameTmp = $a2wDocumentPar->getName();

    #---- Get the document id
    my $iDocIdTmp = $a2wDocumentPar->getId();

    #---- Get the policy number (document index)
    my $sPloicyNrTmp = _getPolicyNumber();

    #---- Get core generated output filename
    my $sDocFilenameTmp = $sOutputFilePath . $a2wDocumentPar->getOutputFilename();

    #---- Evaluate unique output file path, name and move output file as needed ----#
    # Syntax: <output path>/<input file basename>/<YYYYMMDD>-<document id>/<policy number>.pdf
	#

    #   0    1    2     3     4    5     6     7     8
    #($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
    my @arrCurrentTimeTmp = localtime( time() );
    @arrCurrentTimeTmp[ 5 ] += 1900;        # Year is not complete 4 digit, so adding 1900
    @arrCurrentTimeTmp[ 4 ]++;              # Day of month starts from 0, so adding 1
    my $sDocSubDirTmp = sprintf(   "%04d%02d%02d_%06d"
                                 , @arrCurrentTimeTmp[ 5 ]
                                 , @arrCurrentTimeTmp[ 4 ]
                                 , @arrCurrentTimeTmp[ 3 ]
                                 , $iDocIdTmp
                               );

    if ( $bLog == $TRUE ){
        printf STDERR (   "Document %d: Name=%s Policy=%s Filename=%s Subdir=%s\n"
                        , $iDocIdTmp
                        , $sInputBasename
                        , $sPloicyNrTmp
                        , $sDocFilenameTmp
                        , $sDocSubDirTmp
                      );
    }

    #---- Check and create the input file basename sub directory in output path
    my $sOutPath1Tmp = $sOutputFilePath . $sInputBasename;
    if ( !(-d $sOutPath1Tmp) ){
        my $iMkDirRetTmp = mkdir( $sOutPath1Tmp );
        if ( $iMkDirRetTmp == 0 ){
            return ( -1, "Unable to create $sInputBasename sub directory in output path $sOutputFilePath, reason: $!" );
        }
    }

    #---- Check and create the document specific unique sub directory in output path
    my $sOutPath2Tmp = $sOutPath1Tmp . "/" . $sDocSubDirTmp;
    if ( !(-d $sOutPath2Tmp) ){
        my $iMkDirRetTmp = mkdir( $sOutPath2Tmp );
        if ( $iMkDirRetTmp == 0 ){
            return ( -2, "Unable to create $sOutPath2Tmp sub directory in output path $sOutPath1Tmp, reason: $!" );
        }
    }

    #---- Move the core generated output to required output path
    my $sNewFilenameTmp = $sOutPath2Tmp . "/" . $sPloicyNrTmp . ".pdf";
    my $iMoveRetTmp = rename( $sDocFilenameTmp, $sNewFilenameTmp );
    if ( $iMoveRetTmp <= 0 ){
        return ( -3, "Unable to rename file $sDocFilenameTmp as $sNewFilenameTmp, reason: $!" );
    }

    return 0;
}

#-----------------------------------------------------------------------
# Finalize once per process
#-----------------------------------------------------------------------
sub finalize(){

    if ( $bLog == $TRUE ){ printf STDERR ( "finalize()\n" ); }

    return 0;
}

#------------------------- Private functions --------------------------#
#-----------------------------------------------------------------------
# Get policy number index value from current document
#-----------------------------------------------------------------------
sub _getPolicyNumber(){

    if ( $bLog == $TRUE ){ printf STDERR ( "_getPolicyNumber()\n" ); }

    #---- Fetch first document index
    my $sPolicyNrTmp = undef;
    my $a2wDocIndexTmp = $a2wDocumentPar->getFirstIndex();
    while ( $a2wDocIndexTmp != 0 ){
        my $sNameTmp = $a2wDocIndexTmp->getName();
        if ( $sNameTmp =~ /policy/i ){
            $sPolicyNrTmp = $a2wDocIndexTmp->getValue();
            last;
        }

        #---- Fetch next document index
        $a2wDocIndexTmp = $a2wDocumentPar->getNextIndex();
    }

    return $sPolicyNrTmp;
}

#------------------------- End of file marker -------------------------#
__END__
