use crate::math::{Determinant, Matrix, Matrix2, Matrix3, Matrix4, Scalar};

pub trait Submatrix : Matrix {
    type Output: Matrix;

    fn submatrix(&self, y: usize, x: usize) -> <Self as Submatrix>::Output;

    fn minor(&self, y: usize, x: usize) -> Scalar {
        self.submatrix(y, x).determinant()
    }

    fn cofactor(&self, y: usize, x: usize) -> Scalar {
        if (x + y) % 2 == 0 {
            self.minor(y, x)
        } else {
            -self.minor(y, x)
        }
    }
}

impl Submatrix for Matrix3 {
    type Output = Matrix2;

    fn submatrix(&self, y: usize, x: usize) -> Matrix2 {
        let mut data = [[0.0; 2]; 2];

        for ny in 0..2 {
            for nx in 0..2 {
                let oy = if ny >= y { ny + 1 } else { ny };
                let ox = if nx >= x { nx + 1 } else 
;

                data[ny][nx] = self[oy][ox];
            }
        }

        Matrix2::new(data)
    }
}

impl Submatrix for Matrix4 {
    type Output = Matrix3;

    fn submatrix(&self, y: usize, x: usize) -> Matrix3 {
        let mut data = [[0.0; 3]; 3];

        for ny in 0..3 {
            for nx in 0..3 {
                let oy = if ny >= y { ny + 1 } else { ny };
                let ox = if nx >= x { nx + 1 } else { nx };

                data[ny][nx] = self[oy][ox];
            }
        }

        Matrix3::new(data)
    }
}

{ nx }