/*
 * class PyramidTree
 *
 * $Date$
 * $Revision$
 *
 */

#ifndef PYRAMID_TREE_HH__
#define PYRAMID_TREE_HH__

#include "WTools/NTree.hh"
#include "WImage/CoeffInformation.hh"
#include "Wave/PyramidTransform.hh"

/** 
 * @addtogroup WTools 
 * @{ */

/**
 * A class for pyramid trees. Rather relaxed attitude towards position 
 * checking; crashes are avoided but errors not always flagged!
 * Each node can have exactly 4 children. Child #0 is the upper left, 
 * the children are stored linewise from there.
 */
class 
PyramidTree : public NTree < CoeffInformation >
{
public:
  /** Constructor, creates a tree from a transformed image at a given
   * position and over a depth of a given number of generations 
   * @param t the transform
   * @param y the row in the image 
   * @param x the col in the image
   * @param position the position in the parent node if applicable
   * @param parent a pointer to the parent node or NULL if root
   * @param generations the number of generations (including this node)
   * @exception invalid_argument if the transform levels are insufficient or
   * the start position in the image's LL */
  PyramidTree (PyramidTransform &t, int y, int x, int position = -1,
               PyramidTree *parent = NULL, int generations = 1);
  /** Destructor, does nothing (destruction done by parent class) */
  ~PyramidTree (void);
  /** Create/replace a number of generations to this node according to 
   * position and subband. 
   * @exception invalid_argument if the subband depth is insufficient 
   * @param depth the depth to recurse into (not counting this node) */
  void addGenerations (int depth);

  /** "Move" the tree to a different position in the image by replacing the positions
   * stored in the leaves.
   * @param y the new row
   * @param x the new column
   * @param position the new position in the parent node (or -1 if no change)
   * @param parent the new parent node (or NULL if no change) */
  void moveTo (int y, int x, int position = -1, PyramidTree *parent = NULL);
  
  /** Return the current depth including this node 
   * @return the depth */
  int depth (void);
  
protected:
  /** Find the upper left of the position for a new child 
   * @param y the row in the image
   * @param x the col in the image
   * @param resY the returned row 
   * @param resX the returned col 
   * @exception invalid_argument if (y,x) is in subband 1 or in LL */
  void findChildPosition (int y, int x, int &resY, int &resX);
  /** Shift the stored positions in the node and all children by a given amount.
   * @param shiftY the number of rows by which to shift
   * @param shiftX the number of columns by which to shift */
  void shiftBy (int shiftY, int shiftX);
private:
  /** The transform (contains a reference to the image) */
  PyramidTransform *m_transform;
}; /* class PyramidTree */

/** @} */

#endif /* PYRAMID_TREE_HH__ */

