
package de.ivu.elect.business.ergebnis.control.mass;

import java.util.Arrays;

import de.ivu.elect.business.ergebnis.entity.Stimmenart;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;

/**
 * arithmetisch mit variabler Grenze
 * Mittelwert der oberen 25 % Maßwerte
 * optional kann man noch die Werte gewichten, den höchsten wert mit 10, den zweit höchsten mit 9..... mit anzahl parteien = 10
 */
public class BrunosRelativesMassArithmetischesMittelVariableGrenze implements StimmenAbweichungMass {
    private final double gewichtungKleinerParteien;

    public BrunosRelativesMassArithmetischesMittelVariableGrenze(double gewichtungKleinerParteien) {
        this.gewichtungKleinerParteien = gewichtungKleinerParteien;
    }
    @Override
    public double berechneAbweichungImGebiet(AbweichungMassStimmenProvider stimmenProvider) {

        double sum=0;
        double sumnew=0;
        //double denominatorsum=0;

        for (Stimmenart stimmabgabeart : stimmenProvider.getStimmenarten()) {

            double gueltigeEingegeben = Math.max(1, stimmenProvider.getAnzahlGueltigeStimmenEingegeben(stimmabgabeart));
            double gueltigeHochgerechnet = Math.max(1, stimmenProvider.getAnzahlGueltigeStimmenHochgerechnet(stimmabgabeart));
            double[] masse= new double[35];//maximale anzahl an parteien BTW 2013
            int i = 0;

            for (PolitischeGruppe politischeGruppe : stimmenProvider.getPolitischeGruppen()) {
                double prozentEingegeben = stimmenProvider.getAnzahlStimmenEingegeben(politischeGruppe, stimmabgabeart) / gueltigeEingegeben;
                double prozentHochgerechnet = stimmenProvider.getAnzahlStimmenHochgerechnet(politischeGruppe, stimmabgabeart) / gueltigeHochgerechnet;
                double mass;

                if(prozentEingegeben!=0 && prozentHochgerechnet!=0) {
                    double min = Math.min(prozentEingegeben, prozentHochgerechnet);
                    mass = Math.abs(prozentEingegeben - prozentHochgerechnet) / Math.pow(min, gewichtungKleinerParteien); //Mass-Formel
                    masse[i] = mass;
                    i++;
                }
                else if (prozentEingegeben==0 && prozentHochgerechnet!=0){
                    double min = 1/gueltigeEingegeben;
                    mass = Math.abs(prozentEingegeben - prozentHochgerechnet) / Math.pow(min, gewichtungKleinerParteien); //Mass-Formel
                    masse[i] = mass;
                    i++;
                }
                else if (prozentEingegeben!=0 && prozentHochgerechnet==0){
                    double min = 1 / prozentEingegeben;
                    mass = Math.abs(prozentEingegeben - prozentHochgerechnet) / Math.pow(min, gewichtungKleinerParteien); //Mass-Formel
                    masse[i] = mass;
                    i++;
                }
                else{
                    //mass = 0;
                    masse[i]=0;
                    i++;
                }
            }
            double[] massenew= Arrays.copyOfRange(masse,0,i);
            Arrays.sort(massenew);
            int count = 0;

            for(int j=massenew.length-1;Math.round((massenew.length/(1.25d))-0.5d)<=j;j--) {//durchlaufe nur die oberen 20 bis 30%
                sum += massenew[j];
                count++;
                //sum += massenew[j]*j;//gewichtung mit eingebaut
                //denominatorsum += j;
            }

            sumnew = sum / Math.max(1, count); // NOSONAR, keine Division durch 0 möglich...
        }

        return 100*(sumnew);
    }



    @Override
    public String getMessageKey() {
        return "stimmen.abweichung.mass.relativ.arithmetisches.mittel.v";
    }
}
