package edu.unl.cse.soft160.statistics;

import java.util.Scanner;

/**
 * Computes simple statistics of three values
 */
public class GeneralizedStatistics {
	public enum StatisticsType {
		MEAN, MEDIAN, // to keep this example shorter, we're omitting maximum and minimum
	}

	private static String getUserInput(String prompt, Scanner scanner) {
		System.out.print(prompt);
		String userInput = scanner.nextLine();
		return userInput;
	}

	private static Number getValue(String ordinal, Scanner scanner) {
		String userInput = getUserInput("Enter the " + ordinal + " value: ", scanner);
		if (userInput.contains(".")) {
			return Double.valueOf(userInput);
		} else {
			return Integer.valueOf(userInput);
		}
	}

	private static StatisticsType getStaticsticsType(Scanner scanner) {
		String userInput = getUserInput("Please enter the statistic to calculate: ", scanner);
		userInput = userInput.toUpperCase();
		StatisticsType statisticsType = StatisticsType.valueOf(userInput);
		return statisticsType;
	}

	private static double computeMean(double firstValue, double secondValue, double thirdValue) {
		double statistic = (firstValue + secondValue + thirdValue) / 3;
		return statistic;
	}

	private static double computeMedian(double firstValue, double secondValue, double thirdValue) {
		double statistic = Double.NaN;
		if (((secondValue <= firstValue) && (firstValue <= thirdValue))
				|| ((secondValue >= firstValue) && (firstValue >= thirdValue))) {
			statistic = secondValue;
		}
		if (((firstValue <= secondValue) && (secondValue <= thirdValue))
				|| ((firstValue >= secondValue) && (secondValue >= thirdValue))) {
			statistic = secondValue;
		}
		if (((firstValue <= thirdValue) && (thirdValue <= secondValue))
				|| ((firstValue >= thirdValue) && (thirdValue >= secondValue))) {
			statistic = secondValue;
		}
		return statistic;
	}

	private static int computeMean(int firstValue, int secondValue, int thirdValue) {
		int statistic = (firstValue + secondValue + thirdValue) / 3;
		return statistic;
	}

	private static int computeMedian(int firstValue, int secondValue, int thirdValue) {
		int statistic = Integer.MAX_VALUE;
		if (((secondValue <= firstValue) && (firstValue <= thirdValue))
				|| ((secondValue >= firstValue) && (firstValue >= thirdValue))) {
			statistic = secondValue;
		}
		if (((firstValue <= secondValue) && (secondValue <= thirdValue))
				|| ((firstValue >= secondValue) && (secondValue >= thirdValue))) {
			statistic = secondValue;
		}
		if (((firstValue <= thirdValue) && (thirdValue <= secondValue))
				|| ((firstValue >= thirdValue) && (thirdValue >= secondValue))) {
			statistic = secondValue;
		}
		return statistic;
	}

	private static Number computeStatisticFromInput(StatisticsType type, Scanner scanner) {
		Number firstInputValue = getValue("first", scanner);
		Number secondInputValue = getValue("second", scanner);
		Number thirdInputValue = getValue("third", scanner);
		Number statisticValue = null;
		if (firstInputValue instanceof Integer 
				&& secondInputValue instanceof Integer
				&& thirdInputValue instanceof Integer) {
			int firstValue = (int) firstInputValue;
			int secondValue = (int) secondInputValue;
			int thirdValue = (int) thirdInputValue;
			if (type == StatisticsType.MEAN) {
				statisticValue = computeMean(firstValue, secondValue, thirdValue);
			} else if (type == StatisticsType.MEDIAN) {
				statisticValue = computeMedian(firstValue, secondValue, thirdValue);
			} else {
				System.err.println("Cannot compute " + type + ".");
				statisticValue = Integer.MAX_VALUE;
			}
		} else {
			double firstValue = (double) firstInputValue;
			double secondValue = (double) secondInputValue;
			double thirdValue = (double) thirdInputValue;
			if (type == StatisticsType.MEAN) {
				statisticValue = computeMean(firstValue, secondValue, thirdValue);
			} else if (type == StatisticsType.MEDIAN) {
				statisticValue = computeMedian(firstValue, secondValue, thirdValue);
			} else {
				System.err.println("Cannot compute " + type + ".");
				statisticValue = Double.NaN;
			}
		}
		return statisticValue;
	}

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		StatisticsType type = getStaticsticsType(scanner);
		Number statistic = computeStatisticFromInput(type, scanner);
		scanner.close();
		System.out.println("The " + type.toString().toLowerCase() + " is " + statistic);
	}
}