#!/usr/bin/perl

#use utf8;
use strict;
use CGI;
use Encode;

use PDF::API2;
use POSIX qw(
    ceil
    floor
);
use Date::Calc qw(Day_of_Week Week_Number Day_of_Year);
use Time::localtime;

use Opals::Context;
use Opals::Constant;
use Opals::User qw(
    user_getInformation
);
use Opals::Date qw(
    date_parse
    date_today
    date_text
    date_f005
);
use Opals::Template qw(
    tmpl_read
    tmpl_write
    tmpl_rangedPageList
    tmpl_preference

);

my $dbh = Opals::Context->dbh();
my $cgi = CGI->new;
my $input = $cgi->Vars();
my $startRow=int($input->{'startRow'});
my $startCol=int($input->{'startCol'});

   
    my $pref = tmpl_preference($dbh);
    my $libname  =  $pref->{'libname'};
       $libname =~ s/<br>/ /g;
    my $printType  = $input->{'prtType'};
    my $printField = $input->{'prtField'};
    my $labelSize  = $input->{'labelSize'};


my $rootDir = Opals::Context->config('rootDir');
my @allFontDirs = PDF::API2::addFontDirs "$rootDir/font/barcode/";

    use constant    LABEL_MAGIN     =>  18;
    use constant    X_TOP_RIGHT_LS_ =>  594;
    use constant    Y_TOP_RIGHT_LS  =>  756;    
    use constant    X_BOT_LEFT_LS   =>  32;
    use constant    Y_BOT_LEFT_LS   =>  65;  
    use constant    ROW_HEIGHT_LS   =>  120;   
    use constant    COL_WIDTH_LS    =>  72;
    
    use constant    X_TOP_RIGHT     =>  594;    
    use constant    Y_TOP_RIGHT     =>  756;   
    use constant    X_BOT_LEFT      =>  18;
    use constant    Y_BOT_LEFT      =>  36;   
    use constant    ROW_HEIGHT      =>  72;    
    use constant    COL_WIDTH       =>  198;
    use constant    COL1_WIDTH      =>  184;
    use constant    COL2_WIDTH      =>  198;
    use constant    COL3_WIDTH      =>  193;
    
    
    my    $BC_FONT  =  20;




umask 007;
if ( ! -d '/tmp/pdf-tmp') {
    `mkdir -p '/tmp/pdf-tmp'`;
}
my $mypdf=`/bin/mktemp -p '/tmp/pdf-tmp'`;#'/tmp/tttbbbsss';#
END { $dbh->disconnect(); }
#----------------------------------------------------------------------------------------------------

my $pdf  = PDF::API2->new(-file => $mypdf);
###if($printType eq 'spine' && $labelSize eq '8by6'){
###    $pdf->mediabox(792,612);
###}
###else{
    $pdf->mediabox(612,792);
###}
my $normalFont = $pdf->corefont('Helvetica');  
my $boldFont = $pdf->corefont('Times New Roman-bold');  
my $barcodeFont = $pdf->ttfont('FREE3OF9.TTF');  
#my $barcodeFont = $pdf->ttfont('FRE3OF9X.TTF');  
#my $barcodeFont = $pdf->ttfont('BARCOD39.TTF');  
#my $barcodeFont = $pdf->ttfont('C39HDW2.TTF');  
#my $barcodeFont = $pdf->ttfont('C39HDW3.TTF');  
#my $barcodeFont = $pdf->ttfont('C39W2.TTF');  
#my $barcodeFont = $pdf->ttfont('C39W3.TTF');  

#----------------------------------------------------------------------------------------------------
my ($permission, $cookie, $template) = tmpl_read(
        {
            dbh             => $dbh,
            cgi             => $cgi,
            tmplFile        =>'report/itemacqst_prt.tmpl',
            reqPermission   => 'rpt_catRec',
        }
);

    
=item
    my $pNum = $input->{'pNum'};
    $pNum = 1 if ( !$pNum );
    my $sort    = $input->{'sort'};
    $sort = 'dateImport' if ( !$sort );
    my $dateToday = date_f005();
    $dateToday =~ s/([\d]{4})([\d]{2})([\d]{2})[\d]+\.(0|1)/$1-$2-$3/;
    #my $bcList    = $cgi->cookie('bcList');
=cut

    my $source = $input->{'source'};
    $source = 'printLabels' if ( !$source );
    my $recOpt = $input->{'recOpt'};
    $recOpt = 'all' if ( !$recOpt );
    my $pHoldingOpt = $input->{'pHoldingOpt'};
    $pHoldingOpt = 'all' if ( !$pHoldingOpt );


    my $recordList;
    my $bcList='';
    my $ridList='';
    if($source eq 'printLabels'){
        $bcList     = $input->{'bclist'};


        if ($bcList){
            $recordList = GetRecordByBarcode($dbh,$bcList );
        }
        
        
        $ridList    = $input->{'ridList'};
        if($ridList){
            my $dateFrom= $input->{'acqstFrom'};
            my $dateTo  = $input->{'acqstTo'};
            my $sort    = $input->{'sort'};
            $sort = 'dateImport' if ( !$sort );
            $recordList = GetRecordByRid($dbh,$ridList, $dateFrom, $dateTo,$sort );
        }

    }
    elsif($source eq 'modDate'){
        my ($modFrom, $modTo);
        $modFrom = $input->{'modFrom'};
        $modTo   = $input->{'modTo'};
        if ($recOpt eq 'sel'){
            my $ridList = $cgi->cookie('modRidList');
            $ridList =~ s/,+/,/g;
            $ridList =~ s/^,|,$//g;
            $recordList = getModRecord($dbh,$modFrom, $modTo,$pHoldingOpt, $ridList)  ;
        }
        else{
            $recordList = getModRecord($dbh,$modFrom, $modTo,$pHoldingOpt)  ;
        }
    }
    elsif($source eq 'range'){
        #Add April 3,2008
        my ($prefix,$start,$qty,$chkDup,$startNum,$numOfSets);
        $start  = $input->{'start'};
        $start  =~ m/(^.*[\D]|^)([\d]+)$/;
        $prefix= $1;

        my $tmp = $2;
        if($tmp=~ m/(^0+)(\d+)/){
            $prefix .=$1;   
        }
        $startNum = $2 +0;
           
        $qty       = $input->{'qty'};
        $chkDup    = $input->{'chkDup'};
        $numOfSets = $input->{'numOfSets'};

        $bcList = createBarcodeList($dbh,$prefix, $startNum,$qty,$chkDup,$numOfSets);
    }



    if($printType eq 'spine' ){
          if($labelSize eq '8by6'){
            printLabel_spine_8by6($recordList,$printType,$printField);
          }
          else{
            printLabel_spine_10by3($recordList,$printType,$printField);
          }
    }
    elsif($printType eq 'barcode'){
        if($source eq 'range'){
            printLabelByRange_BC($bcList,$printField);
        }
        else{
            printLabel_BC($recordList,$printType,$printField);
        }
    }
    else{
        printLabel($recordList,$printType,$printField);
    }

 #================= OPEN PDF File ========================
#my $mypdf ="../circ/mypdf.pdf";
  open PDF, "<$mypdf";
    print $cgi->header(
        -type           => 'application/pdf',
        -attachement    => 'spineLabel.pdf'
    );
    while (<PDF>) {
        print $_;
    }
    close PDF;
    open ccc, '>/tmp/mypdf.lst';
    unlink $mypdf || warn "$mypdf: having trouble deleting $mypdf: $!\n";
    close ccc;


################################################################################
sub createBarcodeList{
    my ($dbh,$prefix, $start,$qty,$chkDup,$numOfSets) = @_;
    my ($bcList, $bc,$tmpNum);   
    $prefix =uc($prefix);   
    for(my $i=0; $i<$qty; $i++){
        $tmpNum = $start+$i;
        #$bc = generateBc($bcLength,$prefix,$tmpNum );
        my $tmpbc = $prefix . $tmpNum;
        my $bc    = $tmpbc;
        for(my $k=1;$k<$numOfSets ;$k++){
             $bc .= ',' . $tmpbc;
        }

        if($chkDup eq 'true'){
            if (!checkDuplicateBc($dbh,$tmpbc)){
                if($bcList ne ''){
                    $bcList .= ',' .  $bc;
                }
                else{
                    $bcList .=  $bc;
                }
            }
            else{
               $qty += 1;
            }
        }
        else{
            if($bcList ne ''){
                $bcList .= ',' .  $bc;
            }
            else{
                $bcList .=  $bc;
            }
        }
    }
      return $bcList;
}

################################################################################
sub generateBc_bk{
    my ($bcLength,$prefix,$bc)=@_;
    my $n=$bcLength - length($prefix) - length($bc);
    for(my $i=0; $i<$n; $i++){
        $prefix .="0";
    }
    return "$prefix$bc";
}
################################################################################
sub getBiggestBc_bk{
    my ($dbh) = @_;
    
    my $sql = <<_STH_;
select  max(barcode) as max
from    opl_item  
where barcode not regexp '^\_\_\_'
_STH_
    
    my $sth = $dbh->prepare($sql);
    $sth->execute();
    while (my $rec = $sth->fetchrow_hashref) {
        return $rec->{'max'}
    }
    
    return ;
}
################################################################################
sub checkDuplicateBc{
    my ($dbh,$bc) = @_;
    
    my $sql = <<_STH_;
select  count(barcode) as count
from    opl_item  
where   barcode = ?
_STH_
    
    my $sth = $dbh->prepare($sql);
    $sth->execute($bc);
    while (my $rec = $sth->fetchrow_hashref) {
        if($rec->{'count'} >0){
            return TRUE;
        }
    }
    
    return FALSE;
}
################################################################################
sub GetRecordByBarcode {
    my ($dbh, $bcList) = @_;

       my $sql = <<_STH_;
select  m.title,m.author,i.callNumber,i.barcode,i.location  
from   opl_marcRecord as m inner join opl_item as i on i.rid=m.rid 
where   substring(i.barcode, 1, 3) <> '___'
_STH_
    $bcList =~ s/,+/,/g;
    $bcList =~ s/(^,|,$)//g;
    $bcList =~ s/,/','/g;
    $bcList = "'" .$bcList ."'" ;

    if ($bcList){
        $sql .= " && i.barcode in ($bcList) ";
    }

    $sql .= "    order by i.callNumber";


    my $sth = $dbh->prepare($sql);
    $sth->execute();
    #my $odd = 0;
    my $pNum = -1;
    my @recordList;
    my $holdingList;
    while (my $rec = $sth->fetchrow_hashref) {
        $rec->{'title'}   =~ s/&amp;/&/g ;
        $rec->{'author'}  =~ s/&amp;/&/g;
        $rec->{'barcode'} = uc($rec->{'barcode'});
        push @recordList, $rec;
    }
    $sth->finish;

    return \@recordList;
}
 ################################################################################
sub GetRecordByRid {
    my ($dbh, $ridList,$dateFrom, $dateTo, $sort) = @_;

       my $sql = <<_STH_;
select  m.title,m.author,i.callNumber,i.barcode,i.location  
from   opl_marcRecord as m inner join opl_item as i on i.rid=m.rid 
where   substring(i.barcode, 1, 3) <> '___' &&
        i.dateImport >= '$dateFrom' &&
        i.dateImport <= '$dateTo 23:59:59'
_STH_
    $ridList =~ s/,+/,/g;
    $ridList =~ s/(^,|,$)//g;
    $ridList =~ s/,$//;
    if ($ridList){
        $sql .= " && i.rid in ($ridList) ";
    }
$sort=$sort eq 'rid'?'i.rid':$sort;
        
$sql .= "  order by $sort asc  ";

    my $sth = $dbh->prepare($sql);
    $sth->execute();
    #my $odd = 0;
    my $pNum = -1;
    my @recordList;
    my $holdingList;
    while (my $rec = $sth->fetchrow_hashref) {
        $rec->{'title'}   =~ s/&amp;/&/g ;
        $rec->{'author'}  =~ s/&amp;/&/g;
        $rec->{'barcode'} = uc($rec->{'barcode'});
        push @recordList, $rec;
    }
    $sth->finish;

    return \@recordList;
}

#----------------------------------------------------------------------------------------------------
sub printLabel_spine_8by6_bk
   {
    my($userData,$printType,$printField)=@_; 
    my  $page  ;
    my $pIndex=0;
    my($x1,$y1);
      ($x1,$y1)=(X_BOT_LEFT_LS,Y_TOP_RIGHT_LS- ROW_HEIGHT_LS);
    my ($numOfRows,$numOfCols)=(8,6);
                    $page = $pdf->page;
                    $page->rotate(270);
                    $page = $pdf->openpage($pIndex++);   
    my ($curRow,$curCol) =($numOfRows - $startCol,$numOfCols - $startRow);
    for(my $i=0; $i<(scalar(@$userData)); $i++){
           if($curRow < 0 ){
                if( $curCol>0){
                    $curRow=$numOfRows-1;
                    $curCol -=1;
                }
                else{
                    $pIndex++;
                    ($curRow,$curCol) =($numOfRows - 1,$numOfCols - 1);
                    $page = $pdf->page;
                    $page->rotate(270);
                    $page = $pdf->openpage($pIndex);   
                }
            }
            $y1=($curRow)*ROW_HEIGHT_LS + Y_BOT_LEFT_LS;
            $x1=($curCol)*COL_WIDTH_LS - X_BOT_LEFT_LS + LABEL_MAGIN;            
            writeLabel_spine($page,$x1,$y1,@$userData[$i]->{'callNumber'});
            $curRow -=1;
            
     }
            
     $pdf->save;
     $pdf->end();
}

#----------------------------------------------------------------------------------------------------
sub printLabel_spine_8by6
   {
    my($userData,$printType,$printField)=@_; 
    my  $page  ;
    my $pIndex=0;
    my($x1,$y1);
    my ($numOfRows,$numOfCols)=(6,8);
    $page = $pdf->page;
    $page = $pdf->openpage($pIndex++);   
    my ($curRow,$curCol) =($startRow,$startCol);
    for(my $i=0; $i<(scalar(@$userData)); $i++){
           if($curCol > $numOfCols ){
                if( $curRow <$numOfRows){
                    $curCol=1;
                    $curRow +=1;
                }
                else{
                    $pIndex++;
                    ($curRow,$curCol) =(1,1);
                    $page = $pdf->page;
                    $page = $pdf->openpage($pIndex);   
                }
            }
            $x1=($curCol-1)*COL_WIDTH_LS - X_BOT_LEFT_LS ;            
            $y1=($numOfRows-$curRow)*ROW_HEIGHT_LS + Y_BOT_LEFT_LS;
            writeLabel_spine($page,$x1,$y1,@$userData[$i]->{'callNumber'},@$userData[$i]->{'location'});
            $curCol +=1;
           
     }
            
     $pdf->save;
     $pdf->end();
}
#----------------------------------------------------------------------------------------------------
sub printLabel_spine_10by3
   {   
    my($userData,$printType,$printField)=@_; 
    my  $page  ;
    my $pIndex=0;
    my($x1,$y1);
    my ($numOfRows,$numOfCols)=(10,3);
    $page = $pdf->page;
    $page = $pdf->openpage($pIndex++);   
    my ($curRow,$curCol) =($startRow,$startCol);
    for(my $i=0; $i<(scalar(@$userData)); $i++){
           if($curCol > $numOfCols ){
                if( $curRow <$numOfRows){
                    $curCol=1;
                    $curRow +=1;
                }
                else{
                    $pIndex++;
                    ($curRow,$curCol) =(1,1);
                    $page = $pdf->page;
                    $page = $pdf->openpage($pIndex);   
                }
            }
            $x1=($curCol-1)*COL_WIDTH + X_BOT_LEFT ;            
            $y1=($numOfRows-$curRow)*ROW_HEIGHT + Y_BOT_LEFT;
            writeLabel_spine($page,$x1,$y1,@$userData[$i]->{'callNumber'},@$userData[$i]->{'location'});
            $curCol +=1;
            
     }
            
     $pdf->save;
     $pdf->end();

   }
#----------------------------------------------------------------------------------------------------
sub printLabel_BC
   {
    my($userData,$printType,$printField)=@_; 
    my  $page  ;
    my $pIndex=0;
    my($x1,$y1);
    my ($numOfRows,$numOfCols)=(10,3);
    $page = $pdf->page;
    $page = $pdf->openpage($pIndex++);   
    my ($curRow,$curCol) =($startRow,$startCol);
    for(my $i=0; $i<(scalar(@$userData)); $i++){
           if($curCol > $numOfCols ){
                if( $curRow <$numOfRows){
                    $curCol=1;
                    $curRow +=1;
                }
                else{
                    $pIndex++;
                    ($curRow,$curCol) =(1,1);
                    $page = $pdf->page;
                    $page = $pdf->openpage($pIndex);   
                }
            }
            $x1=($curCol-1)*COL_WIDTH + X_BOT_LEFT ;            
            $y1=($numOfRows-$curRow)*ROW_HEIGHT + Y_BOT_LEFT;
            writeLabel_card($page,$x1,$y1,@$userData[$i]->{'callNumber'},
                            decode('utf8', @$userData[$i]->{'author'}),
                            decode('utf8', @$userData[$i]->{'title'}),
                            decode('utf8', $libname),
                            @$userData[$i]->{'barcode'},
                            $printField);
            $curCol +=1;
            
     }
            
     $pdf->save;
     $pdf->end();
}
#----------------------------------------------------------------------------------------------------
sub printLabelByRange_BC
   {
    my($bcList,$printField)=@_; 
    my  $page  ;
    my $pIndex=0;
    my($x1,$y1);
    my ($numOfRows,$numOfCols)=(10,3);
    $page = $pdf->page;
    $page = $pdf->openpage($pIndex++);   
    my ($curRow,$curCol) =($startRow,$startCol);
    my @bcArray = split(',', $bcList);

    for(my $i=0; $i<(scalar(@bcArray)); $i++){
           if($curCol > $numOfCols ){
                if( $curRow <$numOfRows){
                    $curCol=1;
                    $curRow +=1;
                }
                else{
                    $pIndex++;
                    ($curRow,$curCol) =(1,1);
                    $page = $pdf->page;
                    $page = $pdf->openpage($pIndex);   
                }
            }
            $x1=($curCol-1)*COL_WIDTH + X_BOT_LEFT ;            
            $y1=($numOfRows-$curRow)*ROW_HEIGHT + Y_BOT_LEFT;
            $BC_FONT = 24;
            writeLabel_card($page,$x1,$y1,'',
                            '',
                            '',
                            decode('utf8', $libname),
                            @bcArray[$i],
                            $printField);
            $curCol +=1;
            
     }
            
     $pdf->save;
     $pdf->end();


}
#----------------------------------------------------------------------------------------------------
sub printLabel{
    my($userData,$printType,$printField)=@_; 
    my  $page  ;
    my $pIndex=0;
    my($x1,$y1);
    my ($numOfRows,$numOfCols)=(10,3);
    my ($curRow,$curCol) =($startRow,$startCol);

   $page = $pdf->page;
   $page = $pdf->openpage($pIndex++);
    
    my $colNo =0;
    for(my $i=0; $i<(scalar(@$userData)); $i++){
       if($curRow >$numOfRows){ 
          $pIndex++;
          $y1  = Y_TOP_RIGHT- ROW_HEIGHT;
          $page = $pdf->page;
          $page = $pdf->openpage($pIndex);
          $curRow=1;
       }

       $y1=($numOfRows-$curRow)*ROW_HEIGHT + Y_BOT_LEFT;
              
       for (my $c=0 ; $c <$numOfCols ; $c++){
           if ($c==0){
               $x1  = X_BOT_LEFT;
               writeLabel_spine($page,$x1,$y1,@$userData[$i]->{'callNumber'},@$userData[$i]->{'location'});
           }
           else{
              $x1 = $x1+(COL_WIDTH); 
              writeLabel_card($page,$x1,$y1,@$userData[$i]->{'callNumber'},
                                            decode('utf8', @$userData[$i]->{'author'}),
                                            decode('utf8', @$userData[$i]->{'title'}),
                                            decode('utf8', $libname),
                                            @$userData[$i]->{'barcode'},
                                            $printField);
            }               
       }
       $curRow++;
     }       
     $pdf->save;
     $pdf->end();
}
   
#----------------------------------------------------------------------------------------------------
sub writeLabel_spine{
   my($page,$x,$y,$callNum,$location)=@_;
    my $i=0;
    $x = $x + COL_WIDTH/2 - 30    ;
    $y = $y +ROW_HEIGHT/2+10;
    my $txt = $page->text;
    $txt->lead(9);
    $txt->textstart;
    # write Call number
    $txt->font($boldFont, 12);
    $txt->translate($x,$y);
    my @cArr=split(' ',$callNum);
    for(my $j=0; $j<scalar(@cArr);$j++){
        $txt->translate($x ,$y - $j*12);
        $txt->text(@cArr[$j]);
    }
    $txt->text($location);
# Tue, Dec 02, 2008 @ 10:14:25 EST
# Add print LOCATION
  
    if($location ne ''){        
        $txt->translate($x,$y-11); 
        $overflowTxt = $txt->paragraph($location,100,9);
    }
        
=item
    my $overflowTxt = $txt->paragraph($callNum,10,9);
    while($overflowTxt ne ''){
        $i +=12;
        $txt->translate($x ,$y - $i);
        $overflowTxt = $txt->paragraph($overflowTxt,10,9);
    }
=cut    
   $txt->textend;
}  


#----------------------------------------------------------------------------------------------------
sub formatTxt{
    my($f,$str,$fs,$w)=@_;
    my $txtWidth=$f->width($str);
    while($txtWidth*$fs > $w){
        $str=substr($str,0,length($str)-1);
        $txtWidth=$f->width($str);
        
    }
    return $str;
    
}
#----------------------------------------------------------------------------------------------------
sub writeLabel_card{
    my($page,$x,$y,$callNum,$author,$title,$libname,$bc,$printField)=@_;
    my $i=0;
    $y = $y +ROW_HEIGHT -15 ;
    my $txt = $page->text;
    $txt->lead(9);
    $txt->textstart;
    # write Call number
    $txt->font($normalFont, 9);
    $txt->translate($x ,$y);
    my @cArr=split(' ',$callNum);
    for(my $j=0; $j<scalar(@cArr);$j++){
        $txt->translate($x ,$y - $j*12);
        $txt->text(formatTxt($normalFont,@cArr[$j],9,34));
    }
    $x += 38;
    my $overflowTxt;
    if($printField eq 'libname'){
         # write library/school name
        $txt->translate($x,$y);
        $overflowTxt = $txt->paragraph(" $libname",100,9);
        if($overflowTxt ne ''){
            $txt->translate($x,$y-11);
            $overflowTxt = $txt->paragraph($overflowTxt,100,9);
        }
    }
    else{
        # write author 
        $txt->translate($x,$y);
        $overflowTxt = $txt->paragraph($author,100,9);
        # write title 
        $txt->translate($x,$y-11);
        $overflowTxt = $txt->paragraph(" $title",100,9);
        if($overflowTxt ne ''){
            $txt->translate($x,$y-20);
            $overflowTxt = $txt->paragraph($overflowTxt,100,9);
        }

    }
    # write BC 
    $txt->font($barcodeFont, $BC_FONT);
    $txt->translate($x,$y-44);
    $overflowTxt = $txt->paragraph("*$bc*",160,28);
    $txt->font($normalFont, 8);
    $txt->translate($x,$y-53);
    $overflowTxt = $txt->paragraph($bc,120,9);
              
     $txt->textend;
}
    
#----------------------------------------------------------
sub getModRecord {
my ($dbh, $dateFrom, $dateTo,$pHoldingOpt, $ridList) = @_;
 
        my $query = <<_STH_;        
select m.title,m.author,i.callNumber,ucase(i.barcode) as barcode, location 
from   opl_item i inner join opl_marcRecord m on i.rid=m.rid
where  i.available=1                
_STH_
   
    if($ridList){ 
        $query .= " && m.rid in($ridList)";
    }
    else{
        $query .= " && m.modDate between '$dateFrom' and  '$dateTo' + interval 1 day" ;
    }
    if ($pHoldingOpt =~ m/^mod$/i) {
        $query .= " && i.modDate between '$dateFrom' and  '$dateTo' + interval 1 day  && i.modDate <> i.dateImport" ;
    }
    $query .= " order by i.callNumber";

;
    
    my $sth = $dbh->prepare($query);
    $sth->execute();
    my @recordList;
    while (my $rec = $sth->fetchrow_hashref) {
        push @recordList, $rec;
    }
    $sth->finish;

    return \@recordList;

   
}
   
