/***************************************************************************
 *                          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-2003 Zanoza Software.                 *
 *                                                                         *
 *                        All rights reserved.                             *
 ***************************************************************************
 *--------------------------------------------------------------------------
 * @author:   Oleg M.
 *--------------------------------------------------------------------------
 * @purpose:  ZModeler 2.x core::undo helpers
 *--------------------------------------------------------------------------
 * @histroy: 21.02.2004. Created
 */
#ifndef coreundohelper_h_included
#define coreundohelper_h_included

#include <zmodeler.h>
#include <services/IUndoService.h>
#include <core/INamed.h>
#include <core/IStatus.h>
#include <scene/INode.h>
#include <scene/ITransformable.h>
#include <scene/IBoundable.h>
#include <scene/ISplineNode.h>
#include <scene/IMeshNode.h>
#include <scene/IDummyNode.h>
#include <scene/ISkeletonNode.h>
#include <scene/IBoneNode.h>
#include <scene/ILight.h>
#include <core/ui/controls/IUserDefinedOptions.h>

namespace core
{
  namespace undo
  {
    //
    // helper functions for using common undo blocks
    //
    DLL_LINKAGE ZRESULT ZAPICALL beginUndoBranch(LPCTSTR pszName);
    DLL_LINKAGE ZRESULT ZAPICALL commitUndoBranch();
    DLL_LINKAGE ZRESULT ZAPICALL rollbackUndoBranch();
    DLL_LINKAGE ZRESULT ZAPICALL isRecording(); //ZRESULT_OK if service recording.
    //
    // wrapper class for begin-commit/rollback on branch transactions
    //
    class DLL_LINKAGE CAutoUndoBranch
    {
    public:
      CAutoUndoBranch() 
      {
        m_bCommit = false;
      }
      CAutoUndoBranch(LPCTSTR pszName) 
      { 
        beginUndoBranch(pszName); 
        m_bCommit = false; 
      }
      ~CAutoUndoBranch() 
      {
        if (ZRESULT_OK == isRecording() && !m_bCommit) 
          rollbackUndoBranch(); 
      }
    public:
      void commit() 
      {
        if (!m_bCommit)//to avoid comitting someone else's branch.
          m_bCommit = (ZRESULT_OK==isRecording()) ? (ZRESULT_OK==commitUndoBranch()): true;
      }
    private:
      bool m_bCommit;
    };


    //serves UNDO_ADD_NODE, UNDO_DROP_NODE, UNDO_RELINK_NODE
    DLL_LINKAGE ZRESULT ZAPICALL undoNodeOperation(
                                          LPCTSTR pszName,
                                          eCommonUndo type,
                                          core::IProcParams* pParams,
                                          scene::INode* pNode);

    //serves UNDO_TRANSFORM
    DLL_LINKAGE ZRESULT ZAPICALL undoTransformOperation(
                                          LPCTSTR pszName,
                                          core::IProcParams* pParams,
                                          scene::ITransformable* pTrans);
    //serves UNDO_MASS_TRANSFORM
    DLL_LINKAGE ZRESULT ZAPICALL undoMassTransformOperation(
                                          LPCTSTR pszName,
                                          core::IProcParams* pParams,
                                          scene::ITransformable** ppTransBuf,
                                          long nCountT,
                                          scene::INode** ppNodeBuf,
                                          long nCountN);
    //serves UNDO_INAMED
    DLL_LINKAGE ZRESULT ZAPICALL undoNamingOperation(
                                          LPCTSTR pszName,
                                          core::IProcParams* pParams,
                                          core::INamed* pNamed);

    //serves UNDO_ISTATUS
    DLL_LINKAGE ZRESULT ZAPICALL undoStatusOperation(
                                          LPCTSTR pszName,
                                          core::IProcParams* pParams,
                                          core::IStatus* pStatus);

    //serves UNDO_IBOUNDARY
    DLL_LINKAGE ZRESULT ZAPICALL undoBoundaryOperation(
                                          LPCTSTR pszName,
                                          core::IProcParams* pParams,
                                          scene::IBoundable* pBound);
    //serves UNDO_ENTITY
    DLL_LINKAGE ZRESULT ZAPICALL undoEntityOperation(
                                          LPCTSTR pszName,
                                          core::IProcParams* pParams,
                                          ZEntityBase* pEntity,
                                          scene::INode* pNode=NULL);

    //serves UNDO_SPLINE_*
    DLL_LINKAGE ZRESULT ZAPICALL undoSplineOperation(
                                          LPCTSTR pszName,
                                          eCommonUndo type,
                                          core::IProcParams* pParams,
                                          scene::ISplineNode* pNode);

    //serves UNDO_VERTEX_*, UNDO_POLY_*
    DLL_LINKAGE ZRESULT ZAPICALL undoPolyMeshOperation(
                                          LPCTSTR pszName,
                                          eCommonUndo type,
                                          core::IProcParams* pParams,
                                          scene::IMeshNode* pNode);

    //serves UNDO_ILIGHT
    DLL_LINKAGE ZRESULT ZAPICALL undoLight(
                                          LPCTSTR pszName,
                                          core::IProcParams* pParams,
                                          scene::ILight* pLight);

    //serves UNDO_IDUMMYNODE
    DLL_LINKAGE ZRESULT ZAPICALL undoDummyNode(
                                          LPCTSTR pszName,
                                          core::IProcParams* pParams,
                                          scene::IDummyNode* pDummy);


    //serves UNDO_IUSERDEFINED
    DLL_LINKAGE ZRESULT ZAPICALL undoUserDefinedOptions(
                                          LPCTSTR pszName,
                                          core::IProcParams* pParams,
                                          core::ui::controls::IUserDefinedOptions* pOptions);


    //serves UNDO_IBONENODE
    DLL_LINKAGE ZRESULT ZAPICALL undoBoneNode(
                                          LPCTSTR pszName,
                                          core::IProcParams* pParams,
                                          scene::IBoneNode*  pBone);
    //serves UNDO_ISKELETONNODE
    DLL_LINKAGE ZRESULT ZAPICALL undoSkeletonNode(
                                          LPCTSTR pszName,
                                          core::IProcParams* pParams,
                                          scene::ISkeletonNode* pSkeleton);

    //serves UNDO_MATERIAL_*
    DLL_LINKAGE ZRESULT ZAPICALL undoMaterialOperation(
                                          LPCTSTR pszName,
                                          eCommonUndo type,
                                          core::IProcParams* pParams,
                                          rend::IMaterial* pMat);

    //serves UNDO_TEXTURE_*
    DLL_LINKAGE ZRESULT ZAPICALL undoTextureOperation(
                                          LPCTSTR pszName,
                                          eCommonUndo type,
                                          core::IProcParams* pParams,
                                          rend::ITexture* pTex);
  };//undo
};//core


#endif //coreundohelper_h_included



