package ciss.phase_viewer.atomcoord.pmodel;

class FractionVector {
    Fraction element[] = new Fraction[3];

    public static void main(String args[]) {
        Fraction a = new Fraction(1, 3);
        Fraction b = new Fraction(1, 4);
        Fraction c = new Fraction(1, 5);
        FractionVector fv1 = new FractionVector(a, b, c);

        a = new Fraction(1, 4);
        b = new Fraction(2, 4);
        c = new Fraction(3, 4);
        FractionVector fv2 = new FractionVector(a, b, c);

        FractionVector fv3 = new FractionVector();
        fv3 = fv1.add(fv2);

        System.out.println("FracVec 1:" + fv1);
        System.out.println("FracVec 2:" + fv2);
        System.out.println("FracVec 3:" + fv3);

        int matrix[][] = { { 0, -1, 0 }, { 1, 0, 0 }, { 0, 0, -1 } };

        fv3 = fv1.rotate(matrix);
        System.out.println("Rotation :" + fv3);
    }

    FractionVector() {
        int i;
        for (i = 0; i < 3; ++i)
            element[i] = new Fraction();
    }

    FractionVector(Fraction f1, Fraction f2, Fraction f3) {
        element[0] = f1;
        element[1] = f2;
        element[2] = f3;
    }

    public String toString() {
        String str = "[" + element[0] + element[1] + element[2] + "]";
        return str;
    }

    FractionVector rotate(int matrix[][]) {
        Fraction a[] = new Fraction[3];
        int numerator0[] = new int[3];
        int denominator, numerator1, i, j;
        // Reduction (TSUU-BUN)
        denominator = Fraction.leastCommonMultiple3(
                this.element[0].denominator, this.element[1].denominator,
                this.element[2].denominator);
        for (i = 0; i < 3; ++i)
            numerator0[i] = this.element[i].numerator * denominator
                    / this.element[i].denominator;

        // Rotation
        for (i = 0; i < 3; ++i) {
            numerator1 = 0;
            for (j = 0; j < 3; ++j)
                numerator1 += matrix[i][j] * numerator0[j];
            a[i] = new Fraction(numerator1, denominator);
            a[i] = a[i].reduction().normalize(); // Reduction (YAKU-BUN) and
                                                 // Normalize
        }
        return new FractionVector(a[0], a[1], a[2]);
    }

    FractionVector add(FractionVector fv2) {
        int numerator, denominator, denomi1, denomi2;

        // fv = this + fv2
        denomi1 = Fraction.leastCommonMultiple3(this.element[0].denominator,
                this.element[1].denominator, this.element[2].denominator);
        denomi2 = Fraction.leastCommonMultiple3(fv2.element[0].denominator,
                fv2.element[1].denominator, fv2.element[2].denominator);
        denominator = Fraction.leastCommonMultiple(denomi1, denomi2);

        FractionVector fv = new FractionVector();
        for (int i = 0; i < 3; ++i) {
            numerator = this.element[i].numerator * denominator
                    / this.element[i].denominator + fv2.element[i].numerator
                    * denominator / fv2.element[i].denominator;
            Fraction f = new Fraction(numerator, denominator);
            f = f.reduction().normalize();
            fv.element[i] = f;
        }
        return fv;
    }

    Atom shift(Atom atom) {
        Atom a1 = atom.copy();

        for (int i = 0; i < 3; ++i)
            a1.position[i] += element[i].toDouble();

        return a1;
    }
}
