package Review;

// Idea: This program implements a gradebook by keeping a two-dimensional
// array of doubles. 
//
// Reviews: two-dimensional arrays of primitives, passing 
// two-dimensional array of primitives to methods, for loops,
// break, Math.max, Math.min.  
public class Gradebook {
	private static final int GRADES_ID_COLUMN = 0;
	private static final int STATS_NUM_COLUMNS = 4;	
	private static final int STATS_ID_INDEX= 0;
	private static final int STATS_MINIMUM_INDEX = 1;
	private static final int STATS_MAXIMUM_INDEX = 2;
	private static final int STATS_AVERAGE_INDEX = 3;

	private double[][] scores;
	private int numStudents;

	public Gradebook(int maxScores, int maxStudents) {
		scores = new double[maxStudents][];
		for (int row=0; row<maxStudents; row++) {
			scores[row] = new double[maxScores + 1];
		}
		
		numStudents = 0;
	}
	
	public void load(double[][] gradebookValues) {
		// For simplicity we are assuming
		// gradebookValues has at least one row
		
		scores = gradebookValues;
		numStudents = gradebookValues.length;
	}
	
	public void inputScore(int studentId, int assignmentIndex, double score){
		int index = mapIDToIndex(studentId);
		if (index != -1) {
			scores[index][assignmentIndex] = score;
		}
	}
	
	private int mapIDToIndex(int studentID) {
		for (int row=0; row<numStudents; row++) {
			if (scores[row][GRADES_ID_COLUMN] == studentID) {
				return row;
			}
		}
		
		return -1;  // Not found condition
	}
	
	public void addStudent(int studentID) {
		// Only add new student if doesn't already exist
		if (mapIDToIndex(studentID) == -1) {
			if (numStudents < scores.length) {
				scores[numStudents][GRADES_ID_COLUMN] = studentID;
				numStudents++;
			}
		}
	}
	
	public boolean isEmpty() {
		return (numStudents == 0);
	}
	
	public void print() {
		System.out.println("Gradebook");
		if (!isEmpty()) {
			for (int row=0; row<numStudents; row++) {
				for (int col=0; col<scores[0].length; col++) {
					if (col != GRADES_ID_COLUMN) {
						System.out.print(scores[row][col] + " ");
					} else {
						System.out.print("SID: " + (int)scores[row][col] + " ");
					}
				}
				System.out.println();
			}
		}
		System.out.println();
	}
	
	public double[][] stats() {
		double maximum, minimum, sum, currentValue;
		int numScores = scores[0].length - 1;  // One column used for ID
		
		// Creating result array
		double[][] result = new double[numStudents][];
		
		for (int row=0; row<numStudents; row++) {
			
			// Computing statistics for each student
			minimum = maximum = scores[row][1];
			sum = 0;
			for (int col=1; col<numScores+1; col++) {
				currentValue = scores[row][col];
				minimum = Math.min(currentValue, minimum);
				maximum = Math.max(currentValue, maximum);
				
				sum += currentValue;
			}
		
			// Saving student's results in array row
			result[row] = new double[STATS_NUM_COLUMNS];
			result[row][STATS_ID_INDEX] = scores[row][GRADES_ID_COLUMN];
			result[row][STATS_MINIMUM_INDEX] = minimum;
			result[row][STATS_MAXIMUM_INDEX] = maximum;
			result[row][STATS_AVERAGE_INDEX] = sum / numScores;
		}
		
		return result;
	}
	
	public void printStats(double[][] stats) {
		System.out.println("ID   MIN  MAX  AVG");
		for (int row=0; row<stats.length; row++) {
			for (int col=0; col<stats[0].length; col++) {
				if (col != STATS_ID_INDEX) {
					System.out.print(stats[row][col] + " ");
				} else {
					System.out.print((int)stats[row][col] + " ");
				}
			}
			System.out.println();
		}
		System.out.println();
	}
	
	public static void main(String[] args) {
		int maxScores = 3, maxStudents = 4, studentId;
		Gradebook gradebook = new Gradebook(maxScores, maxStudents);
		gradebook.print();
		
		// Initialize gradebook with some data
		studentId = 4120;
		gradebook.addStudent(studentId);
		gradebook.inputScore(studentId, 1, 85);
		gradebook.inputScore(studentId, 2, 90);

		studentId = 3100;
		gradebook.addStudent(studentId);
		gradebook.inputScore(studentId, 2, 70);
		gradebook.inputScore(studentId, 1, 81);
		gradebook.print();
		
		// Load some data
		double[][] dataToLoad = {{1024,  80, 30, 70, 90},
				                 {1500,  90, 90, 80, 75},
								 {1700,  99, 99, 99, 99}};
		
		gradebook.load(dataToLoad);
		gradebook.print();
		
		// Some statistics
		double[][] stats = gradebook.stats();
		gradebook.printStats(stats);
	}
}