/***************************************************************************
 *                          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) 2003 Zanoza Software.                   *
 *                                                                         *
 *                        All rights reserved.                             *
 ***************************************************************************
 *--------------------------------------------------------------------------
 * @author:   Oleg M.
 *--------------------------------------------------------------------------
 * @purpose:  ZModeler's native boundary volume
 *--------------------------------------------------------------------------
 * @histroy: 08.03.2003. Created
 */
#ifndef zboundary_h_included
#define zboundary_h_included

#ifndef zsequence_h_included
# include "zsequence.h"
#endif

//------------------------------------------------------
//  ZBoundary - ZModeler's native Boundary
//------------------------------------------------------
class DLL_LINKAGE ZBoundary
{
public:
  enum eBoundType
  {
    NONE    = 0x00, /*just a placeholder*/
    RECT    = 0x01, /*screen-coord*/
    CIRCLE  = 0x02, /*screen-coord*/
    BOX     = 0x04,
    SPHERE  = 0x08,
    //CONE    = 0x20, /*reserved*/
    CYLINDER= 0x40,
    BOUND_DWORD = 0x7FFFFFFF  /*force DWORD compilation*/
  };
  //
  // Constructor/Destructor
  //
  ZBoundary();
  ZBoundary(const ZBoundary& bound);
  ~ZBoundary();

public:
  //
  // operations:
  //
  inline eBoundType getBoundType() const { return m_nBoundType; }
  inline bool isBoundType(eBoundType _type) const { return ((m_nBoundType & _type) != 0); }
  inline ZRESULT addBoundType(eBoundType _type)  { (DWORD&)m_nBoundType |= (DWORD)_type; return ZRESULT_OK; }
  inline ZRESULT removeBoundType(eBoundType _type)  { (DWORD&)m_nBoundType &= ~(DWORD)_type; return ZRESULT_OK; }

public:
  ZRESULT setWorldTransform(ZMatrix& mat); //modifies boundary to new world transform;
  //
  // bound-type specific operations
  //

  // RECT
  ZRESULT getRectBound(ZRect& rect) const;
  ZRESULT setRectBound(ZRect  rect);

  // CIRCLE
  ZRESULT getCircleBound(ZPoint& center, float& radius) const;
  ZRESULT setCircleBound(ZPoint  center, float  radius);

  // WSPHERE, SPHERE
  ZRESULT getSphereBound(ZPoint3D& center, float& radius) const;
  ZRESULT setSphereBound(ZPoint3D center, float radius);

  // BOX
  ZRESULT getBoxBound(ZPoint3D& minCorner, ZPoint3D& maxCorner) const;
  ZRESULT setBoxBound(ZPoint3D minCorner, ZPoint3D maxCorner);

  // LSPHERE
  ZRESULT getCylinderBound(ZPoint3D& center, float& length, float& radius) const;
  ZRESULT setCylinderBound(ZPoint3D center, float length, float radius);

  //
  // variouse intersection/containment tests:
  //
  ZRESULT lineIntersect(/*in*/ZLine3D& line, 
                        /*out*/ZPoint3D& ptIntersect,
                        /*out*/ZVector& vecNormal);

//-------------------------------------------------------
// @name : planeTest
// testes the bound situation agains supplied plane
// @param ZPlane& plane             : plane to test
// @param ZPlane::ePlanePos position: position about the plane
//
// @return ZRESULT : 
//-------------------------------------------------------
  ZRESULT planeTest(/*in*/  ZPlane& plane, 
                    /*out*/ ZPlane::ePlanePos position);
private:
  //
  // data members:
  //
  eBoundType  m_nBoundType;
  ZPoint3D    m_ptMin, m_ptMax;
  ZPoint3D    m_ptCenter3;
  float       m_fRadius, m_fLength;
  ZPoint      m_ptCenter2;
  ZRect       m_rect;
};

typedef ZSequence<ZBoundary>  ZBoundarySeq;


#endif //zboundary_h_included

