#----------Random Vector Node-------------#
#----------------Version 1.0-------------------#
#--------------By Peter Rabel-----------------#
import maya.OpenMaya as OpenMaya
import maya.OpenMayaMPx as OpenMayaMPx
import sys
import math
import random

kcompUtilNodeTypeName = "randomNumber"
kcompUtilNodeClassify = "utility/general"
kcompUtilNodeId = OpenMaya.MTypeId(0x87549)

class randomNode(OpenMayaMPx.MPxNode):

	#define class variables
	inputMin = OpenMaya.MObject()
	inputMinX = OpenMaya.MObject()
	inputMinY = OpenMaya.MObject()
	inputMinZ = OpenMaya.MObject()
	inputMax = OpenMaya.MObject()
	inputMaxX = OpenMaya.MObject()
	inputMaxY = OpenMaya.MObject()
	inputMaxZ = OpenMaya.MObject()
	
	outValue = OpenMaya.MObject()
	outX = OpenMaya.MObject()
	outY = OpenMaya.MObject()
	outZ = OpenMaya.MObject()
	
	inTime = OpenMaya.MObject()
	
	def __init__(self):
		OpenMayaMPx.MPxNode.__init__(self)
		
	def compute(self, plug, dataBlock):
	
		# if these attributes are requested, recompute their values
		if plug == randomNode.outX or \
			randomNode.outY or randomNode.outZ:
		
			# get MDataHandle's to attributes
			try:
				inputMin_dataHandle = dataBlock.inputValue( randomNode.inputMin )
			except:
				sys.stderr.write( "Failed to get MDataHandle inputMin input" )
				raise
			try:
				inputMinX_dataHandle = dataBlock.inputValue( randomNode.inputMinX )
			except:
				sys.stderr.write( "Failed to get MDataHandle inputMinX input" )
				raise
			try:
				inputMinY_dataHandle = dataBlock.inputValue( randomNode.inputMinY )
			except:
				sys.stderr.write( "Failed to get MDataHandle inputMinY input" )
				raise
			try:
				inputMinZ_dataHandle = dataBlock.inputValue( randomNode.inputMinZ )
			except:
				sys.stderr.write( "Failed to get MDataHandle inputMinZ input" )
				raise
			try:
				inputMax_dataHandle = dataBlock.inputValue( randomNode.inputMax )
			except:
				sys.stderr.write( "Failed to get MDataHandle inputMax input" )
				raise
			try:
				inputMaxX_dataHandle = dataBlock.inputValue( randomNode.inputMaxX )
			except:
				sys.stderr.write( "Failed to get MDataHandle inputMaxX input" )
				raise
			try:
				inputMaxY_dataHandle = dataBlock.inputValue( randomNode.inputMaxY )
			except:
				sys.stderr.write( "Failed to get MDataHandle inputMaxY input" )
				raise
			try:
				inputMaxZ_dataHandle = dataBlock.inputValue( randomNode.inputMaxZ )
			except:
				sys.stderr.write( "Failed to get MDataHandle inputMaxZ input" )
				raise
				
			try:
				outValue_dataHandle = dataBlock.outputValue( randomNode.outValue )
			except:
				sys.stderr.write( "Failed to get MDataHandle out output" )
				raise	
			try:
				outX_dataHandle = dataBlock.outputValue( randomNode.outX )
			except:
				sys.stderr.write( "Failed to get MDataHandle outX output" )
				raise
			try:
				outY_dataHandle = dataBlock.outputValue( randomNode.outY )
			except:
				sys.stderr.write( "Failed to get MDataHandle outY output" )
				raise
			try:
				outZ_dataHandle = dataBlock.outputValue( randomNode.outZ )
			except:
				sys.stderr.write( "Failed to get MDataHandle outZ output" )
				raise
			try:
				inTime_dataHandle = dataBlock.inputValue( randomNode.inTime )
			except:
				sys.stderr.write( "Failed to get MDataHandle inTime" )
				raise
			
				
			#get values from data handles
			inputMin = inputMin_dataHandle.asFloat()
			inputMinX = inputMinX_dataHandle.asFloat()
			inputMinY = inputMinY_dataHandle.asFloat()
			inputMinZ = inputMinZ_dataHandle.asFloat()
			inputMax = inputMax_dataHandle.asFloat()
			inputMaxX = inputMaxX_dataHandle.asFloat()
			inputMaxY = inputMaxY_dataHandle.asFloat()
			inputMaxZ = inputMaxZ_dataHandle.asFloat()
			outValue = outValue_dataHandle.asFloat()
			outX = outX_dataHandle.asFloat()
			outY = outY_dataHandle.asFloat()
			outZ = outZ_dataHandle.asFloat()
			inTime = inTime_dataHandle.asInt()
			
		else:
			return OpenMaya.kUnknownParameter
			
		#run computation
################Compute
		outX = random.uniform(inputMinX, inputMaxX)
		outY = random.uniform(inputMinY, inputMaxY)
		outZ = random.uniform(inputMinZ, inputMaxZ)
				
		#Set output attribute values
		outX_dataHandle.setFloat( outX )
		outY_dataHandle.setFloat( outY )
		outZ_dataHandle.setFloat( outZ )
				
		dataBlock.setClean(plug)
		
		
		return OpenMaya.MStatus.kSuccess
		
# defines createNode function in maya for this node.
def nodeCreator():
	return OpenMayaMPx.asMPxPtr( randomNode() )
	
# create and initialize the attributes to the node
def nodeInitializer():

	nAttr = OpenMaya.MFnNumericAttribute()
	cAttr = OpenMaya.MFnCompoundAttribute()
	eAttr = OpenMaya.MFnEnumAttribute()


	# create input attributes
	randomNode.inputMinX = nAttr.create("inputMinX", "inx", OpenMaya.MFnNumericData.kFloat, 0.0)
	nAttr.setWritable(True)
	nAttr.setStorable(True)
	nAttr.setReadable(True)
	nAttr.setKeyable(True)
	
	randomNode.inputMinY = nAttr.create("inputMinY", "iny", OpenMaya.MFnNumericData.kFloat, 0.0)
	nAttr.setWritable(True)
	nAttr.setStorable(True)
	nAttr.setReadable(True)
	nAttr.setKeyable(True)
	
	randomNode.inputMinZ = nAttr.create("inputMinZ", "inz", OpenMaya.MFnNumericData.kFloat, 0.0)
	nAttr.setWritable(True)
	nAttr.setStorable(True)
	nAttr.setReadable(True)
	nAttr.setKeyable(True)
	
	randomNode.inputMaxX = nAttr.create("inputMaxX", "ixx", OpenMaya.MFnNumericData.kFloat, 0.0)
	nAttr.setWritable(True)
	nAttr.setStorable(True)
	nAttr.setReadable(True)
	nAttr.setKeyable(True)
	
	randomNode.inputMaxY = nAttr.create("inputMaxY", "ixy", OpenMaya.MFnNumericData.kFloat, 0.0)
	nAttr.setWritable(True)
	nAttr.setStorable(True)
	nAttr.setReadable(True)
	nAttr.setKeyable(True)
	
	randomNode.inputMaxZ = nAttr.create("inputMaxZ", "ixz", OpenMaya.MFnNumericData.kFloat, 0.0)
	nAttr.setWritable(True)
	nAttr.setStorable(True)
	nAttr.setReadable(True)
	nAttr.setKeyable(True)
	
	randomNode.inTime = nAttr.create("inTime", "it", OpenMaya.MFnNumericData.kFloat, 0.0)
	nAttr.setWritable(True)
	nAttr.setStorable(True)
	nAttr.setReadable(True)
	nAttr.setKeyable(True)
	
	# create output attributes
	randomNode.outX = nAttr.create("outX", "ox", OpenMaya.MFnNumericData.kFloat, 0.0)
	nAttr.setWritable(False)
	nAttr.setStorable(False)
	nAttr.setReadable(True)
	
	randomNode.outY = nAttr.create("outY", "oy", OpenMaya.MFnNumericData.kFloat, 0.0)
	nAttr.setWritable(False)
	nAttr.setStorable(False)
	nAttr.setReadable(True)
	
	randomNode.outZ = nAttr.create("outZ", "oz", OpenMaya.MFnNumericData.kFloat, 0.0)
	nAttr.setWritable(False)
	nAttr.setStorable(False)
	nAttr.setReadable(True)
	
	#create compound attributes
	randomNode.inputMin = cAttr.create( "inputMin", "in")
	cAttr.addChild(randomNode.inputMinX)
	cAttr.addChild(randomNode.inputMinY)
	cAttr.addChild(randomNode.inputMinZ)
	
	randomNode.inputMax = cAttr.create( "inputMax", "ix")
	cAttr.addChild(randomNode.inputMaxX)
	cAttr.addChild(randomNode.inputMaxY)
	cAttr.addChild(randomNode.inputMaxZ)
	
	randomNode.outValue = cAttr.create( "outValue", "o")
	cAttr.addChild(randomNode.outX)
	cAttr.addChild(randomNode.outY)
	cAttr.addChild(randomNode.outZ)
	
	# add attribues
	#
	randomNode.addAttribute( randomNode.inTime)
	randomNode.addAttribute( randomNode.inputMin)
	randomNode.addAttribute( randomNode.inputMax)
	randomNode.addAttribute( randomNode.outValue)
	
	# Setup which attributes affect each other
	randomNode.attributeAffects ( randomNode.inTime,  randomNode.outValue )
	randomNode.attributeAffects ( randomNode.inputMin,  randomNode.outValue )
	randomNode.attributeAffects ( randomNode.inputMax,  randomNode.outValue )
	
# initialize the script plug-in
def initializePlugin(mobject):
	mplugin = OpenMayaMPx.MFnPlugin(mobject, "Autodesk", "1.0", "Any")
	try:
		mplugin.registerNode( kcompUtilNodeTypeName, kcompUtilNodeId, nodeCreator, nodeInitializer, OpenMayaMPx.MPxNode.kDependNode, kcompUtilNodeClassify)
	except:
		sys.stderr.write( "Failed to register node: %s" % kcompUtilNodeTypeName )
		raise
		
# uninitialize the script plug-in
def uninitializePlugin(mobject):
	mplugin = OpenMayaMPx.MFnPlugin(mobject)
	try:
		mplugin.deregisterNode( kcompUtilNodeId )
	except:
		sys.stderr.write( "Failed to deregister node: %s" % kcompUtilNodeTypeName )
		raise
