/***************************************************************************
 *                          Zanoza Modeler v2.x                            *
 *      This is unpublished propietary source code of Zanoza Software.     *
 *      The copyright notice does not evidence any actual or intended      *
 *                    publication of such source code.                     *
 *                                                                         *
 *                   Copyright (c) 2002 Zanoza Software.                   *
 *                                                                         *
 *                        All rights reserved.                             *
 ***************************************************************************
 *--------------------------------------------------------------------------
 * @author:   Oleg M.
 *--------------------------------------------------------------------------
 * @purpose:  ZModeler's polygon helpers
 *--------------------------------------------------------------------------
 * @histroy: 25.04.2003. Created
 */
#ifndef zpolygonshelper_h_included
#define zpolygonshelper_h_included

#include <zmodeler.h>

//------------------------------------------------------
//
//  ZTriangle - ZModeler's triangle.
//              3 vertices convex polygon
//  
//------------------------------------------------------
class DLL_LINKAGE ZTriangle : public ZPoly
{
public:
  //
  // constructors/destructors
  //
  ZTriangle();
  ZTriangle(const WORD i1, const WORD i2, const WORD i3);
  virtual ~ZTriangle();

public:
  virtual ePolyType type() const;
  virtual bool type(const ePolyType t) const;
  virtual DWORD size() const {return sizeof(ZTriangle);}

public:
  //
  // assignment operators
  //
  virtual ZPoly& operator = ( const ZPoly& poly);

public:
  //
  // compare operators
  //
  virtual bool operator == ( const ZPoly& poly) const;
  virtual bool operator != ( const ZPoly& poly) const;

public:
  //
  // accessors
  //
  virtual WORD& operator [] (const long _indx);
  virtual const WORD operator [] (const long _indx) const;

  //
  // operations
  //
  virtual short     verts();
  virtual short     tris();
  virtual ZRESULT   verts(const short v, const WORD* data=NULL);
  virtual ZVector&  normal();
  virtual bool      isUsed(const WORD nVert) const;
  virtual bool      isUsed(const tUShortSeq& verts) const;
  //-------------------------------------------------------
  // @name :      invalidate
  // notifies polygon that vertices has changed.
  //-------------------------------------------------------
  virtual void      invalidate();
  //-------------------------------------------------------
  // @name :      flip
  // flips visible side of the polygon
  //-------------------------------------------------------
  virtual void      flip();
  //-------------------------------------------------------
  // @name :   getTriangles
  // Provides triangulated polygon data. Triplet of longs
  // makes a single triangle [0,1,2] then [3,4,5] and so on.
  // @param const ZVertexBuf& vBuf         : [new] vertex buffer
  // @param tUShortSeq& triples              : ret-val arg
  //-------------------------------------------------------
  virtual ZRESULT   getTriangles(const ZVertexBuf& vBuf, tUShortSeq& triples);
  virtual ZRESULT   getExterior(tUShortSeq& verts);
  virtual ZRESULT   setExterior(tUShortSeq& verts);
  virtual ZPoint3D& getCenter() const;

private:
  //
  // additional data members
  //
  bool            m_bInvalid;
  WORD            m_triangle[3];
  ZVector         m_vNormal;
  ZPoint3D        m_ptCenter;
};


//------------------------------------------------------
//
//  ZQuad - Quad (4 vertices) polygon
//  
//------------------------------------------------------
class DLL_LINKAGE ZQuad : public ZPoly
{
public:
  //
  // constructors/destructors
  //
  ZQuad();
  ZQuad(const WORD i1, const WORD i2, const WORD i3, const WORD i4);
  virtual ~ZQuad();

public:
  virtual ePolyType type() const;
  virtual bool type(const ePolyType t) const;
  virtual DWORD size() const {return sizeof(ZQuad);}

public:
  //
  // assignment operators
  //
  virtual ZPoly& operator = ( const ZPoly& poly);

public:
  //
  // compare operators
  //
  virtual bool operator == ( const ZPoly& poly) const;
  virtual bool operator != ( const ZPoly& poly) const;

public:
  //
  // accessors
  //
  virtual WORD& operator [] (const long _indx);
  virtual const WORD operator [] (const long _indx) const;

  //
  // operations
  //
  virtual short     verts();
  virtual short     tris();
  virtual ZRESULT   verts(const short v, const WORD* data=NULL);
  virtual ZVector&  normal();
  virtual bool      isUsed(const WORD nVert) const;
  virtual bool      isUsed(const tUShortSeq& verts) const;
  //-------------------------------------------------------
  // @name :      invalidate
  // notifies polygon that vertices has changed.
  //-------------------------------------------------------
  virtual void      invalidate();
  //-------------------------------------------------------
  // @name :      flip
  // flips visible side of the polygon
  //-------------------------------------------------------
  virtual void      flip();
  //-------------------------------------------------------
  // @name :   getTriangles
  // Provides triangulated polygon data. Triplet of longs
  // makes a single triangle [0,1,2] then [3,4,5] and so on.
  // @param const ZVertexBuf& vBuf         : [new] vertex buffer
  // @param tUShortSeq& triples              : ret-val arg
  //-------------------------------------------------------
  // i1, i2, i3, i4, i1, i3
  virtual ZRESULT   getTriangles(const ZVertexBuf& vBuf, tUShortSeq& triples);
  virtual ZRESULT   getExterior(tUShortSeq& verts);
  virtual ZRESULT   setExterior(tUShortSeq& verts);
  virtual ZPoint3D& getCenter() const;

private:
  //
  // additional data members
  //
  bool            m_bInvalid;
  WORD            m_quad[4];
  ZVector         m_vNormal;  //not guaranteed to be valid. i1,i2,i3 are used for calc.
  ZPoint3D        m_ptCenter;
};


//------------------------------------------------------
//
//  ZPolygon - Standard polygon (support concave, convex, holes)
//  
//------------------------------------------------------
class DLL_LINKAGE ZPolygon : public ZPoly
{
public:
  //
  // constructors/destructors
  //
  ZPolygon();
  virtual ~ZPolygon();

public:
  virtual ePolyType type() const;
  virtual bool type(const ePolyType t) const;
  virtual DWORD size() const {return sizeof(ZPolygon);}

public:
  //
  // assignment operators
  //
  virtual ZPoly& operator = ( const ZPoly& poly);

public:
  //
  // compare operators
  //
  virtual bool operator == ( const ZPoly& poly) const;
  virtual bool operator != ( const ZPoly& poly) const;

public:
  //
  // accessors
  //
  virtual WORD& operator [] (const long _indx);
  virtual const WORD operator [] (const long _indx) const;

  //
  // operations
  //
  virtual short     verts();
  virtual short     tris() ;
  virtual ZRESULT   verts(const short v, const WORD* data=NULL);
  virtual ZVector&  normal();
  virtual bool      isUsed(const WORD nVert) const;
  virtual bool      isUsed(const tUShortSeq& verts) const;
  //-------------------------------------------------------
  // @name :      invalidate
  // notifies polygon that vertices has changed.
  //-------------------------------------------------------
  virtual void      invalidate();
  //-------------------------------------------------------
  // @name :      flip
  // flips visible side of the polygon
  //-------------------------------------------------------
  virtual void      flip();
  //-------------------------------------------------------
  // @name :   getTriangles
  // Provides triangulated polygon data. Triplet of longs
  // makes a single triangle [0,1,2] then [3,4,5] and so on.
  // @param const ZVertexBuf& vBuf         : [new] vertex buffer
  // @param tUShortSeq& triples              : ret-val arg
  //-------------------------------------------------------
  virtual ZRESULT   getTriangles(const ZVertexBuf& vBuf, tUShortSeq& triples);
  virtual ZRESULT   getExterior(tUShortSeq& verts);
  virtual ZRESULT   setExterior(tUShortSeq& verts);
  virtual ZRESULT   setExteriorLength(const long nLen);
  virtual ZPoint3D& getCenter() const;
  virtual long numHoles() const;
  virtual ZRESULT getHole(const int i, tUShortSeq& verts) const;
  virtual ZRESULT setHole(const int i, tUShortSeq& verts);
  virtual ZRESULT removeHole(const int i);

private:
  // helpers:
  ZVector     getNormal(const ZVertexBuf& vBuf);
  ZPoint3D    getCenter(const ZVertexBuf& vBuf);
  bool        isClockwise(const ZVertexBuf& vBuf, const tUShortSeq& seq);
  bool        canCutTriangle( const ZVertexBuf& vBuf,
                              tUShortSeq& seq,
                              const WORD nIndex,
                              bool bClockwise);
  bool        insertHole( const ZVertexBuf& vBuf,
                          tUShortSeq& seq,
                          const short nHoleIndex);

  //
  // additional data members
  //
  bool                  m_bInvalid;
  tUShortSeq            m_triangles;
  tUShortSeq            m_exterior;
  ZSequence<tUShortSeq> m_holes;
  short                 m_numVerts;
  short                 m_numTris;
  ZVector               m_vNormal;
  ZPoint3D              m_ptCenter;
};



#endif //zpolygonshelper_h_included

