'/// ReplaceImageClips 1.0 for XSI 3.5+
'/// By Homam Bahnassi - In|Framez 2004
'--------------------------------------

set oSelection = Application.Selection
UserReplaceImageClips oSelection,666,"UserDefined","UserDefined"

sub UserReplaceImageClips(oInObjectCollection,iDoClusters,sSrcClip,sDstClip)
	
	'-- Checking inputs...
	on error resume next
	if oInObjectCollection.count < 1 then
		logmessage "ImageClipReplacer: Object collection is not valid..."
		exit sub
	end if
	on error goto 0

	if typename(sSrcClip) <> "ImageClip" then
		PickElement "object", "Select Source Image Clip",, sSrcClip, button,, modifier
		if button = 0 then
			logmessage "ImageClipReplacer: Cancelled by user"
			exit sub
		end if
		sSrcClip = sSrcClip.name
	end if

	if typename(sDstClip) <> "ImageClip" then
		PickElement "object", "Select Destination Image Clip",, sDstClip, button,, modifier
		if button = 0 then
			logmessage "ImageClipReplacer: Cancelled by user"
			exit sub
		end if
		sDstClip = sDstClip.name
	end if

	'-- Replace object material...
	for each oObj in oInObjectCollection
		ReplaceImageClips oObj, sSrcClip, sDstClip
	next

	if iDoClusters <> 6 and iDoClusters <> 7 then
		iDoClusters = MsgBox("Process clusters?",vbYesNo,"ImageClipReplacer")
	end if
	
	'-- Searching for clusters materials...
	if iDoClusters = 6 then
		for each oObj in oInObjectCollection
			set oClusters = oObj.activeprimitive.geometry.Clusters
			for each oCluster in oClusters
				if oCluster.type = "poly" then
					ReplaceImageClips oCluster, sSrcClip, sDstClip
				end if
			next
		next
	end if

	logmessage "Done............"
	
end sub

sub ReplaceImageClips( in_oObj , sSrcClip, sDestClip )

	logmessage "Prossecing " & in_oObj & "............"
	logmessage "----------------------------------"
	dim oShaderList, oImageClipList

	set oShaderList = CreateObject( "XSI.Collection" )
	oShaderList.Unique = true

	set oImageClipList = CreateObject( "XSI.Collection" )

	'We expect the input object to be a "SceneItem" object
	set oMat = in_oObj.Material

	'Although not actually a shader, we start searching
	'for shaders from the parameters of the material
	SearchShader oMat, oShaderList, oImageClipList

	logmessage "SUMMARY: Searched " & oShaderList.Count & _
	  	" shader(s), found " & oImageClipList.Count & " image clip(s)"

	if ( oShaderList.Count > 0 ) then
		logmessage "SHADERS SEARCHED:"

		for each o in oShaderList
			logmessage o.Fullname
		next
		logmessage "----------------------------------"
	end if

	if ( oImageClipList.Count > 0 ) then
		logmessage "IMAGE CLIPS FOUND:"
		for each o in oImageClipList
			if o.source.name = sSrcClip then
				logmessage "Replacing " & o.source.name
				SIConnectShaderToCnxPoint "clips." & sDestClip, o
			end if
		next
		logmessage "----------------------------------"
	end if
	
	logmessage ""
end sub

'Look for image clips on the parameters of a shader
'Will recursively search any connected shaders
'Each shader is visited only once
sub SearchShader( in_oShader, io_oVisitedShaderList, io_oImageClipList )

	for each oParam in in_oShader.Parameters
		if typename( oParam.Source ) = "Shader" OR _
			typename( oParam.Source ) = "Texture" then
			if ( NOT IsShaderInList( oParam.Source, io_oVisitedShaderList ) ) then
				io_oVisitedShaderList.Add( oParam.Source )

				'Recursively search this shader
				SearchShader oParam.Source, io_oVisitedShaderList, io_oImageClipList
			end if 
		elseif typename( oParam.Source ) = "ImageClip" then
			io_oImageClipList.Add oParam
		end if
	next

end sub

'Determines if a shader is already in a XSI Collection
function IsShaderInList( oShader, io_oVisitedShaderList )

	for each o in io_oVisitedShaderList	
		if ( o.FullName = oShader.FullName ) then
			logmessage "Skipping " & oShader.FullName
			IsShaderInList = true
			exit function
		end if
	next

	IsShaderInList = false 
end function