#include "IO.h"

#include "Vect.h"
#include <fstream>
#include <iostream>

std::ostream& operator<<(std::ostream& stream, const Matrix& mat) {
	stream << mat.GetRawCount() << " " << mat.GetColumnCount() << "\n";
	for (std::size_t i = 0; i < mat.GetRawCount(); i++) {
		for (std::size_t j = 0; j < mat.GetColumnCount(); j++) {
			stream << mat.at(i, j) << " ";
		}
		stream << "\n";
	}
	return stream;
}

std::istream& operator>>(std::istream& stream, Matrix& mat) {
	std::size_t raw, column;
	stream >> raw >> column;

	Matrix result {raw, column};
	mat = result;

	for (std::size_t i = 0; i < mat.GetRawCount(); i++) {
		for (std::size_t j = 0; j < mat.GetColumnCount(); j++) {
			stream >> mat.at(i, j);
		}
	}

	return stream;
}

Matrix LoadMatrix(const std::string& fileName) {
	std::ifstream in {fileName};
	if (!in) {
		std::cerr << "Impossible de charger la matrice !\n";
		return {};
	}
	Matrix result;
	in >> result;

	return result;
}

void SaveMatrix(const Matrix& mat, const std::string& fileName) {
	std::ofstream out {fileName};
	if (!out) {
		std::cerr << "Impossible de sauvegarder la matrice !\n";
		return;
	}
	out << mat;
}

Matrix InsertMatrix() {
	std::cout << "Quelle est le nombre de lignes de votre matrice ?" << std::endl;
	std::size_t lignes;
	std::cin >> lignes;
	std::cout << "Quelle est le nombre de colonnes de votre matrice ?" << std::endl;
	std::size_t colonnes;
	std::cin >> colonnes;
	std::cout << "Rentrez les coefficients de la matrice" << std::endl;
	Matrix result(lignes, colonnes);
	for (size_t i = 0; i < result.GetRawCount(); ++i) {
		for (size_t j = 0; j < result.GetColumnCount(); ++j) {
			std::cin >> result.at(i, j);
		}
		std::cout << std::endl;
	}

	return result;
}

void Print(const Matrix& mat) {
	for (size_t i = 0; i < mat.GetRawCount(); ++i) {
		std::cout << "[ ";
		for (size_t j = 0; j < mat.GetColumnCount(); ++j) {
			std::cout << mat.at(i, j) << " ";
		}
		std::cout << "]";
		std::cout << std::endl;
	}
}

void Print(const Vect& vect) {
	std::cout << "Espace vectoriel de dimension " << vect.GetCardinal() << " de base :\n\n";
	for (std::size_t i = 0; i < vect.GetDimension(); i++) {
		for (std::size_t j = 0; j < vect.GetCardinal(); j++) {
			Matrix vector = vect.GetVector(j);
			std::cout << "[ " << vector.at(i, 0) << " ]\t";
		}
		std::cout << "\n";
	}
}

void Print(const VectAffine& vect) {
	std::cout << "\tEspace Affine :\n\n";
	Print(vect.GetBase());
	std::cout << "\nOrigine :\n\n";
	Print(vect.GetOrigin());
}