package math.bmi;

public class BMI {
    public static final int WE_BIALKO = 4;// w kcal
    public static final int WE_TLUSZCZ = 9;// w kcal
    public static final int WE_CUKIER = 4;// w kcal
    public static final int WE_1KG_TLUSZCZ = 7000;//w kcal
    public static final String[] PLEC = {"M", "K"};
    public static final String[] STAN_ODZYWIENIA = {"NIEDOZYWIENIE", "NORMA",
            "NADWAGA", "OTYLOSC_I", "OTYLOSC_II", "OTYLOSC_III"};
    public static final String[] TYP_OTYLOSCI = {"BEZ_OTYLOSCI", "BRZUSZNA",
            "POSLADKOWO_UDOWA"};
    public static final String[] TRYB_ZYCIA = {"LEZACY", "SIEDZACY",
            "UMIARKOWANY", "SREDNI", "INTENSYWNY"};
    public static final String[] BUDOWA_CIALA = {"DROBNA", "PRZECIETNA",
            "MASYWNA"};
    private double wagaAkt;
    private double wzrost;
    private int wiek;
    private String plec;
    private double obwodPepka;
    private double obwodBioder;
    private double bmi;
    private String stanOdzywienia;
    private double whr;
    private String typOtylosci;
    private double wagaMax;
    private double wagaMin;
    private double wagaOpt;
    private double nadwaga;
    private String trybZycia;
    private String budowa;
    private int Epodst;
    private int Eaktyw;
    private int Ewiek;
    private int Ebud;
    private int Eopt;
    private int szybkoscOdchudzania;//kcal/24h
    private int Ediety;
    private int nadwyzkaKalorii;
    private int czasOdchudzania;

    public BMI(double wagaAkt, double wzrost, int wiek, String plec,
               double obwodPepka, double obwodBioder, String trybZycia,
               String budowa, int szybkoscOdchudzania) {
        this.wagaAkt = wagaAkt;
        this.wzrost = wzrost;
        this.wiek = wiek;
        this.plec = plec;
        this.obwodPepka = obwodPepka;
        this.obwodBioder = obwodBioder;
        bmi = obliczBMI(wagaAkt, wzrost);
        stanOdzywienia = obliczStanOdzywienia(bmi, plec, wiek);
        whr = whr(obwodPepka, obwodBioder);
        typOtylosci = obliczTypOtylosci(whr, bmi, plec);
        wagaMax = wagaMax(wzrost);
        wagaMin = wagaMin(wzrost);
        wagaOpt = wagaOpt(wzrost);
        nadwaga = nadwaga(wagaAkt, wagaOpt);
        Epodst = obliczEpodst(wagaOpt);
        Eaktyw = obliczEaktyw(trybZycia, wagaOpt);
        Ewiek = obliczEwiek(wiek);
        Ebud = obliczEbud(budowa, Epodst, Eaktyw, Ewiek);
        Eopt = Epodst + Eaktyw + Ewiek + Ebud;
        this.szybkoscOdchudzania = szybkoscOdchudzania;
        nadwyzkaKalorii = (int) (nadwaga * WE_1KG_TLUSZCZ);
        if (nadwyzkaKalorii > 0) {
            Ediety = Eopt - szybkoscOdchudzania;
            if (Ediety < 600) {
                Ediety = 600;
                szybkoscOdchudzania = Eopt - Ediety;
            }
        } else {
            Ediety = Eopt + szybkoscOdchudzania;
            if (Ediety > 3000) {
                Ediety = 3000;
                szybkoscOdchudzania = Ediety - Eopt;
            }
        }
        czasOdchudzania = Math.abs((nadwyzkaKalorii / szybkoscOdchudzania));
    }

    public double getWagaAkt() {
        return wagaAkt;
    }

    public double getWzrost() {
        return wzrost;
    }

    public double getObwodPepka() {
        return obwodPepka;
    }

    public String getPlec() {
        return plec;
    }

    public double getObwodBioder() {
        return obwodBioder;
    }

    public double getBmi() {
        return bmi;
    }

    public String getStanOdzywienia() {
        return stanOdzywienia;
    }

    public double getWhr() {
        return whr;
    }

    public String getTypOtylosci() {
        return typOtylosci;
    }

    public int getSzybkoscOdchudzania() {
        return szybkoscOdchudzania;
    }

    public void setSzybkoscOdchudzania(int szybkoscOdchudzania) {
        this.szybkoscOdchudzania = szybkoscOdchudzania;
    }

    public double getWagaMax() {
        return wagaMax;
    }

    public double getWagaMin() {
        return wagaMin;
    }

    public double getWagaOpt() {
        return wagaOpt;
    }

    public double getNadwaga() {
        return nadwaga;
    }

    public int getWiek() {
        return wiek;
    }

    public String getTrybZycia() {
        return trybZycia;
    }

    public void setTrybZycia(String trybZycia) {
        this.trybZycia = trybZycia;
    }

    public String getBudowa() {
        return budowa;
    }

    public void setBudowa(String budowa) {
        this.budowa = budowa;
    }

    public int getEpodst() {
        return Epodst;
    }

    public void setEpodst(int epodst) {
        Epodst = epodst;
    }

    public int getEaktyw() {
        return Eaktyw;
    }

    public void setEaktyw(int eaktyw) {
        Eaktyw = eaktyw;
    }

    public int getEwiek() {
        return Ewiek;
    }

    public void setEwiek(int ewiek) {
        Ewiek = ewiek;
    }

    public int getEbud() {
        return Ebud;
    }

    public void setEbud(int ebud) {
        Ebud = ebud;
    }

    public int getEopt() {
        return Eopt;
    }

    public void setEopt(int eopt) {
        Eopt = eopt;
    }

    public static int getWeBialko() {
        return WE_BIALKO;
    }

    public static int getWeTluszcz() {
        return WE_TLUSZCZ;
    }

    public static int getWeCukier() {
        return WE_CUKIER;
    }

    public static String[] getBudowaCiala() {
        return BUDOWA_CIALA;
    }

    public void setWagaAkt(double wagaAkt) {
        this.wagaAkt = wagaAkt;
    }

    public void setWzrost(double wzrost) {
        this.wzrost = wzrost;
    }

    public void setWiek(int wiek) {
        this.wiek = wiek;
    }

    public void setPlec(String plec) {
        this.plec = plec;
    }

    public void setObwodPepka(double obwodPepka) {
        this.obwodPepka = obwodPepka;
    }

    public void setObwodBioder(double obwodBioder) {
        this.obwodBioder = obwodBioder;
    }

    public void setBmi(double bmi) {
        this.bmi = bmi;
    }

    public void setStanOdzywienia(String stanOdzywienia) {
        this.stanOdzywienia = stanOdzywienia;
    }

    public void setWhr(double whr) {
        this.whr = whr;
    }

    public void setTypOtylosci(String typOtylosci) {
        this.typOtylosci = typOtylosci;
    }

    public void setWagaMax(double wagaMax) {
        this.wagaMax = wagaMax;
    }

    public void setWagaMin(double wagaMin) {
        this.wagaMin = wagaMin;
    }

    public void setWagaOpt(double wagaOpt) {
        this.wagaOpt = wagaOpt;
    }

    public void setNadwaga(double nadwaga) {
        this.nadwaga = nadwaga;
    }

    private static double obliczBMI(double masa, double wzrost) {
        return roundToDecimal(masa / Math.pow(wzrost / 100, 2), 1);
    }

    private static String obliczStanOdzywienia(double bmi, String plec, int wiek) {
        String sto = null;
        if (plec.equals(PLEC[0])) {
            if (bmi < 18.5) {
                sto = STAN_ODZYWIENIA[0];
            } else if ((bmi >= 18.5) && (bmi < 25.0)) {
                sto = STAN_ODZYWIENIA[1];
            } else if ((bmi >= 25.0) && (bmi < 30.0)) {
                sto = STAN_ODZYWIENIA[2];
            } else if ((bmi >= 30.0) && (bmi < 35.0)) {
                sto = STAN_ODZYWIENIA[3];
            } else if ((bmi >= 35.0) && (bmi < 40.0)) {
                sto = STAN_ODZYWIENIA[4];
            } else {
                sto = STAN_ODZYWIENIA[5];
            }
        } else if (plec.equals(PLEC[1])) {
            if (wiek < 35) {
                if (bmi < 18.5) {
                    sto = STAN_ODZYWIENIA[0];
                } else if ((bmi >= 18.5) && (bmi < 25.0)) {
                    sto = STAN_ODZYWIENIA[1];
                } else if ((bmi >= 25.0) && (bmi < 30.0)) {
                    sto = STAN_ODZYWIENIA[2];
                } else if ((bmi >= 30.0) && (bmi < 35.0)) {
                    sto = STAN_ODZYWIENIA[3];
                } else if ((bmi >= 35.0) && (bmi < 40.0)) {
                    sto = STAN_ODZYWIENIA[4];
                } else {
                    sto = STAN_ODZYWIENIA[5];
                }
            } else if (wiek >= 35 && wiek < 45) {
                if (bmi < 19.5) {
                    sto = STAN_ODZYWIENIA[0];
                } else if ((bmi >= 19.5) && (bmi < 26.0)) {
                    sto = STAN_ODZYWIENIA[1];
                } else if ((bmi >= 26.0) && (bmi < 30.0)) {
                    sto = STAN_ODZYWIENIA[2];
                } else if ((bmi >= 30.0) && (bmi < 35.0)) {
                    sto = STAN_ODZYWIENIA[3];
                } else if ((bmi >= 35.0) && (bmi < 40.0)) {
                    sto = STAN_ODZYWIENIA[4];
                } else {
                    sto = STAN_ODZYWIENIA[5];
                }
            } else if (wiek >= 45 && wiek < 55) {
                if (bmi < 20.5) {
                    sto = STAN_ODZYWIENIA[0];
                } else if ((bmi >= 20.5) && (bmi < 27.0)) {
                    sto = STAN_ODZYWIENIA[1];
                } else if ((bmi >= 27.0) && (bmi < 30.0)) {
                    sto = STAN_ODZYWIENIA[2];
                } else if ((bmi >= 30.0) && (bmi < 35.0)) {
                    sto = STAN_ODZYWIENIA[3];
                } else if ((bmi >= 35.0) && (bmi < 40.0)) {
                    sto = STAN_ODZYWIENIA[4];
                } else {
                    sto = STAN_ODZYWIENIA[5];
                }
            } else if (wiek >= 55 && wiek < 65) {
                if (bmi < 21.5) {
                    sto = STAN_ODZYWIENIA[0];
                } else if ((bmi >= 21.5) && (bmi < 27.0)) {
                    sto = STAN_ODZYWIENIA[1];
                } else if ((bmi >= 27.0) && (bmi < 31.0)) {
                    sto = STAN_ODZYWIENIA[2];
                } else if ((bmi >= 31.0) && (bmi < 35.0)) {
                    sto = STAN_ODZYWIENIA[3];
                } else if ((bmi >= 35.0) && (bmi < 40.0)) {
                    sto = STAN_ODZYWIENIA[4];
                } else {
                    sto = STAN_ODZYWIENIA[5];
                }
            } else if (wiek >= 65) {
                if (bmi < 22.5) {
                    sto = STAN_ODZYWIENIA[0];
                } else if ((bmi >= 22.5) && (bmi < 28.0)) {
                    sto = STAN_ODZYWIENIA[1];
                } else if ((bmi >= 28.0) && (bmi < 31.0)) {
                    sto = STAN_ODZYWIENIA[2];
                } else if ((bmi >= 31.0) && (bmi < 35.0)) {
                    sto = STAN_ODZYWIENIA[3];
                } else if ((bmi >= 35.0) && (bmi < 40.0)) {
                    sto = STAN_ODZYWIENIA[4];
                } else {
                    sto = STAN_ODZYWIENIA[5];
                }
            }
        }
        return sto;
    }

    private static String obliczTypOtylosci(double whr, double bmi, String plec) {
        String to = null;
        if (bmi >= 30) {
            if (plec.equals(PLEC[0])) {
                if (whr >= 1.0) {
                    to = TYP_OTYLOSCI[1];
                } else if (whr < 1.0) {
                    to = TYP_OTYLOSCI[2];
                }
            } else if (plec.equals(PLEC[1])) {
                if (whr >= 0.85) {
                    to = TYP_OTYLOSCI[1];
                } else if (whr < 0.85) {
                    to = TYP_OTYLOSCI[2];
                }
            }
        } else {
            to = TYP_OTYLOSCI[0];
        }
        return to;
    }

    private static double wagaMin(double wzrost) {
        return roundToDecimal(19.0 * Math.pow(wzrost / 100, 2), 1);
    }

    private static double wagaMax(double wzrost) {
        return roundToDecimal(25.0 * Math.pow(wzrost / 100, 2), 1);
    }

    private static double wagaOpt(double wzrost) {
        double max = wagaMax(wzrost);
        double min = wagaMin(wzrost);
        return roundToDecimal(max - ((max - min) / 2), 1);
    }

    private static double nadwaga(double wagaAkt, double wagaOpt) {
        return roundToDecimal(wagaAkt - wagaOpt, 2);
    }

    private static double whr(double obwodPepka, double obwodBioder) {
        return roundToDecimal(obwodPepka / obwodBioder, 2);
    }

    public static double roundToDecimal(double num, int dec) {
        int multi = (int) Math.pow(10, dec);
        int temp = (int) Math.round(num * multi);
        return (double) temp / multi;
    }

    private static int obliczEaktyw(String trybZycia, double wagaOpt) {
        int e = 0;
        if (trybZycia.equals(TRYB_ZYCIA[0])) {
            e = 0;
        } else if (trybZycia.equals(TRYB_ZYCIA[1])) {
            e = (int) (wagaOpt * 6);
        } else if (trybZycia.equals(TRYB_ZYCIA[2])) {
            e = (int) (wagaOpt * 10);
        } else if (trybZycia.equals(TRYB_ZYCIA[3])) {
            e = (int) (wagaOpt * 15);
        } else if (trybZycia.equals(TRYB_ZYCIA[4])) {
            e = (int) (wagaOpt * 20);
        }
        return e;
    }

    private static int obliczEpodst(double wagaOpt) {
        return (int) (wagaOpt * 20);
    }

    private static int obliczEwiek(int wiek) {
        int e = 0;
        if ((wiek > 10) && (wiek < 18)) {
            e = 400;
        }
        if (wiek > 70) {
            e = -300;
        }
        if (wiek > 60) {
            e = -200;
        }
        return e;
    }

    private static int obliczEbud(String budowa, int epodst, int eaktyw,
                                  int ewiek) {
        int e = 0;
        if (budowa.equals(BUDOWA_CIALA[0])) {
            e = -(int) (0.1 * (epodst + eaktyw + ewiek));
        } else if (budowa.equals(BUDOWA_CIALA[2])) {
            e = (int) (0.1 * (epodst + eaktyw + ewiek));
        } else if (budowa.equals(BUDOWA_CIALA[1])) {
            e = 0;
        }
        return e;
    }

    public int getEdiety() {
        return Ediety;
    }

    public void setEdiety(int ediety) {
        Ediety = ediety;
    }

    public int getNadwyzkaKalorii() {
        return nadwyzkaKalorii;
    }

    public void setNadwyzkaKalorii(int nadwyzkaKalorii) {
        this.nadwyzkaKalorii = nadwyzkaKalorii;
    }

    public int getCzasOdchudzania() {
        return czasOdchudzania;
    }

    public void setCzasOdchudzania(int czasOdchudzania) {
        this.czasOdchudzania = czasOdchudzania;
    }
}
