/****************************************************************************
** GMAF - The Geometry Modeling Algorithms Framework
**
** Created : 03262000
**
** Copyright (C) 2000 by Le-Jeng Shiue.  All rights reserved.
**
****************************************************************************/
#ifndef gmafMatrixCirculator_H
#define gmafMatrixCirculator_H

#include "blitzConfig.h"

/**
   gmafMatrixCirculator will traverse the matrix in CCW.
   You can only plug in a 2D matrix from blitz
*/
template <class MatrixType> 
class gmafMatrixCirculator {
// ENUMS
public:

// VARIABLES
/**@name Class Variables */
//@{
protected:
  /**
     The traversed matrix
   */
  MatrixType mMatrix;

  blitz::TinyVector<int, 2> mIdx[4];
  int mCurPos;
private:

//@}

// METHODS
/**@name Class Methods */
//@{
public:
  /**
     Constructor of gmafMatrixCirculator -- traverse counterclockwise
     qm is the matrix 
     r,c are the distance to upper-left corner -- the fisrt traversed corner
  */
  gmafMatrixCirculator(MatrixType& m, int r = 0, int c = 0)
    : mMatrix(m) {
    //assert(x >= 0 && y >= 0);
    mCurPos = 0;
    
    int w = mMatrix.cols();
    int h = mMatrix.rows();
    mIdx[0] = r, c;         //Relate to upper-left corner
    mIdx[1] = h-c-1, r;     //Relate to lower-left corner
    mIdx[2] = h-r-1, w-c-1; //Relate to lower-right corner
    mIdx[3] = c, w-r-1; //Relate to upper-right corner
  }

  /**
     Destructor of gmafMatrixCirculator
  */    
  virtual ~gmafMatrixCirculator() {}
  
  inline int size() const {  return 4; } // Always have 4 corners
  inline void restart() { mCurPos = 0; }
  inline void next() { mCurPos = (mCurPos+1)%4; }
  inline virtual typename MatrixType::T_numtype& current() {
    return mMatrix(mIdx[mCurPos]);
  }
  
protected:

private:
};

#endif gmafMatrixCirculator_H

