/***************************************************************************
 *                          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 base vertex
 *--------------------------------------------------------------------------
 * @histroy: 22.04.2003. Created
 */
#ifndef zvertex_h_included
#define zvertex_h_included

//------------------------------------------------------
//  ZVertex - ZModeler's base Vertex
//------------------------------------------------------
class DLL_LINKAGE ZVertex : public ZEntityBase
{
public:
  //
  // constructors/destructors
  //
  ZVertex();
  virtual ~ZVertex();

public:
  //
  // typedefs
  //
  enum eVertexColor { DIFFUSE = 0, SPECULAR = 1 };

public:
  //
  // the actual size:
  //
  virtual DWORD size() const;    //in bytes
  virtual DWORD format() const;  //VERTEX_HAS_ bit-masked value

public:
  //
  // casting operators
  //
  virtual operator float* ();
  virtual operator const float* () const;

public:
  //
  // assignment operators
  //
  virtual ZVertex& operator =  ( const ZVertex& vtx);
  virtual ZVertex& operator += ( const ZVertex& vtx);
  virtual ZVertex& operator -= ( const ZVertex& vtx);
  virtual ZVertex& operator *= ( float v);
  virtual ZVertex& operator /= ( float v);

public:
  //
  // unary operators
  //
  virtual ZVertex& operator + () const;
  virtual ZVertex& operator - () const;

public:
  //
  // binary operators
  //
  virtual ZVertex& operator + ( const ZVertex& vtx) const;
  virtual ZVertex& operator - ( const ZVertex& vtx) const;
  virtual ZVertex& operator * ( const ZVertex& vtx) const; //cross product
  virtual ZVertex& operator * ( float v) const;
  virtual ZVertex& operator / ( float v) const;
  virtual float   operator ^ ( const ZVertex& vtx) const; //dot product

public:
  //
  // compare operators
  //
  virtual bool operator == ( const ZVertex& vtx) const;
  virtual bool operator != ( const ZVertex& vtx) const;
  virtual bool operator < ( const ZVertex& vtx) const;
  virtual bool operator <= ( const ZVertex& vtx) const;

public:
  //
  // accessors
  //
  virtual ZPoint3D&     position();
  virtual ZPoint3D&     position(const ZPoint3D& p);
  virtual ZVector&      normal(const int nWhich=0);
  virtual ZVector&      normal(const ZVector& n, const int nWhich=0);
  virtual ZPoint2D&     uv(const int i);
  virtual ZPoint2D&     uv(const int i, const ZPoint2D& uv);
  virtual ZColor&       color(const eVertexColor c);
  virtual ZColor&       color(const eVertexColor c, const ZColor& col);
  virtual BYTE&         boneID(const int i);
  virtual BYTE&         boneID(const int i, const BYTE b);
  virtual float&        boneW(const int i);
  virtual float&        boneW(const int i, const float w);
  //
  // quick accessors
  //
  inline float&        x() { return position().x; }
  inline float&        y() { return position().y; }
  inline float&        z() { return position().z; }
  inline float&        nx() { return normal().x; }
  inline float&        ny() { return normal().y; }
  inline float&        nz() { return normal().z; }
  inline float&        u() { return uv(0).u; }
  inline float&        v() { return uv(0).v; }
  inline float&        x(const float _x) { return position().x = _x; }
  inline float&        y(const float _y) { return position().y = _y; }
  inline float&        z(const float _z) { return position().z = _z; }
  inline float&        nx(const float _nx) { return normal().x = _nx; }
  inline float&        ny(const float _ny) { return normal().y = _ny; }
  inline float&        nz(const float _nz) { return normal().z = _nz; }
  inline float&        u(const float _u) { return uv(0).u = _u; }
  inline float&        v(const float _v) { return uv(0).v = _v; }

private:
  //
  // data members are hidden
  //
};

// helper function. obtians default compatibility's vertex format
DLL_LINKAGE DWORD getDefaultVertexFormat();

#endif //zvertex_h_included

