package modified;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Scanner;

/**
 * A short program for editing a list, to confirm that it works. This program
 * does not validate input, and will likely crash if used incorrectly.
 * 
 * @author Chad Hogg, William Killian
 */
public class ListProgram {

	/**
	 * Runs the program.
	 * 
	 * @param args Unused.
	 */
	public static void main(String[] args) {
		MUList<String> list = null;
		String choice = null;
		Iterator<String> iter = null;

		Scanner console = new Scanner(System.in);
		do {
			System.out.print("Command > ");
			choice = console.next();
			try {
				switch (choice) {
				case "create":
					list = create(console);
					break;
				case "print":
					print(list);
					break;
				case "insert":
					insert(list, console);
					break;
				case "remove":
					remove(list, console);
					break;
				case "iter":
					iter = iterator(iter, list, console);
					break;
				case "quit":
					System.out.println("Goodbye!");
					break;
				default:
					throw new IllegalArgumentException("Unknown command: " + choice);
				case "?":
				case "help":
					printMenu();
					break;
				}
			} catch (IllegalArgumentException e) {
				System.out.println(e.getMessage());
				printMenu();
			} catch (NullPointerException e) {
				System.out.println("Error: NullPointerException ... Did you create the list?");
			} catch (NoSuchElementException e) {
				System.out.println("Error: NoSuchElementException ... unable to tokenize input");
			}
		} while (!choice.equals("quit"));
		console.close();
	}

	private static MUList<String> create(Scanner console) {
		MUList<String> newList = null;
		String choice = console.next();
		switch (choice) {
		case "array":
			newList = new MUArrayList<String>();
			break;
		case "linked":
			newList = new MULinkedList<String>();
			break;
		default:
			throw new IllegalArgumentException("Unknown option for \"create\": " + choice);
		}
		return newList;
	}

	private static void insert(MUList<String> list, Scanner console) {
		String choice = console.next();
		switch (choice) {
		case "before":
			list.insertBefore(console.nextInt(), console.next());
			break;
		case "after":
			list.insertAfter(console.nextInt(), console.next());
			break;
		case "front":
			list.insertFront(console.next());
			break;
		case "back":
			list.insertBack(console.next());
			break;
		default:
			throw new IllegalArgumentException("Unknown option for \"insert\": " + choice);
		}
	}

	private static void remove(MUList<String> list, Scanner console) {
		String choice = console.next();
		String removed = null;
		switch (choice) {
		case "at":
			removed = list.removeAt(console.nextInt());
			break;
		case "front":
			removed = list.removeFront();
			break;
		case "back":
			removed = list.removeBack();
			break;
		default:
			throw new IllegalArgumentException("Unknown option for \"remove\": " + choice);
		}
		System.out.println("INFO: Removed " + removed + " from the list");
	}

	private static Iterator<String> iterator(Iterator<String> iter, MUList<String> list, Scanner console) {
		String choice = console.next();
		switch (choice) {
		case "init":
			return list.iterator();
		case "next":
			String value = iter.next();
			System.out.println("INFO: next element is " + value);
			return iter;
		case "hasnext":
			System.out.println("INFO: hasnext is " + iter.hasNext());
			return iter;
		case "remove":
			iter.remove();
			System.out.println("INFO: removed last element \"next\"-ed");
			return iter;
		default:
			throw new IllegalArgumentException("Unknown option for \"iter\": " + choice);
		}
	}

	private static void print(MUList<String> list) {
		System.out.println(list.toString());
	}

	/**
	 * Prints a menu of options.
	 */
	public static void printMenu() {
		System.out.println("  create [array|linked] -- creates a new List");
		System.out.println();
		System.out.println("  insert [front|back] [value]");
		System.out.println("  insert [before|after] [index] [value]");
		System.out.println();
		System.out.println("  remove [front|back]");
		System.out.println("  remove at [index]");
		System.out.println();
		System.out.println("  iter init -- initializes a new iterator");
		System.out.println("  iter next -- calls .next() on the current iterator");
		System.out.println("  iter remove -- calls .remove() on the current iterator");
		System.out.println("  iter hasnext -- calls .hasNext() on the current iterator");
		System.out.println();
		System.out.println("  help");
		System.out.println("  quit");
	}

}
