#ifndef _MItEdits
#define _MItEdits
//-
// ==========================================================================
// Copyright (C) 2012 Autodesk, Inc., and/or its licensors.  All
// rights reserved.
//
// The coded instructions, statements, computer programs, and/or related
// material (collectively the "Data") in these files contain unpublished
// information proprietary to Autodesk, Inc. ("Autodesk") and/or its
// licensors,  which is protected by U.S. and Canadian federal copyright law
// and by international treaties.
//
// The Data may not be disclosed or distributed to third parties or be
// copied or duplicated, in whole or in part, without the prior written
// consent of Autodesk.
//
// The copyright notices in the Software and this entire statement,
// including the above license grant, this restriction and the following
// disclaimer, must be included in all copies of the Software, in whole
// or in part, and all derivative works of the Software, unless such copies
// or derivative works are solely in the form of machine-executable object
// code generated by a source language processor.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED
// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF
// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE,
// OR ARISING FROM A COURSE OF DEALING, USAGE, OR TRADE PRACTICE. IN NO
// EVENT WILL AUTODESK AND/OR ITS LICENSORS BE LIABLE FOR ANY LOST
// REVENUES, DATA, OR PROFITS, OR SPECIAL, DIRECT, INDIRECT, OR
// CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK AND/OR ITS LICENSORS HAS
// BEEN ADVISED OF THE POSSIBILITY OR PROBABILITY OF SUCH DAMAGES.
// ==========================================================================
//+
//
// CLASS:    MItEdits
//
// ****************************************************************************

#if defined __cplusplus

// ****************************************************************************
// INCLUDED HEADER FILES


#include <maya/MObject.h>
#include <maya/MStatus.h>
#include <maya/MEdit.h>

class MSetAttrEdit;
class MConnectDisconnectAttrEdit;
class MParentingEdit;
class MAddRemoveAttrEdit;
class MFcurveEdit;

// ****************************************************************************
// CLASS DECLARATION (MItEdits)

//! \ingroup OpenMaya
//! \brief Edits iterator. 
/*!

Use the edits iterator to traverse all the edits on a reference
or assembly. An edit is any operation that modifies the dependency graph
such as modifications to values, connections, parenting and so on. 

In the case of references, edits are the changes that occur to referenced nodes. 
In the case of assemblies, edits are the changes that occur to assembly members.

Edits are returned as either strings representing an equivalent MEL call, or as
a class derived from MEdit. 

The edits iterator works regardless of whether the related reference
or assembly is loaded or unloaded. However, please note that loading
or unloading the related reference or assembly will cause any
in-progress iteration to be reset.

If new edits were created while iterating, the iterator will not necessarily 
traverse them.

To control which edits you will traverse over, use the combination of the 
'editsOwner' and 'targetNode'/'targetNodeName' parameters.

The editsOwner is the reference or assembly node that "owns" edits. This is the 
top-level assembly/reference at the time the edit was made. If you were to save 
a file, this is the node that the edits would be stored on.

The targetNode is the innermost reference or assembly node containing the edited 
nodes. Edits will be physically stored on the edits owner, so use targetNode to
get just edits that affect nodes in a specific assembly/reference. If the nested 
assembly or reference is not loaded, you can still query edits that affect that 
node by specifying a string targetNodeName, instead of a targetNode MObject.

Hierarchical Example:

The following example explains the above terminology in the hierarchical case.
Suppose you have a reference or assembly hierarchy that looks like this.

\verbatim
A
|_ B
   |_ C
\endverbatim

Edits can be made at three different levels:
<ol>
<li> Edits made from C to nodes in C. These edits were made from the C file/assembly.  These edits are stored on C

<li> Edits made from B to nodes in B or C. These edits were made from the B file/assembly.  These edits are stored on B

<li> Edits made from A to nodes in A, B or C. These edits were made from the main scene.  These edits are stored on A
</ol>

To query all the edits stored on A, use:
editsOwner = A
targetNode = MObject::kNullObj

To query edits stored on A that affect nodes in A, use: 
editsOwner = A
targetNode = A

To query edits stored on A that affect nodes in B, use:
editsOwner = A
targetNode = B

To query all the edits stored on B, use:
editsOwner = B
targetNode = MObject::kNullObj

To only query edits stored on B that affect nodes in C, use:
editsOwner = B
targetNode = C
*/

class OPENMAYA_EXPORT MItEdits
{
public:
    class Imp;
    friend class Imp;

	//! The status of edits this iterator will visit
	enum EditStatus
	{
		//! Visit successful edits only
		SUCCESSFUL_EDITS, 
		//! Visit all the edits
		ALL_EDITS
	};

	//! The direction in which the iterator will visit its edits
	enum Direction
	{
		//! Visit the edits in the order in which they were added
		kForward, 
		//! Visit the edits in the reverse order from how they were added
		kReverse
	};

	MItEdits( MObject& editsOwner,
			  MObject& targetNode = MObject::kNullObj,
			  EditStatus editStatus = ALL_EDITS,
			  Direction direction = kForward,
			  MStatus * ReturnStatus = NULL );

	MItEdits( MObject& editsOwner,
		      const MString& targetNodeName,
			  EditStatus editStatus = ALL_EDITS,
			  Direction direction = kForward,
		      MStatus * ReturnStatus = NULL );

	virtual		~MItEdits();

	MStatus		reset();
	MStatus		next();
	bool		isDone( MStatus * ReturnStatus = NULL );
	bool		isReverse( MStatus * ReturnStatus = NULL ) const;

	MString		currentEditString( MStatus* ReturnStatus = NULL ) const;
	MEdit::EditType	currentEditType( MStatus* ReturnStatus = NULL ) const;
	bool		removeCurrentEdit(MStatus* ReturnStatus = NULL);

	MEdit				edit( MStatus * ReturnStatus = NULL ) const;
	MAddRemoveAttrEdit 	addRemoveAttrEdit( MStatus * ReturnStatus = NULL ) const;
	MSetAttrEdit 		setAttrEdit( MStatus * ReturnStatus = NULL ) const;
	MParentingEdit		parentingEdit( MStatus * ReturnStatus = NULL ) const;
	MFcurveEdit 		fcurveEdit( MStatus * ReturnStatus = NULL ) const;	
	MConnectDisconnectAttrEdit connectDisconnectEdit( MStatus * ReturnStatus = NULL ) const;

	static const char* className();

protected:
// No protected members

private:
	void		validateInitialization();

	static MEdit							makeEdit(void* edit, bool loaded);
	static MConnectDisconnectAttrEdit		makeConnectDisconnectAttrEdit(void* edit, bool loaded, bool isConnect);
	static MAddRemoveAttrEdit				makeAddRemoveAttrEdit(void* edit, bool loaded, bool isAdd);
	static MSetAttrEdit						makeSetEdit(void* edit, bool loaded);
	static MParentingEdit					makeParentingEdit(void* edit, bool loaded);
    static MFcurveEdit						makeFcurveEdit(void* edit, bool loaded);
	

    Imp* fImp;
};

#endif /* __cplusplus */
#endif /* _MItEdits */
