package vismon.data;


import vismon.gui.Vismon;
import vismon.util.Util;

public class Indicator {

    public static final double DEFAULT_PROB_VALUE = 0.0;

    private static final double ROUND_10 = 10;
    public static final int MIN_BEST = 1330;
    public static final int MAX_BEST = 1342;

    public static int numOfVisibleIndicators = 0;

    private String name;
    private String shortName;
    private String unit;

    private double min;                    //min of simulation values
    private double max;
    private double constraintValue;
    private double probabilityValue;

    private double avgContourStep;
    private int avgContourStepNumber;
    private double[] avgIsolineValues;

    private double roundValue;

    private int bestValue;
    private boolean visible;

    public Indicator() {
        min = Double.MAX_VALUE;
        max = Double.MIN_VALUE;
        visible = true;
        probabilityValue = DEFAULT_PROB_VALUE;

        ++numOfVisibleIndicators;
    }

    private void roundMinMax() {
        double diff = max - min;
        if (diff <= 0.1) {
            roundValue = 0.01;
            max = Math.floor(100 * max) * 0.01;
            min = Math.floor(100 * min) * 0.01;
        } else if (diff <= 1.0) {
            roundValue = 0.1;
            max = Math.floor(10 * max) * 0.1;
            min = Math.floor(10 * min) * 0.1;
        } else {
            roundValue = 1.0;
            max = Math.floor(max);
            min = Math.floor(min);
        }

        for (DataItem dataItem : Session.getDataItems()) {
            for (int i = 0; i < Session.getSimulationNum(); ++i) {
                double v = dataItem.getValue(i, this);
                if (v >= max)
                    dataItem.addValue(i, this, max - 1e-5);
            }
        }
    }


    public void doComputations() {
        roundMinMax();

        if (bestValue == MIN_BEST)
            constraintValue = max;
        else
            constraintValue = min;
    }

    public void setBestValue(int bestValue) {
        this.bestValue = bestValue;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getShortName() {
        return shortName;
    }

    public void setShortName(String shortName) {
        this.shortName = shortName;
    }

    public String getUnit() {
        return unit;
    }

    public void setUnit(String unit) {
        this.unit = unit;
    }

    public boolean isMaxBest() {
        return bestValue == MAX_BEST;
    }

    public boolean isMinBest() {
        return !isMaxBest();
    }

    public boolean isVisible() {
        return visible;
    }

    public void setVisible(boolean visible) {
        if (this.visible == visible)
            return;

        this.visible = visible;

        if (visible)
            ++numOfVisibleIndicators;
        else
            --numOfVisibleIndicators;

        Session.calculateDrawnRowCalNum();
    }

    public double getMin() {
        return min;
    }

    public void setMin(double min) {
        this.min = min;
    }

    public double getMax() {
        return max;
    }

    public void setMax(double max) {
        this.max = max;
    }

    public double getConstraintValue() {
        return constraintValue;
    }

    public void setConstraintValue(double constraintValue) {
        this.constraintValue = constraintValue;
    }

    public double getRoundValue() {
        return roundValue;
    }

    public void setAvgContourStep(double avgContourStep) {
        this.avgContourStep = avgContourStep;
    }

    public double getAvgContourStep() {
        return avgContourStep;
    }

    public int getAvgContourStepNumber() {
        return avgContourStepNumber;
    }

    public void setAvgContourStepNumber(int avgContourStepNumber) {
        this.avgContourStepNumber = avgContourStepNumber;
    }

    public void setAvgIsolineValues(double[] avgIsolineValues) {
        this.avgIsolineValues = avgIsolineValues;
    }

    public double getIsolineValue(int i) {
        return avgIsolineValues[i];
    }

    public void resetConstraintValue() {
        if (isMaxBest())
            constraintValue = min;
        else
            constraintValue = max;
    }

    public double getProbabilityValue() {
        return probabilityValue;
    }

    public void setProbabilityValue(double probabilityValue) {
        this.probabilityValue = probabilityValue;
        Session.checkIfShowProbCrossesOnCPs();
    }

    public void resetProbabilityValue() {
        this.setProbabilityValue(DEFAULT_PROB_VALUE);
        Session.checkIfShowProbCrossesOnCPs();
    }

    public boolean isDefaultProbabilityValue() {
        return Util.equals(probabilityValue, DEFAULT_PROB_VALUE);
    }

    @Override
    public String toString() {
        return name + " [" + shortName + "]";
    }

    @Override
    public boolean equals(Object o) {
        Indicator indO = (Indicator) o;
        return (indO.getName().equals(name));
    }
}
