#include <iostream>
#include <iomanip>
#include <sstream>
#include <vector>
#include "matrix.h"
using namespace std;

ostream& operator<<(ostream& out, const matrix& m) {
  string temp;

  unsigned int maxfield = 0;
  for (int r=0; r < m.numRows(); r++) {
    for (int c=0; c < m.numColumns(); c++) {
      stringstream s;
      s << fixed << setprecision(3);
      s << m(r,c);
      s >> temp;
      if (temp.size() > maxfield)
	maxfield = temp.size();
    }
  }

  for (int r=0; r < m.numRows(); r++) {
    for (int c=0; c < m.numColumns(); c++) {
      stringstream s;
      s << fixed << setprecision(3);
      s << m(r,c);
      s >> temp;
      out << " " << setw(maxfield) << temp;
    }
    out << endl;
  }

  return out;
}


istream& operator>>(istream& in, matrix& m) {
  // presumes that there is a blank line to terminate the matrix
  vector< vector<double> >  data;

  unsigned int numColumns = 0;
  bool done = false;
  while (!done) {
    vector<double> row;
    string temp;
    getline(in, temp);
    stringstream s(temp);
    double val;

    while (s >> val) {
      row.push_back(val);
    }

    if (row.size() == 0)
      done = true;
    else if (numColumns > 0 and numColumns != row.size())
      done = true;
    else {
      numColumns = row.size();
      data.push_back(row);
    }
  }

  m = matrix(data.size(), numColumns);
  for (int r=0; r < m.numRows(); r++)
    for (int c=0; c< m.numColumns(); c++)
      m(r,c) = data[r][c];

  return in;
}

