#!/usr/bin/perl
#
# PDFlib+PDI client: invoice generation demo
# Required software: PDFlib+PDI or PDFlib Personalization Server (PPS)
#

use PDFlib::PDFlib;
use strict;

my $x_table = 55;
my $tablewidth = 475;

my $y_address = 682;
my $x_salesrep = 455;
my $y_invoice = 542;
my $imagesize = 90;

my $fontsize = 11;
my $fontsizesmall = 9;

my $fontname= "NotoSerif-Regular";
my $basefontoptions = "";
my $optlist;


# -----------------------------------
# Place company stationery as background
# -----------------------------------

sub create_stationery
{
    my $p = shift @_;
    my $sender =
        "Kraxi Systems, Inc. &#x2022; 17, Aviation Road &#x2022; Paperfield";
    my $stationeryfontname= "NotoSerif-Regular";

    my $stationeryfilename = "kraxi_logo.pdf";

    my $y_company_logo = 748;

    my $senderfull =
        "17, Aviation Road\n" .
        "Paperfield<nextline leading=50%><nextparagraph leading=120%>" .
        "Phone 7079-4301\n" .
        "Fax 7079-4302<nextline leading=50%><nextparagraph leading=120%>" .
        "info\@kraxi.com\n" .
        "www.kraxi.com\n";

    my $stationery = $p->open_pdi_document($stationeryfilename, "");
    my $page = $p->open_pdi_page($stationery, 1, "");

    $p->fit_pdi_page($page, 0, $y_company_logo,
            "boxsize={595 85} position={65 center}");
    $p->close_pdi_page($page);
    $p->close_pdi_document($stationery);

    $optlist =  $basefontoptions . " fontsize=" . $fontsizesmall . 
        " fontname=" . $stationeryfontname . " charref=true";
    $p->fit_textline($sender, $x_table, $y_address + $fontsize,
            $optlist);

    # -----------------------------------
    # Print full company contact details
    # -----------------------------------
    
    $optlist = $basefontoptions . " fontname=" . $stationeryfontname . 
    " leading=125% fillcolor={cmyk 0.64 0.55 0.52 0.27}";
    my $tf = $p->create_textflow($senderfull, $optlist);
    $p->fit_textflow($tf, $x_salesrep, $y_address,
            $x_salesrep+$imagesize, $y_address + 150, "verticalalign=bottom");
    $p->delete_textflow($tf);
}

# -----------------------------------
# Place address and header text
# -----------------------------------

sub create_header
{
    my $p = shift @_;
    my $salesrepfilename = "sales_rep4.jpg";
    my $salesrepname = "Lucy Irwin";
    my $salesrepcaption = "Local sales rep:";
    my $invoiceheader = "INVOICE 2012-03";

    my $address =
        "John Q. Doe\n" .
        "255 Customer Lane\n" .
        "Suite B\n" .
        "12345 User Town\n" .
        "Everland";

    my @months = ( "January", "February", "March", "April", "May", "June",
	    "July", "August", "September", "October", "November", "December");



    # -----------------------------------
    # Print address
    # -----------------------------------
    
    $optlist = $basefontoptions . " leading=120%";

    my $tf = $p->create_textflow($address, $optlist);
    $p->fit_textflow($tf,
            $x_table, $y_address, $x_table+$tablewidth/2, $y_address-100, "");
    $p->delete_textflow($tf);

    # -----------------------------------
    # Place name and image of local sales rep
    # -----------------------------------

    $optlist = $basefontoptions . " fontsize=" . $fontsizesmall;
    $p->fit_textline($salesrepcaption, $x_salesrep, $y_address-$fontsizesmall,
            $optlist);
    $p->fit_textline($salesrepname, $x_salesrep, $y_address-2*$fontsizesmall,
            $optlist);

    my $salesrepimage = $p->load_image("auto", $salesrepfilename, "");

    $optlist = "boxsize={" . $imagesize . " " .  $imagesize . "} fitmethod=meet";
    $p->fit_image($salesrepimage,
            $x_salesrep, $y_address-3*$fontsizesmall-$imagesize, $optlist);
    $p->close_image($salesrepimage);

    # -----------------------------------
    # Print the header and date
    # -----------------------------------

    # Add a bookmark with the header text 
    $p->create_bookmark($invoiceheader, "");

    $optlist =  $basefontoptions;
    $p->fit_textline($invoiceheader, $x_table, $y_invoice, $optlist);

    my $date = sprintf("%s %d, %d", $months[(localtime)[4]], (localtime)[3],
    (localtime)[5]+1900);


    $optlist =  "position {100 0} " . $basefontoptions;
    $p->fit_textline($date, $x_table+$tablewidth, $y_invoice, $optlist);
}


# This is where font/image/PDF input files live. Adjust as necessary. 
my $searchpath = "../data";

# By default annotations are also imported. In some cases this
# requires the Noto fonts for creating annotation appearance streams.
#
my $fontpath = "../../resource/font";

my $closingtext =
"Terms of payment: <fillcolor={rgb 1 0 0}>30 days net. " .
"<fillcolor={gray 0}>90 days warranty starting at the day of sale. " .
"This warranty covers defects in workmanship only. " .
"Kraxi Systems, Inc. will, at its option, repair or replace the " .
"product under the warranty. This warranty is not transferable. " .
"No returns or exchanges will be accepted for wet products.";

my @dataset = (
    {name => "Super Kite",	price => 20, quantity => 2},
    {name => "Turbo Flyer",	price => 40, quantity => 5} ,
    {name => "Giga Trash",	price => 180, quantity => 1}, 
    {name => "Bare Bone Kit",price => 50, quantity => 3}, 
    {name => "Nitty Gritty",price => 20,   quantity => 10} ,
    {name => "Pretty Dark Flyer",price => 75, quantity => 1} ,
    {name => "Free Gift",price => 0, quantity => 1} 
);

my @headers = ( "ITEM", "DESCRIPTION", "QUANTITY", "PRICE", "AMOUNT");

my @alignments = ( "right", "left", "right", "right", "right");

eval {
    my $pagecount = 0;
    my $top = 0;
    my $result;

    # create a new PDFlib object 
    my $p = new PDFlib::PDFlib;

    $p->set_option("SearchPath={{" . $searchpath . "}}");
    $p->set_option("SearchPath={{" . $fontpath . "}}");

    # This mean we don't have to check error return values, but will
    # get an exception in case of runtime problems.
    
    $p->set_option("errorpolicy=exception");

    $p->begin_document("invoice.pdf", "");

    $p->set_info("Creator", "invoice");
    $p->set_info("Author", "Thomas Merz");
    $p->set_info("Title", "PDFlib invoice generation demo");

        $basefontoptions = "fontname=" . $fontname . " fontsize=" . 
            $fontsize . "";

        # -----------------------------------
        # Create and place table with article list
        # -----------------------------------
        
        # ---------- Header row 
        my $row = 1;
        my $col = 1;
        my $tbl = -1; 
        my $buf;

        for ($col=1; $col <= $#headers+1; $col++)
        {
            $optlist =  "fittextline={position={" . $alignments[$col-1] . 
                " center} " . $basefontoptions . "} margin=2";
            $tbl = $p->add_table_cell($tbl, $col, $row, $headers[$col-1], 
            $optlist);
        }
        $row++;

        # ---------- Data rows: one for each article 
        my $total = 0;

        for (my $i = 0; $i <  $#dataset+1; $i++) {
            my $sum = $dataset[$i]{price} * $dataset[$i]{quantity};
            $col = 1;

            # column 1: ITEM 
            $buf = sprintf("%d", $i + 1);
            $optlist = "fittextline={position={" . $alignments[$col-1] . 
                " center} " . $basefontoptions . "} margin=2";
            $tbl = $p->add_table_cell($tbl, $col++, $row, $buf, $optlist);

            # column 2: DESCRIPTION 
            $optlist = "fittextline={position={" . $alignments[$col-1] . 
                " center} " . $basefontoptions . "} colwidth=50% margin=2";
            $tbl = $p->add_table_cell($tbl, $col++, $row, $dataset[$i]{name},
                    $optlist);

            # column 3: QUANTITY 
            $buf = sprintf("%d", $dataset[$i]{quantity});
            $optlist = "fittextline={position={" . $alignments[$col-1] . 
                " center} " . $basefontoptions . "} margin=2";
            $tbl = $p->add_table_cell($tbl, $col++, $row, $buf, $optlist);

            # column 4: PRICE 
            $buf =  sprintf("%.2f", $dataset[$i]{price});
            $optlist = "fittextline={position={" . $alignments[$col-1] . 
                " center} " . $basefontoptions . "} margin=2";
            $tbl = $p->add_table_cell($tbl, $col++, $row, $buf, $optlist);

            # column 5: AMOUNT 
            $buf = sprintf("%.2f", $sum);
            $optlist = "fittextline={position={" . $alignments[$col - 1] . 
                " center} " . $basefontoptions . " " . "} margin=2";
            $tbl = $p->add_table_cell($tbl, $col++, $row, $buf, $optlist);

            $total += $sum;
            $row++;
        }

        # ---------- Print total in the rightmost column 
        $buf = sprintf("%.2f", $total);
        $optlist = "fittextline={position={" .
            $alignments[$#headers - 1] . " center} " .
            $basefontoptions . "} margin=2";
        $tbl = $p->add_table_cell($tbl, $#headers+1, $row++, $buf, $optlist);


        # ---------- Footer row with terms of payment 
        $optlist = $basefontoptions . " alignment=justify leading=120%";
        my $tf = $p->create_textflow($closingtext, $optlist);

        $optlist = "rowheight=1 margin=2 margintop=" . 2*$fontsize . 
            " textflow=" . $tf . " colspan= " . ($#headers+1);
        $tbl = $p->add_table_cell($tbl, 1, $row++, "", $optlist);


        # ---------- Place the table instance(s), creating pages as required 
        do {

            $p->begin_page_ext(0, 0, "width=a4.width height=a4.height");

            if (++$pagecount == 1)
            {
                create_stationery($p);
                create_header($p);
                $top = $y_invoice - 3*$fontsize;
            }
            else
            {
                $top = 50;
            }

            # Place the table on the page; Shade every other row. 
            $optlist =  "header=1 fill={{area=rowodd fillcolor={gray 0.9}}} ";

            $result = $p->fit_table($tbl,
                    $x_table, $top, $x_table+$tablewidth, 20, $optlist);

            if ($result eq "_error") {
                throw new Exception("Couldn't place table: "
                    . $p->get_errmsg());
            }

            $p->end_page_ext("");
        } while ($result eq "_boxfull");

        $p->delete_table($tbl, "");

        $p->end_document("");


};

if ($@) {
    die("$0: PDFlib Exception occurred:\n$@");
}
