/*
 * FXGL - JavaFX Game Library. The MIT License (MIT).
 * Copyright (c) AlmasB (almaslvl@gmail.com).
 * See LICENSE for details.
 */

package com.almasb.fxgl.physics.box2d.common;

import com.almasb.fxgl.core.math.Vec2;

import java.io.Serializable;

/**
 * A 2-by-2 matrix. Stored in column-major order.
 */
public final class Mat22 implements Serializable {
    private static final long serialVersionUID = 2L;

    public final Vec2 ex = new Vec2();
    public final Vec2 ey = new Vec2();

    /**
     * Set as the zero matrix.
     */
    public void setZero() {
        ex.x = 0.0f;
        ey.x = 0.0f;
        ex.y = 0.0f;
        ey.y = 0.0f;
    }

    public void invertToOut(Mat22 out) {
        float a = ex.x, b = ey.x, c = ex.y, d = ey.y;
        float det = a * d - b * c;

        det = 1.0f / det;
        out.ex.x = det * d;
        out.ey.x = -det * b;
        out.ex.y = -det * c;
        out.ey.y = det * a;
    }

    public void solveToOut(Vec2 b, Vec2 out) {
        float a11 = ex.x, a12 = ey.x, a21 = ex.y, a22 = ey.y;
        float det = a11 * a22 - a12 * a21;
        if (det != 0.0f) {
            det = 1.0f / det;
        }
        float tempy = det * (a11 * b.y - a21 * b.x);
        out.x = det * (a22 * b.x - a12 * b.y);
        out.y = tempy;
    }

    public static void mulToOutUnsafe(Mat22 R, Vec2 v, Vec2 out) {
        assert v != out;
        out.x = R.ex.x * v.x + R.ey.x * v.y;
        out.y = R.ex.y * v.x + R.ey.y * v.y;
    }

    @Override
    public int hashCode() {
        int prime = 31;
        int result = 1;
        result = prime * result + ex.hashCode();
        result = prime * result + ey.hashCode();
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        Mat22 other = (Mat22) obj;
        if (ex == null) {
            if (other.ex != null) return false;
        } else if (!ex.equals(other.ex)) return false;
        if (ey == null) {
            if (other.ey != null) return false;
        } else if (!ey.equals(other.ey)) return false;
        return true;
    }

    @Override
    public String toString() {
        return "[" + ex.x + "," + ey.x + "]\n"
                +"[" + ex.y + "," + ey.y + "]";
    }
}

@@ -409,16 +409,63 @@
  = 2L;%0A%0A
+    // %5B ex.x   ey.x %5D%0A    // %5B ex.y   ey.y %5D%0A%0A
     publ
@@ -491,24 +491,24 @@
 new Vec2();%0A
-
     public f
@@ -768,29 +768,71 @@
 ex.x
-, b = ey.x, c = ex.y,
+;%0A        float b = ey.x;%0A        float c = ex.y;%0A        float
  d =
@@ -1096,33 +1096,75 @@
 ex.x
-, a12 = ey.x, a21 = ex.y,
+;%0A        float a12 = ey.x;%0A        float a21 = ex.y;%0A        float
  a22
@@ -1164,32 +1164,33 @@
 oat a22 = ey.y;%0A
+%0A
         float de
@@ -1283,16 +1283,17 @@
       %7D%0A
+%0A
         
@@ -1406,32 +1406,32 @@
 = tempy;%0A    %7D%0A%0A
+
     public stati
@@ -1485,33 +1485,8 @@
 ) %7B%0A
-        assert v != out;%0A
     

clean up