package Schema;
use Tangram;

# Export the Schema.
#
use Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw($schema);

# Create the schema object.
#
my $schema_def = {

    classes => {

        Patron => {
            fields => {
                string => [ "name" ],

                # All the books currently loaned
                # to this Patron
                array  => { books => 'Book' }
            }
        },

        Book => {
            fields => {
                string => [ "title" ],

                # The patron who has this book
                ref    => [ "borrower" ],

                # All the Authors of this book
                array  => { authors => 'Author' }
            }
        },

        Author => {
            fields => {
                string => [ "name" ]
            }
        }
    }

};
$schema = Tangram::Schema->new($schema_def);

package Patron;

  sub new {
      my $class = shift;
      my $name = shift;

      my $self = {};
      bless ($self, $class);

      $self->{name} = $name;
      $self->{books} = undef;

      return $self;
  }

  # Borrow a book
  sub borrow {
      my $self = shift;
      my $book = shift;
      push @{ $self->{books} }, $book;

      # Tell the book who borrowed it.
      $book->record_borrower($self);
  }

  # Record the return of a book.
  # (returns are initiated by the Book object)
  sub record_return {
      my $self = shift;
      my $book = shift;

      # Remove this book from the list
      # of books the patron's borrowed.
      my @tmp = @{ $self->{books} };
      @tmp = grep $_ ne $book, @tmp ;
      @{ $self->{books} } = @tmp;
  }

package Book;

  sub new {

      my $class = shift;
      my $title = shift;

      my $self = {};
      bless ($self, $class);

      $self->{title}  = $title;

      return $self;
  }

  # Add an author to this book.
  sub add_author {
      my $self = shift;
      my $author = shift;
      push @{ $self->{authors} }, $author;
  }

  # Record the Patron who borrowed this book.
  # (this is initiated by the Patron)
  sub record_borrower {
      my $self = shift;
      my $patron = shift;
      $self->{borrower} = $patron;
  }

  # Return this book.
  sub return {
      my $self = shift;
      my $borrower = $self->{borrower};
      if ($borrower) {

          # Tell the Patron object the book
          # was returned
          $borrower->record_return($self);
          $self->{borrower} = undef;
          return $borrower;
      }
  }

package Author;

  sub new {
      my $class = shift;
      my $name = shift;

      my $self = {};
      bless ($self, $class);

      $self->{name} = $name;

      return $self;
  }

1;