/* --- ---------------- --- */
/* --- SCRIPT INFO --- */
/* --- ---------------- --- */

	clearlistener()	
	SCRIPTNAME = "ImageCustomizer";
	VERSION = "V0.5";
	AUTHOR = "AAN /REV KIJ";

/* -------------------------*/
/* DATA FORMAT */
/* -------------------------*/

/*
	LIN;02-084-01;Pearl Dining chair - SS15;02-084-01_2106673;<note>
	DIM;L Quattro
	DIM;Black
	DIM;White oak
	
	LIN;02-084-01;Pearl Dining chair - SS15;Temp1;<note>
	DIM;L Quattro
	DIM;Black
	DIM;Oil Oak
*/


	/* Data ID description
		1 - Product ID
		2 - Model name / Product name
		3 - Product full ID 
		4.X - Mat01, Mat02, Mat03 etc. 
	*/
	
	-- Image data
	/*imageData = #("02-084-01", "Scandinavia Cornersofa 5 seater (2� corner 2)", "02-084-01_2106673", "L Quattro Black", "Stainless Steel")*/
	imageData = #("L:\Clients\Lekolar\3D\Models\Dalman.max","Dalman","Dalman_Wood_Natural_Oak_F1079_Metal_Alu_RAL9006_Cam_Main.png","mat_Legs","Metal_Alu_RAL9006","mat_Main","Wood_Natural_Oak_F1079")

	-- Optional addon models to import
	addOns = #()
	-- ADDON_POSITIONS

	-- CUSTOM DATA VARIABLES
	
	-- Optional scripts to execute before render
	customScripts = #("VFB_CC.ms")

	-- Folder variables and paths
	systemFilesPath = @"L:\\Clients\\#ImageCustomizer\\"
	clientRootPath = @"L:\Clients\Lekolar\3D\"
	renderFilesRootPath = @"p:\Clients\Lekolar\"
	maxFilesPath = @"L:\Clients\Lekolar\3D\Models\"
	materialLibPath = @"L:\Clients\Lekolar\3D\Materials\"
	sceneFilePath = @"L:\Clients\Lekolar\3D\Studios\Lekolar_Studio_Main.max"
	presetFilePath = @"L:\Clients\Lekolar\3D\Presets\Lekolar_Studio_Preset.rps"
	
	tempFilesPath = renderFilesRootPath + @"1_Temp\\"
	renderFilesPath = renderFilesRootPath + @"2_Render\\\"
	finalFilesPath = renderFilesRootPath + @"3_Final\\"
	exportedFilesPath = renderFilesRootPath + @"4_Exported\\"
	
	renderFileName = "Dalman_Wood_Natural_Oak_F1079_Metal_Alu_RAL9006_Cam_Main"

	-- Camera settings
	/*currentCameraType = "Cam01"*/
	currentCameraType = "CamMain"
	
	-- Frame Settings
	frametoRender = 1
	
	clientName = filterstring clientRootPath @"\"
	-- Deadline settings
	deadlineBatchName = SCRIPTNAME + " " + clientName[clientName.count]
	deadlineServerName = "cs02"
	deadlineRenderPriority = 60
	
	renderFileExtension = @".png"
	
	materialStrSearch = ""
	
	failsafe_BreakOnMissingBitmaps = true
	
	maxFiles
	renderFiles
	
	dominoMatLib
	dominoSubMaterial
	dominoSecondarySubMaterial
	
	undefinedDominoMaterial = VrayLightMtl()
	undefinedDominoMaterial.name = "UndefinedSysMtl"
	undefinedDominoMaterial.color = orange
	undefinedDominoMaterial.multiplier = 3
	
	
	modelsToSubmitArray = #()
	
	currentLoadedModel
	
-- 	DEADLINE render setttings
	global SMTDSettings
	global SMTDFunctions

	remoteScript = @"\\cs02\\DeadlineRepository10\\submission\\3dsmax\\Main\\SubmitMaxToDeadline_Functions.ms"
	fileIn remoteScript 
	
	
	theTime
	frameOffset = 1
	frameStart = 1
	
	currentFrameTime = 1
	
	defaultSubMaterial
	
	currentRenderSessionID
	
	
	-- FUNCTIONS	
	function setCurrentCamera = 
	(
		if cameras.count > 0 then 
		(
			found = false
			for i = 1 to cameras.count while found == false do
			(
				cName = cameras[i].name
				cNamePrefix = tolower (filterString cName "_")[1]
				print cNamePrefix
				if classof cameras[i] != Targetobject and cNamePrefix == tolower currentCameraType then (
					viewport.setCamera cameras[i]
					return Cameras[i]
					found = true
				)
			)
		)
		if found == false then ( print "SYSTEM: Camera not found" )
	)
	
	function customIntegerStringConverter intToConvert numberOfDigits =
	(
		str = intToConvert as string
		for i = 0 to (numberOfDigits - 1 - str.count) do
		(
			str = "0" + str
		)
		return str
	)
	
	function updateUniqueID =
	(
		theTime = getLocalTime()
		digit01 = theTime[5]
		digit02 = theTime[6]
		digit03 = theTime[7]
		currentRenderSessionID = ((customIntegerStringConverter digit01 2) + (customIntegerStringConverter digit02 2) + (customIntegerStringConverter digit03 2))
		print ("SETTING RENDERSESSION - " + currentRenderSessionID)
	)
	
	function searchForString searchForStr searchInStr =
	(
		useLowerCasing = true
		
		newStr = searchInStr
		if useLowerCasing then
		(
			searchForStr = toLower searchForStr
			searchInStr = toLower searchInStr
		)
		
		strFound = false
		for i = 1 to (searchInStr.count-searchForStr.count+1) while not strFound do 
		(
			endIndex = searchForStr.count
			if ( substring searchInStr i endIndex ) == searchForStr then 
			(
				strFound = true
			)
		)
		return strFound
	)
	
	function getMaxFilePath byName =
	(
		maxFilePathStr = for filePath in maxFiles where tolower byName == tolower (getFileNameFile filePath) collect filePath
		return maxFilePathStr[1]
	)

	
-- 	
-- 		HANDLING OF CSV DATA
-- 		
	function convertArrayToString arrayToConvert = 
	(
		str = ""
		for i in arrayToConvert where (classOf i == String) do append str i
		return str
	)
	
	function convertArrayToStringWDelimiter arrayToConvert delimiter = 
	(
		str = ""
		for i in arrayToConvert where (classOf i == String) do append str (i+delimiter)
		
		return (substring str 1 (str.count-1) )
	)
	
	function removeCharacterFromString whatStr whatChar = 
	(
		strDelimiter = " "
		strArray = filterstring whatStr whatChar
		returnStr = ""
		for i = 1 to strArray.count do 
		(
			returnStr += strArray[i]
			if i != strArray.count then (
				returnStr += strDelimiter
			) 
		)
		return returnStr
	)
	
	function cleanupString strToJoin =
	(
		-- Remove Unwanted Spaces
		finalStr = removeCharacterFromString strToJoin ". "
		
		return finalStr
	)
	
-- 	
-- 	HANDLE MATERIAL LIBRARY
-- 	
	-- Returns standard material (looks for search key words and returns material from objects
	function getDefaultSubmaterial =
	(
		for obj in objects do
		(
			if ( ( searchForString material02StrSearch obj.name or searchForString material05StrSearch obj.name ) and obj.material != undefined) then 
			(
				print "FOUND MATERIAL"
				print obj.material
				return obj.material
			)
		)
		return false
	)

	
	function loadMaterials =
	(
		dominoMatLib = loadTempMaterialLibrary materialLibPath
		print ("SYSTEM: Loaded - " + dominoMatLib.count as string + " materials")
	)
	
	materialCounter = 0
	function applyMaterial materialKey materialName = 
	(
		
-- 		matlibName = "Wonderland_Cloth_Fabric_Jubilaeum"
-- 		matLibPath = @"m:\\_Materials_\\Beta\\" + matlibName + ".max"

		SetQuietMode true
-- 		$.material = currentMaterialLibrary[matlibName]
		
		materialCounter += 1
		print ("SYSTEM: Applying material - " + materialLibPath + materialName)
		mat = loadMaterialLibrary (materialLibPath + materialName + ".max")
		matToAssign = currentMaterialLibrary[materialName]
		
		SetQuietMode false
		if matToAssign != undefined then
		(
			for obj in objects where (searchForString (materialStrSearch + materialKey) obj.name) do (obj.material = matToAssign)
			
		) else (
			print ("Error!\nMaterial '" + materialName + "' does not exist!\n\nMake sure the actual material match the file name")
			return false
		)
	)
	
-- 	
-- 	HANDLE ANIMATION
-- 	
	
	

	
-- 
-- TYPE HANDLING
--  
	
	function loadScenePreset scenePresetName =
	(
		try 
		(
			renderpresets.LoadAll 0 (presetFilePath)
		) catch ( messageBox "Could not load renderpreset"; return false )
		return true
	) 
	
	function mergeScene studioSetup =
	(
		result = false
		try (
			result = (mergeMaxFile (sceneFilePath))
		) catch ( messageBox "Could not merge Scene"; return false )
		return result
	)

	function mergeModel sceneModelName =
	(
		result = false
		try (
			print ( "trying to load - " + sceneModelName)
			maxFilePathStr = maxFilesPath + sceneModelName + @".max"
			result = (mergeMaxFile maxFilePathStr)
			print ("model load - " + maxFilePathStr + " - " + result as string)
			currentLoadedModel = sceneModelName
		) catch ( messageBox "Could not merge Model"; print "Could not merge model"; print maxFilePathStr; return false)
		return result
	)
	
	
-- 	
-- 	HANDLING OF MAX FILE LOADING
-- 	
	function getFilesRecursive root pattern =
	(
		dir_array = GetDirectories (root+"/*")
		for d in dir_array do
			join dir_array (GetDirectories (d+"/*"))
		my_files = #()
		for f in dir_array do
			join my_files (getFiles (f + pattern))
		my_files
	)
	
		
	function loadData =
	(
		maxFiles = getFilesRecursive  maxFilesPath  @"\*.max"
		print ("SYSTEM: Loaded - " + maxFiles.count as string + " max model files")
	)
-- 	
-- 	HANDLE NETWORK RENDER
-- 	
	function loadSceneTypeByData sceneTypeRenderjobData =
	(
		framerate = 30
		-- Load preset
		if not (loadScenePreset presetFilePath) then return false
		-- Merge model
		if not (mergeModel (sceneTypeRenderjobData[2])) then return false
		

		-- THIS IS A HACK!!!!!! PUUUHAA!
		-- Merge scene
		if cameras.count > 0 then (
-- 			print "HACK!!"
			
			if not (mergeScene cameras[1].name) then return false
		) else (
			if not (mergeScene undefined) then return false
		)
		setCurrentCamera()


		-- Import addon models
		for i = 1 to addOns.count do
		(
			if(mergeMAXFile addOns[i] #select #mergeDups quiet:true) then (
			
				print ("addon model loaded: " + addOns[i])

				-- Reposition?
				if (addOnPositions != undefined) then (
					if (addOnPositions.count >= addOns.count) then (
						if (addOnPositions[i] != "") then (
							--gr = getNodeByName (getFilenameFile (addOns[i]))
							pa = getNodeByName ("Position_" + addOnPositions[i])

							if (pa == undefined) then (
								pa = getNodeByName (addOnPositions[i])
							)

							if (pa != undefined) then (
							
								print ("repositioning addon to: " + addOnPositions[i])

								gr = selection as Array
								for obj in gr do
								(
									--SUCK virker kun i ét niveau
									--obj.transform = copy pa.transform
									
									-- Bedre men meeeh
									--obj.transform = preTranslate obj.transform pa.transform.translationpart
									
									-- IMPORTANT: Rotate before translate!
									newTransform = copy obj.transform
									rotate newTransform pa.transform.rotation
									translate newTransform pa.transform.translation
									obj.transform = newTransform
								)

							) else (
								print ("Could not locate addon position element: (Position_)" + addOnPositions[i])
							)
							
						)
					)
				)
			)
		)


		-- Apply materials
		
		-- remove duplicates

		
		for i = 4 to imageData.count by 2 do
		(
			result = applyMaterial imageData[i] imageData[i+1]
			if result == true and failsafe_BreakOnMissingBitmaps == true then
			(
				resetMaxFile #noPrompt 
				return false
			)
		)
		

		-- Set to frame 1
		sliderTime = frametoRender

		-- Execute optional custom scripts
		if (customScripts != undefined) then (
			for i = 1 to customScripts.count do
			(
				print ("Executing custom script: " + clientRootPath + "\\Scripts\\" + customScripts[i])
				fileIn (clientRootPath + "\\Scripts\\" + customScripts[i])
			)
		)

		
		
		
		return true
	)
	
	/*
		Submits the selected jobs to render
	*/	
	
	function setGamma =
	(
		-- GAMMA correction disable
		IDisplayGamma.colorCorrectionMode = #gamma -- enable Gamma (don't modify)
		IDisplayGamma.gamma = 2.2 -- adjusts the gamma to 2.2
		IDisplayGamma.affectColorPickers = true -- disables Affect Color Selectors (to enable this option, use "true")
		IDisplayGamma.affectMEdit = true -- disables Affect Material Editor (to enable this option, use "true")
		fileInGamma = 2.2 -- adjusts the Input gamma, in "Bitmap Files", to 1.0
		fileOutGamma = 2.2 
	)
	
	function submitToDeadline outputName endFrame = 
	(
		local maxFileToSubmit = SMTDPaths.tempdir + maxFileName
-- 		SMTDFunctions.SaveMaxFileCopy maxFileToSubmit
		
		-- Remove unwanted characters before submitting job to render queue. 
		renderOutputName = outputName
		charactersToRemove = @"��"
		finalChar = ""
		renderOutputName = filterstring renderOutputName charactersToRemove
		for c in renderOutputName do
		(
			finalChar += c
		)
		renderOutputName = finalChar as string
				
		-- SETUP MAX BEFORE
		
		

		/* ---------------------------- */
		-- DEADLINE
		/* ---------------------------- */

		SMTDFunctions.loadSettings()
		SMTDSettings.JobName = renderOutputName
		SMTDSettings.Comment = "Scripted Submitter"
		SMTDSettings.Priority = deadlineRenderPriority 
		SMTDSettings.RunPreFrameScript = false
        
		local maxFileToSubmit = SMTDPaths.tempdir + @"temp_submitfile.max"
		SMTDFunctions.SaveMaxFileCopy maxFileToSubmit
			
		local SubmitInfoFile = SMTDPaths.tempdir + "\\max_submit_info.job"
		local JobInfoFile = SMTDPaths.tempdir  + "\\max_job_info.job"

		SMTDFunctions.CreateSubmitInfoFile SubmitInfoFile batchName:deadlineBatchName
		SMTDFunctions.CreateJobInfoFile JobInfoFile  
									
		local initialArgs = "\""+SubmitInfoFile+"\" \""+JobInfoFile+"\" \""+maxFileToSubmit+"\" " 
		local result = SMTDFunctions.waitForCommandToComplete initialArgs SMTDSettings.TimeoutSubmission

		local renderMsg = SMTDFunctions.getRenderMessage() 
		SMTDFunctions.getJobIDFromMessage renderMsg
			
		if result == #success then 
		(
			format "Submitted successfully as Job %.\n\n%\n\n" \
			SMTDSettings.DeadlineSubmissionLastJobID renderMsg
		)
		else 
			format "Job Submission FAILED.\n\n%" renderMsg 
		
		
		
		/* ---------------------------- */
		-- DEADLINE END
		/* ---------------------------- */
	)
	
	
	function dominoNetworkRenderInit submitJobToNetwork =
	(
		frameOffset = 1
		frameStart = frameOffset
		if not (loadScenePreset presetFilePath) then return false
		
		updateUniqueID()
		
		--IMPORTANT - used to ensure that animated material ID frames in the merged files are consistent with material ID's applied. 
		--disableSceneRedraw()
	

-- 		Collect data
-- 		Iterate for each model submit job to render
		jobCount = 0
		--print "SYSTEM: Submitting jobs to render server"
		
		autosave.resettimer() 
		
		
		/* CONSTRUCTOR */
		result = loadSceneTypeByData imageData
		if (result == false and failsafe_BreakOnMissingBitmaps) then ( resetMaxFile #noPrompt; return false ) 
		
		renderOutputName = ( imageData[1] + " " + imageData[2] + "_" + currentCameraType + "_" + currentRenderSessionID + "_" )
		datFileName = (imageData[1] + " " + imageData[2] + "_" + currentCameraType + "_" + currentRenderSessionID)
		datFileValue = (imageData[1] + " " + imageData[2] + " " + imageData[3] + " " + currentCameraType)
		-- CREATES DAT FILE
		renderCount = 1
		totalCount = 1
		
		
		jobCount = 1
		
		-- Setup render settings

		renderSceneDialog.close()
		setGamma()
		-- Handle PNG Format settings
		pngio.ipngio.setAlpha true
		pngio.ipngio.setType #true24

		-- Force alpha on TIF
		TIF.setAlpha true
		TIF.setType #color
		TIF.setCompression #packBits

		-- Handle JPG Format Settings
		jpeg.setQuality(100)

		-- Handle TGA Format Settings
		Targa.setColorDepth 32
		Targa.setCompressed false
		-- Targa.setPreMultAlpha false -- (HEIM)
		Targa.setPreMultAlpha true -- (FLEXA)
		
		rendSaveFile = true
		rendOutputFilename = renderFilesPath + renderFileName + renderFileExtension
		--rendTimeType = 4
		
		--rendPickupFrames = framestart as string + "-"+(totalCount+frameOffset-1) as string
	
		
		setrendertype #view -- Ensures no region
		
		currentCamera = setCurrentCamera()

		-- Net submissions

		if submitJobToNetwork then 
		(
			print ("SYSTEM: Submitting " + jobCount as string + " of " + totalCount as string + " to network render")
			submitToDeadline renderOutputName totalCount 
		)
		
		
		if submitJobToNetwork then 
			resetMaxFile #noPrompt 
		
		enableSceneRedraw()
	)
	
	
	function initSystem =
	(
		-- Reset scene
		resetMaxFile #noPrompt
		units.SystemType = #Millimeters
		gc()
		loadData()

	)
	

-- 	loadMaterials()
	
	--ROLLOUT
	
	initSystem()
	
	-- After render script action 	convertTempName()
	
-- 	dominoNetworkRenderInit true -- SETUP TO DEADLINE
	dominoNetworkRenderInit false -- TEST FROM MAX 
	