/**
 * Subscriber:  a class to model a subscriber to a NetFlix-type 
 * movie-rental system.
 *
 * @author CS117 3a (Carleton College, Winter 2006)
 * @version 1.00 (designed in class 10 February 2006, written 15 February 2006)
 */

class Subscriber {

    // Full name of the subscriber.
    private String name;

    // Flag of whether subscriber currently has a movie (true == has a movie).
    private boolean hasMovie;

    // Ranked list of movie titles that the subscriber currently wants.
    // queue[0] is the most-desired movie, queue[1] is next, etc.
    private String[] queue;

    // The maximum number of movies that the user can have in his/her queue.
    private final int MAX_QUEUE_SIZE = 10;
    
    // The Movie that the subscriber currently has, or null if !hasMovie.
    private Movie rental;

    // The Netflix server from which the subscriber gets his/her movies.
    private Netflix local;


    /**
     * Construct a new subscriber object with an empty queue.
     */
    public Subscriber(String name, Netflix local) {
	this.name = name;
	hasMovie = false;
	queue = new String[MAX_QUEUE_SIZE];
	for (int i = 0; i < MAX_QUEUE_SIZE; i++) {
	    queue[i] = "";
	}
	rental = null;
	this.local = local;
    }

    /**
     * Adds a given title to the subscriber's queue, so that it is the
     * (priority)th movie in the queue.  Shifts all lower-priority
     * movies down one slot to make room for this title.  Drops any
     * titles that are lower priority than MAX_QUEUE_SIZE.
     */
    public boolean addToQueue(String title, int priority) {

	// plan:  move everything from priority-1 through the end over by one.
	for (int i=MAX_QUEUE_SIZE-1; i > priority - 1; i--) {
	    queue[i] = queue[i-1];
	}
	// then:  put title in as priority-1
	queue[priority-1] = title;
	return false;
    }

    /**
     * Sets the current movie, if the subscriber does not currently
     * have another movie.  Sets the movie's renter to this
     * subscriber.  Wipes the movie's title from the queue.  Returns
     * false if unsuccessful (because the subscriber already has a movie).
     */
    public boolean setMovie(Movie movie) {
	if (hasMovie || movie == null) {   // movie == null added after class.
	                                   // This will happen if nothing
	                                   // in the queue is available.
	    return false;
	} else {
	    hasMovie = true;
	    for (int i = 0; i < MAX_QUEUE_SIZE; i++) {
		if (queue[i].equals(movie.getTitle())) {
		    for (int j = i; j < MAX_QUEUE_SIZE - 1; j++) {
			queue[j] = queue[j+1];
		    }
		    queue[MAX_QUEUE_SIZE-1] = "";
		}
	    }
	    rental = movie;
	    movie.setRenter(this);
	    return true;
	}
    }

    /**
     * Get the best available movie from the Netflix server, and set
     * it as the current rental.  Does nothing if the subscriber
     * already has a movie.
     */
    public boolean request() {
	if (hasMovie) {
	    return false;
	} else {
	    Movie newMovie = local.fulfillRequest(queue);
	    setMovie(newMovie);
	    return true;
	}
    }

    /**
     * Send back the currently rented movie to the Netflix server.
     */
    public boolean sendBack() {
	if (hasMovie) {
	    hasMovie = false;
	    rental.unsetRenter();
	    rental = null;
	    return true;
	} else {
	    return false;
	}
    }

    /**
     * Converts the subscriber's state into a string.  For debugging.
     */
    public String toString() {
	String str = "";

	str += "Name = " + name + "\n";
	str += "Currently has a movie: " + hasMovie + "\n";
	if (hasMovie) {
	    str += "Current movie: " + rental.getTitle() + "\n";
	}
	str += "Queue: (1) \"" + queue[0];
	for (int i=1; i < MAX_QUEUE_SIZE; i++) {
	    str = str + "\"; (" + (i+1) + ") \"" + queue[i];
	}
	str += "\"\n";
	return str;
    }
	    
}
