##########################################################################
#
#  Copyright (c) 2011, Image Engine Design Inc. All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are
#  met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#
#     * Neither the name of Image Engine Design nor the names of any
#       other contributors to this software may be used to endorse or
#       promote products derived from this software without specific prior
#       written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
#  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
#  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
#  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
#  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
#  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
#  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
#  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
##########################################################################

import hou

import IECore

## A context manager for controlling houdini parameter values in with statements.
# It sets parameters to requested values on entering the block and resets them to
# their previous values on exiting the block.
class TemporaryParameterValues :

	def __init__( self, parametersAndValues = {}, **kw ) :

		self.__parametersAndValues = parametersAndValues
		self.__parametersAndValues.update( kw )

	def __enter__( self ) :

		handlers = {
			"Int" : self.__simpleParmHandler,
			"Float" : self.__simpleParmHandler,
			"String" : self.__simpleParmHandler,
		}

		self.__restoreCommands = []
		for parmName, value in self.__parametersAndValues.items() :

			# check we can handle this type
			parm = hou.parm( parmName ) or hou.parmTuple( parmName )
			if not parm :
				raise TypeError( "Parameter \"%s\" does not exist." % parmName )

			parmType = parm.parmTemplate().dataType().name()
			handler = handlers.get( parmType, None )
			if not handler :
				raise TypeError( "Parameter \"%s\" has unsupported type \"%s\"." % ( parmName, parmType ) )

			# store a command to restore the parameter value later
			self.__restoreCommands.append( parm.asCode() )

			# and change the parameter value
			handler( parm, value )

	def __exit__( self, type, value, traceBack ) :

		for command in self.__restoreCommands :
			exec( command )

	def __simpleParmHandler( self, parm, value ) :

		if isinstance( parm, hou.ParmTuple ) and not isinstance( value, tuple ) :
			value = value,

		parm.deleteAllKeyframes()
		parm.set( value )
