package Pica::Record;

use strict;
use warnings;

use Data::Dumper;

our $SF = chr(131);

# Constructor, Aufruf ohne weitere Parameter
sub new
{
  	my $class    = shift;
  	my $classref = ref($class) || $class;
  	my $self = {};
  	bless $self,$classref;

  	$self->{'fields'} = [];
  	$self->{'parents'} = [];
  	$self->{'type'} = undef;
  	$self->{'id'} = undef;

  	return $self;
}

# Einlesen von mehreren Feldern auf einmal 
# (wenn das Objekt nich über Pica::Records erzeugt wird)
sub read_fields
{
	my $self = shift;
	my $string = shift;
	my @lines = split(/\n/,$string);
	foreach my $line (@lines)
	{
		$self->add_field($line);
	}
	return 1;
}

# Erzeugt eine Feldstruktur bestehend aus den Elementen 'tag', 'occurrence' und 'subfields'
# 'subfields' ist eine Liste bestehend aus Referenzen auf jeweils eine Struktur bestehend aus 'code' und 'content'
# die Reihenfolge ist hierbei wichtig
sub add_field
{
	my $self = shift;
	my $string = shift;
	my $field = {};
	$field->{'tag'} = substr($string,0,4);
	$field->{'occurrence'} = substr($string,5,2) if (substr($string,4,1) eq "/");
	$field->{'subfields'} = [];
	my @subfields = split(/$SF/,substr($string,index($string,' ')+1));
	foreach my $subfield (@subfields)
	{
		if ($subfield ne '')
		{
			my $sfield = {};
			   $sfield->{'code'} = substr($subfield,0,1);
			   $sfield->{'content'} = substr($subfield,1);
			   push @{$field->{'subfields'}},$sfield;
		}
	}
	push @{$self->{'fields'}},$field;
	$self->type(substr($field->{'subfields'}->[0]->{'content'},1,1)) if ($field->{'tag'} eq '002@');
	return 1;
	
}

# Feld 4070 in As/Os-Saetzen wird ausgewertet und die fuer die Sortierung notwendigen Werte
# werden in den entsprechenden properties gespeichert.
sub add_position
{
	my $self = shift;
	my $field = shift || die "Method call without mandatory argument (Field 031A)";
	$field = substr($field,5);
	my @parts = split(/$SF/,$field);
	foreach my $subfield (@parts)
	{
		my $code = substr($subfield,0,1);
		if ($code eq 'd')
		{
			$self->{'volume'} = substr($subfield,1);
		}
		elsif ($code eq	'j')
		{
			$self->{'year'} = substr($subfield,1);
		}
		elsif ($code eq	'e')
		{
			$self->{'issue'} = substr($subfield,1);
		}
		elsif ($code eq	'b')
		{
			$self->{'day'} = substr($subfield,1);
		}
		elsif ($code eq	'c')
		{
			$self->{'month'} = substr($subfield,1);
		}
		elsif ($code eq	'g')
		{
			$self->{'pages'} = substr($subfield,1);
		}
		elsif ($code eq	'f')
		{
			$self->{'special_issue'} = substr($subfield,1);
		}
		elsif ($code eq	'h')
		{
			my @pages = split(/-/,substr($subfield,1)); 
			$self->{'start_page'} = $pages[0];
			$self->{'end_page'} = $pages[1];
		}
	}
	return 1;
}

# Start und Endseiten
# Getter und Setter
sub start_page
{
	my $self = shift;
	my $page = shift || undef;
	$self->{'start_page'} = $page if ($page);
	return $self->{'start_page'};
}

sub end_page
{
	my $self = shift;
	my $page = shift || undef;
	$self->{'end_page'} = $page if ($page);
	return $self->{'end_page'};
}

sub hierarchy_level
{
	my $self = shift;
	my $level = shift || undef;
	$self->{'hierarchy_level'} = $level if ($level);
	return $self->{'hierarchy_level'};
}

sub pointer
{
	my $self = shift;
	my $url = shift || undef;
	$self->{'pointer'} = $url if ($url);
	return $self->{'pointer'};
	
}
# Datensatztyp (2. Position Feld 0500)
# Getter und Setter
sub type
{
	my $self = shift;
	my $type = shift || undef;
	$self->{'type'} = $type if ($type);
	return $self->{'type'};
}

# Primaerschluessel (PPN)
# Getter und Setter
sub id
{
	my $self = shift;
	my $id = shift || undef;
	$self->{'id'} = $id if ($id);
	return $self->{'id'};	
}

# Liste der uebergeordneten Saetze
# Getter und Setter
sub add_parent
{
	my $self = shift;
	my $parent = shift || undef;
	push @{$self->{'parents'}},$parent if ($parent);
	return $self->{'parents'};
}

# Alias fuer add_parent als Getter Methode
sub parents
{
	my $self = shift;
	return $self->add_parent;
}

# Gibt wahr zurueck wenn der Datensatz dem angebenen untergeordnet ist
# tatsaechlich gibt es die Anzahl der Vorkommen zurueck, es sollten aber in $self->{'parents'}
# keine dubletten Werte sein.
sub child_of
{
	my $self = shift;
	my $hostitem = shift || undef;
	my $flag = 0;
	if ($hostitem)
	{
		my $hostitem_test = '^'.$hostitem.'$';
		$flag = grep /$hostitem_test/, @{$self->{'parents'}};
	}
	return $flag;
}

# uebergeben wird ein Objekt
sub add_child
{
	my $self = shift;
	my $object = shift || undef;
	push @{$self->{'children'}},$object;
	return 1;
}

# sortieren der abhaengigen Datensaetze nach der Reihenfolge in der Vorlage
sub sort_children
{
	my $self = shift;
	if (ref($self->{'children'}) eq 'ARRAY')
	{
		@{$self->{'children'}} = sort {$a->{'start_page'} <=> $b->{'start_page'}} @{$self->{'children'}};
	}
	return 1;
}

# gibt eine Referenz auf das Array der abhaengigen Datensaetze zurueck
sub children
{
	my $self = shift;
	return $self->{'children'};
}

# Rueckgabewert soll ein Objekt sein
sub hostitem
{
	my $self = shift;
	my $hostitem = shift || undef;
	$self->{'hostitem'} = $hostitem if ($hostitem);
	return $self->{'hostitem'};
}

# Die Ausgabemethode fuer Template Toolkit
# Es wird eine Liste (Arrayref) von Listen (Arrayref) zurueckgegben
# SYNTAX
# r.subfields('Feldbezeichner', 'Unterfeldbezeichner', 'Occurrence')
# Fuer jedes Feld wird ein Array mit Unterfeldinhalten zurueckgegeben
# BEISPIEL
# r.subfields('021A','a').item(0).item(0) 
# gibt den Inhalt des ersten Unterfelds $a im ersten Feld 021A zurueck
sub subfields
{
	my $self = shift;
	my $tag = shift;
	my $deid = shift;
	my $occ = shift || undef;
	my @result_fields = ();
	
	foreach my $field (@{$self->{'fields'}})
	{
		if (($tag eq $field->{'tag'})&&(!$occ || ($occ eq $field->{'occurrence'})))
		{
			my @result_subfields = ();
			foreach my $subfield (@{$field->{'subfields'}})
			{
				if ($deid eq $subfield->{'code'})
				{
					push @result_subfields, $subfield->{'content'};
				}
			}
			push @result_fields, \@result_subfields;
		}
	}
	
	return \@result_fields;
}

# gibt ein Array von Feldern als hashrefs zurueck
sub fieldgroup
{
	my $self = shift;
	my $tags = shift;
	my @result_fields = ();
	foreach my $tag (@{$tags})
	{
		foreach my $field (@{$self->{'fields'}})
		{
			if ($tag eq $field->{'tag'})
			{
				push @result_fields,$field;				
			}
			
		}
	}
	
	return \@result_fields;
}

sub in_field
{
	my $self = shift;
	my $field = shift;
	my $subfield = shift;
	my $position = shift || 1;

	
	my $counter = 0;
	my $result = undef;
	
	foreach my $sf (@{$field->{'subfields'}})
	{
		if ($subfield eq $sf->{'code'})
		{
			$counter++;
			$result = $sf->{'content'} if ($counter == $position);
		}
	}
	
	return $result;
}

# gibt den vollstaendigen Datensatz in PICA+ zurueck
sub print_record
{
  my $self = shift;
  my $params = shift;
  my $output = '';
  foreach my $field (@{$self->{'fields'}})
  {
    $output .= $field->{'tag'};
    $output .= $field->{'occurrence'};
    $output .= ' ';
    foreach my $subfield (@{$field->{'subfields'}})
    {
      my $content = $subfield->{'content'};
         $content = _xml($content) if ($params->{'xml'} == 1);
      $output .= $SF.$subfield->{'code'}.$content;
    }
    $output .= "\n";
  }
  return $output;
}

sub _xml
{
  my $text = shift;
  $text =~ s/&/&amp;/g;
  $text =~ s/</&lt;/g;
  $text =~ s/>/&gt;/g;
  return $text;
}
1;