#!/usr/bin/perl

#use utf8;
use strict;
use CGI;
use Encode;
use PDF::Create;
use POSIX qw(
    floor
    ceil
);
use JSON;
use Opals::Context;

use Time::localtime;

use Opals::Date qw(
    date_parse
    date_today
    date_text
    date_f005
);

use Opals::Template qw(
    tmpl_read
    tmpl_write
    tmpl_preference
);

use Opals::Locale qw(
    loc_getMsgFile
    loc_write
    
);

use Opals::Tb_Transactions qw(
    trans_getUnpaidFineList
    trans_getBalance
    trans_getPreviousBalance
    trans_getTotalCharge
    trans_getTotalForgiven
);

my $dbh = Opals::Context->dbh();
END { $dbh->disconnect(); }

my $cgi    = CGI->new;
my $input  = $cgi->Vars();
my $pref   = tmpl_preference($dbh);
my $libname    = decode('utf8', $pref->{'libname'});
my $libAddress = decode('utf8', $pref->{'libAddress'});
my $libCity    = decode('utf8', $pref->{'libCity'});
my $libState   = decode('utf8', $pref->{'libState'});
my $libZip     = decode('utf8', $pref->{'libZip'});
my $libPhone   = decode('utf8', $pref->{'libPhone'});
my $libFax     = decode('utf8', $pref->{'libFax'});
my $libEmail   = decode('utf8', $pref->{'libEmail'});
#-------------------------------------------------------------------------------------

my $op       = $input->{'op'}; #print or email
my $sort1    = $input->{'sort1'};
my $sort2    = $input->{'sort2'};
my $optTitle = $input->{'optTitle'};
my $optBilg  = $input->{'optBilg'};
my $prtType  = $input->{'prtType'};
my $optPrice = $input->{'optPrice'};
my $optPage  = $input->{'optPage'};
my $printGreeting =$input->{'optGreeting'};

my $msgTopCbox = $input->{'msgTopCbox'} ;
my $msgBotCbox = $input->{'msgBotCbox'} ;

my $srcCall    = $input->{'srcCall'};
my $incOpt     = $input->{'incOpt'};
my $msg        = $input->{'msg'};
my @msgArr=();
my @lang;
my $l;
if($optBilg eq 'enSp'){
   @lang=('en','sp');
   $l ='en';
}
elsif($optBilg eq 'frOnly'){
   @lang=('fr');
   $l='fr';
}
else{
   @lang=('en');
   $l='en';
}
#-------------------------------------------------------------------------------------
use constant    X_PAGE         =>  612;
use constant    X_LEFT_MARGIN  =>  25;
use constant    X_RIGHT_MARGIN =>  25;
use constant    Y_PAGE         =>  792;
use constant    X_TABLE        =>  558;
use constant    ROW_HEIGHT     =>   18;
use constant    ROW_HEIGHT_10  =>   12;
use constant    X_ADDRESS      =>   86;
use constant    Y_ADDRESS_FR   =>   772;
use constant    Y_ADDRESS_TO   =>   640;
use constant    Y_BODY         =>   578;
use constant    HEADER_HEIGHT_1=>   50;
use constant    HEADER_HEIGHT_2=>   50;
use constant    FOOTER_HEIGHT  =>   20;


   my $todayStr ="";                         
   my  $inMsgTop = decode('utf8',$input->{'msgTop'});
       $inMsgTop =~ s/_EOL_/\n/;
       $inMsgTop =~ s/\n+/\n/;
      
   my  $inMsgBot = decode('utf8',$input->{'msgBot'});
       $inMsgBot =~ s/_EOL_/\n/;
       $inMsgBot =~ s/\n+/\n/;
      

    my $mypdf=`/bin/mktemp`;
    my $pdf = new PDF::Create('filename' => $mypdf,
                              'Version'  => 1.2,
                              'PageMode' => 'UseOutlines',
                              'Title'    => 'Textbook Fine Transactions',
                         );

    my $root = $pdf->new_page('MediaBox' => [ 0, 0, X_PAGE,Y_PAGE ]);

    my $f1 = $pdf->font('Subtype'  => 'Type1',
                        'Encoding' => 'WinAnsiEncoding',
                        'BaseFont' => 'Helvetica');
    my $f2 = $pdf->font('Subtype'  => 'Type1',
                        'Encoding' => 'WinAnsiEncoding',
                        'BaseFont' => 'Helvetica-Bold');
    my $f3 = $pdf->font('Subtype'  => 'Type1',
                        'Encoding' => 'WinAnsiEncoding',
                        'BaseFont' => 'Times-Italic');

    my $messages= {
        title=>{en=>'Overdue Item(s) Reminder',
                fr=>'Avis de la bibliothèque',
                sp=>'Carta de notificación de tardía'
                },
        messageTo=>{
                en=>'To the parents or guardians of:',
                fr=>'Aux parents de:',
                sp=>'A los padres o guardián de:'
        },
        messageSlip=>{
                en=>'Materials being checked out/renewed: ',
                fr=>'Materials being checked out/renewed: ',
                sp=>'Materials being checked out/renewed: '
        },        
        message1=>{
                en=>'The following items that you borrowed from the library/media center are now past due:',
                fr=>'Les ouvrages ou documents suivants sont en retard.' ,
                sp=>'El libro siguiente prestado de la biblioteca:'
                },
        
       message2=>{
                en=>'Please return any items that may be overdue. Thank you in advance for your cooperation.',
                fr=>'Veuillez les rapporter au plus tôt. Merci de votre collaboration.',
                sp=>'Por favor devuelva el libro lo mas pronto posible.  Gracias por su cooperación.'
                }
        };

    my $itemTblHeader= {
        title       =>{en=>'Title',fr=>'Titre', sp=>'Título' },
        barcode     =>{en=>'Barcode',fr=>'#Code',sp=>'Código'},
        price       =>{en=>'Price',fr=>'Prix',sp=>'Precio'},
        fineType    =>{en=>'Type',fr=>'Type',sp=>'Type'},
        dewey       =>{en=>'Dewey',fr=>'# Classification',sp=>'Clasificación'},
        dateLoan    =>{en=>'Loan Date',fr=>'Date ',sp=>'Fecha'},
        dateDue     =>{en=>'Due Date', fr=>'Date d\'échéance',sp=>'Fecha de vencimiento'},
        date        =>{en=>'Date',fr=>'Date', sp=>'Fecha'},
        amount      =>{en=>'Charge', fr=>'Montant', sp=>'Cantidad' },
        overdue     =>{en=>'Overdue', fr=>'En retard',sp=>'Dias' }
    };
    foreach my $key(keys %{$messages}){
        foreach my $l('en','fr','sp'){
            $messages->{$key}->{$l}=decode('utf8',$messages->{$key}->{$l} );
        }
    }
    foreach my $key(keys %{$itemTblHeader}){
        foreach my $l('en','fr','sp'){
            $itemTblHeader->{$key}->{$l}=decode('utf8',$itemTblHeader->{$key}->{$l} );
        }
    }
   my $headers={
        odNotice        => ['title', 'barcode', 'price', 'dewey', 'dateLoan', 'dateDue'],
        unpaidItem      => ['title', 'barcode', 'fineType', 'date', 'amount']
    };
   my $tblDef={
       odNoticeData=>{
            title   =>{width=>150  , padding=>5 ,font=>$f1,fontSize=>10,align=>'left'  },
            barcode =>{width=>100  , padding=>5 ,font=>$f1,fontSize=>10,align=>'left'  },
            price   =>{width=>45   , padding=>5 ,font=>$f1,fontSize=>10,align=>'right' },
            dewey   =>{width=>88   , padding=>5 ,font=>$f1,fontSize=>10,align=>'left'  },
            dateLoan=>{width=>88   , padding=>5 ,font=>$f1,fontSize=>10,align=>'left'  },
            dateDue =>{width=>87   , padding=>5 ,font=>$f1,fontSize=>10,align=>'left'  }
           },
       odNoticeData_sub=>{
            title   =>{width=>150  , padding=>5 ,font=>$f1,fontSize=>10,align=>'left'  },
            barcode =>{width=>100  , padding=>5 ,font=>$f1,fontSize=>10,align=>'left'  },
            price   =>{width=>45   , padding=>5 ,font=>$f1,fontSize=>10,align=>'right' },
            dewey   =>{width=>88   , padding=>5 ,font=>$f1,fontSize=>10,align=>'left'  },
            dateLoan=>{width=>88   , padding=>5 ,font=>$f1,fontSize=>10,align=>'left'  },
            dateDue =>{width=>87   , padding=>5 ,font=>$f1,fontSize=>10,align=>'left'  }
           },
       odNoticeHeaderMain=>{
            title   =>{width=>150  , padding=>5 ,font=>$f2,fontSize=>10,align=>'center'},
            barcode =>{width=>100  , padding=>5 ,font=>$f2,fontSize=>10,align=>'center'},
            price   =>{width=>45   , padding=>5 ,font=>$f2,fontSize=>10,align=>'center'},
            dewey   =>{width=>88   , padding=>5 ,font=>$f2,fontSize=>10,align=>'center'},
            dateLoan=>{width=>88   , padding=>5 ,font=>$f2,fontSize=>10,align=>'center'},
            dateDue =>{width=>87   , padding=>5 ,font=>$f2,fontSize=>10,align=>'center'}
           },
       odNoticeHeaderSub=>{
            title   =>{width=>150  , padding=>5 ,font=>$f3,fontSize=>10,align=>'center' },
            barcode =>{width=>100  , padding=>5 ,font=>$f3,fontSize=>10,align=>'center' },
            price   =>{width=>45   , padding=>5 ,font=>$f3,fontSize=>10,align=>'center' },
            dewey   =>{width=>88   , padding=>5 ,font=>$f3,fontSize=>10,align=>'center' },
            dateLoan=>{width=>88   , padding=>5 ,font=>$f3,fontSize=>10,align=>'center' },
            dateDue =>{width=>87   , padding=>5 ,font=>$f3,fontSize=>10,align=>'center' }
           },
      unpaidItemData=>{
            title   =>{width=>200   , padding=>5,font=>$f1,fontSize=>10,align=>'left'  },
            barcode =>{width=>130   , padding=>5,font=>$f1,fontSize=>10,align=>'left'  },
            fineType=>{width=>55    , padding=>5,font=>$f1,fontSize=>10,align=>'left'  },
            date    =>{width=>95    , padding=>5,font=>$f1,fontSize=>10,align=>'left'  },
            amount  =>{width=>78    , padding=>5,font=>$f1,fontSize=>10,align=>'right' }
           },
     unpaidItemData_sub=>{
            title   =>{width=>200   , padding=>5,font=>$f1,fontSize=>10,align=>'left'  },
            barcode =>{width=>130   , padding=>5,font=>$f1,fontSize=>10,align=>'left'  },
            fineType=>{width=>55    , padding=>5,font=>$f1,fontSize=>10,align=>'left'  },
            date    =>{width=>95    , padding=>5,font=>$f1,fontSize=>10,align=>'left'  },
            amount  =>{width=>78    , padding=>5,font=>$f1,fontSize=>10,align=>'right' }
           },
     unpaidItemHeaderMain=>{
            title   =>{width=>200   , padding=>5,font=>$f2,fontSize=>10,align=>'center'},
            barcode =>{width=>130   , padding=>5,font=>$f2,fontSize=>10,align=>'center'},
            fineType=>{width=>55    , padding=>5,font=>$f2,fontSize=>10,align=>'center'},
            date    =>{width=>95    , padding=>5,font=>$f2,fontSize=>10,align=>'center'},
            amount  =>{width=>78    , padding=>5,font=>$f2,fontSize=>10,align=>'center'}
           },
     unpaidItemHeaderSub=>{
            title   =>{width=>200   , padding=>5,font=>$f3,fontSize=>10,align=>'center'},
            barcode =>{width=>130   , padding=>5,font=>$f3,fontSize=>10,align=>'center'},
            fineType=>{width=>55    , padding=>5,font=>$f3,fontSize=>10,align=>'center'},
            date    =>{width=>95    , padding=>5,font=>$f3,fontSize=>10,align=>'center'},
            amount  =>{width=>78    , padding=>5,font=>$f3,fontSize=>10,align=>'center'}
           },
     text_uInfo =>{width=>558   , padding=>5,font=>$f1,fontSize=>10,align=>'center'},
     text_msg1 =>{width=>558   , padding=>5,font=>$f2,fontSize=>10,align=>'center'},
     text_msg2 =>{width=>558   , padding=>5,font=>$f3,fontSize=>10,align=>'center'},
     text_msg3 =>{width=>558   , padding=>5,font=>$f3,fontSize=>10,align=>'center'},
     text_uBalance =>{width=>558  , padding=>35,font=>$f1,fontSize=>10,align=>'right'},

     
     rowHeight=>{
          odNoticeData          =>16,
          odNoticeData_sub      =>12,
          odNoticeHeaderMain    =>16,
          odNoticeHeaderSub     =>12,
          unpaidItemData        =>16,
          unpaidItemData_sub    =>12,
          unpaidItemHeaderMain  =>16,
          unpaidItemHeaderSub   =>12,
          textMsg               =>16,
          text_uInfo            =>10,
          text_msg1             =>10,
          text_msg2             =>12,
          text_msg3             =>16,
          text_uBalance         =>10
      }
    };

my $pageN = $root->new_page;
my $msgTop =formatMsg($pageN,$inMsgTop,"text_msg2",X_TABLE);        
   #my $msgBottom =formatMsg($pageN,$inMsgBot,"text_msg2",X_TABLE);
   my $msgBottom =formatMsg($pageN,$msg,"text_msg2",X_TABLE);
   @$msgTop =(@$msgTop,{type=>'text_msg2',text=>''}) if(scalar(@$msgTop)>0);
   @$msgBottom =({type=>'text_msg2',text=>''} ,@$msgBottom) if(scalar(@$msgBottom)>0);


#----------------------------------------------------------------------------------------------------
sub formatMsg{
    my ($pageN,$msg,$msgType,$msgWidth)=@_;
    my @retMsgArr=();
    my @tmpArr =split(/\n/g,$msg);
    foreach my $m(@tmpArr){
       my $msgArr    =formatStr_nRow($pageN,
                                    $tblDef->{$msgType}->{'font'},
                                    $tblDef->{$msgType}->{'fontSize'},
                                    $m,$msgWidth,100);
       foreach my $s(@$msgArr){
            push @retMsgArr,{type=>$msgType, text=>$s};
       }
    }
    return \@retMsgArr
}

my $DataRecs;

if ( $sort1 eq '' ){
    $sort1 = "homeroom";
}
if ( !$sort2 ){
    if ( $sort1 eq "username" ) { $sort2 = "title"; }
    else { $sort2 = "username"; }
}

my $dateFrom =  $input->{'dateFrom'};
my $dateTo =    $input->{'dateTo'};
my $dateToday = date_f005();
$dateToday =~ s/([\d]{4})([\d]{2})([\d]{2})[\d]+\.(0|1)/$1-$2-$3/;
$todayStr = date_text($dateToday,1,$l);
$dateFrom = $dateToday if ( !$dateFrom );
$dateTo = $dateToday if ( !$dateTo );
my $pNum = $input->{'pNum'};

my $uidList = $input->{'idlist'};

    open debug, ">/tmp/debugK";
    #$DataRecs = getFineNoticeList($dbh,$uidList);
    if(defined $input->{'incOpt'} &&  $input->{'incOpt'}  eq 'incOdNotice'){
        foreach my $data(@$DataRecs){
            my $odItemList=GetUserOverdue($dbh,$data->{'uid'});
            foreach my $od(@$odItemList){
                $od->{'type'}='odNoticeData';
            }
            $data->{'oditems'} =$odItemList;
        }
    }
    $DataRecs = getFineNoticeList($dbh,$uidList);
    print debug "tojson", to_json($DataRecs , {pretty=>1});

    open PDF, "<$mypdf";
    print $cgi->header(
        -type           => 'application/pdf',
        -attachement    => 'fineList.pdf'
    );
    print_pdf($DataRecs);
    while (<PDF>) {
        print $_;
    }
    close PDF;
    close debug;
#--------------------------------------------------------
sub print_pdf {
    my ($fineData) = @_;
    my $subPageCount = 1;
    my ($x,$y)=(X_LEFT_MARGIN,0);
    my ($x1,$x2) =(X_LEFT_MARGIN,X_LEFT_MARGIN + X_TABLE);
    my $totalPage=0;
    my $rowPerPage;
    my $i=0;
    my $header_Y=0;
    my $xRow=4;
    my $printAdd=0;
    if($prtType eq 'address'){
        $printAdd=1;
    }
    if(!defined $optPage || $optPage >3 || $optPage<1  ){
        $optPage=1;
    }
    if($optPage ==1){
       $rowPerPage=38; 
    }
    elsif($optPage ==2){
        $rowPerPage=16;
    }
    elsif($optPage ==3){
        $rowPerPage=9;
    }
    else{
        $rowPerPage=38;
        $optPage =1;
        #$printAdd=1;
    }
    my $deviderLine_X=0;
    my $deviderLine_Y=($optPage-$subPageCount)*(Y_PAGE/$optPage);
                $header_Y =$deviderLine_Y -20;
    my $firstTblLine=0; 
    my $row_H=12;
    my $pageCount=1;
    my $firstPage=1;
    my $ii=0;
    print debug "subPageCount:$subPageCount\n";
    my $size = scalar (@$fineData);
    print debug "size: $size\n";
    foreach my $fd(@$fineData){
        my $pNo=1;
        $xRow=4;
        if((($subPageCount % $optPage)==1 || ($optPage==1)) && $i>0){
          $pageN = $root->new_page;
        }
        $x = X_LEFT_MARGIN;
        $y = (Y_PAGE - $subPageCount*(Y_PAGE/$optPage)) + 40  ;
        print debug "y:$y\n";
        #my $paddingRows=  scalar(@msgArr)  + scalar(@lang) ;
        my $paddingRows=  2;
        $paddingRows += 4 if($printAdd);
        if($prtType eq 'address'){
            #printMailingInfo($pageN,$fd);
            for(my $k=0; $k<5;$k++){
                #push @{$od->{'oditems'}},{type=>'text_msg2',text=>''}; #space line
            }
            $y =Y_BODY;
        }
        else{
            my $userInfo=getUserInfo_line($fd);
            push @$userInfo,{type=>'text_uInfo',text=>''}; #space line
            $fd->{'userInfo'}= \@$userInfo;
            printHeader_handout($pageN,$f1,$x,$y);
            $y = $y - HEADER_HEIGHT_1;
            my $userBalanceInfo=getUserBalance_line($fd);
            $fd->{'userBalanceInfo'}=\@$userBalanceInfo;
        }
        my ($totalPage,$upItems)= formatNoticeData($fd,$optPage,$prtType);
        foreach my $item(@$upItems){
            $row_H=defined $tblDef->{'rowHeight'}->{$item->{'type'}}?$tblDef->{'rowHeight'}->{$item->{'type'}}:12;
            if($y - $row_H < FOOTER_HEIGHT){
                $y = Y_PAGE - HEADER_HEIGHT_2 ;
                $subPageCount = 1;
                $deviderLine_Y=($optPage-$subPageCount)*(Y_PAGE/$optPage);
                $header_Y =$deviderLine_Y -20;
                $pageN = $root->new_page;
            }
            if(($y - $row_H) < $deviderLine_Y + FOOTER_HEIGHT  ){
                $pageN->line(0,$deviderLine_Y, X_PAGE,$deviderLine_Y );
                $firstTblLine =0;
                #--------------- print header page
                printHeader_handout_2($pageN,$f1,$x, $header_Y,$fd);
                #--------------- print footer page
                $pageN->stringr($f1, 10,X_PAGE - X_RIGHT_MARGIN, $deviderLine_Y+10, "Page $pageCount/$totalPage");
                $pageCount++;
                $y = $deviderLine_Y - HEADER_HEIGHT_2;
                $subPageCount +=1;
                $deviderLine_Y=($optPage-$subPageCount)*(Y_PAGE/$optPage);
                $header_Y =$deviderLine_Y -20;
            }
            $y -=$row_H;
            if($item->{'border_B'} == 1 ){
                $pageN->line($x1, $y, $x2, $y);
            }
            if($item->{'type'} =~ m/^text/g){
                $firstTblLine=0;
            }
            elsif($firstTblLine ==0 && $item->{'type'} !~ m/text/g ){
                $pageN->line($x1, $y + $row_H, $x2, $y + $row_H);
                $firstTblLine=1;
            }
            $ii++;
            writeRow($pageN,$x1,$y,$x2,$y+$row_H,$item);
        }
        $pageN->line(0,$deviderLine_Y, X_PAGE,$deviderLine_Y );
        $pageN->stringr($f1, 10,X_PAGE -  X_RIGHT_MARGIN, $deviderLine_Y+10, "Page $pageCount/$totalPage");
        $deviderLine_Y=($optPage-$subPageCount)*(Y_PAGE/$optPage);
        $header_Y =$deviderLine_Y -20;
    }   
    $pdf->close;
}


sub print_pdf_bk {
    my ($fineData) = @_;
    my $subPageCount = 1;
    my ($x,$y)=(X_LEFT_MARGIN,0);
    my ($x1,$x2) =(X_LEFT_MARGIN,X_LEFT_MARGIN + X_TABLE);
    my $totalPage=0;
    my $i=0;
    my $header_Y=0;
    if(!defined $optPage || $optPage >3 || $optPage<1  ){
        $optPage=1;
    }
    my $deviderLine_X=0;
    my $deviderLine_Y=($optPage-$subPageCount)*(Y_PAGE/$optPage);
                $header_Y =$deviderLine_Y -20;
    my $firstTblLine=0; 
    my $row_H=12;
    my $pageCount=1;
    my $firstPage=1;
    my $ii=0;
    print debug "subPageCount:$subPageCount\n";
    foreach my $fd(@$fineData){
        print debug "subpageCount: $subPageCount \n";
        if($subPageCount == 1 && !$firstPage ){
            print debug "where in here : $subPageCount \t $firstPage\n";
            $pageN = $root->new_page;
        }
        $firstPage=0;
        $y = Y_PAGE - (Y_PAGE /$optPage)*($subPageCount-1) ;
        if($prtType eq 'address'){
            printMailingInfo($pageN,$fd);
            for(my $k=0; $k<5;$k++){
                #push @{$od->{'oditems'}},{type=>'text_msg2',text=>''}; #space line
            }
            $y =Y_BODY;
        }
        else{
            my $userInfo=getUserInfo_line($fd);
            push @$userInfo,{type=>'text_uInfo',text=>''}; #space line
            $fd->{'userInfo'}= \@$userInfo;
            printHeader_handout($pageN,$f1,$x,$y);
            $y = $y - HEADER_HEIGHT_1;
            my $userBalanceInfo=getUserBalance_line($fd);
            $fd->{'userBalanceInfo'}=\@$userBalanceInfo;
        }
        my ($totalPage,$upItems)= formatNoticeData($fd,$optPage,$prtType);
        foreach my $item(@$upItems){
            $row_H=defined $tblDef->{'rowHeight'}->{$item->{'type'}}?$tblDef->{'rowHeight'}->{$item->{'type'}}:12;
            if($y - $row_H < FOOTER_HEIGHT){
                $y = Y_PAGE - HEADER_HEIGHT_2 ;
                $subPageCount = 1;
                $deviderLine_Y=($optPage-$subPageCount)*(Y_PAGE/$optPage);
                $header_Y =$deviderLine_Y -20;
                $pageN = $root->new_page;
            }
            if(($y - $row_H) < $deviderLine_Y + FOOTER_HEIGHT  ){
                $pageN->line(0,$deviderLine_Y, X_PAGE,$deviderLine_Y );
                $firstTblLine =0;
                #--------------- print header page
                printHeader_handout_2($pageN,$f1,$x, $header_Y,$fd);
                #--------------- print footer page
                $pageN->stringr($f1, 10,X_PAGE - X_RIGHT_MARGIN, $deviderLine_Y+10, "Page $pageCount/$totalPage");
                $pageCount++;
                $y = $deviderLine_Y - HEADER_HEIGHT_2;
                $subPageCount +=1;
                $deviderLine_Y=($optPage-$subPageCount)*(Y_PAGE/$optPage);
                $header_Y =$deviderLine_Y -20;
            }
            print debug "subpagecount:$subPageCount\n ";
            $y -=$row_H;
            if($item->{'border_B'} == 1 ){
                $pageN->line($x1, $y, $x2, $y);
            }
            if($item->{'type'} =~ m/^text/g){
                $firstTblLine=0;
            }
            elsif($firstTblLine ==0 && $item->{'type'} !~ m/text/g ){
                $pageN->line($x1, $y + $row_H, $x2, $y + $row_H);
                $firstTblLine=1;
            }
            $ii++;
            writeRow($pageN,$x1,$y,$x2,$y+$row_H,$item);
        }
        $pageN->line(0,$deviderLine_Y, X_PAGE,$deviderLine_Y );
        $pageN->stringr($f1, 10,X_PAGE -  X_RIGHT_MARGIN, $deviderLine_Y+10, "Page $pageCount/$totalPage");
        $deviderLine_Y=($optPage-$subPageCount)*(Y_PAGE/$optPage);
        $header_Y =$deviderLine_Y -20;
    }   
    $pdf->close;
}


sub formatNoticeData{
    my ($notice,$optPage,$prtType)=@_;
    my $retArr;
       @$retArr=();
    my $totalPage=0;
    my $odItemList;
       @$odItemList=();
    my $upItemList ;
       @$upItemList=();
    @$retArr=(@$msgTop)if(scalar(@$msgTop)>0);

    my $headerRow_od=getHeaderRow('odNotice');
    my $headerRow_unpaid=getHeaderRow('unpaidItem');

    if(defined $notice->{'userInfo'}){
         @$retArr=(@{$notice->{'userInfo'}},@$retArr);
    }
    if(defined $notice->{'oditems'} && scalar(@{$notice->{'oditems'}}) >0){
        $odItemList =formatRowData($notice->{'oditems'}) ;
        @$odItemList =(
                @$headerRow_od,
                @$odItemList);
    }
    if(defined $notice->{'unpaidItems'} && scalar(@{$notice->{'unpaidItems'}}) >0){
        $upItemList =formatRowData($notice->{'unpaidItems'});
          @$upItemList =(
                @$headerRow_unpaid,
                @$upItemList);
    }
    if($srcCall eq 'odCirc'){
        @$retArr =(@$retArr,
                    {type=>'text_msg1',text=>''},
                    {type=>'text_msg1',text=>'Overdue Item List'},
                    @$odItemList
                   );
        if( $input->{'incOpt'}  eq 'incUnpaidNotice' && scalar(@$upItemList)>0){
            @$retArr =(@$retArr,
                        {type=>'text_msg1',text=>''},
                        {type=>'text_msg1',text=>''},
                        {type=>'text_msg1',text=>'Unpaid Item List'},
                        @$upItemList
                     );        
        }
    }
    else{
        if(scalar(@$upItemList)>0){
            @$retArr =(@$retArr,
                  {type=>'text_msg1',text=>''},
                  {type=>'text_msg1',text=>'Unpaid Item List'},
                  @$upItemList                 );
        }
        if(defined $notice->{'userBalanceInfo'}){
            @$retArr=(@$retArr,@{$notice->{'userBalanceInfo'}});
        } 
        if($input->{'incOpt'}  eq 'incOdNotice' && scalar @$odItemList){
            @$retArr =(@$retArr,{type=>'text_msg1',text=>''},
                      {type=>'text_msg1',text=>''},
                      {type=>'text_msg1',text=>'Overdue Item List'},
                      @$odItemList
                     );
        }
   }
    @$retArr =(@$retArr,@$msgBottom) if(scalar(@$msgBottom)>0);
    if($prtType eq 'address'){
        for(my $k=0; $k<5;$k++){
            push @$retArr,{type=>'text_msg2',text=>''}; #space line
        }
    }
    ($totalPage,$retArr)=formatPage($retArr,$optPage,$prtType);
    return ($totalPage,$retArr);
}

sub getHeaderRow{
    my ($headerType)=@_;
    my @hRow=();
    my $headerName=$headerType ."HeaderMain";
    my $i=1;
    foreach my $l(@lang){
        my $hr={type    =>$headerName,
                height  =>$tblDef->{'rowHeight'}->{$headerName}
                };
        foreach my $h(@{$headers->{$headerType}}){
             $hr->{$h} =$itemTblHeader->{$h}->{$l};
        }
        $hr->{'border_B'} =($i==scalar(@lang))?1:0;
        $i++;
        push @hRow,$hr;
        $headerName=$headerType ."HeaderSub";
    }
    return \@hRow;
}

sub formatPage{
    my($odArr,$optPage,$prtType)=@_;
    my $total=1;
    my @retArr=();
    my $pageH= floor(Y_PAGE /$optPage);
    my $sumRowH=FOOTER_HEIGHT;
    $sumRowH += $prtType eq 'address' ?Y_BODY : HEADER_HEIGHT_1;
    my ($cType,$nType,$cRowH,$nRowH)=(0,0,0,0);
    for(my $i =0; $i< scalar(@$odArr); $i++){
        $cType = @$odArr[$i]->{'type'};
        $cRowH = $tblDef->{'rowHeight'}->{$cType};
        if($i +1 < scalar(@$odArr)) {
            $nType =@$odArr[$i +1]->{'type'};
            $nRowH= $tblDef->{'rowHeight'}->{$nType};
            if($nType =~ m/Data_sub$/g && ($sumRowH + 2*$cRowH )>= $pageH){
                push @retArr,{type=>'text_msg3',text=>''};
                $sumRowH=HEADER_HEIGHT_2 + FOOTER_HEIGHT;
                $total++;
            }
        }

        if($sumRowH +$cRowH  > $pageH){

            $total++;
            $sumRowH=HEADER_HEIGHT_2 + FOOTER_HEIGHT;
        }
        $sumRowH += $cRowH;
        
        push @retArr,@$odArr[$i];
    }
    return ($total,\@retArr);
}

sub formatRowData{
    my ($rData)=@_;
    my @retArr=();
    foreach my $r(@$rData){
        $r->{'border_B'}=1;
        my $type=$r->{'type'};
        my $tDef    = $tblDef->{$type}->{'title'};
        my $f       =$tDef->{'font'};
        my $fs      =$tDef->{'fontSize'};
        my $dddLen = $fs*$pageN->string_width($f,'...') ;
        my $width   =$tDef->{'width'} - $tDef->{'padding'} - $dddLen;
        my $height= $r->{'height'};

        my $titleArr=formatStr_nRow($pageN,$f,$fs,$r->{'title'},$width,2);
        my $deweyArr ;
           @$deweyArr =();
        if($type eq 'odNoticeData' ){
             $tDef    = $tblDef->{$type}->{'dewey'};
             $f       =$tDef->{'font'};
             $fs      =$tDef->{'fontSize'};
             $dddLen = $fs*$pageN->string_width($f,'...') ;
             $width   =$tDef->{'width'} - $tDef->{'padding'} - $dddLen;
             $deweyArr =formatStr_nRow($pageN,$f,$fs,$r->{'dewey'},$width,2)  
        }

        my $subrow=undef;
        if(scalar(@$titleArr)>1){
            $r->{'title'}=@$titleArr[0];
            $r->{'border_B'}=0;
            $subrow->{'title'}  =@$titleArr[1];
            $subrow->{'type'}   = $type ."_sub";
            $subrow->{'border_B'}   =1;
        }
        if(scalar(@$deweyArr)>1){
            $r->{'dewey'}=@$deweyArr[0];
            $r->{'border_B'}=0;
            $subrow->{'dewey'}  =@$deweyArr[1];
            $subrow->{'type'}   = $type ."_sub";
            $subrow->{'border_B'}   =1;
        }
        push @retArr,$r;
        push @retArr,$subrow if(defined $subrow);
    }
    return \@retArr;
}
sub formatStr{
    my($pageN,$f,$fs,$inStr,$len)=@_;
    my $outStr=$inStr;
    $outStr =~ s/\s+$//g;

    my $sWidth= $fs * $pageN->string_width($f,$outStr);
    if($sWidth<=$len){
        return $outStr;
    }
    while($sWidth > $len){
       $outStr =~ s/\S+$//g;
       $outStr =~ s/\s+$//g;
       $sWidth= $fs * $pageN->string_width($f,$outStr );
    }
    return $outStr  ;
}

sub formatStr_nRow{
    my($pageN,$f,$fs,$inStr,$len,$nRow)=@_;
    my $outStr=$inStr;
    my @outStrArr=();
    $outStr =~ s/\s+$//g;
    my $n=1;
    my $sWidth= $fs * $pageN->string_width($f,$outStr);
    if($sWidth<=$len){
        $outStr =~ s/(\(|\))/\\$1/g;
        push @outStrArr,$outStr;
        return \@outStrArr;
    }
    while($n<$nRow && $outStr ne ''){
        while($sWidth > $len){
           $outStr =~ s/\S+$//g;
           $outStr =~ s/\s+$//g;
           $sWidth= $fs * $pageN->string_width($f,$outStr );
        }
        push @outStrArr,$outStr;
        $inStr =substr($inStr,length($outStr)); 
        $inStr =~ s/^\s+//g;
        $outStr=$inStr;
        $sWidth= $fs * $pageN->string_width($f,$outStr);
        $n++;
    }
    if($n >=$nRow && $inStr ne ''){
        push @outStrArr,formatStr($pageN,$f,$fs,$inStr,$len);
    }
    foreach my $str(@outStrArr){
         $str=~ s/(\(|\))/\\$1/g;
    }
    return \@outStrArr  ;
}


sub printHeader_handout{
    my($pageN,$f1,$x,$y)=@_;
    $pageN->stringr($f1, 10,580, $y-16, $todayStr) ;
    $pageN->stringc($f1, 14,306, $y-36, $libname);
}

sub printHeader_handout_2{
    my($pageN,$f1,$x,$y,$od)=@_;
    $pageN->stringl($f2, 10,$x, $y , "$od->{'lastname'}, $od->{'firstname'}");
    my $sWidth= 10 * $pageN->string_width($f2,"$od->{'lastname'}, $od->{'firstname'}");
    $pageN->stringl($f1, 10,$x+$sWidth, $y , " User Barcode: $od->{'userbarcode'}");
}

sub printMailingInfo {
    my ($pageN,$fd) = @_;

}
sub getUserInfo_line{
    my ($odData)=@_;
    my $optNotice = Opals::Context->preference('reportGroup');
    my @userInfo=();
    my $lastname  = decode('utf8',$odData->{'lastname'});
    my $firstname  = decode('utf8', $odData->{'firstname'});
    my $classInfo ="";
    $classInfo .= 'Homeroom: ' . $odData->{'homeroom'} if(index($optNotice,'1') >=0);
    $classInfo .= ' Teacher: ' . $odData->{'teacher'}  if(index($optNotice,"2") >=0);
    $classInfo .= ' Grade: ' .   $odData->{'grade'}    if(index($optNotice,"3") >=0);
    push @userInfo,{type=>'text_uInfo',text=>$classInfo};
    my $ubc ="$lastname, $firstname";
       $ubc .= "  " . $odData->{'userbarcode'} if(index($optNotice,"5") >=0 && $odData->{'userbarcode'} ne "");
    push @userInfo,{type=>'text_uInfo',text=>$ubc} ;
    push @userInfo,{type=>'text_uInfo',text=>'Phone: ' . $odData->{'phone'}} if(index($optNotice,"4") >=0 && $odData->{'phone'} ne"");

    return \@userInfo;
}

sub getUserBalance_line{
    my ($odData)=@_;
    return if(!defined $odData->{"balance"} || $odData->{"balance"} ==0);
    my $amtTypeStr = { balance    => 'Amount to pay: $',
                       totalFgvPmt=> 'Previous forgiven/paid: $',
                       totalFineCharge=> 'Total charge: $'
                     };
   
    my @userBalanceInfo= ();
    my $txt =   sprintf("%72s", ""); 
    foreach my $k (reverse sort keys %{$amtTypeStr}){
        $odData->{$k} = '0.00' if($odData->{$k} ==0);
        $txt .= '   ' . $amtTypeStr->{$k} .  $odData->{$k};
    }
     
    push @userBalanceInfo,{type=>'text_uBalance',text=>''};
    push @userBalanceInfo,{type=>'text_uBalance',text=>$txt};
    return \@userBalanceInfo;

}

sub  getFineNoticeList{
    my($dbh,$uidList)=@_;
    my @uidArr =  split /,/, $uidList;
    my $upData=undef; 
    foreach my $uid(@uidArr){
        my $info =getUserInfo($dbh,$uid);
         
        if(defined $info->{'uid'} && $info->{'uid'}>0){
            # Thu, Oct 20, 2011 @ 14:44:01 EDT
            # Add user balance
            my $uBalanceInfo = _getUserBalanceInfo($dbh,$uid);
            my @upItemList=trans_getUnpaidFineList($dbh,$uid);

            if(scalar(@upItemList)>0){
                foreach my $f(@upItemList){
                    $f->{'type'}='unpaidItemData';
                    $f->{'amount'}=$f->{'damount'};
                    $f->{'fineType'}=$f->{'description'};
                    $f->{'date'}=date_text($f->{'date'}, 0,$l);
                    push @{$info->{'unpaidItems'}}, $f;
                }
                $info->{'totalFineCharge'}  = $uBalanceInfo->{'totalFineCharge'};
                $info->{'totalFgvPmt'}      = $uBalanceInfo->{'totalFgvPmt'};
                $info->{'previousBalance'}  = $uBalanceInfo->{'previousBalance'};
                $info->{'balance'}          = $uBalanceInfo->{'balance'};
                $upData=[]if(!defined $upData);
                push @$upData,$info;
            }
        }
    }
    return $upData;
}

sub _getUserBalanceInfo{
    my($dbh,$uid) =@_;
    my $uBalanceInfo =undef;
    my $balance = trans_getBalance($dbh,$uid);
    if($balance ==0){
        $uBalanceInfo->{'zeroBalance'}=1;
    }

    my $prevBalance=trans_getPreviousBalance($dbh,$uid);
    my $totalFineCharge = trans_getTotalCharge($dbh,$uid);
    $totalFineCharge = sprintf("%.2f",$totalFineCharge);
    my $totalFgvPmt =trans_getTotalForgiven($dbh,$uid);
    my $totalUnpaid = $totalFineCharge - $totalFgvPmt + $prevBalance;
    $balance = sprintf("%.2f",$balance);
    if($balance>0 && $balance != $totalFineCharge){
        $uBalanceInfo->{'unBalance'}        = 1;
        $uBalanceInfo->{'totalFgvPmt'}      = $totalFgvPmt!=0?$totalFgvPmt:0;
        $uBalanceInfo->{'previousBalance'}  = $prevBalance!=0?$prevBalance:0;         
    }
    $uBalanceInfo->{'balance'} = $balance>0?$balance:0;
    $uBalanceInfo->{'totalFineCharge'} = $totalFineCharge!=0?$totalFineCharge:0;
    return $uBalanceInfo;
}

sub getUserInfo{
    my($dbh,$uid)=@_;

    my $user =$dbh->selectrow_hashref(<<_SQL_);
    select uid,userbarcode,firstname,lastname,teacher,grade,homeroom,buildingcode,
    addrLine1,addrLine2,city,zip,state,phone,yeargraduation
    from opl_user
    where uid= $uid
_SQL_
    if($user &&  $user->{'uid'} && $user->{'addrLine1'} eq ''){
        my $address=getGuardianAddress($dbh,$user->{'uid'});
        $user->{'addrLine1'}=$address->{'addrLine1'} || "";
        $user->{'addrLine2'}=$address->{'addrLine2'} || "";
        $user->{'city'}=$address->{'city'} || "";
        $user->{'zip'}=$address->{'zip'} || "";
        $user->{'state'}=$address->{'state'} || "";
        $user->{'homeroom'} = $user->{'homeroom'} || "";
        $user->{'teacher'} = $user->{'teacher'} || "";
    }
    return $user;
}
sub getGuardianAddress{
    my ($dbh,$uid)=@_;
    my $address={};
    my $sth=$dbh->prepare("select gaddrLine1 addrLine1,gaddrLine2 addrLine2,gcity city,gzip zip,gstate state,gemail email from opl_guardian where uid=$uid limit 1");
    $sth->execute();
    $address =$sth->fetchrow_hashref;
    $sth->finish;
    return $address;	
    
}
####################################################
sub getguardianEmail{
    my ($dbh,$uid)=@_;
    my $email={};
    my $sth=$dbh->prepare("select gemail email from opl_guardian where uid=$uid limit 1");
    $sth->execute();
    $email =$sth->fetchrow_hashref;
    $sth->finish;
    return $email;	
    
}

sub writeRow{
    my($pageN,$x1,$y1,$x2,$y2,$text)=@_;
      my ($font,$fontSize) = ($f1,10);  
      $font =$tblDef->{$text->{'type'}}->{'font'} if(defined $tblDef->{$text->{'type'}}->{'font'}  );
      if($text->{'type'} =~ m/odNotice|unpaidItem/g){
          writeRow_headerData($pageN,$font,$fontSize,$x1,$y1,$x2,$y2,$text );
      }
      elsif($text->{'type'}=~ m/^text/g){
          writeRowText($pageN,$font,$fontSize,$x1,$y1,$x2,$y2,$text);
      }
}

sub writeRowText{
    my($pageN,$font,$fontSize,$x1,$y1,$x2,$y2,$text)=@_;
    writeCell('left',$pageN,$font,$fontSize, $x1, $y1 +5,   $text->{'text'}) ;
}

sub writeRow_headerData{
    my($pageN,$font,$fontSize,$x1,$y1,$x2,$y2,$text)=@_;
    my $x=$x1;
    my $type=$text->{'type'};
    my $tDef    = $tblDef->{$type};
    my ($align,$width,$font,$fontSize,$padding);
    $pageN->line($x, $y1, $x,$y2);   
    my $xPos;
    my $columns;
    if($type =~ m/odNotice/g) {
        $columns=$headers->{'odNotice'};
    }
    else{
        $columns=$headers->{'unpaidItem'};
    }
    foreach my $field(@$columns){
        if(($field eq 'title' && $optTitle !=1)||
           ($field eq 'price' && $optPrice !=1)){
            next;
        }
        else{
            $align      =$tDef->{$field}->{'align'};
            $width      =$tDef->{$field}->{'width'};
            $font       =$tDef->{$field}->{'font'};
            $padding    =$tDef->{$field}->{'padding'};
            $fontSize   =$tDef->{$field}->{'fontSize'};
            $xPos =$x;
            if($align eq 'center'){
                $xPos +=ceil($width/2);
            }
            elsif($align eq 'right'){
                $xPos +=$width -$padding;
            }
            else{
                $xPos +=$padding;
            }
            writeCell($align,$pageN,$font,$fontSize,$xPos, $y1 +5, $text->{$field}) ; 
            $x +=$width;
        }
        $pageN->line($x, $y1, $x,$y2);   
    }
    $pageN->line($x2, $y1, $x2,$y2);
} 

sub writeCell{
    my($pos,$pageN,$f,$fs,$x,$y,$txtStr)=@_; 
    if ($pos eq "left"){   
        $pageN->stringl($f,$fs,$x,$y,$txtStr);
    }
    elsif ($pos eq "right"){   
        $pageN->stringr($f,$fs,$x,$y,$txtStr);
    }
    else{   
        $pageN->stringc($f,$fs,$x,$y,$txtStr);
    }
   # print $pageN->string_width($f,$txtStr) ." -- $txtStr\n";
}

     
