package ij.util;
import java.util.Arrays;

public class ArrayUtil {
    private int size;
    float[] values;
    boolean sorted;

    public void setSize(int si) {
        size = si;
    }

    /**
     * constructeur
     *
     * @param size number of elements
     */
    public ArrayUtil(int size) {
        this.size = size;
        values = new float[size];
        sorted = false;
    }
    
    /**
     * constructeur
     *
     * @param data float array
     */
    public ArrayUtil(float[] data) {
        this.size = data.length;
        sorted = false;
        values = data;
    }

    /**
     * put a value to a index
     *
     * @param pos position in the array
     * @param value value to put
     * @return false if position does not exist
     */
    public boolean putValue(int pos, float value) {
        if (pos<size) {
            values[pos] = value;
            sorted = false;
            return true;
        } else {
            return false;
        }
    }

    /**
     * Average value
     * @return average value
     */
    public double getMean() {
        double total = 0;
        for (int i=0; i<size; i++)
            total += values[i];
        return total/size;
    }

    /**
     * The median (sorted array)
     * @return mediane
     */
    public double medianSort() {
        if (!sorted)
            sort();
        if (size % 2==1)
            return values[size/2];
        else
            return (0.5f * (values[size/2 - 1] + values[size/2]));
    }

    public void sort() {
        if (size<values.length) {
            float[] tosort = new float[size];
            System.arraycopy(values, 0, tosort, 0, size);
            Arrays.sort(tosort);
            System.arraycopy(tosort, 0, values, 0, size);
        } else
            Arrays.sort(values);
        sorted = true;
    }

    public boolean isMaximum(double val) {
        int i = 0;
        boolean maxok = true;
        while ((i<size) && (values[i]<=val)) {
            i++;
        }
        if (i < size) {
            maxok = false;
        }
        return maxok;
    }

    /**
     * The minimum value
     *
     * @return min value
     */
    public double getMinimum() {
        double min = values[0];
        for (int i = 1; i < size; i++) {
            if (values[i] < min) {
                min = values[i];
            }
        }
        return min;
    }

    /**
     * The maximum value
     *
     * @return max value
     */
    public double getMaximum() {
        double max = values[0];
        for (int i = 1; i < size; i++) {
            if (values[i] > max) {
                max = values[i];
            }
        }
        return max;
    }

    /**
     * Variance value 
     *
     * @return variance
     */
    public double getVariance() {
       if (size == 1) {
            return 0;
        }

        double total = 0;
        double total2 = 0;

        for (int i = 0; i < size; i++) {
            total += values[i];
            total2 += values[i] * values[i];
        }

        double var = (double) ((total2 - (total * total / size)) / (size - 1));
        return var;
    }
    
    
    /**
     * information to be displayed
     *
     * @return text
     */
    public String toString() {
        String str = "{" + values[0];
        for (int i = 1; i < size; i++) {
            str = str + ", " + values[i];
        }
        return str + "}";
    }
}