#include "Matrix.h"

#include <string>
#include <stdexcept>

Matrix::Matrix(std::size_t numRows, std::size_t numColumns)
    : mNumRows(numRows),
      mNumColumns(numColumns)
{
    mData = std::vector<double>(numRows * numColumns, 0.0);
}

bool Matrix::isIdentity() const
{
    if (!isSquare())
    {
        return false;
    }

    for(std::size_t idx=0; idx<mNumRows; idx++)
    {
        for(std::size_t jdx=0; jdx<mNumColumns; jdx++)
        {
            if (idx == jdx)
            {
                if (getItem(idx, jdx) != 1.0)
                {
                    return false;
                }
            }
            else
            {
                if (getItem(idx, jdx) != 0.0)
                {
                    return false;
                }
            }
        }
    }
    return true;
}

double Matrix::getItem(std::size_t rowId, std::size_t columnId) const
{
    const auto index = getFlatIndex(rowId, columnId);
    if (index >= mData.size())
    {
        throw std::range_error("Out of bounds array access: " + std::to_string(index) + " for size " + std::to_string(mData.size()));
    }
    return mData[getFlatIndex(rowId, columnId)];
}

bool Matrix::isSquare() const
{
    return mNumRows == mNumColumns;
}

bool Matrix::isEqual(const Matrix& matrix) const
{
    return mData == matrix.mData;
}

std::size_t Matrix::getFlatIndex(std::size_t rowId, std::size_t columnId) const
{
    return columnId + rowId*mNumColumns;
}
