package sk.upjs.umv;
import java.util.List;
import org.apache.commons.math3.util.*;
public class Zlomok extends Number implements Comparable<Zlomok>,Roundable {
        private final int citatel;
        private final int menovatel;
        public static final Zlomok POLOVICA = new Zlomok(1,2);
        public Zlomok(int citatel, int menovatel) {
                this.citatel = citatel;
                this.menovatel = menovatel;
        }
        public int getCitatel() {
                return this.citatel;
        }
        public int getMenovatel() {
                return this.menovatel;
        }
        public Zlomok normalize() {
                int najSpolocnyDelitel = ArithmeticUtils.gcd(menovatel, citatel);
                int novyMenovatel = menovatel / najSpolocnyDelitel;
                int novyCitatel = citatel / najSpolocnyDelitel;
                return new Zlomok(novyCitatel, novyMenovatel);
        }
        public String toString() {
                return citatel + "/" + menovatel;
        }
        public boolean equals2(Object obj) {
                if (obj instanceof Zlomok) {
                        Zlomok z = (Zlomok) obj;
                        Zlomok nasZlomok = this.normalize();
                        Zlomok vonkajsiZlomok = z.normalize();
                        return nasZlomok.getCitatel() == vonkajsiZlomok.getCitatel()
                                        && nasZlomok.menovatel == vonkajsiZlomok.menovatel;
                } else {
                        return false;
                }
        }
        public boolean equals(Object obj) {
                if (obj instanceof Zlomok) {
                        Zlomok z = (Zlomok) obj;
                        return this.hashCode()== z.hashCode();
                } else {
                        return false;
                }
        }
        public int hashCode() {
                final int prvoCislo = 311;
                Zlomok normalized = this.normalize();
                int result = 1;
                result=prvoCislo * result + normalized.citatel;
                result=prvoCislo * result + normalized.menovatel;
                return result;
        }
        public Zlomok pripocitaj(Zlomok z) {
                int spolocnyMenovatel = this.menovatel * z.menovatel;
                int citatelNasho = this.citatel * z.menovatel;
                int citatelZ = z.citatel * this.menovatel;
                int sucetCitatel = citatelNasho + citatelZ;
                return new Zlomok(sucetCitatel, spolocnyMenovatel).normalize();
        }
        @Override
        public int intValue() {
                return citatel/menovatel;
        }
        @Override
        public long longValue() {
                return citatel/menovatel;
        }
        @Override
        public float floatValue() {
                return (float) (citatel)/menovatel;
        }
        @Override
        public double doubleValue() {
                return (double) (citatel)/menovatel;
        }
        public static Zlomok sucet(List<Zlomok> zlomky) { 
                Zlomok novyZlomok = new Zlomok(0, 1); 
                for (Zlomok zlomok : zlomky) { 
                        novyZlomok = novyZlomok.pripocitaj(zlomok.normalize()); 
                } 
                return novyZlomok; 
        }
        public int compareTo(Zlomok o) {
                if(this.citatel*o.menovatel<o.citatel*this.menovatel) {
                        return -1;
                } 
                if(this.citatel*o.menovatel>o.citatel*this.menovatel) {
                        return 1;
                }
                return 0;
        }
        @Override
        public int roundValue() {
                double val =this.doubleValue();
                int fullVal = (int) val;
                if(val-fullVal<0.5) {
                        return (int)Math.floor(val);
                }
                return (int) Math.ceil(val);
        }
}