/* 
GeoGebra - Dynamic Mathematics for Everyone
http://www.geogebra.org

This file is part of GeoGebra.

This program is free software; you can redistribute it and/or modify it 
under the terms of the GNU General Public License as published by 
the Free Software Foundation.

 */

package geogebra.kernel.statistics;

import geogebra.kernel.AlgoElement;
import geogebra.kernel.Construction;
import geogebra.kernel.GeoElement;
import geogebra.kernel.GeoList;
import geogebra.kernel.GeoNumeric;
import geogebra.kernel.arithmetic.NumberValue;

import org.apache.commons.math.stat.descriptive.rank.Percentile;


/**
 * Returns the percentile for a given percentage  in a list of numbers
 */

public class AlgoPercentile extends AlgoElement {

	private static final long serialVersionUID = 1L;
	private GeoList inputList; //input
	private GeoNumeric value; //input
	private GeoNumeric result; //output	
	private int size;
	private Percentile percentile;
	private double[] inputArray;
	private double val;



	public AlgoPercentile(Construction cons, String label, GeoList inputList, GeoNumeric value) {
		super(cons);
		this.inputList = inputList;
		this.value = value;
		result = new GeoNumeric(cons);

		setInputOutput();
		compute();
		result.setLabel(label);
	}

	public String getClassName() {
		return "AlgoPercentile";
	}

	protected void setInputOutput(){
		input = new GeoElement[2];
		input[0] = inputList;
		input[1] = value;

		output = new GeoElement[1];
		output[0] = result;
		setDependencies(); // done by AlgoElement
	}

	public GeoNumeric getResult() {
		return result;
	}

	protected final void compute() {

		//==========================
		// validation
		size = inputList.size();
		if (!inputList.isDefined() ||  size == 0) {
			result.setUndefined();
			return;
		} 

		if(value == null){
			result.setUndefined();
			return;
		}else{
			val = value.getDouble()*100;
		}

		if(val <= 0 || val > 100){
			result.setUndefined();
			return;
		}


		//==========================
		// compute result

		inputArray = new double[size];

		// load input value array from  geoList
		for (int i=0; i < size; i++) {
			GeoElement geo = inputList.get(i);
			if (geo.isNumberValue()) {
				NumberValue num = (NumberValue) geo;
				inputArray[i] = num.getDouble();	
			} else {
				result.setUndefined();
				return;
			}    		    		
		}   

		if(percentile == null)
			percentile = new Percentile();

		percentile.setData(inputArray);
		result.setValue(percentile.evaluate(val));
	}


}
