// ==========================================================================
// $Id: point_n_dim.cpp,v 1.3 2017/11/16 15:04:07 jlang Exp $
// CSI2372 example Code for lecture 9
// ==========================================================================
// (C)opyright:
//
//   Jochen Lang
//   SITE, University of Ottawa
//   800 King Edward Ave.
//   Ottawa, On., K1N 6N5
//   Canada. 
//   http://www.site.uottawa.ca
// 
// Creator: jlang (Jochen Lang)
// Email:   jlang@site.uottawa.ca
// ==========================================================================
// $Log: point_n_dim.cpp,v $
// Revision 1.3  2017/11/16 15:04:07  jlang
// Included global insertion operator
//
// Revision 1.2  2011/09/10 01:08:19  jlang
// Updates F10
//
// Revision 1.1  2006/10/29 00:32:05  jlang
// Check in for lecture 9
//
//
// ==========================================================================
#include <iostream>

using std::cout;
using std::endl;

using std::ostream;

template <class T, const int NUM>
class Point{
  T d_components[NUM];
public:
  Point();
  Point( T* _components );
  Point<T,NUM> add( const Point<T,NUM>& _oPoint ) const;
  friend ostream& operator<<( ostream& os, const Point<T,NUM>& p ) {
    for ( int i=0; i<NUM; i++ ) {
      if (i!=0) os  << ", ";
      os << p.d_components[i];
    }  
  }
  void pprint() const;
};

template <class T, const int NUM>
Point<T,NUM>::Point() 
{}

template <class T, const int NUM>
Point<T,NUM>::Point( T* _components ) 
{
  for ( int i=0; i<NUM; i++ ) {
    d_components[i] = _components[i];
  }
}

template <class T, const int NUM>
Point<T,NUM> Point<T,NUM>::add( const Point<T,NUM>& _oPoint ) const 
{
  Point<T,NUM> res;
  for ( int i=0; i<NUM; i++ ) {
    res.d_components[i] = d_components[i] + _oPoint.d_components[i];
  }  
  return res;
}

template <class T, const int NUM>
void Point<T,NUM>::pprint() const
{
  cout << "( ";
  cout << *this;
  cout << " )";
}


int main() {
  int initA[] = {3,8};
  int initB[] = {-24,12};
  Point<int,2> intPt1(initA), intPt2(initB), intPt3;
  intPt3 = intPt1.add( intPt2 );
  intPt1.pprint();
  cout << " + ";
  intPt2.pprint();
  cout << " = ";
  intPt3.pprint();
  cout << endl; 

  double initC[] = {3.2,8.09,7.1};
  double initD[] = {-24.9,12.1,2.3};
  Point<double,3> dPt1(initC), dPt2(initD), dPt3;
  dPt3 = dPt1.add( dPt2 );
  dPt1.pprint();
  cout << " + ";
  dPt2.pprint();
  cout << " = ";
  dPt3.pprint();
  cout << endl;

  // dPt3 = dPt1.add( intPt1 );
}
