package Opals::Marc::Record;

require Exporter;
@ISA       = qw(Exporter);
# Symbols to be exported by default
#@EXPORT    = qw(
#    opl_
#);
# Symbols to be exported on request
@EXPORT_OK = qw(
    
);
# Version number
$VERSION   = 0.01;      

#use utf8;
use strict;
use MARC::Record;

use Opals::Utility qw(
    util_restoreLiteral
);
#    util_html_to_char

sub newFromXml {
    my ($xml) = @_;

    # remove empty subfields
    $xml =~ s/<(control|data|sub)field[^<]*\/>/\n/g;

#    $xml = util_html_to_char($xml);
    my $record = MARC::Record->new();

    my ($tag, $ind1, $ind2, $sfCode, $data);

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

    # Extract control field
    while ($xml =~ s/[\s]*<controlfield tag="(00[\d])">(.*)<\/controlfield>//) {
        $tag  = $1;
        $data = util_restoreLiteral($2);
        $record->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);
            }
        }

        $record->insert_fields_ordered($field) if $field;
        #$record->append_fields($field) if $field;
    }

    return $record;
}


=item
Reference:
www.oclc.org/support/documentation/worldcat/tb/253/default.htm
=cut
sub convert_OCoLC_number {
    my ($marc, $source) = @_;

    $marc = convert_OCoLC_number_from_001($marc, $source);
    $marc = normalize_OCoLC_number_in_035a($marc, $source);

    return $marc;
}


sub convert_OCoLC_number_from_001 {
    my ($marc, $source) = @_;

    my $f001 = $marc->field('001') || return $marc;
    my $f001_data = $f001->data();

    my $OCoLC_num;
    if ($source eq 'OCoLC') {
        $OCoLC_num = extract_OCoLC_number($f001_data);
    }
    else {
        if ($f001_data =~ m/ocl7([\d]{7}) /) {
            $OCoLC_num = $1;
            $OCoLC_num =~ s/^0+//;
        }
        elsif ($f001_data =~ m/ocm([\d]{8}) /) {
            $OCoLC_num = $1;
            $OCoLC_num =~ s/^0+//;
        }
        elsif ($f001_data =~ m/ocn([1-9][\d]{8,})/) {
            $OCoLC_num = $1;
        }
        else {
            my $f003 = $marc->field('003');

            if ($f003 && $f003->data() =~ m/OCoLC/i) {
                $OCoLC_num = extract_OCoLC_number($f001_data);
            }
        }
    }

    $marc = delete_fields($marc, '001');
    $marc = delete_fields($marc, '003');

    if ($OCoLC_num) {
        my @f035 = (MARC::Field->new(
            '035', 
            ' ', ' ', 
            'a' => '(OCoLC)' . $OCoLC_num)
        );

        $marc->insert_fields_ordered(@f035);
    }

    return $marc;
}


sub normalize_OCoLC_number_in_035a {
    my ($marc, $source) = @_;

    #my $f003 = $marc->field('003');
    if ($source ne 'OCoLC') {# && (!$f003 || $f003->data() !~ m/OCoLC/i)) {
        return $marc;
    }

    my $OCoLC_num;
    foreach my $f035 ($marc->field('035')) {
        $OCoLC_num = extract_OCoLC_number($f035->subfield('a'));
        $f035->update(a => '(OCoLC)' . $OCoLC_num);
    }

    return $marc;
}

=item
$str is a string that stores valid or invalid OCoLC number
=cut
sub extract_OCoLC_number {
    my ($str) = @_;

    return unless $str;

    my $OCoLC_num;
    if ($str =~ m/([\d]+)/) {
        $OCoLC_num = $1;
        $OCoLC_num =~ s/^0+//;
    }

    return $OCoLC_num;
}


sub delete_fields {
    my ($marc, $tag) = @_;

    my @fields = $marc->field($tag);
    $marc->delete_fields(@fields);
#    foreach my $f (@fields) {
#        $marc->delete_field($f);
#    }

    return $marc;
}


1;
