/** \file
 *
 *  Contains the Point2D class definition.
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 *
 */

#ifndef POINT2D_H_
#define POINT2D_H_

#include "data/I1D.h"
#include "utils/Str.h"

/**
 *  Wraps two double precision (8-byte) floating point numbers.
 *
 *  The 3 numbers are normally accessed as
 *  \li x and y
 *  \n -OR-
 *  \li u, and v
 *
 * \ingroup data
 */
class Point2D: public I1D<double>
{
public:
    /// X positive along the vehicle axis, starting at the nose
    inline void setX( const double x )
    {
        value_[0] = x;
    }
    inline double getX() const
    {
        return value_[0];
    }

    /// Y
    inline void setY( const double y )
    {
        value_[1] = y;
    }
    inline double getY() const
    {
        return value_[1];
    }

    /// U -- shares storage with X, alias for dX/dt
    inline void setU( const double u )
    {
        value_[0] = u;
    }
    inline double getU() const
    {
        return value_[0];
    }

    /// V -- shares storage with Y, alias for dY/dt
    inline void setV( const double v )
    {
        value_[1] = v;
    }
    inline double getV() const
    {
        return value_[1];
    }

    /// Default constructior
    Point2D();

    /// Single value constructior
    Point2D( const double& init );

    /// Multi value constructior
    Point2D( const double& x, const double& y );

    /// Copy Constructor
    Point2D( const Point2D& value );

    /// Destructor
    virtual ~Point2D()
    {}

    /// Return a pointer to a new copy
    Point2D* copy() const;

    // as a Str
    virtual Str toString() const;

    Point2D& operator=( const Point2D & rhs );

    Point2D& operator=( const double rhs );

    Point2D& operator+=( const Point2D & rhs );

    Point2D& operator+=( const double rhs );

    Point2D operator+( const Point2D & rhs );

    Point2D& operator-=( const Point2D & rhs );

    Point2D operator-( const Point2D & rhs );

    Point2D& operator-=( const double rhs );

    Point2D& operator*=( const Point2D & rhs );

    Point2D operator*( const double rhs );

    Point2D& operator*=( const double rhs );

    Point2D& toAbs();

    bool isNan() const;

    double getMagnitude() const;

    double& operator[]( int index );

    const double sum() const;

    const double sumSquared() const;

    const double dot( const Point2D& rhs ) const;

    /// Implement abstract I1D method
    virtual double* getPtr1d()
    {
        return value_;
    }

    /// Implement abstract I1D method
    virtual int getM() const
    {
        return 3;
    }

protected:

    // The actual data
    double value_[2];
};

#endif /*POINT2D_H_*/
