/*
 * class VectorPosition
 *
 * $Date$
 * $Revision$
 *
 */

#ifndef VECTOR_POSITION_HH__
#define VECTOR_POSITION_HH__

#include "WImage/ReferenceVector.hh"

/** 
 * @addtogroup Wave 
 * @{ */

/** 
 * A Vector index (abstract). Performs symmetric, periodic and whatever
 * extensions to a vector or a part of it.
 */
/*abstract*/
class 
VectorPosition
{
public:
  /** Constructor. Sets standard values. */
  VectorPosition (void);
  /** Constructor. Sets the real vector size to be used if not 
   * passed on to pos () method.
   * @param newsize
   * the size */
  VectorPosition (int newsize);

  /** Destructor. Does nothing. */
  virtual ~VectorPosition (void) {}
  
  /** Set a new size. 
   * @param newsize
   * the new size */
  inline void size (int newsize) { m_vsize = newsize; }

  /** Return the current size. 
   * @return
   * the current size */
  inline int size (void ) { return m_vsize; }

  /** Calculate real position. If a position is greater than the size
   * or less than zero we mirror the position back into range.
   * @param position
   * the requested position
   * @return
   * the new position */
  inline int pos (int position) { 
    int dummy; return pos (position, 0, this->m_vsize, dummy); 
  } 

  /** Calculate real position assuming a given vector length. If a 
   * position is greater than the assumed size or less than zero we 
   * mirror the position back into range.
   * @param position
   * the requested position
   * @param length
   * the assumed length
   * @return
   * the new position */
  inline int pos (int position, int length) { 
    int dummy; return pos (position, 0, length, dummy);
  }

  /** Calculate real position assuming a given vector start and length. 
   * If a position is greater than the assumed size or less than the 
   * assumed start position we mirror the position back into range.
   * @param position
   * the requested position
   * @param start
   * the assumed start
   * @param length
   * the assumed length
   * @return
   * the new position */
  inline int pos (int position, int start, int length) { 
    int dummy; return pos (position, start, length, dummy);
  }
  
  /** Calculate real position assuming a given vector start and length. 
   * If a position is greater than the assumed size or less than the 
   * assumed start position we mirror the position back into range.
   * @param position
   * the requested position
   * @param start
   * the assumed start
   * @param end
   * the assumed end point
   * @param sign
   * set to -1 if a sign change has taken place
   * @return
   * the new position */
  virtual int pos (int position, int start, int end, int &sign) = 0;

  /** Set symmetry property. If set we get a sign change with every half 
   * period.
   * @param symm
   * if symmetric: {\em true} */
  inline void setsymm (bool symm) { m_symmetry = symm; }

  /** Return the symmetry settings.
   * @return 
   * if symmetric sign change occurs: {\em true} else {\em false} */
  inline bool issymm (void) { return m_symmetry; }

protected: 
  /** The default vector size. */
  int m_vsize;
  /** The symmetric sign change setting. */
  bool m_symmetry;
}; /* class VectorPosition */

/** @} */

#endif /* VECTOR_POSITION_HH__ */

