
/*CSU 214 - QUIZ 5

The following class diagram defines a list of movie shows.
Make examples of three lists of movie shows.
Write the method 'allmovies' that consumes two lists sorted 
in the order of the time of show, and produces a list of movies 
in both lists, ordered by the time of show.
----------------------------------------------------------------
           +------+               
           | ALoM |<-------------+
           +------+              |
           +------+              |
              / \                |
              ---                |
               |                 |
      ----------------           |
      |              |           |
  +-------+    +-------------+   |
  | MTLoM |    | ConsLoM     |   |
  +-------+    +-------------+   |
  +-------+  +-| Movie first |   |
             | | ALoM rest   |---+
             | +-------------+ 
             v
      +----------------+
      | Movie          |
      +----------------+
      | String title   |
      | String theater |
      | int hour      |
      +----------------+ 

--------------------- SHOW THE METHOD BELOW ---------------------
*/
/*
+----------------+
| Movie          |
+----------------+
| String title   |
| String theater |
| int hour       |
+----------------+

*/

// to represent a movie
class Movie {
  String title;
  String theater;
  int hour;

  Movie(String title, String theater, int hour) {
    this.title = title;
    this.theater = theater;
    this.hour = hour;
  }

  String toString(){
    return "Movie: ".concat(this.title)
                    .concat(" in ")
		    .concat(this.theater)
		    .concat(" at ")
                    .concat(String.valueOf(this.hour))
                    .concat(".");
  }
}
/*
            +------+               
            | ALoM |<-------------+
            +------+              |
            +------+              |
              / \                 |
              ---                 |
               |                  |
      -----------------           |
      |               |           |
  +-------+    +-------------+    |
  | MTLoM |    | ConsLoM     |    |
  +-------+    +-------------+    |
  +-------+    | Movie first |    |
               | ALoM rest   |-+  |
               +-------------+ |  |
                               |  |
                               +--+

*/

// to represent a list of movies
abstract class ALoM {

  // represent this list as a String
  abstract String toString();

  // is this an empty list?
  abstract boolean empty();
}

// to represent an empty list of movies
class MTLoM extends ALoM {

  MTLoM() {
  }

  String toString(){
    return "***";
  }

  boolean empty(){
    return true;
  }
}

// to represent a nonempty list of movies
class ConsLoM extends ALoM {
  Movie first;
  ALoM rest;

  ConsLoM(Movie first, ALoM rest) {
    this.first = first;
    this.rest = rest;
  }

  String toString(){
    return "Cons( ".concat(this.first.toString()).
                    concat(", ").
                    concat(this.rest.toString()).
                    concat(")");
  }

  boolean empty(){
    return false;
  }
}

class Examples{

  Movie gwtw = new Movie("Gone with the Wind", "Loews", 4);
  Movie kk = new Movie("King Kong", "Circle", 6);
  Movie mat = new Movie("Matrix", "Showcase", 8);
  Movie mat2 = new Movie("Matrix", "Loews", 5);

  ALoM mtlist = new MTLoM();
  ALoM list1 = new ConsLoM(this.gwtw,
                 new ConsLoM(this.kk, 
                   new ConsLoM(this.mat, this.mtlist)));
  ALoM list2 = new ConsLoM(this.mat2, this.mtlist);

  // produce a combined list sorted by time from two sorted lists
  ALoM allmovies(ALoM list1, ALoM list2){
    if (list1.empty())
      return list2;
    else 
      if (list2.empty())
        return list1;
      else
         if (((ConsLoM)list1).first.hour < ((ConsLoM)list2).first.hour)
           return new ConsLoM(((ConsLoM)list1).first,
                              allmovies(((ConsLoM)list1).rest, list2));
         else
           return new ConsLoM(((ConsLoM)list2).first,
                              allmovies(list1, ((ConsLoM)list2).rest));
  }

  ALoM movies = allmovies(list1, list2);
  // expected a list with gwtwm mat2, kk, matt)

  ALoM m1 = allmovies(list1, mtlist);
  ALoM m2 = allmovies(mtlist, list2);


  // should also include tests for 'toString' and 'empty' methods
 


}
