/* CookieJarList implementation of the CookieJar ADT
   H. Conrad Cunningham
   Version #1:  15 March 2010

123456789012345678901234567890123456789012345678901234567890123456789012345678

*/


/* Class CookieJarList implements the CookieJar ADT using Scala's List
   data structure to implement the jar (mathematical bag) of cookies.
   The cookies occur in the list the same number of times they do in 
   the cookie jar.

   IMPLEMENTATION INVARIANT: 
     (ForAll c : c IN CookieType ::
                  OCCURRENCES(c,Bag) == jar.filter(_==c).length )

   Remember that an implementation invariant must be made true by the
   class constructors and each public method of the class must
   preserve it.  That is, it is both a precondition and postcondition
   on all mutator and accessor methods. An implementation invariant
   relates the values of the concrete data structures to the values of
   the model.

   Also remember that the class operations must preserve the interface
   invariant and the preconditions and postconditions of the trait
   CookieJar to be a subtype.

*/

class CookieJarList[CookieType] extends CookieJar[CookieType] {

  // CookieJar's bag model is implemented by List jar.
  private var jar = List[CookieType]()
 
  def putIn(cookie: CookieType) { jar = cookie :: jar }
 
  def eat(cookie: CookieType) {
    jar.span(_ != cookie) match { // pair (not equal from head, rest)
      case (l,_::r) => jar = l ++ r 
      case _        => throw new RuntimeException(
        "Attempt to eat cookie \"" + cookie + "\", which is not in the jar.")
    }
  }
      
  def isEmpty: Boolean                 = jar.isEmpty

  def has(cookie: CookieType): Boolean = jar.contains(cookie)

  /* Redefine toString to return form "CookieJar(e1,e2,e3,...,en)" with all 
     elements of bag in arbitrary order. 
  */

  override def toString = "CookieJar(" + jar.mkString(",") + ")"

}

