// FILE: apmatrixAP1.cpp
// PURPOSE: AP Exam practice problem: apmatrix class
// OTHER FILES: apvector.h, apvector.cpp, apstring.h apstring.cpp
//              apmatrix.h, apmatrix.cpp
//---------------------------------------------------------------
// COMPILATION INSTRUCTIONS: g++ and gxx 
// 1. FILES: apvector.h, apvector.cpp, apstring.h apstring.cpp, apmatrix.h
//    apmatrix.cpp must be in folder or directory in which you compile
// 2. COMMAND LINE: 
//    g++ (or gxx) apmatrixAP1.cpp apstring.cpp 
//---------------------------------------------------------------
// PROGRAMMING INSTRUCTIONS:
// 1. Study the affect of sumBorder() and deleteBorder() with
//    the three examples of apmatrix object A shown below 
// 2. Complete sumBorder() and deleteBorder() as specified below,
//    and run program to validate your solutions.
/*****************************************************************
               PRACTICE AP EXAM A QUESTION: using apmatrix class
   sumBorder(A) = 15 when A is:
   1   0   2   1
   0   1   2   2
   2   3   0   4
   A after deleteBorder:
   1   2
-----------------------------------------------------
   sumBorder(A) = 33 when A is:
   2   3   0   4
   5   0   1   2
   3   6   0   4
   1   2   3   4
   A after deleteBorder:
   0   1
   6   0
-----------------------------------------------------
   sumBorder(A) = 10 when A is:
   1   2
   3   4
   A after deleteBorder:
   Table is empty.
*****************************************************************/
#include <iomanip.h>
#include "apmatrix.h"
#include "apstring.h"
int sumBorder(const apmatrix<int> &M) {
  //precondition:  M.numrows() > 1, M.numcols() > 1
  //postcondition: returns the sum of the values in the border of the matrix
  //----------------------------------------------------------------------
  const int ROWS = M.numrows(), COLS = M.numcols();
  cout << "\n *** sumBorder() not installed *** ";
  return -77;
}//*** sumBorder
void deleteBorder(apmatrix<int> &M) {
  //precondition:  M.numrows() > 1, M.numcols() > 1
  //postcondition: removes the border of M by moving rows up and columns left
  //               and by resizing M to have 2 fewer rows and 2 fewer columns
  //               EXAMPLE: M.resize(M.numrows()-2, M.numcols()-2);
  //------------------------------------------------------------------------
  const int ROWS = M.numrows(), COLS = M.numcols();
  cout << "\n *** deleteBorder() not installed *** ";
}//*** deleteBorder
void print(const apmatrix<int> &M, apstring msg);
void load(apmatrix<int> &, apmatrix<int> &, apmatrix<int> &);
void load(apmatrix<int> &, const int *A);
void test(apmatrix<int> &);
int main(void) {
  apmatrix<int> A, B, C;
  apstring title("PRACTICE AP EXAM A QUESTION: using apmatrix class");
  cout << "\n\n\n\n\n\n" << setw(39 + title.length()/2) << title.c_str() << endl << endl;
  load(A, B, C);
  test(A);
  cout << "Press <ENTER>: "; cin.ignore(10, '\n');
  test(B);
  cout << "Press <ENTER>: "; cin.ignore(10, '\n');
  test(C);
  return 0;
}
void test(apmatrix<int> &M) {
  cout << "\n\n   sumBorder(M) = " << sumBorder(M) << " when A is:"; 
  print(M, "");
  deleteBorder(M); 
  print(M, "\n   A after deleteBorder:");
  cout << "\n   sumBorder(M) = " << sumBorder(M) << endl;
  cout << "----------------------------------------\n\n";
}
void print(const apmatrix<int> &M, apstring msg) {
  const int wdth = 4;
  int Rows = M.numrows(), Cols = M.numcols();
  cout << msg << endl;
  if ( Rows < 1 || Cols < 1 ) {
    cout << "   Table is empty." << endl;
    return;
  }
  for (int r = 0; r < Rows; r++) {
    for (int c = 0; c < Cols; c++)
      cout << setw(wdth) << M[r][c];
    cout << endl;
  }//for r
}//*** print
void load(apmatrix<int> &m1, apmatrix<int> &m2, apmatrix<int> &m3) {
  const int A1[3][4] = { {1, 0, 2, 1}, {0, 1, 2, 2}, {2, 3, 0, 4}};
  const int A2[4][4] = { {2, 3, 0, 4}, {5, 0, 1, 2}, {3, 6, 0, 4},
			 {1, 2, 3, 4}};
  const int A3[2][2] = { {1, 2}, {3, 4}};
  m1.resize(sizeof(A1)/sizeof(A1[0]), sizeof(A1[0])/sizeof(int));
  load(m1, &A1[0][0]); 
  m2.resize(sizeof(A2)/sizeof(A2[0]), sizeof(A2[0])/sizeof(int));
  load(m2, &A2[0][0]); 
  m3.resize(sizeof(A3)/sizeof(A3[0]), sizeof(A3[0])/sizeof(int));
  load(m3, &A3[0][0]); 
}//*** load
void load(apmatrix<int> &M, const int *A) {
  const int COLS = M.numcols();
  for (int r = 0; r < M.numrows(); r++)
    for (int c = 0; c < COLS; c++)
      M[r][c] = *(A + r*COLS + c); 
}//*** load