

class Book

  attr :copies

  protected #==============================
  attr :author
  attr :name
  attr :isbn

  def initialize(author, name, isbn)
    @author = author
    @name = name
    @isbn = isbn
    @copies = Array.new
  end

  public #=================================

  def getAuthor()
    return @author
  end

  def getName()
    return @name
  end

  def getISBN()
    return @isbn
  end

  def registerCopy(copy)
    @copies.push(copy)
    return @copies.length
  end

  def to_s
    return "#{@author}: #{@name} [#{@isbn}]"
  end
end

class BookCopy

  attr :book
  attr :borrowed_by
  attr :nr

  def initialize(book)
    @book = book
    @nr = book.registerCopy(self)
    @borrowed_by = nil
  end

  def borrow(person)
    raise "#{@book}: copy #{@nr} already borrowed !!!" if (borrowed_by)
    @borrowed_by = person
  end

  def returnIt()
    @borrowed_by = nil
  end

  def isAvailable
    return @borrowed_by.nil?
  end

  def to_s
    return (@borrowed_by ? "borrowed" : "available")
  end

  def <=>(other)
    return "#{@book.getName}#{@nr.to_s}"<=>"#{other.book.getName}#{other.nr.to_s}"
  end
end

class BookManager
  
  protected #==============================
  
  attr :books
  attr :status

  def initialize()
    @books = Array.new
    @status = Hash.new
  end

  public #=================================
  
  def addBook(book)
    @books.push(book)
  end

  def removeBook(book)
    @books.delete(book)
  end

  def buy(copy)
    @status[copy] = copy.to_s
  end

  def drop(copy)
    @status.delete(copy)
  end

  def updateStatus(copy)
    @status[copy] = copy.to_s
  end

  def printStatus(book)
    result = book.to_s+"\n"
    book.copies.each { |copy|
      result += "  - #{copy.nr} => #{@status[copy]}\n"
    }
    puts result
  end

  def printAll()
    @status.sort.each { |copy, currentstate|
      puts " -#{copy.book.to_s}: #{copy.nr} -> #{currentstate}"
    }
  end
end

class Person
  attr :name
  def initialize(name)
    @name = name
  end
  def to_s
    @name
  end
end

