import cs1.Keyboard;

/**
GradeBook class asks the user to supply the number of grades,
uses that number to initialize a GradeBook object, and
Collects grades from the user (keyboard) then
computes and displays statistics about the grades
@author Ron Davidson
*/

public class GradeBook1
{
	private int numElements;
	private double[ ] scores;

	/**
	Creates a GradeBook object and initializes the internal
	array to the number of elements specified by the user.
	*/

	//parametrized constructor that accepts one parameter (passed from main)
	public GradeBook1 (int numElements)
	{
		this.numElements = numElements;
	}


	/**
	Uses the Console readDouble class to read values entered
	by the user and assigns them into the array.
	*/
	public void fillScores()
	{
		scores = new double[numElements];	//scores.length

		for (int i=0; i<=numElements-1; i++)
		{
			System.out.print ("Grade for class " + (i+1) + ":\t");
			scores[i] = Keyboard.readDouble();

			while (scores[i] < 0 || scores[i] > 4)
			{
				System.out.println ("Invalid grade");
				System.out.print ("Grade for class " + (i+1) + ": \t");
				scores[i] = Keyboard.readDouble();
			}
			//System.out.println ("entered score :" +scores[i]);
		}
	}


	/**
	Performs a linear search for the minimum value in the array
	@return the minimum value
	*/
	public double findMinimum()
	{
		double min = scores[0];

		for (int i=0; i<=scores.length-1; i++)
		{
			if (scores[i] < min)
			{
				min = scores[i];
			}
		}
		return min;
	}


	/**
	Performs a linear search for the maximum value in the array
	@return the maximum value
	*/
	public double findMaximum()
	{
		double max = 0;

		for (int i=0; i<=scores.length-1; i++)
		{
			if (scores[i] > max)
			{
				max = scores[i];
			}
		}
		return max;
	}


	/**
	Sums the grades and calculates the mean (average).
	@return the mean
	*/
	public double calcMean()
	{
		double total_score = 0;
		double mean =0 ;

		for (int i=0; i<scores.length; i++)
		{
			total_score = total_score + scores[i];
			mean = total_score / scores.length;
		}
		return mean;
	}


	/** Find # grades above average */

	public int countGoodGrades()
	{
		int count_goods=0;
		for (int i=0; i<scores.length; i++)
		{
			if (scores[i] > calcMean())
			{
				count_goods++;
			}
		}
		return count_goods;
	}


	/**
	Sums the squares of the variance of each grade from mean,
	divides by the count, and takes the square root of the result
	(result is the square root of the total variance) which is the StdDev
	@returns the Standard deviation.
	*/
	public double calcStdDev()
	{
		double sumVarianceSq = 0;
		double variance;
		double stdDeviation = 0;

		for (int i=0; i<scores.length; i++)
		{
			variance = scores[i] - calcMean();
			sumVarianceSq = sumVarianceSq + (variance*variance);
		}
		stdDeviation = Math.sqrt(sumVarianceSq / scores.length);
		return stdDeviation;
	}

/*
	public double calcStdDev()
	{
		double sumGradeSq = 0;
		double stdDeviation = 0;

		for (int i=0; i<scores.length; i++)
		{
			sumGradeSq = sumGradeSq + scores[i]*scores[i];
		}
		stdDeviation=Math.sqrt(sumGradeSq/scores.length - calcMean()*calcMean());
		return stdDeviation;
	}

*/

	/**
	Finds the median grade where ½ the grades are less and ½ are greater
	It sorts the data first by calling a private sort method based on the
	BubbleSort Algorithm @return the median value
	*/
	public double findMedian()
	{
		double median = 0;

		sort();

		if (scores.length % 2 != 0)
		{
			median = scores[(scores.length/2)];
		}
		else
		{
			//find the average of the two middle elements
			median = (
					  scores[(scores.length/2)] +
					  scores[(scores.length/2)-1]
					  ) / 2;
		}
		return median;
	}



	/**
		Sorts the array using the Bubblesort Algorithm.
	*/
	//Bubble sort goes through all elements of array and swap
  	//adjacent values until whole list is sorted.

	public void sort()
	{
		int i, n;

		for(i=0; i<scores.length; i++)
		{
		   for(n=1; n<(scores.length-i); n++)
		   {
			  if( scores[n-1]>scores[n] )
			  {
				  double temp = scores[n];
				  scores[n] = scores[n-1];
				  scores[n-1] = temp;
			  }
		   }
	    }

	    for (int x = 0; x < scores.length; x++)
		{
				System.out.println (scores[x]);
		}
	}


	/**
	Converts the array contents into a String for display
	@return a string representing the contents of the grade book object.
	*/
	public String toString()
	{
		String gradesStr = "";
		return gradesStr;
	}
}