package rr;

BEGIN { 
$VERSION = '2.18'; 
}

##  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.


=head1 NAME

rr.pm - perl module for reading ReDIF data (obsolete now, see ReDIF::Parser)

=head1 SYNOPSIS

    use rr;

    rr::OpenRDF( $filename ) 
         or die "can't open file $filename";

    $t_ok = rr::NextTemplate();

    rr::OpenDir( $ReDIF_data_dir, $ReDIF_home ) 
         or die "can't open directory $ReDIF_data_dir for reading data files";

    rr::OpenDirTree ( $ReDIF_data_dir, $ReDIF_home ) ;

=head1 DESCRIPTION

  This module is part of ReDIF perl suite for processing (parsing) 
  ReDIF data files. 

  It is a high-level interface to the ReDIF parser, grown out of rech.

=head1 SEE ALSO

  Please look for documentation in doc/ dir of the distribution.

  For more information about ReDIF and RePEc, see
  http://www.repec.org/ 

  also: 
  http://netec.mcc.ac.uk/RePEc/ and http://netec.mcc.ac.uk/RePEc/ReDIF/

  And checkout http://openlib.org/ (under construction, expected). 

=head1 AUTHORS

Ivan Kurmanov, kurmanov(at)openlib(dot)org

=cut

BEGIN {

require Exporter;

@ISA = qw( Exporter );
@EXPORT_OK = qw( OpenRDF NextHashRDF OpenDir OpenDirTree NextTemplate 
                 $RedifDir $RedifRemo $Archive $Authority $Address
                 $RemoNotFound $Redif_Data_Dir
);

}

# FindRDFHash ReadRDFHash
###########################################################################
# Why not insert 'use' statements here.

use ReDIF::init;

use vars qw( $spec_o );

BEGIN {
    if (defined $ReDIF::init_verbose) {
         ReDIF::initialize( {'print_results' => 1 } );
#         print "ReDIF-init: internal revision $VERSION\n"; 
    } else {
         ReDIF::initialize( );
    }

    require ReDIF::Parser::Core
	or ( print( "Can't load libs (modules). No way to go." ) 
	     and die );
    ReDIF::Parser::Core -> import();
    
    # specification
    
    use ReDIF::Spec ();

    my $spec_file = $ReDIF::CONFIG{spec_full_name} ;

    $spec_o = ReDIF::Spec -> new( $spec_file );

   $RedifDir = $ReDIF::CONFIG{redif_home}; 
   if(
      defined ( $ReDIF::CONFIG{redif_home_type} )
      and ( $ReDIF::CONFIG{redif_home_type} eq 'RePEc' ) 
      ) {
         if ( $RedifDir =~ /(.*)\/(\w{3})\/?$/i ) {
            my $arc = $2;
            my $main = $1 ;
            $RedifRemo = $main . '/remo' ;
         }
         if ( not (-e $RedifRemo and -d _) ) {
             $RemoNotFound = 1;
             warn "Cannot find correct ReDIF-remo (remote) directory: " . 
                  "$RedifRemo ?\n";
         } else {
             $RemoNotFound = 0;
         }
   } else {
         $RedifRemo = '';
   }
   $Redif_Data_Dir = $ReDIF::CONFIG{data_path};

   $Archive =   $ReDIF::CONFIG{archive_id};
   $Authority = $ReDIF::CONFIG{authority_id};
   $Address =   $ReDIF::CONFIG{address};

}

sub import {

    my $fix;
    for( my $i = 1; $#_ >= $i; $i++ ) {
	if( $_[$i] eq 'BUG_FIX' ) {
	    $fix = 1;
	    splice @_, $i, 1;
	}
    }

    'rr'->export_to_level( 1, @_ );

    if ( $fix or $::RR_BUG_FIX) { 
	&ReDIF::Parser::Core::multiple_values_bug_fix();
	$rr::BUG_FIXED = 1;
    }
}


# Standard Library

use File::Find;

# other libraries
# Own-written

# use ReDIF::messages;
# use ReDIF::ReadRedif;


%Options = (
	    'HashT' => 1,
	    'quote_source' => 0,
	    'build_template_hash' => 1,
	    'x_attributes' => 0,
	    'rech_mode' => 0,
	    'message_threshold' => 2,
	    'use_parser_input' => 1,
	    'remove_newline_from_values' => 1,
);


$Options{redif_specification} = $spec_o;

ReDIF::Parser::Core::init( \%Options ) 
    || die "'Parser::Core' module initialization failed";

###########################################################################
# Basic functions #
###########################################################################

sub set_options {
    my %opts = @_;
    foreach my $k ( keys %opts ) {
	my $v = $opts{$k};
	$Options{$k} = $v;
    }
  ReDIF::Parser::Core::init( \%Options ) 
      || die "'Parser::Core' module initialization failed";
} 


use ReDIF::Parser::Input;

sub OpenRDF {

  my ($file, $pos, $showname) = @_;

  if ($pos) {
      if ( not ReDIF::Parser::Input::start_file ( $file, $pos ) ) {
          return 0;
      }
  } else {
      if ( not ReDIF::Parser::Input::start_file ( $file, $pos ) ) {
          return 0;
      }
  }
  if ( defined $showname ) {$file = $showname;}

  $fileopen = 1;
  ReDIF::Parser::Core::starting_new_file( $file );

  return 1;
}


sub NextHashRDF {

   return 0 if not $fileopen;

   my @data;
   my $R = 1;

   while( $R ) {
       warn "getting next attribute"
	   if $DEBUG;
       $R = &ReDIF::Parser::Input::extract_next_attribute();

       if( not $R ) {
	   undef $fileopen;
	   last;
       }

       if( ReDIF::Parser::Core::get_current_template_status() eq 'good' ) { 
	   return 1; 
       }
   }

   $fileopen = 0;
   return 0;
}


##########################################################################
# Further interface #
##########################################################################

sub OpenDir {

  ( $dir, $ShowPrefix, $FilterSub, my $sort_flag ) = @_;

  @FileList = ();
  %Statistics = ();
  $Statistics{'start-time'} = time;

  opendir ( DIR , $dir );
  if ($dir !~ /[\\\/]$/) { $dir .= "\/"; }

  my ( $c, $f, $a );
  $c = 0;
  while ( defined ( $f = readdir DIR ) )
  {
      $a++;
      next unless $f =~ /\.rdf$/i;     # filtering out non-ReDIF files
      my $fname = "$dir$f";             # making full name
      next unless -f $fname && -e _;   # a check
      push @FileList, $f;         # saving a name in a list
      $c ++;                        # control counter
  }
  if ( $sort_flag ) { @FileList = sort @FileList; }
  closedir DIR;

  $Statistics{'all-files'}=$a;
  $Statistics{'rdf-files'}=$c;

  $FILE = 0;
  if ( not $c ) {
     $MODE = '';
     return 0;
  } else {
     $MODE = 'dir';
     $ListPrefix = $dir;
     return $c;
  }
}


sub OpenDirTree {

  ( $dir, $ShowPrefix, $FilterSub , my $sort_flag ) = @_;

  @FileList = ();
  %Statistics = ();
  $Statistics{'start-time'} = time;

  $DirPrefix = length ($dir);

  find ( \&RdfFound, "$dir" );
  if ( $sort_flag ) { @FileList = sort @FileList; }

  $Statistics{'all-files'}=$a;
  $Statistics{'rdf-files'}=$c;

  $FILE = 0;
  if (not $c) {
     $MODE = '';
     return 0;
  } else {
     $MODE = 'tree';
     $ListPrefix = '';
     return $c;
  }
}


sub nextfile {

  # for efficiency this is better
  # to include without a separate function call

    return undef if $#FileList < 0;
    return ( $ListPrefix . (shift @FileList) );

}


sub NextTemplate {

    if (not $MODE) {
        return NextHashRDF();
    }
    my ($OK, $f) ;
    while (not $OK) {
        while (not $FILE) {
           $f = nextfile();
           $MODE = '' if not $f;
           return 0 if not $f;
	   my $sh_name = $f;
	   if( defined $ShowPrefix ) { $sh_name = substr ($f, $ShowPrefix); }
           $FILE = OpenRDF ( $f, 0, $sh_name );
        }
        $OK = NextHashRDF();
        if (not $OK) { $FILE = undef; }
        else {
           $Statistics{'t-read-good'}++;
           if ( $FilterSub ) {
              $OK = &$FilterSub ();
              $Statistics{'t-read-filter'}++;
           }
        }
    }
    $Statistics{'t-read-ok'}++;
    return 1;
}


sub SetFilter {
    $FilterSub = shift;
}


sub CloseRDF {
    ReadRedif::finishfile();
}


#####################################################################
## RdfFound
#

sub RdfFound {

   $a ++;
   return unless /\.rdf$/i;     # filtering out non-ReDIF files
   my $fname = $File::Find::name;             # making full name
   return unless -f $fname && -e _;       # a check

   push @FileList, $fname ;        # saving a name in a list
   $c ++;                        # control counter

}


#############################################################
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#############################################################


1;


__END__
