#!/usr/bin/perl

#use utf8;
use strict;
use CGI;

use Opals::Context;#use MARC::File::USMARC;
#use MARC::File::XML;

use Opals::Context;

use POSIX qw(
    ceil
);

use Opals::Utility qw(
    
    util_filterMarcXml
);

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

use Opals::Tb_Record qw(

    tb_record_findByRId

);

use Opals::Utility qw(
    util_escapeXml
);
my $dbh = Opals::Context->dbh();
my  $barcodeType =Opals::Context->preference('barcodeType');
END { $dbh->disconnect(); }

my $cgi = CGI->new;
my $input = $cgi->Vars();
my ($query, $pqf, $sTerm);


my @sInput;

my $sortOrder = $input->{'sortOrder'};
    $sortOrder = " asc " if (! $sortOrder);
my $sortAttr = $input->{'sortAttr'};
    $sortAttr = " barcode " if (! $sortAttr);


my $pSize = 20;
my $curPage = $input->{'pNum'};
($curPage && $curPage >= 1) || ($curPage = 1);
my $offset = ($curPage - 1) * $pSize + $ENV{'Z_INDEX_BASE'};

my $requestXml="";
 $requestXml .="<request>\n";        
 $requestXml .="<page>$curPage</page>\n";
 $requestXml .="<sortAttr>$sortAttr</sortAttr>\n";
 $requestXml .="<sortOrder>$sortOrder</sortOrder>\n";

my ($resultSize, $result,$bcMatchedList) ;
my $sf=$input->{'sf0'};
my $kw =$input->{'kw0'};


 $requestXml .= "</request>\n";


    my ($resultSize , $itemList) = getRecs($dbh,$sf, $kw, $sortAttr, $sortOrder,$offset,$pSize  );
    my $recReturned = scalar(@$itemList);
    
    my  $retStr   ="<?xml version=\"1.0\" encoding=\"UTF-8\"?><collection numberOfHits=\"$resultSize\" recordReturned=\"$recReturned\" > ";

    $retStr .=$requestXml;
    my $xmlList;
    $xmlList .= "<recordList>";
    my $recordTag = "";
    my $curRecId= 0;
    my $bFirst = 0;
    my $items;
    my $recXML;

    if ($resultSize > 0){
        foreach my $rec (@$itemList){
            if ($rec->{'rid'} != $curRecId){
                $curRecId = $rec->{'rid'};
                $recXML = getXMLByRid($dbh, $curRecId);
                if ( $bFirst && $bFirst == 1) {
                    $items .= "</record>";
                    $items .= "<record " . " rid=\"" .  $rec->{'rid'} . "\" title=\"" . encodeXMLchar($rec->{'title'}) . "\" author= \"" .  encodeXMLchar($rec->{'author'}) . "\">";
                    #$bFirst = 0;
                    $items .= $recXML;
                }
                else{
                    $bFirst = 1;
                    $items .= "<record " . " rid=\"" .  $rec->{'rid'} . "\" title=\"" .  encodeXMLchar($rec->{'title'}) . "\" author= \"" .  encodeXMLchar($rec->{'author'}) . "\">";
                    $items .= $recXML;
                }
                $recXML = "";
            }
            $items .= "<item>";
            $items .= "<barcode>" . $rec->{'barcode'} . "</barcode>";
            $items .= "<callNumber>" . $rec->{'classNumber'} . " </callNumber>";
            $items .= "</item>\n";
        }
        if ($items !~ m/<\/record>$/){
            $items .= "</record>\n"; 
        }
    }
    $xmlList .= $items . "</recordList>\n";
    $retStr .= $xmlList;
    $retStr .= " </collection>\n";
    print "Content-type: text/html\n\n";
    print $retStr;

sub getRecs {
  
    my ($dbh, $sfCode, $kw, $sortAttr, $sortOrder,  $pOffset, $pSize) = @_;
    if ($sfCode !~ m/barcode/i){ 
        $kw =~ s/[\s]+/ +/g;
        $kw = "+" . $kw;
    }
    my $sqlCount = "select count(distinct i.barcode)  
            from tb_items i 
            inner join tb_records rTitle on rTitle.rid = i.rid && rTitle.fId = '245_a '
            inner join tb_records rAuthor on rAuthor.rid = i.rid && rAuthor.fId = '100_a'";

    my $sql = " select i.rid as rid , rTitle.fVal as title, group_concat(rAuthor.fVal order by rAuthor.fVal SEPARATOR ';') as author, i.barcode, i.classNumber
            from tb_items i 
            inner join tb_records rTitle on rTitle.rid = i.rid && rTitle.fId = '245_a '
            inner join tb_records rAuthor on rAuthor.rid = i.rid && rAuthor.fId = '100_a'";

    my $sqlWhere = "";
    my $sqlOrderBy = "";
    if ($sfCode =~ m/000_a/i){
        $sqlWhere .=  " inner join tb_records r on r.rid = i.rid where MATCH(r.fVal) AGAINST(? IN BOOLEAN MODE) ";
    }
    elsif($sfCode =~ m/245_a/i){
        $sqlWhere .=  "  where MATCH(rTitle.fVal) AGAINST(? IN BOOLEAN MODE) && rTitle.fId = '$sfCode' " ;   
    }
    elsif($sfCode =~ m/100_a/i) {
        $sqlWhere .=  "  where MATCH(rAuthor.fVal) AGAINST(? IN BOOLEAN MODE) && rAuthor.fId = '$sfCode' " ;  
    }
    elsif($sfCode =~ m/callNumber/i){
        $sqlWhere .=  "  where i.classNumber regexp ? ";
    }
    elsif($sfCode =~ m/barcode/i){
        $sqlWhere .=  "  where i.barcode = ? ";
    }
    $sqlWhere .= " && i.barcode not regexp '^\_\_\_'";
    
    my $sqlGroupBy  = " group by barcode ";
    $sqlOrderBy = " order by i.rid, $sortAttr $sortOrder limit $pOffset , $pSize ";
    $sql .= $sqlWhere . $sqlGroupBy . $sqlOrderBy ;
    $sqlCount .= $sqlWhere;
    my $resultSize = 0;
    $resultSize = $dbh->selectrow_array($sqlCount, undef, $kw);
    my @itemList = ();
    my $sth = $dbh->prepare($sql);
    $sth->execute($kw);
    while (my $rec = $sth->fetchrow_hashref){
        push @itemList, $rec;
    }
    $sth->finish;
    return ($resultSize , \@itemList);
}

sub getXMLByRid {

    my ($dbh, $rid) = @_;
    my $record = getRecordInfo($dbh,$rid);
    my $xmlStr = "";
    my $h ;
    my $key="";
    foreach my $f (@{$record}){
        $key = $f->{'tag'} . $f->{'subfield'};
        if (!$h->{$key}){
            $h->{$key}->{'tag'} = $f->{'tag'};
            $h->{$key}->{'subfield'} = $f->{'subfield'};
            $h->{$key}->{'label'} = $f->{'label'} ;
            $h->{$key}->{'rept'} = $f->{'rept'} ;
            $h->{$key}->{'ord'} = $f->{'ord'} ;
        }
        push @{$h->{$key}->{'val'}} , $f->{'val'};
    }
    foreach my $k (sort { $h->{$a}{'ord'} <=> $h->{$b}->{'ord'} } keys %{$h}){
        $xmlStr .=  "<recInfo ";
        $xmlStr .= " tag = \"" . encodeXMLchar($h->{$k}->{'tag'}) . "\" ";
        $xmlStr .= " subfield = \"" . encodeXMLchar($h->{$k}->{'subfield'}) . "\" ";
        $xmlStr .= " label = \"" . encodeXMLchar($h->{$k}->{'label'}) . "\" ";
        $xmlStr .= " rept = \"" . $h->{$k}->{'rept'} . "\" ";
        $xmlStr .= " >";
        foreach my $val (@{$h->{$k}->{'val'}}){
            $xmlStr .= "<val>";
            $xmlStr .=  encodeXMLchar($val)? encodeXMLchar($val): " " ;
            $xmlStr .= "</val>";
        }
        $xmlStr .=  "</recInfo>\n";
    }
    return $xmlStr;
}

sub getRecordInfo {

    my ($dbh,$rid) = @_;
    my $sql = " select r.id, r.fVal as val,
                    m.fieldId as tag, m.subfield as subfield, m.fieldName as label,m.repeatable as rept , m.displayOrder as ord
                from tb_records r 
                inner join tb_index_map m on r.fId = concat(m.fieldId, '_' , m.subfield)
                where m.showed = 1 && r .rid = ? 
                order by displayOrder ";

    my  @val =($rid);
    my $recField = $dbh->selectall_arrayref($sql, {Slice => {}}, @val);
    return $recField;
}


sub encodeXMLchar {
    my ($str) = @_;
    return unless $str;
    #$str =~ s/'/&apos;/g;
    $str =~ s/"/&quot;/g;
    $str =~ s/&/&amp;/g;
    $str =~ s/>/&gt;/g;
    $str =~ s/</&lt;/g;
    return $str;

}

