import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;

public class LibraryGUI extends JFrame
{
	private Vector patronVector;
	private Vector itemVector;

	private String patronNames[];
	private String itemTitles[];
	private String patronsItems[];

	JList listPatronIn;
	JList listPatronOut;
	JList listPatronsItems;
	JList listItems;
	JButton btncheckIn;
	JButton btncheckOut;
	JButton exitFromOut;
	JButton exitFromIn;
	JTabbedPane tab;
	JPanel pnlOut;
	JPanel pnlIn;
	JPanel view;
	JTextArea patronsSummary;

	JFrame f;


	public static void main(String[] args)
	{
		LibraryGUI lgui = new LibraryGUI();

		//Fill vectors
		lgui.populateItems();
		lgui.populatePatrons();
		lgui.layoutGUI();
	}

	//Create a frame
	public LibraryGUI()
	{
		f = new JFrame("Library App");

		//Initialize vectors
		itemVector = new Vector();
		patronVector = new Vector();
	}

						//Call methods that fill lists and set up the gui
	public void layoutGUI()
	{
		//fill the lists
		makeLists();

		//set up panels
		panels();

		//set up tabs
		tabbedPanes();

		//set up Jframe
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.getContentPane().setLayout(new FlowLayout());
		f.getContentPane().add(tab);
		f.pack();
		f.show();
	}

	//Fill the panels with needed components
	public void panels()
	{
		btncheckIn=new JButton("Check Item In");
		btncheckIn.addActionListener(new CheckInHandler());
		btncheckIn.setEnabled(true);
		btncheckIn.setBackground(new Color(0,255,0));

		btncheckOut=new JButton("Check Item Out");
		btncheckOut.addActionListener(new  CheckOutHandler());
		btncheckOut.setEnabled(true);
		btncheckOut.setBackground(new Color(255,0,0));

		exitFromOut = new JButton("Exit Program");
		exitFromOut.addActionListener(new  ExitHandler());
		exitFromIn = new JButton("Exit Program");
		exitFromIn.addActionListener(new  ExitHandler());

		pnlIn = new JPanel();
		pnlIn.setLayout(new GridLayout(2,2) );
		pnlIn.add(new JScrollPane (listPatronIn));
		pnlIn.add(new JScrollPane (listPatronsItems));
		pnlIn.add(btncheckIn);
		pnlIn.add(exitFromIn);


		pnlOut = new JPanel();
		pnlOut.setLayout(new GridLayout(2,2) );
		pnlOut.add(new JScrollPane (listPatronOut));
		pnlOut.add(new JScrollPane (listItems));
		pnlOut.add(btncheckOut);
		pnlOut.add(exitFromOut);



		view = new JPanel();
		view.setLayout(new FlowLayout());

		patronsSummary = new JTextArea();
		reportOut();
		view.add(patronsSummary);
	}

	//Set the text in the JText area
	public void reportOut()
	{
		String temp = "";

		//Loop through each patron in vector
		for (int i = 0; i < patronVector.size(); i++)
		{
			//Append name to string
			temp+=((Patron)(patronVector.get(i))).getName();
			temp+="\n";

			//Get each patrons items
			Vector tempVector = new Vector();
			tempVector = ((Patron)(patronVector.get(i))).getItemVector();

			if(tempVector.size() == 0)
			{
				temp+= "--No Items\n\n";
			}
			else
			{
				//Loop through each patrons items, appending item names to the string
				for ( int x = 0; x < tempVector.size(); x++)
				{
						temp+=((Item)(tempVector.get(x))).getTitle();
						temp+="\n";
				}
				temp+="\n";
			}
		}

		//Set the JTextArea to contain the text that was created
		patronsSummary.setText(temp);
	}


	//Set up lists to contain proper info
	public void makeLists()
	{
		//Contains the list of patron names
		listPatronIn = new JList(patronNames);//Initialize list to hold the array of patron names
		listPatronIn.setVisibleRowCount(10);//Sets the visible number of lines in the list
		listPatronIn.setFixedCellWidth(150);//Sets the width of list cell in pixels
		listPatronIn.setFixedCellHeight(15);//Sets tge height of list cell in pixels
					//Set property to allow single selection only and disable multiple selections.
		listPatronIn.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		listPatronIn.setOpaque(true);

		//contains the list of patron names
		listPatronOut = new JList(patronNames);
		listPatronOut.setVisibleRowCount(10);
		listPatronOut.setFixedCellWidth(150);
		listPatronOut.setFixedCellHeight(15);
		listPatronOut.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		listPatronOut.setOpaque(true);

		//contains the patron items
		String[] empty = {"<empty>"};
		listPatronsItems = new JList(empty);
		listPatronsItems.setVisibleRowCount(10);
		listPatronsItems.setFixedCellWidth(150);
		listPatronsItems.setFixedCellHeight(15);
		listPatronsItems.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		listPatronsItems.setOpaque(true);

		//contains library items
		listItems = new JList(itemTitles);
		listItems.setVisibleRowCount(10);
		listItems.setFixedCellWidth(150);
		listItems.setFixedCellHeight(15);
		listItems.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		listItems.setOpaque(true);

		//Add list selection listener to listPatronIn, located in the check in panel
		listPatronIn.addListSelectionListener(
			new ListSelectionListener()
			{
				public void valueChanged(ListSelectionEvent event)
				{
					//When an item on the left(the patron list) is selected,
					if (listPatronIn.isSelectionEmpty()==false)
					{
						//Update the items check out for that patron into the list (on the right).

						//Find the location of the selected patron in the list
						int patSelected = listPatronIn.getSelectedIndex();

						//call method, that updates the list (on the right) for specified patron
						updatePatronItems(getPatron(patSelected));

						checkIfEmpty();

					}

				}
			}
		);
	}

	//Checks if the items checked out are empty, if so, disables list
	public void checkIfEmpty()
	{
		if (patronsItems[0].equals("No items checked out"))
		{
			listPatronsItems.setEnabled(false);
		}
		else
		{
			listPatronsItems.setEnabled(true);
		}
	}


		public void updatePatronItems(Patron pat)		//Updates patron items
	{
		//call method that initialize patronsItems array to hold the titles of the items check out
		initPatronItemNameArr(pat);

		//set the list data of the list of the right to hold that array of titles.
		listPatronsItems.setListData(patronsItems);
	}


	public void tabbedPanes()		//Set up tabs
	{
		tab = new JTabbedPane();
		tab.setSize(300,250);
		tab.addTab("Patron Check Out", null, pnlOut, "Checking Out");
		tab.addTab("Patron Check In", null , pnlIn, "Checking In");
		tab.addTab("View", null, view, "View Patron");
	}


	public void populateItems()			//Fill items vector
	{
		Item []  item = new Item[7];

		Author [] author = new Author[1];
		Artist [] artist = new Artist[1];

		author[0] = new Author (001, "Harper Lee", "5/23/54");
		item[0] = new Book (101, "To kill a Mockingbird", author , 2);

		author = new Author[2];	//---- 2 authors in this book
		author[0] = new Author (003, "Jack London", "1/12/06");
		author[1] = new Author (002, "Amy Tan", "1/03/14");
		item[1] = new Book (102, "Hearts of the Three", author, 1);

		author = new Author[1];
		author[0] = new Author (004, "C.S.Lewis", "2/03/74");
		item[2] = new Book (103, "Perelandra", author, 2);

		artist = new Artist[1];
		artist[0] = new Artist (601, "combined", "nonclassical");
		item[3] = new CD (501, "Greatest Hits", artist, 61, 3);

		artist = new Artist[1];
		artist[0] = new Artist (602, "combined", "nonclassical");
		item[4] = new CD (502, "Hymns to the Silence", artist, 50, 1);

		artist = new Artist[1];
		artist[0] = new Artist (603, "Peter Tchaykovsky", "classical");
		item[5] = new CD (503, "First Concert", artist, 75, 1);

		artist = new Artist[1];
		artist[0] = new Artist (604, "The Beatles", "nonclassical");
		item[6] = new CD (504, "Yesterday", artist, 58, 3);


		//transfer items created in array /*** into the itemVector
		//(we cannot populate a vector directly in this case since item could be either book or CD)
		itemVector.add(item[0]);
		itemVector.add(item[1]);
		itemVector.add(item[2]);
		itemVector.add(item[3]);
		itemVector.add(item[4]);
		itemVector.add(item[5]);
		itemVector.add(item[6]);


		initItemNameArr();		//Update item info
		//gets the titles of each item and adds the names to the array of titles,
		//which gets added to the list in the check out panel

	}


	public void populatePatrons()						//Fill patrons vector
	{
		//Created new patron, add them to the vector
		patronVector.add(new Patron(1, "Fred Capestany"));
		patronVector.add(new Patron(2, "Gurpreet Kaur"));
		patronVector.add(new Patron(3, "Serezha Doroshenko"));

		//add specific item to the vector of items of that specific patron
		checkOut(getPatron(0),getItem(0));
		checkOut(getPatron(1),getItem(1));
		checkOut(getPatron(2),getItem(2));

		//Gets the name of each patron, adds it to an array
		//of names, adds that to the list in the check out panel
		initPatronNameArr();
	}


	//Check out handler that gets called when btnCheckOut gets clicked
	private class CheckOutHandler implements ActionListener		//---------- ActionListener
	{
		public void actionPerformed(ActionEvent event)
		{
			//Clear selection of other lists
			listPatronIn.clearSelection();
			listPatronsItems.clearSelection();


			if(listPatronOut.isSelectionEmpty() == true)
			{
				JOptionPane.showMessageDialog(null,"You must select a patron",
										"ERROR", JOptionPane.ERROR_MESSAGE);
			}
			else if (listItems.isSelectionEmpty() == true)
			{
				JOptionPane.showMessageDialog(null,"You must select an Item",
										"ERROR", JOptionPane.ERROR_MESSAGE);
			}

			else
			{
				//get the indexes of the patron and item clicked
				int pIndex = listPatronOut.getSelectedIndex();//selected patron
				int iIndex = listItems.getSelectedIndex();//selected item

				//getPatron at that index
				Patron tempPat = new Patron();
				tempPat = getPatron(pIndex);//get us that specific patron object
				//located at pIndex, and assign the patron object into tempPat

				//getItem at the index
				Item tempItem = new Item();
				tempItem = getItem(iIndex);

				//Check out the item, if it goes through
				//let user know
				if( checkOut(tempPat,tempItem) == true)
				{
					String check = "";
					check +=tempPat.getName() + " checking out " + tempItem.getTitle();
					JOptionPane.showMessageDialog(null, check,
								"Check Out Complete", JOptionPane.PLAIN_MESSAGE);
					updatePatronItems(tempPat);
					reportOut();//updates the JTextArea of panel view to show changes made
				}
				//if check out doesnt go through, let user know
				else
				{
					JOptionPane.showMessageDialog(null, "Error Checking out",
								"Check Out Incomplete", JOptionPane.ERROR_MESSAGE);
				}
			}
		}
	}

	//Check in handler that gets called when btnCheck in gets clicked
	private class CheckInHandler implements ActionListener			//---------- ActionListener
	{
		public void actionPerformed(ActionEvent event)
		{

			//Clear selection of patron and items when done checking out
			listPatronOut.clearSelection();
			listItems.clearSelection();


			if(listPatronIn.isSelectionEmpty() == true)
			{
				JOptionPane.showMessageDialog(null,"You must select a patron",
									"ERROR", JOptionPane.ERROR_MESSAGE);
			}
			else if (listPatronsItems.isSelectionEmpty() == true)
			{
				JOptionPane.showMessageDialog(null,"You must select an item",
									"ERROR", JOptionPane.ERROR_MESSAGE);
			}

			else
			{
				//get the index of the list item clicked
				int pIndex = listPatronIn.getSelectedIndex();
				int iIndex = listPatronsItems.getSelectedIndex();

				//getPatron at that index
				Patron tempPat = new Patron();
				tempPat = getPatron(pIndex);

				//getItem at the index
				Item tempItem = new Item();
				tempItem =tempPat.getItem(iIndex);

							//Check int the item, if it goes through let user know
				if( checkIn(tempPat,tempItem) == true)
				{
					String check = "";
					check +=tempPat.getName() + " checking in " + tempItem.getTitle();
					JOptionPane.showMessageDialog(null, check,
									"Check In Complete", JOptionPane.PLAIN_MESSAGE);
					updatePatronItems(tempPat);
					reportOut();
				}
				//if check in doesnt go through, let user know
				else
				{
					JOptionPane.showMessageDialog(null, "Error Checking In",
									"Check In Incomplete", JOptionPane.ERROR_MESSAGE);
				}
			}
		}
	}


	//Check out handler that gets called when btnExit gets clicked
	private class ExitHandler implements ActionListener			//---------- ActionListener
	{
		public void actionPerformed(ActionEvent event)
		{
			System.exit(0);
		}
	}



	//Get patron from patron vector at specific location
	public Patron getPatron(int i)
	{
		return (Patron)(patronVector.get(i));
	}

	//get item from item vector at specific location
	public Item getItem(int i)
	{
		return (Item)(itemVector.get(i));
	}

	//initialize string array of names to hold patrons names
	//from patrons vector
	public void initPatronNameArr()
	{
		//set up string array to hold enough elements
		patronNames = new String[patronVector.size()];	//size in vector; length in array

		//loop through patron vector assingning patron
		//names to array
		for (int i = 0; i < patronNames.length; i++)
		{
			patronNames[i] = (getPatron(i).getName());
		}
	}

	//initialize string array of item titles to hold item names
	//from items vector
	public void initItemNameArr()
	{
		//set up string array to hold enough elements
		itemTitles = new String[itemVector.size()];

		//loop through item vector assigning item title to array of item titles (itemTitles)
		for (int i = 0; i < itemTitles.length; i++)
		{
			 itemTitles[i] = (getItem(i).getTitle());
		}
	}

	//Initialize a string array to a specific patrons items
	public void initPatronItemNameArr(Patron out)
	{
		//set up string array to hold enough elements
		patronsItems = new String[out.getItemTitles().length];

		//get the item titles from patron object(class)
		patronsItems = out.getItemTitles();
	}

	//check out specific item for specific patron
	public boolean checkOut(Patron patronOut, Item item)
	{
		//If check out goes through, return true
		if(patronOut.checkItemOut(item)==true)
		{
			//update the titles of the items checked out for specific patron
			initPatronItemNameArr(patronOut);
			return true;
		}
		return false;
	}

	//check in specific item for specific patron
	public  boolean checkIn(Patron patronIn, Item item)
	{
		//If check in goes through, return true
		if( patronIn.checkItemIn(item)== true)
		{
			//update the titles of the items checked out for specific patron
			initPatronItemNameArr(patronIn);
		 	return true;
		 }
		 return false;
	}
}
