/*
    ChemCon - molecular mechanics and molecular graphics
    Copyright (C) 1998-2002  Alexei Nikitin

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#ifndef VECT_H
#define VECT_H

#ifndef DEFS_H
#include "Defs.h" //fix
#endif

struct Vector
  {
       real                        x_, y_, z_;

       Vector()                                   : x_( 0.0 ), y_( 0.0 ), z_( 0.0 )  { }
       ~Vector()                                  { x_ = 0.0;   y_ = 0.0;   z_ = 0.0; }
       Vector( real X, real Y, real Z )           : x_( X ),   y_( Y ),   z_( Z )    { }
       Vector( const Vector & r )               : x_( r.x_ ), y_( r.y_ ), z_( r.z_ )  { }
       const Vector & operator = ( const Vector & r );

       Vector   operator -  ( ) const                 { return Vector( -x_, -y_, -z_ ); }
       real   length2() const                       { return x_ * x_ + y_ * y_ + z_ * z_; }
friend real   length2( const Vector & v);
       Vector   operator +  ( const Vector & v ) const  { return Vector( x_ + v.x_, y_ + v.y_, z_ + v.z_ ); }
       Vector & operator += ( const Vector & v )        { x_ += v.x_; y_ += v.y_; z_ += v.z_; return *this; }
       Vector   operator -  ( const Vector & v ) const  { return Vector( x_ - v.x_, y_ - v.y_, z_ - v.z_ ); }
       Vector & operator -= ( const Vector & v )        { x_ -= v.x_; y_ -= v.y_; z_ -= v.z_; return *this; }
       Vector   operator *  ( const Vector & v ) const  { return Vector( y_ * v.z_ - z_ * v.y_, z_ * v.x_ - x_ * v.z_, x_ * v.y_ - y_ * v.x_ ); }
       real   operator ^  ( const Vector & v ) const  { return x_ * v.x_ + y_ * v.y_ + z_ * v.z_; }
       Vector   operator *  ( const real a ) const    { return Vector( x_ * a, y_ * a, z_ * a ); }
       Vector   operator /  ( const real a ) const;
       Vector & operator *= ( const real a )          { x_ *= a; y_ *= a; z_ *= a; return * this; }
       Vector & operator /= ( const real );
       real & operator [] ( const int i )           { return ( &x_ )[i]; }
       real   length() const; 
friend real   length( const Vector & v );
       operator real() const;
       Vector   norm();
friend Vector   norm( const Vector & v );
       Vector & operator () ();           // to norm itself

       Vector   rotate( const Vector & v );
       Vector   rotate( const Vector & v, const Vector & v0 );

//friend ostream& operator << ( ostream&, const Vector& );
      int     operator >  ( const Vector & V ) const  { return length2() >  V.length2(); }
      int     operator <  ( const Vector & V ) const  { return length2() <  V.length2(); }
      int     operator >= ( const Vector & V ) const { return length2() >= V.length2(); }
      int     operator <= ( const Vector & V ) const { return length2() <= V.length2(); }
      int     operator == ( const Vector & V ) const { return x_ == V.x_ && y_ == V.y_ && z_ == V.z_; }
      int     operator != ( const Vector & V ) const { return x_ != V.x_ || y_ != V.y_ || z_ != V.z_; }
  };

inline Vector operator * ( const real a, const Vector & v ) { return Vector( v.x_ * a, v.y_ * a, v.z_ * a ); }

#endif//VECT_H
