package Opals::Marc::OpalsMarc;

# Version number
$VERSION   = 0.01;

use strict;
use Encode;
use MARC::Record;
use Opals::Utility qw(
    util_restoreLiteral
);

require Exporter;
our @ISA = qw (MARC::Record );
my $langCodeMap;
my $recTypeDef;
my $literaryFormMap;
my $genInfoRecFielMap;
#////////////////////////////////////////////////////////////////////////////
sub new {
    my ($class) = @_;
    # Call the constructor of the parent class, Person.
    my $self = $class->SUPER::new();
    my $xml=$_[1];
    my ($tag, $ind1, $ind2, $sfCode, $data);

    # Extract leader
    if ($xml =~ s/[\s]*<leader>([\w ]{24})<\/leader>//) {
        $self->leader($1);
    }

    # Extract control field
    while ($xml =~ s/[\s]*<controlfield tag="(00[\d])">(.*)<\/controlfield>//) {
        $tag  = $1;
        $data = util_restoreLiteral($2);
        $self->append_fields(MARC::Field->new($tag, $data));
    }

    # Extract data field
    my $sfXml;
    my $field;
    while ($xml =~ s/[\s]*<datafield tag="([\d]{3})" ind1="([\d ])" ind2="([\d ])">(([\s]*<subfield code=".">.*<\/subfield>)*)[\s]*<\/datafield>//) {
        $tag   = $1;
        $ind1  = $2;
        $ind2  = $3;
        $sfXml = $4;
        $field = undef;

        my @subfield = ();
        #while ($sfXml =~ s/[\s]*<subfield code="([\w])">(.*)<\/subfield>//) {
        while ($sfXml =~ s/[\s]*<subfield code="(.)">(.*)<\/subfield>//) {
            ($sfCode, $data) = ($1, util_restoreLiteral($2));
            ($data) || ($data = ' '); # fix empty (sub)field
            if (!$field) {
                $field = MARC::Field->new(
                    $tag,
                    $ind1, $ind2,
                    $sfCode => $data
                );
            }
            else {
                $field->add_subfields($sfCode => $data);
            }
        }

        $self->append_fields($field) if $field;
    }
    bless $self, $class;
    return $self;
}

#////////////////////////////////////////////////////////////////////////////

sub getRecLanguageCode{
    my($self)=@_;

    my $cf008=$self->field('008')->data();
    my $language='English';#default;
    my $lanCode=undef;
    if(length($cf008)>=38){
        $lanCode= substr($cf008,35,3);
    }
    return $lanCode;
}
#////////////////////////////////////////////////////////////////////////////

sub getRecLanguage{
    my($self)=@_;

    my $cf008=$self->field('008')->data();
    my $language='English';#default;
    if(length($cf008)>=38){
        my $lanCode= substr($cf008,35,3);
        $language=$langCodeMap->{$lanCode} if(defined $langCodeMap->{$lanCode});
    }
    return $language;
}

#////////////////////////////////////////////////////////////////////////////
sub getGeneralInfo{
    my($self)=@_;
    my $leader  =$self->leader();
    my $cf008   =$self->field('008')->data();
    
   my $retRec={};
   $retRec->{'rid'} =$self->field('001')->data() if($self->field('001'));;
   $retRec->{'bid'} =$self->field('002')->data() if($self->field('002'));
   $retRec->{'cid'} =$self->field('004')->data() if($self->field('004'));
   $retRec->{'recFormat'} =$self->getRecFormat();
   $retRec->{'literaryForm'} =$self->getRecLiteraryForm();
   $retRec->{'languageCode'} =$self->getRecLanguageCode();
   $retRec->{'language'}    =$self->getRecLanguage();
   foreach my $tag(keys %$genInfoRecFielMap){
       foreach my $prop(@{$genInfoRecFielMap->{$tag}}){
            my $multiple=(lc $prop->{'multiple'} eq 'true');
            my $fieldName=$prop->{'name'};
            my $tagExcl=$prop->{'tagExcl'};
            next if( !$multiple && defined $retRec->{$fieldName});
            foreach my $f ($self->field($tag) ){

                next if((defined $prop->{'ind1'} && $f->indicator(1) ne $prop->{'ind1'})
                        || (defined $prop->{'ind2'} && $f->indicator(2) ne $prop->{'ind2'})); 

                my $fv ;
                if(!defined $prop->{'func'}){
                    $fv= $self->_getDataField($f,$prop);
                }
                else{
                    $fv= $prop->{'func'}($f);
                }
                next if(!defined $fv);
                if(!$multiple){
                    $retRec->{$fieldName} = $fv;
                }
                else{
                     $retRec->{$fieldName}=[] if(!defined $retRec->{$fieldName});
                     push @{$retRec->{$fieldName}},{item=>$fv};
                }
            }
       }
   }
   return $retRec;
    
}

#////////////////////////////////////////////////////////////////////////////

sub _getDataField{
    my ($self,$field,$prop)=@_;
    my $sfIncl   = $prop->{'subfieldIncl'};
    my $sfExcl   = $prop->{'subfieldExcl'};
    my $sfConStr = $prop->{'sfConcatStr'};
    my $tagExcl=$prop->{'tagExcl'} || "";
    my $multiple = $prop->{'multiple'};
    my $tag =$field->tag();
    my $ind1=$field->indicator(1);
    my $ind2=$field->indicator(2);

    my $fieldVal=undef;

    if($tagExcl !~ m/$tag/g 
        && (!defined $prop->{'ind1'} ||  $prop->{'ind1'} eq $ind1)
        && (!defined $prop->{'ind2'} ||  $prop->{'ind2'} eq $ind2)){

        foreach my $sf ( $field->subfields() ){
            my($code,$data)= @$sf;
            if(($sfIncl  ne '' && $sfIncl =~ /$code/gi) 
                || ($sfExcl ne '' && $sfExcl !~ /$code/gi)){
                    $fieldVal="" if(!defined $fieldVal);
                    $fieldVal .= $sfConStr if($fieldVal ne "");
                    $fieldVal .= $data;
            }
        }
    }
                 
    return $fieldVal;
}
#////////////////////////////////////////////////////////////////////////////
sub getRecFormat{
    my ($self) = @_;

    my $leader  =$self->leader();
    my $cf006= ($self->field('006'))?lc($self->field('006')->data()) :"";
    my $cf007= ($self->field('007'))?lc($self->field('007')->data()) :"";
    my $cf008= ($self->field('008'))?lc($self->field('008')->data()) :"";
    
    my $recProp={leader=>$leader,
                  '006'=>$cf006,
                  '007'=>$cf007,
                  '008'=>$cf008
                 };
    my ($score,$lastScore,$complete)=(0,0,1);    
    my @recType=();
    my $recFormat="book";
    foreach my $mType(keys %$recTypeDef){
        next if( $mType eq '_default');
        my $typeDef=$recTypeDef->{$mType};
        $score=0;
        $complete=1;
        foreach my $f(keys %$typeDef){
            next if($f !~ m/leader|00[1-9]/g);
            my @pArr=@{$typeDef->{$f}->{'prop'}} ;
            foreach my $e(@pArr){
                if($e->{'v'} ne substr($recProp->{$f},$e->{'p'},1)){
                    $complete=0;
                    last;
                }
                $score++;
            }
        }
        if($complete && $score>$lastScore){
            $lastScore=$score ;
            $recFormat = $mType;
        }
    }
    return $recFormat;
}
#////////////////////////////////////////////////////////////////////////////
sub getRecLiteraryForm{
    my ($self) = @_;
    my $cf008=($self->field('008'))?lc($self->field('008')->data()) :"";
    my $litForm="unknown";
    if(length($cf008)>=34){
        my $c= substr($cf008,33,1);
        $litForm = $literaryFormMap->{$c} if(defined $literaryFormMap->{$c});
    }
    return $litForm;
}
#////////////////////////////////////////////////////////////////////////////

sub _getIllustrator{
    my($field)=@_;
    my $sf_a = $field->subfield('a');
    my $sf_e = $field->subfield('e');
    my $illustrator=undef;
    if($sf_e =~ m/^ill/gi && $sf_a ne ''){
        $illustrator = $sf_a;
    }
    return $illustrator;
}
#////////////////////////////////////////////////////////////////////////////
sub _getContentNote{
    my ($field)=@_;
    my $curNote=undef;
    my @contNoteList=();
    my @titleRespList=();
    my @uriList=();
    my($title,$resp)=('','');
    my $contentNote=undef;
    $contentNote->{'format'}=" ";
    foreach my $sf($field->subfields()){
        my ($code,$data)=@$sf;
        $data =~ s/"/&quot;/g;
        if($code eq 'a'){
            $contentNote->{'format'}=$data;
        }
        elsif($code eq 'g'){
            if($title ne ''){
               push @{$curNote->{'titleRespList'}},{cnTitle=>$title,cnResp=>''};
                $title=undef;
            }

            push @contNoteList, $curNote if(defined $curNote);
            $curNote={miscInfo=>$data};
        }
        elsif($code eq 't'){
            if($title ne''){
                push @{$curNote->{'titleRespList'}},{cnTitle=>$title,cnResp=>''};
                $title=undef;
            }
            $title = $data;
            $title =~ s/^\s+|\s+$//;
        }
        elsif($code eq 'r'){
            $resp = $data;
            $resp =~ s/^\s+|\s+$//;
            push @{$curNote->{'titleRespList'}},{cnTitle=>$title,cnResp=>$resp};
            ($title,$resp)=(undef,undef);
            
        }
        elsif($code eq 'u'){
            push @{$curNote->{'cnUriList'}}, {uri=>$data};
        }
        
    }
    push @{$curNote->{'titleRespList'}},{cnTitle=>$title,cnResp=>''}if($title ne'');
    push @contNoteList, $curNote if(defined $curNote);
    $contentNote->{'toc'}=\@contNoteList if(scalar(@contNoteList)>0);
   
    return $contentNote ;

}

#////////////////////////////////////////////////////////////////////////////
sub _getStudyProgram{
    my ($field)=@_;
    my $studyProgram=undef;
    my $map={a=>'studyPrgm_name',
          b=>'interestLevel',
          c=>'readingLevel' ,
          d=>'pointValue',
          z=>'quizNumber'
          };

    foreach my $sf($field->subfields()){
        my ($code,$data)=@$sf;
        if(defined $map->{$code}){
            $studyProgram->{$map->{$code}} = $data;
        }
    }
    return $studyProgram;

}
#////////////////////////////////////////////////////////////////////////////
sub _getLexileMeasure{
    my ($field)=@_;
    my $ind1 =$field->indicator(1);
    my $lexile=undef;
    if($ind1 && $ind1 eq '8'){
        my $sfa = $field->subfield('a');
        my $sfb = $field->subfield('b');
        if(defined $sfb  && $sfb =~ m/lexile/i
           && defined $sfa && $sfa ne '' ){
            $lexile=$sfa;
        }

    }
    return $lexile;

}
#////////////////////////////////////////////////////////////////////////////
sub _getFountasPinnell{
    my ($field)=@_;
    my $fp=undef;
    my $ind1 =$field->indicator(1);
    if($ind1 && $ind1 eq '8'){
        my $sfa = $field->subfield('a');
        my $sfb = $field->subfield('b');
        
         $sfb =~ s/&amp;/&/g;
         if($sfb =~ m/.*((Fountas|f)(\s*)(and|&|&amp;)*(\s*)(p|Pinnell)).*/i
             && defined $sfa && $sfa ne ''){
            $fp=$sfa;
         }
    }
    return $fp;

}
#////////////////////////////////////////////////////////////////////////////
sub  _getHoldingInfo{
    my ($field)=@_;
    my $callnumber='';
   
    foreach my $code(qw(k h i m)){
        my $data =$field->subfield($code);
        $callnumber .= " $data" if($data && $data ne "");
    }
    $callnumber =~ s/^\s+|\s+$//g;

    return {sysCode     =>$field->subfield('a'),
            libCode     =>$field->subfield('b'),
            location    =>$field->subfield('c'),
            barcode     =>$field->subfield('p'),
            price       =>$field->subfield('9'),
            typeCircCode=>$field->subfield('3'),
            callnumber  =>$callnumber
           };

}
#////////////////////////////////////////////////////////////////////////////
sub _getUri{
    my ($field)=@_;
    my $ret=undef;
    my $uri_desc= $field->subfield('3');
    if(!defined $uri_desc || $uri_desc eq ''){
        $uri_desc= $field->subfield('y');
    }
    my $uri = $field->subfield('u');

    if(defined $uri){
        $ret ={uri_desc=>$uri_desc, uri=>$uri};
    }
    return $ret;
}
#////////////////////////////////////////////////////////////////////////////
sub _getAuthor880{
    my ($field)=@_;
    my $sf880_a = $field->subfield('a');            
    my $sf880_6 =  $field->subfield('6'); 
    my $ret=undef;
    if(defined $sf880_6 && $sf880_6 =~ m/100/g 
        && defined $sf880_a && $sf880_a ne ""){

        $ret  = $sf880_a;
    }
    return $ret;
}
#////////////////////////////////////////////////////////////////////////////
sub _getTitle880{
    my ($field)=@_;
    my $sf880_a = $field->subfield('a');            
    my $sf880_6 =  $field->subfield('6'); 
    my $ret=undef;
    if(defined $sf880_6 && $sf880_6 =~ m/245/g 
        && defined $sf880_a && $sf880_a ne ""){

        $ret  = $sf880_a;
    }
    return $ret;
      
}
#////////////////////////////////////////////////////////////////////////////
sub _getPlace880{
    my ($field)=@_;
    my $sf880_a = $field->subfield('a');            
    my $sf880_6 =  $field->subfield('6'); 
    my $ret=undef;
    if(defined $sf880_a && $sf880_a ne "" && defined $sf880_6){
        if($sf880_6 =~ m/260/g || ($field->indicator(2) eq '1' && $sf880_6 =~ m/264/g) ){
            $ret =$sf880_a;
        }
    }
    return $ret;
       
}
#////////////////////////////////////////////////////////////////////////////
sub _getPublisher880{
    my ($field)=@_;
    my $sf880_b = $field->subfield('b');            
    my $sf880_6 =  $field->subfield('6'); 
    my $ret=undef;
    if(defined $sf880_b && $sf880_b ne "" && defined $sf880_6){
        if($sf880_6 =~ m/260/g || ($field->indicator(2) eq '1' && $sf880_6 =~ m/264/g) ){
            $ret =$sf880_b;
        }
    }
    return $ret;
}

#////////////////////////////////////////////////////////////////////////////
sub _getTitleSort{
    my ($field)=@_;
    my $ind2 = $field->indicator(2);
    my $sf245_a=$field->subfield('a');
    my $sf245_b=$field->subfield('b');
    if($ind2>0){
        $sf245_a =substr($sf245_a, $ind2);
    }
    my $ret = $sf245_a; 
    $ret .= ":" . $field->subfield('b') if( defined $sf245_b);          
    return $ret;
       
}
#////////////////////////////////////////////////////////////////////////////
sub _getPubDateSort260{
    my ($field)=@_;
    my $ret =undef; 
    my $sf260_c = $field->subfield('c');
    if(defined $sf260_c && $sf260_c =~ m/([\d]{4})/){
        $ret .= $1;
    }
    return $ret;
}

#////////////////////////////////////////////////////////////////////////////
sub _getPubDateSort264{
    my ($field)=@_;
    my $ret =undef;   
    my $sf264_c = $field->subfield('c');
    my $ind2    = $field->indicator(2);
    if(defined $sf264_c && defined $ind2 && $ind2 eq '1' && $sf264_c =~ m/([\d]{4})/){
        $ret .= $1;
    }
    return $ret;
}

#////////////////////////////////////////////////////////////////////////////
$genInfoRecFielMap={
                    '010'=>[{name=>'lccn',              subfieldIncl=>"a",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"}],
                    '020'=>[{name=>'isbn_first',        subfieldIncl=>"a",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"},
                            {name=>'isbn',              subfieldIncl=>"a",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"true"}],
                    '100'=>[{name=>'author',            subfieldIncl=>"a",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"}],
                    '245'=>[{name=>'title',             subfieldIncl=>"a",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"},
                            {name=>'subtitle',          subfieldIncl=>"b",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"},
                            {name=>'titleSort',         func=>\&_getTitleSort,                                      multiple=>"false"},
                            {name=>'responsibleStmnt',  subfieldIncl=>"c",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"},
                            {name=>'medium',            subfieldIncl=>"h",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"},
                            {name=>'nameOfPart',        subfieldIncl=>"p",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"true"},
                            {name=>'numOfPart',         subfieldIncl=>"n",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"true"},
                            {name=>'version',           subfieldIncl=>"s",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"}
                           ],
                    '260'=>[{name=>'placePublication',  subfieldIncl=>"a",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"},
                            {name=>'namePublisher',     subfieldIncl=>"b",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"},
                            {name=>'datePublication',   subfieldIncl=>"c",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"},
                            {name=>'pubDateSort',       func=>\&_getPubDateSort260,                                 multiple=>"false"}
                           ],
                    '264'=>[{name=>'placePublication',  subfieldIncl=>"a",  subfieldExcl=>"", sfConcatStr=>" ", ind2=>'1',   multiple=>"false"},
                            {name=>'namePublisher',     subfieldIncl=>"b",  subfieldExcl=>"", sfConcatStr=>" ", ind2=>'1',   multiple=>"false"},
                            {name=>'datePublication',   subfieldIncl=>"c",  subfieldExcl=>"", sfConcatStr=>" ", ind2=>'1',   multiple=>"false"},
                            {name=>'pubDateSort',       func=>\&_getPubDateSort264,                                          multiple=>"false"}
                           ],
                    '300'=>[{name=>'page',              subfieldIncl=>"a",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"}],
                    '440'=>[{name=>'title_series_a',    subfieldIncl=>"a",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"},
                            {name=>'title_series_v',    subfieldIncl=>"v",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"}
                           ],
                    '490'=>[{name=>'title_series_a',    subfieldIncl=>"a",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"},
                            {name=>'title_series_v',    subfieldIncl=>"v",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"}
                           ],
                    '505'=>[{name=>'contentNote',       func=>\&_getContentNote,                                    multiple=>"true"}],
                    '510'=>[{name=>'citationRefNote',   subfieldIncl=>"a,c",  subfieldExcl=>"", sfConcatStr=>" --", multiple=>"true"}],
                    '520'=>[{name=>'summary',           subfieldIncl=>"a,c",  subfieldExcl=>"", sfConcatStr=>" --", multiple=>"true"}],
                    '521'=>[{name=>'lexileMeasure',     func=>\&_getLexileMeasure,                                  multiple=>"false"},
                            {name=>'fountasPinnell',    func=>\&_getFountasPinnell,                                 multiple=>"false"},
                            {name=>'note',              subfieldIncl=>"a,b",   subfieldExcl=>"", sfConcatStr=>" ",  multiple=>"true"}],
                    '526'=>[{name=>'studyProgram',      func=>\&_getStudyProgram,                                   multiple=>"true"}],
                    '5..'=>[{name=>'note',              subfieldIncl=>"a",   subfieldExcl=>"", sfConcatStr=>" ",    multiple=>"true", tagExcl=>"505,510,520,521,526"}],
                    '650'=>[{name=>'era',               subfieldIncl=>"y",   subfieldExcl=>"", sfConcatStr=>" ",    multiple=>"true"}],
                    '651'=>[{name=>'era',               subfieldIncl=>"y",   subfieldExcl=>"", sfConcatStr=>" ",    multiple=>"true"}],
                    '6..'=>[{name=>'subject',           subfieldIncl=>"",   subfieldExcl=>"2", sfConcatStr=>" -- ", multiple=>"true"}],
                    '700'=>[{name=>'illustrator',       func=>\&_getIllustrator,                                    multiple=>"true"}],
                    '852'=>[{name=>'callnum1St',        subfieldIncl=>"k,h,i,m",  subfieldExcl=>"", sfConcatStr=>" ",    multiple=>"false"},
                            {name=>'852_h',             subfieldIncl=>"h",  subfieldExcl=>"", sfConcatStr=>" ",     multiple=>"false"},
                            {name=>'callnumberPrefix_first',     subfieldIncl=>"k",  subfieldExcl=>"", sfConcatStr=>" ",    multiple=>"false"},
                            {name=>'classificationPart_first',   subfieldIncl=>"h",  subfieldExcl=>"", sfConcatStr=>" ",    multiple=>"false"},
                            {name=>'itemPart_first',             subfieldIncl=>"i",  subfieldExcl=>"", sfConcatStr=>" ",    multiple=>"false"},
                            {name=>'callnumberSubfix_first',     subfieldIncl=>"m",  subfieldExcl=>"", sfConcatStr=>" ",    multiple=>"false"},
                            {name=>'itemList',          func=>\&_getHoldingInfo,                                 multiple=>"true"}],
                    '856'=>[{name=>'uriList',           func=>\&_getUri,                                         multiple=>"true"}],
                    '880'=>[{name=>'author_880',        func=>\&_getAuthor880,                                   multiple=>"false"},
                            {name=>'title_880',         func=>\&_getTitle880,                                    multiple=>"false"},
                            {name=>'place_880',         func=>\&_getPlace880,                                    multiple=>"false"},
                            {name=>'publisher_880',     func=>\&_getPublisher880,                                multiple=>"false"},
                           ]
    };

#////////////////////////////////////////////////////////////////////////////
#
# Literary form map
#

$literaryFormMap={
    '0'  	=>'nonFiction',
	'1' 	=>'fiction',
	'c' 	=>'comicStrips',
	'd' 	=>'dramas',
	'e' 	=>'essays',
	'f' 	=>'novels',
	'h' 	=>'humor',
	'i' 	=>'letters',
	'j' 	=>'shortStories',
	'm' 	=>'mixedDorms',
	'p' 	=>'poetry',
	's' 	=>'speeches',
	'u' 	=>'unknown'
};


#////////////////////////////////////////////////////////////////////////////
$recTypeDef ={
          _default       => {leader =>{prop    => [{ p => 6, v => 'a'},{ p => 7, v => ' '}]},
                             '006'  =>{prop    => [{ p => 0, v => ' '}]},            
                             '007'  =>{prop    => [{ p => 0, v => ' '},{ p => 1, v => ' '},{ p => 4, v => ' '}]},            
                             '008'  =>{prop    => [{ p => 23,v => ' '},{ p => 26,v => ' '}]} 
                            },

          book           => {leader =>{prop   => [{ p => 6,v => 'a'} ],
                                       default=> "00496nam  2200157 a 4500"},
                             group  =>{name=>'BOOKS', order =>1 , subOrder=>1 }           
                            },

         bookManuscript  => {leader =>{prop   => [{ p => 6,v => 't'} ],
                                       default=> "00496ntm  2200157 a 4500"},
                             group  =>{name=>'BOOKS', order =>1 , subOrder=>2 }
                            },

         ebook           => {leader =>{prop    => [{ p => 6,v => 'a'}],
                                       default => "00496nam  2200157 a 4500"},
                             '006'  =>{prop    => [{ p => 0,v => 'm'}],
                                       default => "m               "},            
                             '007'  =>{prop    => [{ p => 0,v => 'c'},{ p => 1,v => 'r'}],
                                       default => "cr      "},            
                             '008'  =>{prop    => [{ p => 23,v => 's'}],
                                       default => "960618s1973    xxu     s      000 0 eng d"},
                             group  =>{name=>'BOOKS', order =>1 , subOrder=>3 } 
                            },

          journal        => {leader =>{prop    => [{ p => 6,v => 'a'},{ p => 7,v => 's'} ],
                                       default => "00496nas  2200157 a 4500"},
                             group  =>{name=>'BOOKS', order =>1 , subOrder=>4 }
                            },

          serial         => {leader =>{prop    => [{ p => 6,v => 'a'},{ p => 7,v => 'b'} ],
                                       default => "00496nab  2200157 a 4500"},
                             group  =>{name=>'BOOKS', order =>1 , subOrder=>5 }
                            },

          electronicMedia  => {leader =>{prop    => [{ p => 6,v => 'm'} ],
                                         default => "00517nmm  2200157 a 4500"},
                               '007'  =>{prop    => [{ p => 0,v => 'c'}],
                                         default => "c      "},
                             group  =>{name=>'COMPUTER_FILES', order =>2 , subOrder=>1 }               
                               },

          internet     => {leader =>{prop    => [{ p => 6,v => 'm'} ],
                                     default => "00517nmm  2200157 a 4500"},
                           '008'  =>{prop    => [{ p => 26,v => 'j'}],
                                     default => "960618s1973    xxu    j      000 0 eng d"},
                             group  =>{name=>'COMPUTER_FILES', order =>2 , subOrder=>2 }                                   
                          },

         compactDisc    => {leader =>{prop     => [{ p => 6,v => 'm'} ],
                                      default  => "00517nmm  2200157 a 4500"},
                            '007'  => {prop    => [{ p => 0,v => 'c'},{ p => 1,v => 'o'}],
                                       default => "co     "}   ,
                             group  =>{name=>'COMPUTER_FILES', order =>2 , subOrder=>3 }            
                                       },
        'map'           => {leader =>{prop    => [{ p => 6,v => 'e'} ],
                                      default => "00503nem  2200157 a 4500"},
                            '007'  =>{prop    => [{ p => 0,v => 'a'}],
                                      default => "a      "},
                             group  =>{name=>'MAPS', order =>3 , subOrder=>1 }                           
                            },

        mapManuscript   => {leader =>{prop    => [{ p => 6,v => 'f'} ],
                                      default => "00503nfm  2200157 a 4500"},
                             group  =>{name=>'MAPS', order =>3 , subOrder=>2 }               
                            },
        bookOnTape      => {leader =>{prop    => [{ p => 6,v => 'i'} ],
                                      default => "00503nim  2200157 a 4500" },
                             group  =>{name=>'MUSIC', order =>4 , subOrder=>1 }               
                            },
        musicCassette   => {leader =>{prop    => [{ p => 6,v => 'j'} ],
                                      default => "00503njm  2200157 a 4500"},
                             group  =>{name=>'MUSIC', order =>4 , subOrder=>2 }               
                            },
        CDMusic         => {leader =>{prop    => [{ p => 6,v => 'j'} ],
                                      default => "00503njm  2200157 a 4500"},
                            '007'  =>{prop    => [{ p => 0,v => 's'},{ p => 1,v => 'd'}],
                                      default => "sd     "}  ,
                             group  =>{name=>'MUSIC', order =>4 , subOrder=>3 }              
                            },

        manuscriptMusic  => {leader =>{prop    => [{ p => 6,v => 'd'} ],
                                       default => "00503ndm  2200157 a 4500"},
                             group  =>{name=>'MUSIC', order =>4 , subOrder=>4 }               
                             },
        sheetMusic       => {leader =>{prop    => [{ p => 6,v => 'c'} ],
                                       default => "00503ncm  2200157 a 4500"},
                             group  =>{name=>'MUSIC', order =>4 , subOrder=>5 }               
                            },
        artifact         => {leader =>{prop    => [{ p => 6,v => 'r'} ],
                                       default => "00503nrm  2200157 a 4500"},
                             group  =>{name=>'VISUAL_MATERIALS', order =>5 , subOrder=> 5}               
                            },
        photoPoster      => {leader =>{prop    => [{ p => 6,v => 'k'} ],
                                       default => "00503nkm  2200157 a 4500"},
                             group  =>{name=>'VISUAL_MATERIALS', order =>5, subOrder=>6 }               
                            },
        movie            => {leader =>{prop    => [{ p => 6,v => 'g'} ],
                                       default => "00503ngm  2200157 a 4500"},
                             group  =>{name=>'VISUAL_MATERIALS', order =>5 , subOrder=>1}              
                             },
        videocassette    => {leader =>{prop    => [{ p => 6,v => 'g'}],
                                       default => "00503ngs  2200157 a 4500" },
                             '007'  =>{prop    => [{ p => 0,v => 'v'},{ p => 1,v => 'f'}],
                                       default => "vf     "},
                             group  =>{name=>'VISUAL_MATERIALS', order =>5, subOrder=> 2} 
                             },
        blu_ray          => {leader =>{prop    => [{ p => 6,v => 'g'}],
                                       default => "00503ngs  2200157 a 4500" },
                             '007'  =>{prop    => [{ p => 0,v => 'v'},{ p => 1,v => 'd'},{p=>4,v=>'s'}],
                                       default => "vd  s  "},
                             group  =>{name=>'VISUAL_MATERIALS', order =>5 , subOrder=> 3} 
                             },
        DVD              => {leader =>{prop    => [{ p => 6,v => 'g'}],
                                       default => "00503ngs  2200157 a 4500" },
                             '007'  =>{prop    => [{ p => 0,v => 'v'},{ p => 1,v => 'd'},{p=>4,v=>'v'}],
                                       default => "vd  v  "},
                             group  =>{name=>'VISUAL_MATERIALS', order =>5 , subOrder=> 4} 
                             },
        libraryKit       => {leader =>{prop    => [{ p => 6,v => 'o'} ],
                                       default => "00503nom  2200157 a 4500"} ,
                             group  =>{name=>'VISUAL_MATERIALS', order =>5 , subOrder=> 7}              
                             },
        mixedMaterial    => {leader =>{prop    => [{ p => 6,v => 'p'} ],
                                       default => "00503npm  2200157 a 4500" } ,
                             group  =>{name=>'MIXED_MATERIALS', order => 6, subOrder=> 1}              
                             }
                                       
};
$langCodeMap={
    aar=>"Afar",
    abk=>"Abkhazian",
    afr=>"Afrikaans",
    alb=>"Albanian",
    sqi=>"Albanian",
    amh=>"Amharic",
    ara=>"Arabic",
    arg=>"Aragonese",
    arm=>"Armenian",
    hye=>"Armenian",
    asm=>"Assamese",
    ave=>"Avestan",
    aym=>"Aymara",
    aze=>"Azerbaijani",
    bak=>"Bashkir",
    baq=>"Basque",
    eus=>"Basque",
    bel=>"Belarusian",
    ben=>"Bengali",
    bih=>"Bihari",
    bis=>"Bislama",
    bos=>"Bosnian",
    bre=>"Breton",
    bul=>"Bulgarian",
    bur=>"Burmese",
    mya=>"Burmese",
    cat=>"Catalan",
    cha=>"Chamorro",
    che=>"Chechen",
    chi=>"Chinese",
    zho=>"Chinese",
    chv=>"Chuvash",
    cor=>"Cornish",
    cos=>"Corsican",
    cze=>"Czech",
    ces=>"Czech",
    dan=>"Danish",
    div=>"Divehi",
    dut=>"Dutch",
    nld=>"Dutch",
    dzo=>"Dzongkha",
    eng=>"English",
    epo=>"Esperanto",
    est=>"Estonian",
    fao=>"Faroese",
    fij=>"Fijian",
    fin=>"Finnish",
    fre=>"French",
    fra=>"French",
    fry=>"Western Frisian",
    geo=>"Georgian",
    kat=>"Georgian",
    ger=>"German",
    deu=>"German",
    gla=>"Gaelic",
    gle=>"Irish",
    glg=>"Galician",
    glv=>"Manx",
    gre=>"Greek",
    ell=>"Greek",
    grn=>"Guarani",
    guj=>"Gujarati",
    hat=>"Haitian",
    hau=>"Hausa",
    heb=>"Hebrew",
    her=>"Herero",
    hin=>"Hindi",
    hmo=>"Hiri Motu",
    hun=>"Hungarian",
    ice=>"Icelandic",
    isl=>"Icelandic",
    ido=>"Ido",
    iii=>"Sichuan Yi",
    iku=>"Inuktitut",
    ile=>"Interlingue",
    ina=>"Interlingua",
    ind=>"Indonesian",
    ipk=>"Inupiaq",
    ita=>"Italian",
    jav=>"Javanese",
    jpn=>"Japanese",
    kal=>"Kalaallisut",
    kan=>"Kannada",
    kas=>"Kashmiri",
    kaz=>"Kazakh",
    khm=>"Khmer",
    kik=>"Kikuyu",
    kin=>"Kinyarwanda",
    kir=>"Kirghiz",
    kom=>"Komi",
    kor=>"Korean",
    kua=>"Kuanyama",
    kur=>"Kurdish",
    lao=>"Lao",
    lat=>"Latin",
    lav=>"Latvian",
    lim=>"Limburgan",
    lin=>"Lingala",
    lit=>"Lithuanian",
    ltz=>"Luxembourgish",
    mac=>"Macedonian",
    mkd=>"Macedonian",
    mah=>"Marshallese",
    mal=>"Malayalam",
    mao=>"Maori",
    mri=>"Maori",
    mar=>"Marathi",
    may=>"Malay",
    msa=>"Malay",
    mlg=>"Malagasy",
    mlt=>"Maltese",
    mol=>"Moldavian",
    mon=>"Mongolian",
    nau=>"Nauru",
    nav=>"Navaho, Navajo",
    nbl=>"Ndebele, South",
    nde=>"Ndebele, North",
    ndo=>"Ndonga",
    nep=>"Nepali",
    nno=>"Norwegian Nynorsk",
    nob=>"Norwegian Bokmal",
    nor=>"Norwegian",
    nya=>"Nyanja",
    oci=>"Occitan",
    ori=>"Oriya",
    orm=>"Oromo",
    oss=>"Ossetian",
    pan=>"Panjabi",
    per=>"Persian",
    fas=>"Persian",
    pli=>"Pali",
    pol=>"Polish",
    por=>"Portuguese",
    pus=>"Pushto",
    que=>"Quechua",
    roh=>"Raeto-Romance",
    rum=>"Romanian",
    ron=>"Romanian",
    run=>"Rundi",
    rus=>"Russian",
    sag=>"Sango",
    san=>"Sanskrit",
    scc=>"Serbian",
    srp=>"Serbian",
    scr=>"Croatian",
    hrv=>"Croatian",
    sin=>"Sinhala",
    slo=>"Slovak",
    slk=>"Slovak",
    slv=>"Slovenian",
    sme=>"Northern Sami",
    smo=>"Samoan",
    sna=>"Shona",
    snd=>"Sindhi",
    som=>"Somali",
    sot=>"Sotho,Southern",
    spa=>"Spanish",
    srd=>"Sardinian",
    ssw=>"Swati",
    sun=>"Sundanese",
    swa=>"Swahili",
    swe=>"Swedish",
    tah=>"Tahitian",
    tam=>"Tamil",
    tat=>"Tatar",
    tel=>"Telugu",
    tgk=>"Tajik",
    tgl=>"Tagalog",
    tha=>"Thai",
    tib=>"Tibetan",
    bod=>"Tibetan",
    tir=>"Tigrinya",
    ton=>"Tonga",
    tsn=>"Tswana",
    tso=>"Tsonga",
    tuk=>"Turkmen",
    tur=>"Turkish",
    twi=>"Twi",
    uig=>"Uighur",
    ukr=>"Ukrainian",
    urd=>"Urdu",
    uzb=>"Uzbek",
    vie=>"Vietnamese",
    vol=>"Volapuk",
    wel=>"Welsh",
    cym=>"Welsh",
    wln=>"Walloon",
    wol=>"Wolof",
    xho=>"Xhosa",
    yid=>"Yiddish",
    yor=>"Yoruba",
    zha=>"Zhuang; Chuang",
    zul=>"Zulu"
 }
