/*********************************************************************
 * Author: B. Alex Bridges                                           *
 * Login ID: brid0129                                                *
 * Class: CPSC-102, Summer 1998                                      *
 * Project: Programming Assignment 3                                 *
 * Description: This program is a simple database query system for a *
 *              video store.                                         *
 * Contents: Methods for dealing with Videos.                        *
 *********************************************************************/

/* IMPORTS */
import java.io.*;


class Videos
{
	/* CONSTANTS */
	final static boolean b_debug = false;	// CONTROLS EXTRA DEBUG OUTPUT
	final static String str_default = "";	// DEFAULT STRING VALUE
	final static int int_default = -1;		// DEFAULT INTEGER VALUE

	/* GLOBAL VARIABLES */
	public String str_title;		// MOVIE'S TITLE
	public int int_year;			// MOVIE'S RELEASE YEAR
	public int int_runtime;			// MOVIE'S RUNTIME IN MINUTES
	public String str_available;	// MOVIE'S AVAILABILITY
	public Videos Videos_next;		// MOVIE'S LINK

	public Videos()
	{
		String str_title = str_default;
		int_year = int_default;
		int_runtime = int_default;
		str_available = str_default;
		Videos_next = null;
	} // constructor Videos

	/*************************************************************************
	 * Method: get_movie                                                     *
	 * Purpose: Gets the movie properties--title, release year, runtime,     *
	 *          and availabilty.                                             *
	 * Input: --PARAMATERS--                                                 *
	 *        => 'br_file_in' = The BufferedReader for the video database.   *
	 * Output: --EXIT VALUE--                                                *
	 *         => FATAL EXCEPTION = -1                                       *
	 *************************************************************************/
	public void get_movie(BufferedReader br_file_in)
	{
		/* READING OF MOVIE PROPERTIES */
		try
		{
			str_title = br_file_in.readLine();
			int_year = Integer.parseInt( br_file_in.readLine() );
			int_runtime = Integer.parseInt( br_file_in.readLine() );
			str_available = br_file_in.readLine();
			Videos_next = null;
		} // try
		/* EXCEPTION HANDLING */
		catch(IOException exception)
		{
			System.out.println(" FATAL EXCEPTION: File input problem.");
			System.exit(-1);
		} // catch
	} // method get_movie

	/*************************************************************************
	 * Method: print_movie                                                   *
	 * Purpose: Prints a movie's properties--title, release year, runtime,   *
	 *          and availabilty.                                             *
	 * Input: none                                                           *
	 * Output: none                                                          *
	 *************************************************************************/
	public void print_movie()
	{
		/* PRINTING OF MOVIE PROPERTIES */
		System.out.print("Title: "+str_title+"\n"+
		                 "Released: "+int_year+"\n"+
		                 "Runtime: "+int_runtime+" minutes\n");
		if( str_available.equals("false") )
			System.out.println("Available: No\n");
		else if( str_available.equals("true") )
			System.out.println("Available: Yes\n");
		else
			System.out.println(" ERROR: Availability of '"+str_available+"' is invalid. Must be 'true' or 'false'.\n");
	} // method print_movie

	/*************************************************************************
	 * Method: print_movie                                                   *
	 * Purpose: Prints a linked list of movies.                              *
	 * Input: --PARAMATERS--                                                 *
	 *        => 'Videos_list'= The linked list of movies.                   *
	 * Output: none                                                          *
	 *************************************************************************/
	public static void print_movie(Videos Videos_list)
	{
		/* LOCAL VARIABLES */
		Videos Videos_tmp = Videos_list;	// VIDEO OBJECT FOR TEMPORARY MOVIE

		/* TRAVERSE LIST UNTIL LAST VIDEO */
		while(Videos_tmp.Videos_next != null)
		{
			// => PRINT CURRENT MOVIE
			Videos_tmp.print_movie();

			// => ADVANCE TO NEXT NODE
			Videos_tmp = Videos_tmp.Videos_next;
		} // while

		/* PRINT LAST VIDEO */
		Videos_tmp.print_movie();
	} // method print_movie

	/*************************************************************************
	 * Method: add_movie                                                     *
	 * Purpose: Appends movie to the end of linked list.                     *
	 * Input: --PARAMATERS--                                                 *
	 *        => 'Videos_list'   = The linked list of movies.                *
	 *        => 'Videos_target' = The movie which is to be added.           *
	 * Output: --RETURNS--                                                   *
	 *        => 'Videos_tmp' = The new linked list of movies.               *
	 *************************************************************************/
	public static Videos add_movie(Videos Videos_list, Videos Videos_target)
	{
		/* LOCAL VARIABLES */
		Videos Videos_tmp = Videos_list;	// VIDEO OBJECT FOR TEMPORARY MOVIE

		/* EMPTY LIST */
		if(Videos_tmp.int_year == int_default)
		{
			System.out.println("EMPTY LIST"); // DEBUG
			// => SO MOVIE IS LIST
			return Videos_target;
		} // if
		/* NON-EMPTY LIST */
		else
		{
			System.out.println("NON-EMPTY LIST"); // DEBUG
			// => LOCATE THE LAST NODE
			while(Videos_tmp.Videos_next != null)
			{
				Videos_tmp = Videos_tmp.Videos_next;
			} // while

			// => LINK MOVIE ONTO END OF LIST
			Videos_tmp.Videos_next = Videos_target;

			return Videos_tmp;
		} // else
	} // method add_movie

	/*************************************************************************
	 * Method: insert_positon                                                *
	 * Purpose: Determines position at which to insert the movie which keeps *
	 *          the sorted order intact.                                     *
	 * Input: --PARAMATERS--                                                 *
	 *        => 'Videos_list'   = The linked list of movies.                *
	 *        => 'Videos_target' = The movie which would be inserted.        *
	 * Output: --VALUES--                                                    *
	 *        => 1+ = The position for new movie.                            *
	 *        => 0  = Empty list.                                            *
	 *************************************************************************/
	public static int insert_positon(Videos Videos_list, Videos Videos_target)
	{
		/* LOCAL VARIABLES */
		Videos Videos_tmp = Videos_list;	// VIDEO OBJECT FOR TEMPORARY MOVIE
		int int_pos = 2;					// CURRENT INSERT POSITION

		/* EMPTY LIST */
		if(Videos_tmp.int_year == int_default)
			return 0;
		/* TARGET < 1st ITEM */
		else if( Videos_target.str_title.compareTo(Videos_tmp.str_title) < 0 )
			return 1;
		/* TARGET > 1st ITEM */
		else
		{
			// => LOCATE THE SORTED POSITION
			while(Videos_tmp.Videos_next != null)
			{
				if( Videos_target.str_title.compareTo(Videos_tmp.Videos_next.str_title) > 0 )
				{
					Videos_tmp = Videos_tmp.Videos_next;
					int_pos++;
				} // if
				else
					return int_pos;
			} // while

			return int_pos;
		} // else
	} // method insert_positon

	/*************************************************************************
	 * Method: insert_movie                                                  *
	 * Purpose: Inserts movie into the linked list--keeping the sorted order.*
	 * Input: --PARAMATERS--                                                 *
	 *        => 'Videos_list'   = The linked list of movies.                *
	 *        => 'int_pos'       = Position at which to insert the movie.    *
	 *        => 'Videos_target' = The movie which is to be inserted.        *
	 * Output: --RETURNS--                                                   *
	 *        => 'Videos_tmp' = The new linked list of movies.               *
	 *************************************************************************/
	public static Videos insert_movie(Videos Videos_list, int int_pos, Videos Videos_target)
	{
		/* LOCAL VARIABLES */
		Videos Videos_tmp = Videos_list;	// VIDEO OBJECT FOR TEMPORARY MOVIE

		switch(int_pos)
		{
			case 0:
				return Videos_target;
			case 1:
				Videos_target.Videos_next = Videos_tmp;
				return Videos_target;
			default:
				if(Videos_tmp == null)
					return null;
				else
				{
					Videos_tmp.Videos_next = insert_movie(Videos_tmp.Videos_next, --int_pos, Videos_target);
					return Videos_tmp;
				} // else
		} // switch
	} // method insert_movie

	/*************************************************************************
	 * Method: delete_movie                                                  *
	 * Purpose: Deletes movie from the linked list.                          *
	 * Input: --PARAMATERS--                                                 *
	 *        => 'Videos_list' = The linked list of movies.                  *
	 *        => 'str_del'     = The title of movie to be deleted.           *
	 * Output: --RETURNS--                                                   *
	 *        => 'Videos_tmp' = The new linked list of movies.               *
	 *************************************************************************/
	public static Videos delete_movie(Videos Videos_list, String str_del)
	{
		/* LOCAL VARIABLES */
		Videos Videos_tmp = Videos_list;	// VIDEO OBJECT FOR TEMPORARY MOVIE

		if(Videos_tmp == null)
			return null;
		else if( Videos_tmp.str_title.equals(str_del) )
			return Videos_tmp.Videos_next;
		else
		{
			Videos_tmp.Videos_next = delete_movie(Videos_tmp.Videos_next, str_del);
			return Videos_tmp;
		} // else

	} // method delete_movie

	/*************************************************************************
	 * Method: find_movie                                                    *
	 * Purpose: Searches for movie in the linked list with matching title.   *
	 * Input: --PARAMATERS--                                                 *
	 *        => 'Videos_list' = The linked list of movies.                  *
 	 *        => 'str_search'  = The title for which to search.              *
	 * Output: --RETURNS--                                                   *
	 *        => SUCCESS = The matching movie with the remaining linked list.*
	 *        => FAILURE = null                                              *
	 *************************************************************************/
	public static Videos find_movie(Videos Videos_list, String str_search)
	{
		/* LOCAL VARIABLES */
		Videos Videos_tmp = Videos_list;	// VIDEO OBJECT FOR TEMPORARY MOVIE

		/* TRAVERSE LIST UNTIL LAST VIDEO */
		while(Videos_tmp.Videos_next != null)
		{
			// => COMPARE TITLES AND RETURN MOVIE IF THEY MATCH
			if( str_search.equals(Videos_tmp.str_title) )
				return(Videos_tmp);
			// => ADVANCE TO NEXT NODE
			else
				Videos_tmp = Videos_tmp.Videos_next;
		} // while

		/* CHECK LAST VIDEO */
		if( str_search.equals(Videos_tmp.str_title) )
		{
			Videos_tmp.Videos_next = null;
			return(Videos_tmp);
		} // if
		else
			return null;
	} // method find_movie
} // class Database
