=pod

=head1 NAME

Pedigree::Parser - parser for the input file

=head1 SYNOPSIS

use Pedigree::Parser;

$parser = new Pedigree::Parser(I{$inputline>, I<$lang>)

$parser->Parse($inputline);


=head1 DESCRIPTION

This package parses input for the pedigree library and is used to
define nodes.


=cut

####################################################################
# Define the package                                               #
####################################################################

package Pedigree::Parser;
use strict;

####################################################################
#    package variables                                             #
####################################################################

#
# %fields_to_convert:  the hash of fields that contain limited 
# number of values and the default value for such field
#

my %fields_to_convert = (
        'Sex'=>'unknown', 
        'Proband'=>0,
        'Condition'=>'normal',
        'Type' => ''
);


####################################################################
# And package methods                                              #
####################################################################

####################################################################
#    new                                                           #
####################################################################

=pod

=over 4

=item B<new>(I<$inputline>, I<$lang>);

Construct a new parser from the pipe-separated line at input

=cut

sub new {
    my ($class,$inputline,$lang)=@_;
    my $self={};

    #
    # The hash $self->{fields} is the main stored data structure.  
    # The key is the field, the value is the number of the field 
    # in the input lines. 
    #
    my %fieldnames=%{$lang->GetFieldNames()};
    chomp $inputline;
    $inputline =~ s/^\s+//;
    $inputline =~ s/\s+$//;
    my @input = split /\s*\|\s*/, $inputline;
    for (my $i=0;  $i<scalar @input; $i++) {
	my $name=$input[$i];
	if (exists $fieldnames{$name}) {
	    my $field=$fieldnames{$name};
	    $self->{fields}->{$field}=$i;
	} else {
	    print STDERR "Warning:  unknown field $name\n";
	}
    }

    if ($main::DEBUG) {
	print STDERR "Field names:\n";
	foreach my $key (keys %fieldnames) {
	    my $field=$fieldnames{$key};
	    my $pos=$self->{fields}->{$field};
	    print STDERR "\t$key\t$field\t$pos\n";
	}
    }

    #
    # The hash $self->{values} contains values for  fields
    # with closed sets of values.
    #
    my %values=%{$lang->GetValues()};
    $self->{values}=\%values;

    if ($main::DEBUG) {
	print STDERR "Field values:\n";
	foreach my $key (keys %values) {
	    my $value=$values{$key};
	    print STDERR "\t$key\t$value\n";
	}
    }


    #
    # The hash $self->{special_names} contains special values
    # for the 'Name' field
    #
    my %special=%{$lang->GetSpecialNames()};
    $self->{'special_names'}=\%special;

    if ($main::DEBUG) {
	print STDERR "Special names:\n";
	foreach my $key (keys %special) {
	    my $value=$special{$key};
	    print STDERR "\t$key\t$value\n";
	}
    }

    if ($main::DEBUG) {
	print STDERR "Special fields:\n";
	foreach my $key (keys %fields_to_convert) {
	    my $value=$fields_to_convert{$key};
	    print STDERR "\t$key\t$value\n";
	}
    }

    bless ($self,$class);
    return $self;
}


####################################################################
#    Parse                                                         #
####################################################################

=pod

=item B<Parse>(I<$inputline>);

Take a line of comma-separated values;  return a reference to a 
hash of parsed values

=cut

sub Parse  {
    my ($self,$inputline)=@_;
    chomp $inputline;
    $inputline =~ s/^\s+//;
    $inputline =~ s/\s+$//;
    my @input = split /\s*\|\s*/, $inputline;
    if ($main::DEBUG) {
	print STDERR "Parsing line:$inputline\n";
    }

    my %result;

    foreach my $field (keys %{$self->{fields}})  {
	my $i=$self->{fields}->{$field};
	my $value=$input[$i];
	#
	# Special fields...
	#
	if (exists $self->{values}->{$value}) {
	    $value=$self->{values}->{$value};
	}
	if (exists $fields_to_convert{$field}) {
	    if (length($value) == 0 ) {
		$value=$fields_to_convert{$field};
	    }
	}
	#
	#  Dropping empty fields
	#
	if (length($value) == 0 ) {
	    next;
	}

	#
	# Converting Name field
	#
	if (($field eq 'Name') && ($value =~ /^\#/)) {
	    foreach my $regexp (keys %{$self->{'special_names'}}) {
		my $name=$self->{'special_names'}->{$regexp};
		$value =~ s/^(\#$regexp.*)/\#$name/i;
	    }
	}

	#
	# And finishing
	#
	$result{$field}=$value;
	if ($main::DEBUG) {
	    print STDERR "\t$field\t$value\n";
	}
    }

    return \%result;

}

####################################################################
#    THE END                                                       #
####################################################################

=pod

=back

=head1 ENVIRONMENT

The calling program should define B<$main::DEBUG> and set it to 0
or 1.

=head1 SEE ALSO

pedigree(1), Pedigree(3)

=head1  AUTHOR

Boris Veytsman, Leila Akhmadeeva, 2006, 2007



=cut

1;

