package ReDIF::Record;

##   This package, this module is not usable yet, and ReDIF::Parser
##   doesn't use it yet, but we have to think about the future and
##   that is why this module is here now.  Please share your ideas
##   about how ReDIF template should be stored and returned from the
##   parser.  Would logical template access be useful?  Send your
##   ideas to kurmanov@openlib.org.

##  Copyright (c) 1997-2001 Ivan Kurmanov. All rights reserved.
##
##  This code is free software; you can redistribute it and/or modify it
##  under the same terms as Perl itself.

$VERSION = "0.1";

=head1 NAME 

ReDIF::Record  -- a future class to store ReDIF templates 

=head1 SYNOPSIS

    use ReDIF::Record;


    ###  record creation and fill-up

    my $template = ReDIF::Record -> new( '-type', 'ReDIF-Person 1.0' );

    $template -> add_property( "title",  "The Paper" );
    $template -> add_property( "handle", "RePEc:wop:aarhec:94-01" );

    $template -> set_scalar_property( "SPECIAL", { data=>"structure" }  );

    $template -> add_root_property( "title", "The Paper" );
    $template -> set_root_scalar_property( "VERYSPECIAL", 
					   { moredata => "morestructure" }  );


    $template -> open_structured_property( "author", "person cluster" );
    $template -> close_structured_property( );




    my $t_hash = $template -> as_hash();


    ###  record reading  (not implemented yet)

    my $values = $template -> get_property( "title" );
    my @values = $template -> get_property_values( "title" );
    my $the_title = $template -> get_property_value( "title", 0 );



    $template -> open( "/author[0]" );       ###  XPath-like expr
    $template -> open( "author", 1, "name" );   ###  same, but in particles
    $template -> close( );    ###  return one level upper

    $template -> get( "/author[1]/name" );  ###  return name of the 2nd author

    $template -> open( "/author[0]" );  ###  open the 1st author
    my @personal_info = 
          $template -> get_multi( "name", "email", 
				  "postal", "homepage", "phone", "fax" );



    $template -> open( "/" );

    my $path = $template -> get_current_path();

=cut
    
    
use strict;


sub new {
    my $class = shift;

    my %args = @_;

    my $obj = {};
    
    if( exists $args{'-type'} ) {
	$obj->{_TYPE_} = $args{'-type'};
    }

    $obj->{_CURRENT_} = $obj;

    bless $obj, $class;
}



sub add_property {
    my $self = shift;
    my $property = shift;
    my $value = shift;

    $self = $self->{_CURRENT_};
    
    if( defined $self->{$property} ) {
	my $array = $self->{$property};
	push @$array, $value;
	return scalar @$array;

    } else {
	$self->{$property} = [ $value ];
	return 1;
    }
}



sub set_scalar_property {
    my $self = shift;
    my $property = shift;
    my $value = shift;

    $self = $self->{_CURRENT_};
    
    $self->{$property} = $value;
    return 1;
}


sub open_structured_property {
    my $self = shift;
    my $property = shift;
    my $type = shift;

    my $value = {};
    
    my $str = $self->{_CURRENT_};
    
    if( defined $str->{$property} ) {
	my $array = $str->{$property};
	push @$array, $value;

    } else {
	$str->{$property} = [ $value ];
    }
    
    my $stack = $self->{_OPENED_STRUCTURED_};
    if( not defined $stack ) {
	$stack = $self->{_OPENED_STRUCTURED_} = [];
    }
    
    push @$stack, $self->{_CURRENT_};
    $self->{_CURRENT_} = $value;

}

sub close_structured_property {
    my $self = shift;

    my $stack = $self->{_OPENED_STRUCTURED_};
    if( not defined $stack or not ( ref( $stack ) eq 'ARRAY' ) ) {
	return undef;
    }
    
    $self->{_CURRENT_} = pop @$stack;
    return 1;

}


sub as_hash { 
    my $self = shift;

    return $self;
}

    1;

