//Copyright © 2008 Autodesk, Inc.
//All Rights Reserved.
//
//The coded instructions, statements, computer programs, and/or related material (collectively "Data")
//in these files contain unpublished information proprietary to Autodesk, Inc., ("Autodesk") which is
//protected by Canada and United States of America federal copyright law and by international treaties.
//
//The Data may not be disclosed or distributed to third parties, in whole or in part, without the prior
//written consent of Autodesk.
//
//THE DATA IS PROVIDED "AS IS" AND WITHOUT WARRANTY. ALL WARRANTIES ARE EXPRESSLY EXCLUDED AND DISCLAIMED.
//AUTODESK MAKES NO WARRANTY OF ANY KIND WITH RESPECT TO THE DATA, EXPRESS, IMPLIED OR ARISING BY CUSTOM
//OR TRADE USAGE, AND DISCLAIMS ANY IMPLIED WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
//FITNESS FOR A PARTICULAR PURPOSE OR USE. WITHOUT LIMITING THE FOREGOING, AUTODESK DOES NOT WARRANT THAT
//THE OPERATION OF THE DATA WILL BE UNINTERRUPTED OR ERROR FREE.
//
//IN NO EVENT SHALL AUTODESK, ITS AFFILIATES, PARENT COMPANIES, LICENSORS OR SUPPLIERS ("AUTODESK GROUP")
//BE LIABLE FOR ANY LOSSES, DAMAGES OR EXPENSES OF ANY KIND (INCLUDING WITHOUT LIMITATION PUNITIVE OR
//MULTIPLE DAMAGES OR OTHER SPECIAL, DIRECT, INDIRECT, EXEMPLARY, INCIDENTAL, LOSS OF PROFITS, REVENUE OR
//DATA, COST OF COVER OR CONSEQUENTIAL LOSSES OR DAMAGES OF ANY KIND), HOWEVER CAUSED, AND REGARDLESS OF
//THE THEORY OF LIABILITY, WHETHER DERIVED FROM CONTRACT, TORT (INCLUDING, BUT NOT LIMITED TO, NEGLIGENCE),
//OR OTHERWISE, ARISING OUT OF OR RELATING TO THE DATA OR ITS USE OR ANY OTHER PERFORMANCE, WHETHER OR NOT
//AUTODESK HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE.

#ifndef HIKPINNINGSTATE_H
#define HIKPINNINGSTATE_H

#ifndef _DLL_
#ifdef _WINDOWS
	#define _DLL_				__declspec(dllimport) 
#else
	#define _DLL_
#endif
#endif

#ifndef COMPILING_MAYAHIK_IN_MAYA
	#include <humanik/humanik.h>
#else
	#include <humanik.h>
#endif

#include <maya/MPxNode.h>
#include <maya/MPxCommand.h>
#include <maya/MSelectionList.h>

#include <stack>

namespace MayaHIK
{
	class _DLL_ MPxHIKPinningState : public MPxNode
	{
	public:
		enum {
			eSize = LastEffectorId
		};
		static MTypeId id;

		static MObject IPinT[eSize];
		static MObject IPinR[eSize];
		
		static MObject IHIKEffectorState;
		static MObject IHIKEffectorStateNoAux;

		static MObject OHIKEffectorState;
		static MObject OHIKEffectorStateNoAux;
		
		MPxHIKPinningState();
		
		static	void*	creator()    { return new MPxHIKPinningState; }
		static	MStatus	initialize();

		MStatus compute( const MPlug & plug, MDataBlock & block );

		MStatus	push( bool ReleaseAll ); 
		MStatus	pop();

		bool IsDescendantPulling(int pEffectorId)const;

        // variables used for setting up 

        enum manipMode
        {
            eTranslate,
            eRotate
        };

        enum characterManipMode
        {
            eBodyPart,
            eFullBody
        };

        enum effectorSelectionState
        {
            eNotSelected,
            eMainSelected,
            ePivotSelected
        };

        unsigned mActiveBodypartMask;
        unsigned mAffectedBodyPartMask;

		// Manipulation mode parameters
        bool                    mManipActive;
        characterManipMode      mCharacterManipMode;
        manipMode               mManipMode;
        effectorSelectionState  mEffectorSelectionState[eSize];
        bool                    mHasActiveAuxT[eSize];
        bool                    mHasActiveAuxR[eSize];
        bool                    mPinningReleased;

        void                    resetManipModeVars();




	protected:
#ifdef _WINDOWS
		//Warning C4251 can be ignored in Microsoft Visual C++ 2005 if you are deriving from a type in the Standard C++ Library,
		//compiling a debug release (/MTd) and where the compiler error message refers to _Container_base.
		#pragma message("Warning C4251 can be ignored in debug build when using Containers")
		#pragma warning( disable : 4251 )
#endif
		std::stack<bool> mStack;
	};

	class MPxPinningPushCmd : public MPxCommand
	{
	public:
		MStatus doIt(const MArgList& args);
		static void* creator() { return new MPxPinningPushCmd; }
	};

	class MPxPinningPopCmd : public MPxCommand
	{
	public:
		MStatus doIt(const MArgList& args);
		static void* creator() { return new MPxPinningPopCmd; }
	};

	class MPxIsDescendentPullingCmd : public MPxCommand
	{
	public:
		MStatus doIt(const MArgList& args);
		MStatus redoIt();
		static void* creator() { return new MPxIsDescendentPullingCmd; }
		static MSyntax newSyntax();
	protected:
		bool mEffectorIdFlagSet;
		int  mEffectorId;
		MSelectionList mObjects;
	};

}

#endif
