//////////////////////////////////////////////////////////////////////////////
//
//       Title           : MathTut3.cpp
//       Project         : OSCAR
//       Created         : 5/30/1998
//       Author          : Mitch Pryor
//       Platforms       : All
///       Copyright      : Copyright© The University of Texas at Austin, 2002. All rights reserved.
///                 
///          This software and documentation constitute an unpublished work
///          and contain valuable trade secrets and proprietary information
///          belonging to University.  None of the foregoing material may be
///          copied  or duplicated or disclosed without the express, written
///          permission of University.  UNIVERSITY EXPRESSLY DISCLAIMS ANY
///          AND ALL WARRANTIES CONCERNING THIS SOFTWARE AND DOCUMENTATION,
///          INCLUDING ANY WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
///          PARTICULAR PURPOSE, AND WARRANTIES OF PERFORMANCE, AND ANY WARRANTY
///          THAT MIGHT OTHERWISE ARISE FROM COURSE OF DEALING OR USAGE OF TRADE.
///          NO WARRANTY IS EITHER EXPRESS OR IMPLIED WITH RESPECT TO THE USE OF
///          THE SOFTWARE OR DOCUMENTATION.  Under no circumstances shall
///          University be liable for incidental, special, indirect, direct or
///          consequential damages or loss of profits, interruption of business,
///          or related expenses which may arise from use of software or documentation,
///          including but not limited to those resulting from defects in software
///          and/or documentation, or loss or inaccuracy of data of any kind.
//       Access          : Company Confidential
//       Purpose         :
//
//----------------------------------------------------------------------------
//
//       Classes:
//               <none>
//
//       Global Functions:
//               <none>
//
//       Global Variables:
//               <none>
//
//----------------------------------------------------------------------------
//
//       $Revisions$
//
//       $Log: MathTut3.cpp,v $
//       Revision 1.4  2006/08/25 19:42:10  jknoll
//       now compatible with current OSCAR
//
//       Revision 1.3  2005/01/11 17:41:17  pmarch
//       no message
//
//       Revision 1.2  2003/09/26 16:25:31  pmarch
//       Changed project settings to match new CVS structure and made minor formatting changes.
//
//       Revision 1.1  2003/08/14 16:47:07  pmarch
//       no message
//
//
//////////////////////////////////////////////////////////////////////////////
#include "Math/Vector.h"

using namespace OSCAR;
using namespace std;


class Vector4 : public Vector {
public:

  //Default constructor for Vector4.  This simply sets all the
  //elements to zero.
  Vector4(){
    size = 4;
    element = _m;
    element[0] = 0.0; element[1] = 0.0; element[2] = 0.0; element[3] = 0.0;
  }

  //This constructor takes a pointer to an array of doubles as an 
  //argument.  If the pointer points to the wrong place or the array
  //is not 4 long, the elements may be filled with garbage.
  Vector4(double *a){
    size = 4;
    element = _m;
    element[0] = a[0]; element[1] = a[1]; element[2] = a[2]; element[3] = a[3];
  }

  //This constructor takes 4 doubles as arguments and sets the elements
  //of the vector equal to them.
  Vector4(double x, double y, double z, double w) {
    size = 4;
    element = _m;
    element[0] = x; element[1] = y; element[2] = z; element[3] = w;
  }

  //This constructor takes a double as an argument and sets each
  //element equal to this value.
  Vector4(double a){
    size = 4; 
    element = _m; 
    element[0] = element[1] = element[2] = element[3] = a;
  }
	
  //Copy Constructor for Vector4.  This calls the init()
  //method to properly initialize the memory.
  Vector4(const Vector4& V){
    init(4,V.GetArray());
  }

  //Constructor that takes a Vector as an argument.  This
  //constructor checks to make sure the Vector object is the
  //correct size before calling init().
  Vector4(const Vector& V){
    if(V.GetSize() != 4)
      DisplayError("Vector4::Vector4(const Vector& V):  V not of size 4\n");
    init(4,V.GetArray());
  }

  //Destructor for Vector4.  This sets element to zero so that the base
  //class destructor won't try to destroy the data.
  ~Vector4(){ element = 0; }

  //Simply methods to return a single element.
  double& X() { return element[0]; }
  double& Y() { return element[1]; }
  double& Z() { return element[2]; }
  double& W() { return element[3]; }


  //A negation operator for Vector4.  This will return an
  //Vector4 with each element negated.
  Vector4 operator-(void) const {
    Vector4 r(-element[0], -element[1], -element[2], -element[3]);
    return r;
  }

  //A division operator for Vector4.  This divides each element
  //by a double and returns the answer.  This method also checks
  //to make sure a Divide By Zero error does not occur.
  Vector4 operator/(double a) const {
    if(a == 0){
      DisplayError("error: Vector4 operator '/', division by zero\n");
      abort();
    }
    Vector4 r(*this);
    r.at(0) /= a; r.at(1) /= a; r.at(2) /= a; r.at(3) /= a;
    return r;
  }

  //A multiplication operator for Vector4.  This multiplies each
  //element by a double and returns the answer.
  Vector4 operator*(double a) const{
    Vector4 r(*this);
    r.at(0) *= a; r.at(1) *= a; r.at(2) *= a; r.at(3) *= a;
    return r;
  }


  //A subtraction operator for Vector4.  This substracts each element
  //by a double and returns the answer.
  Vector4& operator=(const Vector4& v){
    if(this != &v)
      at(0) = v.at(0); at(1) = v.at(1);	at(2) = v.at(2); at(3) = v.at(3);
    return *this;
  }

protected:
  double  _m[4];
};


//////////////////////////////////////////////////////////////////////////////
// Begin main
//////////////////////////////////////////////////////////////////////////////
int main(void)
{
  Vector4 testVector(6.4, -7.2, 4.0, -7.8);

  cout << "testVector: "  <<  testVector << "\n" << endl;
  cout << "Z of testVector: "  <<  testVector.Z() << "\n" << endl;
  cout << "Multiply by 5: " << testVector*5  << "\n" << endl;
  cout << "Divide by 5: " << testVector/5  << "\n" << endl;
  	
  return 0;
}