package ciss.phase_viewer.atomcoord.pmodel;

class Fraction {
    int numerator;
    int denominator;

    public static void main(String args[]) {
        Fraction a = new Fraction(7, 17);
        Fraction b = new Fraction(-9, 7);
        Fraction c = new Fraction(12, 27);
        Fraction d = new Fraction(8, 2);

        System.out.println("TEST:" + a + b + c + d);
        b = b.reduction().normalize();
        c = c.reduction();
        d = d.reduction().normalize();
        System.out.println("TEST:" + a + b + c + d);
    }

    Fraction() {
        numerator = 0;
        denominator = 1;
    }

    Fraction(int n, int d) {
        if (d == 0) {
            // divide by zero
            PmodelRuntimeException ex = new PmodelRuntimeException();
            throw ex;
        }
        if (d < 0) { // denominator must be positive.
            n = -n;
            d = -d;
        }
        numerator = n;
        denominator = d;
    }

    public String toString() {
        String str = "(" + numerator + " / " + denominator + ")";
        return str;
    }

    public double toDouble() {
        return ((double) numerator / (double) denominator);
    }

    Fraction reduction() {
        int n, d, tmp;

        n = this.numerator;
        d = this.denominator;

        if (d == 0) {
            // divide by zero
            PmodelRuntimeException ex = new PmodelRuntimeException();
            throw ex;
        }

        if (n == 0)
            return new Fraction();

        tmp = greatestCommonMeasure(Math.abs(n), d);
        n /= tmp;
        d /= tmp;

        return new Fraction(n, d);
    }

    Fraction normalize() {
        int n, d;

        n = this.numerator;
        d = this.denominator;

        if (d == 0) {
            // divide by zero
            PmodelRuntimeException ex = new PmodelRuntimeException();
            throw ex;
        }
        if (n == 0)
            return new Fraction();

        n = n % d;

        if (n < 0)
            n = n + d;

        return new Fraction(n, d);
    }

    private static int greatestCommonMeasure2(int bigger, int smaller) {
        int temp;

        if (bigger < 0) {
            // bigger = abs(bigger);
            PmodelRuntimeException ex = new PmodelRuntimeException();
            throw ex;
        }
        if (smaller < 0) {
            // smaller = abs(smaller);
            PmodelRuntimeException ex = new PmodelRuntimeException();
            throw ex;
        }

        while (smaller != 0) {
            temp = bigger % smaller;
            bigger = smaller;
            smaller = temp;
        }
        return bigger;
    }

    private static int greatestCommonMeasure(int bigger, int smaller) {
        if (bigger < 0 || smaller < 0) {
            PmodelRuntimeException ex = new PmodelRuntimeException();
            throw ex;
        }

        if (bigger < smaller)
            return greatestCommonMeasure(smaller, bigger);

        if (smaller == 0)
            return bigger;

        return greatestCommonMeasure(smaller, bigger % smaller);
    }

    private static int greatestCommonMeasure(int n1, int n2, int n3) {
        int temp;

        temp = greatestCommonMeasure(n1, n2);
        return greatestCommonMeasure(temp, n3);
    }

    static int leastCommonMultiple(int n1, int n2) {
        int temp = greatestCommonMeasure(n1, n2);
        if (temp < 0) {
            PmodelRuntimeException ex = new PmodelRuntimeException();
            throw ex;
        }
        return (n1 * n2 / temp);
    }

    static int leastCommonMultiple3(int n1, int n2, int n3) {
        int temp;

        temp = greatestCommonMeasure(n1, n2, n3);
        if (temp < 0) {
            PmodelRuntimeException ex = new PmodelRuntimeException();
            throw ex;
        }
        return (n1 * n2 * n3 / temp / temp);
    }
}
