/*
 * class CoeffInformation
 *
 * $Date$
 * $Revision$
 *
 */

#ifndef COEFF_INFORMATION_HH__
#define COEFF_INFORMATION_HH__
#include "WImage/miscdefs.h"
#include "WImage/Image.hh"

/** 
 * @addtogroup WImage 
 * @{ */

/**
 * Coefficient information. The information consists of value, x-offset, 
 * y-offset and absolute offset. This is used for statistics and to obtain
 * alternative image representations.
 */
class 
CoeffInformation
{
public:
  /** Constructor. Creates a new Coefficient. 
   * @param val
   * the coeff's value
   * @param y
   * the coeff's row
   * @param x
   * the coeff's col
   * @param abs
   * the coeff's absolute offset 
   * @param id the coeff's unique id 
   * @param misc for additional information */
  CoeffInformation (coeff val = 0.0, int y = 0, int x = 0, 
                    int abs = 0, long id = -1, coeff misc = 0.0);
  /** Copy Constructor.
   * @param c
   * the object to copy from */
  CoeffInformation (const CoeffInformation &c) { set (c); }
  /* Destructor. Does nothing. */
  ~CoeffInformation (void) { }
  /** Get the value.
   * @return
   * the coeff's value */
  coeff val (void) const { return m_value; }
  /** Get the row.
   * @return
   * the coeff's row */
  int ypos (void) const { return m_yposition; }
  /** Get the col.
   * @return
   * the coeff's col*/
  int xpos (void) const { return m_xposition; }
  /** Get the ID.
   * @return
   * the id */
  int id (void) const { return m_id; }
  /** Set the ID.
   * @param id the id */
  inline void id (long id) { m_id = id; }
  /** Set the misc data.
   * @param misc the misc data */
  inline void misc (coeff misc) { m_misc = misc; }
  /** Get the misc data.
   * @return
   * the misc data */
  coeff misc (void) const { return m_misc; }
  /** Get the absolute offset.
   * @return
   * the coeff's absolute offset */
  int xypos (void) const { return m_xyposition; }
  /** Assign a new value.
   * @param val
   * the coeff's new value */
  inline void val (coeff val) { m_value = val; }
  /** Assign a new coefficient value only leaving the rest as is.
   * @param val
   * the coeff's new value 
   * @param y
   * the coeff's row
   * @param x
   * the coeff's col
   * @param abs
   * the coeff's absolute position
   * @param id
   * the new ID 
   * @param misc
   * the new misc data */
  void set (coeff val, int y, int x, int abs, long id = -1, coeff misc = 0.0);
  /** Copy a coefficient.
   * @param c
   * the other coeff */
  void set (const CoeffInformation &c);
  /** Copy from an Image location.
   * @param img the image
   * @param ypos the row in the image
   * @param xpos the col in the image */
  void set (const Image &img, int ypos, int xpos);
  /** Signed object comparison. If both values are identical, first the 
   * y, then the x component will be compared.
   * @param c
   * the other coeff
   * @return 
   * 1: the other value is less, -1: the other value is greater, 2: the
   * values are equal, but the other y component is less, -2: the values
   * are equal, but the other y component is greater, 3: the values and
   * y components are equal, but the other x component is less, -2: the 
   * values and y components are equal, but the other x component is 
   * greater, 0: both are equal */
  int socmp (const CoeffInformation &c) const;
  /** Unsigned object comparison (absolute values). If both values are 
   * identical, first the y, then the x component will be compared.
   * @param c
   * the other coeff
   * @return 
   * 1: the other value is less, -1: the other value is greater, 2: the
   * values are equal, but the other y component is less, -2: the values
   * are equal, but the other y component is greater, 3: the values and
   * y components are equal, but the other x component is less, -2: the 
   * values and y components are equal, but the other x component is 
   * greater, 0: both are equal */
  int aocmp (const CoeffInformation &c) const;
  /** Position comparison. 
   * @param c
   * the other coeff
   * @return 
   * 2: the other y component is less, -2: the other y component is greater, 
   * 3: the other x component is less, -2: the other x component is greater, 
   * 0: both are equal */
  int pcmp (const CoeffInformation &c) const;
  /** Signed value comparison.
   * @param c
   * the other coeff
   * @return 
   * 1: the other coeff is less, -1: the other coeff is greater, 0: both 
   * are equal */
  int svcmp (const CoeffInformation &c) const;
  /** Unsigned value comparison (absolute values).
   * @param c
   * the other coeff
   * @return 
   * 1: the other coeff is less, -1: the other coeff is greater, 0: both 
   * are equal */
  int avcmp (const CoeffInformation &c) const;
  /** Equality test. This includes both, the value and the coordinates.
   * @param c
   * the other coeff
   * @return 
   * both are equal: {\em true}, else {\em false} */
  bool equals (const CoeffInformation &c) const; 

#ifndef _WIN32_WCE
  /** Writes all data to stdout or a file. 
   * @exception ios_base::failure if the file could not be opened for writing.
   * @param delim what to print between two entries 
   * @param file the name of the file (empty string for stdout) */
  void dump (const char *delim = " ", const char *file = "") const;
#endif

  /** Convenience equality operator to avoid trouble in some cases.
   * @param c the other object
   * @return true if the objects are equal */
  inline bool operator== (const CoeffInformation &c) const { 
    return equals (c); }
  /** Convenience inequality operator to avoid trouble in some cases.
   * @param c the other object
   * @return true if the objects are not equal */
  inline bool operator!= (const CoeffInformation &c) const { 
    return !equals (c); }
  /** Convenience assignment operator to avoid trouble in some cases.
   * @param c the other object
   * @return a reference to `this' */
  inline CoeffInformation & operator= (const CoeffInformation &c) { 
    set (c); return *this; }

private:
  /** The coefficient value. */
  coeff m_value;
  /** The coefficient row. */
  int m_yposition;
  /** The coefficient col. */
  int m_xposition;
  /** The coefficient absolute offset. */
  int m_xyposition;
  /** The absolute ID (needed for tracking a coefficient. */
  long m_id;
  /** Other data for free use. */
  coeff m_misc;
}; /* class CoeffInformation */

/** @} */

#endif /* COEFF_INFORMATION_HH__ */

