package Biblio::Doc;
use strict;
use vars('$AUTOLOAD');

# Separate intitialization from construction

{
  my $_count = 0;
  sub get_count { $_count }
  sub _incr_count { $_count++ }
  sub _decr_count { $_count-- }
}

{
  my %_defaults = (             #   Default   Access 
                    _identifier => ["unknown",'read'],
                    _author     => ["unknown",'read/write'],
                    _publisher  => ["unknown",'read'],
                    _title      => ["unknown",'read'],
                    _year       => ["unknown",'read'],
                    _url        => ["unknown",'read/write']
                  );

  sub _standard_keys {
    return keys %_defaults;
  }

  sub _default_for {
    my ($self, $attr) = @_;
    
    return $_defaults{$attr}[0];
  }

  sub _accesible {
    my ($self, $attr, $access) = @_;
    return $_defaults{$attr}[1] =~ /$access/;
  }

  sub _init {
    my ($self, %args) = @_;
    my %inits;
    my ($i, $j);

    for $i ($self->_standard_keys) {
      $j = $i;
      $j =~ s/_//;
      $inits{$i} = $args{$j} || $self->_default_for($i);
    }
    %$self = %inits;
  }
}

sub new {
  my $class = shift;
  my $self = {};

  bless $self, $class;

  $self->_incr_count();
  $self->_init(@_);

  return $self;
}

sub DESTROY {
  my $self = shift;

  $self->_decr_count();
}

sub AUTOLOAD {
  no strict "refs";
  my $self = shift;
  if (($AUTOLOAD =~ /\w+::\w+::get(_.*)/) && ($self->_accesible($1,'read'))) {
    my $n = $1;
    return unless exists $self->{$n};

    # Declarar el metodo get_*****
    *{$AUTOLOAD} = sub { return "(nuevo get) ".$_[0]->{$n}; };

    return "(autoload) ".$self->{$n};
  } elsif (($AUTOLOAD =~ /\w+::\w+::set(_.*)/) && ($self->_accesible($1,'write'))) {
    my $n = $1;
    return unless exists $self->{$n};
    $self->{$n} = "(autoload) ".shift;

    # Declarar el metodo set_*****
    *{$AUTOLOAD} = sub { $_[0]->{$n} = "(nuevo set) ".$_[1]; };
  } else {
    @_ = map { "\"".$_."\""; } @_;   # Comillas a los argumentos...
    print "Has llamado a $AUTOLOAD(",join(", ",@_),")\n";
  }
}

1;
