// Sean Szumlanski, Fall 2017

// AdorableSingingCreature.java
// ============================
// This example covers some basics related to classes, constructor methods,
// method overload, ArrayLists, and creating multiple instances of a class.

// Suggested Exercises:
// ====================
//
// 1. Set up the AdorableSingingCreature() constructor so that it always creates
//    a new ArrayList for the creature's songs. (With the code structured as it
//    is now, we saw that if we create multiple creatures in main() and pass the
//    same ArrayList to their constructors each time, then changing the list
//    for one creature changes the list for all of the creatures. This is
//    problematic, and creating a new ArrayList inside the constructor solves
//    that problem.)
//
// 2. Overload the sing() method so that you can request a specific song from
//    your creature. If your creature does not know the song, it should lose
//    some happiness.
//
// 3. Create an array list of creatures. Add an option to the menu where you get
//    to create new creatures at runtime, and prompt the user to give each new
//    creature a name.
//
// 4. Add an option to the main menu where you print a list of the current
//    creatures.
//
// 5. Add an option to the main menu that allows you to list all the songs a
//    certain creature can sing. Try this two ways:
//
//      a. When the user selects this option, print a numbered list of creatures
//         and ask the user to enter the number of the creatures whose song list
//         he/she wants to view.
//
//      b. Ask the user to enter the name of the creature whose songs he/she
//         wants to view. Then find a way to print the songs that particular
//         creature can sing. (If the user enters an invalid name, display an
//         error message that explains that.)
//
// 6. Add a feature where you ask the user to select which creature he/she wants
//    to interact with after selecting one of the main menu options.
//
// 7. Add a hunger feature. Your creature should refuse to sing if it is too
//    hungry. You can feed the creature to make it less hungry, but you should
//    also implement a feature where the creature becomes very unhappy if you
//    feed it too much. (In order for this feature to make sense, the creature
//    needs to be able to become more hungry after certain actions. You might
//    want to increase its hunger every time it sings, learns a new song, or
//    performs other actions.)


import java.util.*;

public class AdorableSingingCreature
{
	String name;
	ArrayList<String> songs;
	int happiness = 7;

	AdorableSingingCreature(String creatureName, String songTitle)
	{
		name = creatureName;
		songs = new ArrayList<>();
		songs.add(songTitle);
	}

	AdorableSingingCreature(String creatureName, ArrayList<String> songList)
	{
		name = creatureName;
		songs = songList;
	}

	AdorableSingingCreature(String creatureName)
	{
		name = creatureName;
	}

	public void changeHappiness(int delta)
	{
		happiness += delta;

		// Never allow happiness to go below zero.
		if (happiness < 0)
			happiness = 0;

		// We don't want our creatures to get *too* happy.
		if (happiness > 10)
			happiness = 10;
	}

	public void sing()
	{
		if (songs == null || songs.size() == 0)
		{
			System.out.println(name + " doesn't know any songs.");
			changeHappiness(-1);
		}
		else if (happiness < 3)
		{
			System.out.println(name + " is in a stormy mood and refuses to sing.");
		}
		else
		{
			int songIndex = (int)(Math.random() * songs.size());
			System.out.println(name + " sings \"" + songs.get(songIndex) + ",\" and it's totally adorable.");
			changeHappiness(1);
		}
	}

	public void poke()
	{
		System.out.println(name + " grumbles irritably and seems rather displeased.");
		changeHappiness(-1);
	}

	public void hug()
	{
		System.out.println(name + " purrs contentedly.");
		changeHappiness(1);
	}

	public void teach(String songTitle)
	{
		if (songs == null)
			songs = new ArrayList<>();

		songs.add(songTitle);
	}

	public static void main(String [] args)
	{
		ArrayList<String> songs = new ArrayList<>();
		songs.add("Despacito");
		songs.add("Look What You Made Me Do");

		AdorableSingingCreature c1 = new AdorableSingingCreature("Pikachu", songs);

		songs.clear();
		songs.add("Twinkle, Twinkle, Little Star");
		songs.add("Mary Had a Little Lamb");

		AdorableSingingCreature c2 = new AdorableSingingCreature("Desmond", songs);

		Scanner in = new Scanner(System.in);

		while (true)
		{
			System.out.println();
			System.out.println("1. Ask your creatures to sing.");
			System.out.println("2. Poke your creatures.");
			System.out.println("3. Hug your creatures.");
			System.out.println("4. Teach your creatures a new song.");
			System.out.println("5. Check on your creatures' happiness.");
			System.out.println();
			System.out.print("What would you like to do? (-1 to exit) ");

			int n = in.nextInt();
			System.out.println();

			if (n == -1)
				break;
			else if (n == 1)
			{
				c1.sing();
				c2.sing();
			}
			else if (n == 2)
			{
				c1.poke();
				c2.poke();
			}
			else if (n == 3)
			{
				c1.hug();
				c2.hug();
			}
			else if (n == 4)
			{
				System.out.print("What song would you like to teach your creatures? ");

				// This is a really weird thing. If the Scanner just consumed
				// an integer, it will have left the "[enter]" hanging around,
				// so when you use nextLine(), you need to call it twice -- once
				// to get rid of that "[enter]", and again to read the string
				// that the user types for this new song.
				String s = in.nextLine();
				s = in.nextLine();
				c1.teach(s);
			}
			else if (n == 5)
			{
				System.out.println(c1.name + "'s happiness: " + c1.happiness);
				System.out.println(c2.name + "'s happiness: " + c2.happiness);
			}
		}
	}
}
