/***************************************************************************
 *                          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 2.x scene::ILinkable helper
 *--------------------------------------------------------------------------
 * @histroy: 21.04.2003. Created
 */
#ifndef zmnodeshelper_h_included
#define zmnodeshelper_h_included

#include <scene/IVisualizeable.h>
#include <scene/ITransformable.h>
#include <scene/IBoundable.h>
#include <scene/IManipulateable.h>
#include <core/INamed.h>
#include <scene/INode.h>
#include <helpers/serializeable.h>
#include "status.h"

namespace core
{
  //--------------------------------------------
  //  CNamed
  //--------------------------------------------
  class DLL_LINKAGE CNamed : public INamed
  {
    public:
      CNamed(){}
      virtual ~CNamed(){}
    public:
    //-----------------------
    // core::INamed
    //-----------------------
      virtual ZRESULT getName(ZString& str);
      virtual ZRESULT setName(ZString str);
      virtual ZRESULT getTitle(ZString& str);
      virtual ZRESULT setTitle(ZString str);
      virtual ZRESULT getDescription(ZStringSeq& seqDesc);
      virtual ZRESULT setDescription(ZStringSeq& seqDesc);

    protected:
    //-----------------------
    // data members:
    //-----------------------
      ZString       m_strTitle;
      ZString       m_strName;
      ZStringSeq    m_seqDesc;
  };
  //helper: provides INamed->getTitle
  DLL_LINKAGE ZRESULT ZAPICALL getINamedTitle(ZUnknown* pUnk, ZString& strTitle);
  DLL_LINKAGE ZRESULT ZAPICALL setINamedTitle(ZUnknown* pUnk, LPCTSTR pszTitle);
};

namespace scene
{
  //helper: calls IScene->boundingChange
  DLL_LINKAGE ZRESULT ZAPICALL boundingChange(INode* pNode);

  //--------------------------------------------
  //  CBoundable
  //--------------------------------------------
  class DLL_LINKAGE CBoundable : public scene::IBoundable
  {
    public:
    //-----------------------
    // IBoundable
    //-----------------------
      virtual ZRESULT getBoundary(ZBoundary& bound);
      virtual ZRESULT setBoundary(ZBoundary& bound);
      virtual ZRESULT updateBoundary() { return ZRESULT_FALSE; }

    protected:
    //-----------------------
    // data members:
    //-----------------------
      ZBoundary             m_Bound;
  };

  //--------------------------------------------
  //  CTransformable
  //--------------------------------------------
  class DLL_LINKAGE CTransformable : public scene::ITransformable
  {
    public:
      CTransformable(){}
      virtual ~CTransformable(){}
    public:
    //-----------------------
    // ITransformable
    //-----------------------
      virtual ZRESULT getTransform(ZMatrix& trans);
      virtual ZRESULT setTransform(ZMatrix& trans);
  

    protected:
    //-----------------------
    // data members:
    //-----------------------
      ZMatrix               m_Transform;
  };
  //helper: provides ITransformable->get/setTransform
  DLL_LINKAGE ZRESULT ZAPICALL getITransformableMatrix(ZUnknown* pUnk, ZMatrix& mat);
  DLL_LINKAGE ZRESULT ZAPICALL setITransformableMatrix(ZUnknown* pUnk, ZMatrix& mat);

  //--------------------------------------------
  //  CVisualizeable
  //--------------------------------------------
  class DLL_LINKAGE CVisualizeable : public scene::IVisualizeable
  {
    public:
      CVisualizeable(){}
      virtual ~CVisualizeable(){}

    public:
    //-----------------------
    // IVisualizeable
    //-----------------------
      virtual ZRESULT getRenderTechnique(rend::IRenderTechnique** ppTech);
      virtual ZRESULT setRenderTechnique(rend::IRenderTechnique* pTech);
    protected:
    //-----------------------
    // data members:
    //-----------------------
      ZPtr<rend::IRenderTechnique>      m_pRenderTechnique;
  };

  //------------------------------
  //
  //  The manipulator class
  //
  //------------------------------
  class DLL_LINKAGE CManipulator :  public IManipulator,
                                    public core::CNamed
  {
    public:
      INTERFACE_DECLAREMAP(CManipulator)

    public:
      CManipulator();
      virtual ~CManipulator();

    public:
    //-----------------------
    // IManipulator
    //-----------------------
      virtual ZRESULT getParent(scene::INode** ppParent);
      virtual ZRESULT hitTest(core::ui::IViewport* pV, ZLine3D line, float fPrecision, ZMatrix* pMatNode=NULL, ZMatrix* pMatView=NULL);
      virtual ZRESULT getDisplayTransform(core::ui::IViewport* pV, ZMatrix& matDisplay, ZMatrix* pMatNode=NULL, ZMatrix* pMatView=NULL);

    public:
    //-----------------------
    // ITransformable
    //-----------------------
      virtual ZRESULT getTransform(ZMatrix& trans);
      virtual ZRESULT setTransform(ZMatrix& trans);

    public:
    //-----------------------
    // IStatus
    //-----------------------
      virtual DWORD   setStatus(const DWORD dwStatus);
      virtual DWORD   changeStatus(const DWORD nAdd, const DWORD nRemove);

    private:
    //-----------------------
    // implementation:
    //-----------------------

    public:
    //-----------------------
    // data members:
    //-----------------------
      ZStdPtr<scene::INode>     m_pParent;
      ZMatrix                   m_Transform;
  };//class


  //------------------------------------------------------------
  //
  //  node-space position manipulator
  //
  //  implements behavior of point-manipulator in node-space
  //  getDisplayTransform, hitTest, getTransform are reffering
  //  to getPosition function.
  //  setTransform reffers to setPosition function
  //------------------------------------------------------------
  class DLL_LINKAGE CNodeSpacePositionManipulator : public CManipulator
  {
    public:
      INTERFACE_OVERLOAD_INSTANCE_CREATOR(CNodeSpacePositionManipulator)

      CNodeSpacePositionManipulator();
      virtual ~CNodeSpacePositionManipulator();
    public:
      //overloads:
      virtual ZRESULT getDisplayTransform(core::ui::IViewport* pV, ZMatrix& matDisplay, ZMatrix* pMatNode=NULL, ZMatrix* pMatView=NULL);
      virtual ZRESULT hitTest(core::ui::IViewport* pV, ZLine3D line, float fPrecision, ZMatrix* pMatNode=NULL, ZMatrix* pMatView=NULL);
      virtual ZRESULT getTransform(ZMatrix& trans);
      virtual ZRESULT setTransform(ZMatrix& trans);
    public:
      //overload these functions in your derived class:
      virtual void getPosition(ZPoint3D& pt) { return; }
      virtual void setPosition(ZPoint3D& pt) { return; }
  };//class

  //------------------------------
  //
  //  The light-weight node class
  //
  //------------------------------
  class DLL_LINKAGE CMiniNode : public scene::INode
  {
    public:
      INTERFACE_DECLAREMAP(CMiniNode)

    public:
      CMiniNode();
      virtual ~CMiniNode();

    public:
    //-----------------------
    // INode
    //-----------------------
      virtual ZRESULT getParent(scene::INode** ppParent);
      virtual ZRESULT getChildren(CNodeCol** ppChildren);
      virtual ZRESULT setParent(scene::INode* pParent);
      virtual ZRESULT setChildren(CNodeCol* pChildren);
      virtual ZRESULT queryNodeOperation(eNodeOperation co, scene::INode* pNode, DWORD dwRes=0);
      virtual ZRESULT changed(DWORD dwBits);
      virtual ZRESULT clone(scene::INode** ppNode, bool bShareData=false);

    public:
      //overloads
      virtual DWORD   setStatus(const DWORD dwStatus);
      virtual DWORD   changeStatus(const DWORD nAdd, const DWORD nRemove);

    public:
    //-----------------------
    // data members:
    //-----------------------
      ZPtr<CNodeCol>        m_pChildren;
      ZStdPtr<INode>        m_pParent;
  };//class


  //--------------------------------------------
  //  CNode
  //--------------------------------------------
  class DLL_LINKAGE CNode : public CMiniNode, 
                            public CBoundable, 
                            public CTransformable,
                            public core::CNamed,
                            public core::io::ISerializeable
  {
    public:
      INTERFACE_DECLAREMAP(CNode)

    public:
      CNode();
      virtual ~CNode();

    public:
    //-----------------------
    // INode
      virtual ZRESULT changed(DWORD dwBits);
      virtual ZRESULT clone(scene::INode** ppNode, bool bShareData=false);

    public:
    //-----------------------
    // ISerializeable
    //-----------------------
      virtual ZRESULT saveDeclaration(core::io::IStream* pStream, services::IOpenSaveService* pSrv, LPCTSTR pszResolver=NULL);
      virtual ZRESULT saveData(core::io::IStream* pStream, DWORD dwID, services::IOpenSaveService* pSrv);
      virtual ZRESULT loadData(core::io::IStream* pStream, services::IOpenSaveService* pSrv, DWORD dwSize, DWORD dwVersion=0, bool bMerge = false);
      virtual ZRESULT getReCreationMode(core::io::eReCreationMode& mode);
 
    //-----------------------
    // data members:
    //-----------------------
    protected:
  };//class
};//scene

#endif //zmnodeshelper_h_included

