#ifndef _MPxIkSolverNode
#define _MPxIkSolverNode
//-
// ==========================================================================
// Copyright (C) 1995 - 2006 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:    MPxIkSolverNode
//
// ****************************************************************************

#if defined __cplusplus

// ****************************************************************************
// INCLUDED HEADER FILES


#include <maya/MStatus.h>
#include <maya/MTypes.h>
#include <maya/MObject.h>
#include <maya/MPxNode.h>

// ****************************************************************************
// DECLARATIONS

class MString;
class MArgList;
class MIkHandleGroup;
class MMatrix;
class MDoubleArray;

// ****************************************************************************
// CLASS DECLARATION (MPxIkSolverNode)

//! \ingroup OpenMayaAnim MPx
//! \brief Base class for user defined IK solvers  
/*!
This is the base class for writing user-defined IK solvers.
Users must at least override the following methods in order to write a solver:

	\li <b>doSolve</b>
	\li <b>solverTypeName</b>

Users can optionally override the following methods if they want to perform work
before or after <b>doSolve</b> is called:

	\li <b>preSolve</b>
	\li <b>postSolve</b>

If users override these methods, they are responsible for calling the base class
implementation of the overridden method(s).  The base class handles a few things
such as solver locking/unlocking and FK/IK solution blending.  If users fail to
call the base class implementation, instabilities can occur leading to wrong
evaluation or even crashes.

Note that the following virtual methods (declared in MPxNode) are
irrelevant for the MPxIkSolverNode. If these methods are overridden in
a class derived from MPxIkSolverNode, they will be ignored.

	\li <b>compute</b>
	\li <b>getInternalValue</b>
	\li <b>setInternalValue</b>
	\li <b>legalConnection</b>
	\li <b>legalDisconnection</b>
	\li <b>connectionMade</b>
	\li <b>connectionBroken</b>


A creator method is necessary to return an instance of the
user solver:

\code
    userSolver::creator() {
        return new userSolver;
    }
\endcode

In order to create and register the solver, execute the mel command:
\code
    createNode userSolver;
\endcode

Once the solver is registered it can be assigned to IK handles and its
solve methods will be called in the same manner as the solvers within
Maya.
*/
class OPENMAYAANIM_EXPORT MPxIkSolverNode : public MPxNode
{
public:
	virtual ~MPxIkSolverNode();
	virtual MPxNode::Type type() const;

	virtual MStatus		preSolve();
	virtual MStatus		doSolve();
	virtual MStatus		postSolve( MStatus );

	virtual MString		solverTypeName() const;

	bool				rotatePlane(MStatus *ReturnStatus = NULL) const;
	MStatus				setRotatePlane(bool rotatePlane);
	bool				singleChainOnly(MStatus *ReturnStatus = NULL) const;
	MStatus				setSingleChainOnly(bool singleChainOnly);
	bool				positionOnly(MStatus *ReturnStatus = NULL) const;
	MStatus				setPositionOnly(bool positionOnly);
	bool				supportJointLimits(MStatus *ReturnStatus = NULL) const;
	MStatus				setSupportJointLimits(bool supportJointLimits);
	bool				uniqueSolution(MStatus *ReturnStatus = NULL) const;
	MStatus				setUniqueSolution(bool uniqueSolution);

	// Obsolete
	virtual bool		isSingleChainOnly() const;
	// Obsolete
	virtual bool		isPositionOnly() const;
	// Obsolete
	virtual bool		hasJointLimitSupport() const;
	// Obsolete
	virtual bool		hasUniqueSolution() const;
	// Obsolete
	virtual bool		groupHandlesByTopology() const;

	virtual MStatus		setFuncValueTolerance( double tolerance );
	virtual MStatus		setMaxIterations( int value );

	MIkHandleGroup * 	handleGroup() const;
	virtual void 		setHandleGroup( MIkHandleGroup* );
	const MMatrix *		toWorldSpace() const;
	const MMatrix *		toSolverSpace() const;
	double 				funcValueTolerance() const;
	int 				maxIterations() const;
	virtual void 		snapHandle( MObject& handle );

	void				create();

	// SCRIPT USE ONLY
	MStatus _getJointAngles( MDoubleArray& da ) const 
		{return getJointAngles(da);}
	MStatus	_setJointAngles( const MDoubleArray& da ) 
		{return setJointAngles(da);}
	void _setToRestAngles() 
		{ setToRestAngles(); }
	//

	static const char*	className();

protected:

	// USE _getJointAngles() IN SCRIPT	
	MStatus				getJointAngles( MDoubleArray& ) const;
	// USE _setJointAngles() IN SCRIPT	
	MStatus				setJointAngles( const MDoubleArray& );
	// USE _setToRestAngles() IN SCRIPT	
	void				setToRestAngles();

	MPxIkSolverNode();

private:
};

#endif /* __cplusplus */
#endif /* _MPxIkSolverNode */
