import java.text.ParseException;
import java.util.NoSuchElementException;
import java.util.Scanner;

/**
 * Demonstrates throwing and catching exceptions,
 * by asking for a number and then possibly throwing
 * one of several possible Exceptions.
 * 
 * Predict what is printed by each of the following inputs:
 * 	9   109   -9    0     non-number    ctrl-Z
 * Then run the program to test your prediction.
 *
 * Also, why does ParseException need a "throws"
 * while RuntimeException does not?
 * 
 * @author David Mutchler.
 *         Created Sep 17, 2008.
 */
public class Main {

	/**
	 * Demonstrates throwing and catching exceptions.
	 *
	 * @param args Command-line arguments (ignored)
	 * @throws ParseException Checked exception that might get back to main
	 */
	public static void main(String[] args) throws ParseException {
		int x = Main.method1();
		System.out.println("method 1 returned " + x);
	}
	
	private static int method1() throws ParseException  {
		System.out.println("Entered method 1");
		
		try {
			int y = Main.method2();
			System.out.println("method 2 returned " + y);
			
		} catch (NullPointerException exception) {
			System.out.println("Caught a NullPointerException");
			
		} catch (NoSuchElementException exception) {
			System.out.println("Caught this exception: " + exception);
			
		} finally {
			System.out.println("Reached finally in method 1");
		}
		
		System.out.println("Reached end of method 1");
		return 1;
	}
	
	private static int method2() throws ParseException {
		System.out.println("Entered method 2");
		
		int z = Main.method3();
		
		System.out.println("method 3 returned " + z);
		System.out.println("Reached end of method 2");
		return 2;
	}
	
	private static int method3() throws ParseException {
		System.out.println("Entered method 3");
		
		try {
			Scanner in = new Scanner(System.in);
			
			System.out.println("Enter a number");
			System.out.print("Try 9, 109, -9, 0, non-number, ctrl-Z: ");
			
			int zztop = in.nextInt();
			
			System.out.println( 1000 / zztop);
			
			if (zztop > 100) {
				throw new RuntimeException("Too big!");
			}
			
			if (zztop < 0) {
				throw new ParseException("No negative numbers, please!", zztop);
			}
			
		} catch (ArithmeticException exception) {
			System.out.println("Caught " + exception + " in method 3");
			
		} finally {
			System.out.println("Reached finally in method 3");
		}
		
		System.out.println("Reached end of method 3");
		return 3;
	}
}