#include <iostream>
#include <fstream>
#include <stdexcept>
#include "matrix.h"
using namespace std;

int main() {

  // perform tests based on a matrix read from a file
  ifstream fin;

  do {
    if (fin.fail()) {
      cout << "Unable to open file." << endl;
      fin.clear();
    }
    string filename;
    cout << "Enter filename containing origin matrix: ";
    cin >> filename;
    fin.open(filename.c_str());
  } while (fin.fail());

  matrix A;
  fin >> A;

  cout << "Matrix A was read as:" << endl;
  cout << A << endl;

  matrix B(A);
  cout << "Matrix B as copy of A:" << endl;
  cout << B << endl;

  matrix_proxy P = B(range(2,5), range(3,7));
  cout << "Proxy P created as B(range(2,5), range(3,7))" << endl;
  cout << "P's contents:" << endl;
  cout << P << endl;

  try {
    P(1,6) = -1000;
    cout << "After assigning P(1,6) = -1000, P appears as:" << endl;
    cout << P << endl;
    cout << "and B appears as:" << endl;
    cout << B;
  } catch (out_of_range& e){
    cout << "P(1,6) threw out_of_range exception: " << e.what() << endl;
  } catch (...) {
    cout << "P(1,6) threw unknown exception" << endl;
  }

  cout << endl;
  cout << "After assigning A(range(3,6), range(4,8)) = P" << endl;
  A(range(3,6), range(4,8)) = P;
  cout << "A appears as:" << endl << A;
  
  cout << endl;
  cout << "After assigning B(range(3,6), range(4,8)) = P" << endl;
  B(range(3,6), range(4,8)) = P;
  cout << "B appears as:" << endl << B;

  cout << endl;
  try {
    A = P;
    cout << "After assigning A = P" << endl;
    cout << A << endl;
  } catch (exception& e) {
    cout << "Command A = P threw exception: " << e.what() << endl;
  } catch (...) {
    cout << "Command A = P threw unexpected exception" << endl;
  }

  cout << endl;
  try {
    B = P;
    cout << "After assigning B = P" << endl;
    cout << B << endl;
  } catch (exception& e) {
    cout << "Command B = P threw exception: " << e.what() << endl;
  } catch (...) {
    cout << "Command B = P threw unexpected exception" << endl;
  }

}
