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

#include <assert.h>

#include "Algorithm/gmafAlgorithm.h"
#include "Algorithm/gmafVisualObject.h"

class gmafDataStructureManager;
class gmafQuadMap;

/**
  gmafCCSubdivision : Catmull-Clark Subdivision
*/
class gmafCCSubdivision : public gmafAlgorithm {
// ENUMS
public:
  enum RULE { STANDARD, SABIN_RULE, BLEND_RATIO_RULE  };
// VARIABLES
/**@name Class Variables */
//@{
protected:
  /**
     This algorithm always create one new layer of the quads and 
     subdivide the current highest layer to the new layer
     (check appendix of PCCM) 
  */    
  gmafQuadMap* mpQuadMap; 

  /**
     The rule for subdivision
   */
  RULE mRule;

  int mDepth; // times to run the subdivision (default = 1)
  float mBlendRatio;
private:

//@}

// METHODS
/**@name Class Methods */
//@{
public:
  /**
     Constructor of gmafCCSubdivision.
  */    
  gmafCCSubdivision(gmafDataStructureManager* dsm, RULE rule = STANDARD);
  /**
     Destructor of gmafCCSubdivision.
  */    
  virtual ~gmafCCSubdivision();
  
  virtual void run();
  virtual void run(RULE rule, int depth = 2, float blrat = 0);
  virtual void exec();
  
  inline gmafQuadMap* getQuadMap() { return mpQuadMap; }
  inline void setRule(RULE rule) { mRule = rule; }
  inline void setDepth(int d)    { assert(d>0);  mDepth = d; }
  inline void setBlrat(float br) { assert(br>=0 && br<=1); mBlendRatio = br; }
  inline int  getRule()   { return mRule; }
  inline int  getDepth()  { return mDepth; }
  inline float getBlrat() { return mBlendRatio;}

  virtual gmafVisualObject* visualize();

protected:
  /**
     Execute one time of the subdivion step
   */
  void subdivide();
  void subdivide_br(); // blend ratio
  void subdivide_sr(); // sabin rule
  
private:

};

#endif gmafCCSubdivision_H

