#ifndef MODULE_MATRIX
#define MODULE_MATRIX

#include <iostream>

using namespace std;

class Matrix {
private:
    int m;
    int n;
    int** data;

    void delete_data();
    void insert_matrix(const Matrix&);
public:
    // todo: minors of m x n matrices (https://lms2.sseu.ru/courses/eresmat/gloss/g87.htm)
    // todo: vector class as part of matrix
    // todo: [0][0] must became [1][1]
    // todo: beautify output of matrix

    Matrix(int, int, int value = 0);
    Matrix(const Matrix&);
    ~Matrix();
    Matrix& operator= (const Matrix&);

    int det();
    int rank();
    Matrix get_transposed_matrix();
    Matrix get_minor_matrix(int, int);
    int alg_add(int, int);
    //int minor(int, int);

    int* operator[] (int);

    friend Matrix operator* (const int&, const Matrix&);
    Matrix operator* (const int& k) {
        return k * (*this);
    }
    void operator*= (const int k) {
        *this = (*this) * k;
    }

    bool operator== (const Matrix&);

    friend Matrix operator+ (const Matrix&, const Matrix&);
    Matrix operator+= (const Matrix& m) {
        return (*this) + m;
    }

    friend ostream& operator<< (ostream&, const Matrix&);

    void init_with_sequence() {
        for (int i = 0; i < this->m; i++) {
            for (int j = 0; j < this->n; j++) {
                this->data[i][j] = j + (i * this->m) + 1;
            }
        }
    }
};

#endif // MODULE_MATRIX
