/*
name: GoB_Import.zsc 
description: Zbrush script for Blender GoB addon
tracker_url: https://github.com/JoseConseco/GoB
author: Daniel Grauer
*/

[VarDef,GoBImport,1]        
[VarDef,reportDuration,-1]      //Display Duration (in seconds) (0:wait for user action(default), -1:combine with next note command),
[VarDef,showFinalReport,0]      // Final Report (1: show, 0 Hide)
[VarDef,finalReportreportDuration,100] //Display Duration (in seconds) (0:wait for user action(default), -1:combine with next note command),
[VarDef,maxSubtools,999]  

[VarDef,GoBList(7),""]          // NOTE: if list size changes gob export list size needs to be updated as well
    /* File: Gob_variables.zvr
        0: fileExtension, 
        1: textureFormat, 
        2: diffSuffix,
        3: normSuffix, 
        4: dispSuffix, 
        5: gobVersion,
        6: gozProjectPath,
    */


[If,GoBImport==1,               //make sure this script runs when loaded
    [RoutineDef,AdjustPath,     //replace backslashes with forward slashes
        [VarDef,pathStr,""]
        [Loop,maxSubtools,
            [VarSet,in,[StrFind,[StrFromAsc,92],pathStr]]
            [If,[Val,in] > -1,//"
                [VarSet,pathStr,[StrMerge,[StrExtract,pathStr,0,[Val,in-1]],"/",[StrExtract,pathStr,[Val,in+1],[StrLength,pathStr]]]]
                ,
                [LoopExit]
            ]		
        ]
    ,pathStr]

    [RoutineDef,GetFullPath,	
        [VarSet,path,[FileNameResolvePath,path]]
        [If,[ZBrushInfo,6],     //is MacOS
            //adjust for Mac OSX
            [VarSet,path,[StrExtract,path,2,256]]
        ]
    ,path]

    [VarSet,publicPath,[FileNameExtract,[FileNameResolvePath,"ZPUBLIC_ZPluginData/"],1]]
    [RoutineCall,AdjustPath,publicPath]         //just as Notes don't display backslashes!
    //[Note,[StrMerge, "\nThe ZBrush Data folder path is: \n    ", publicPath],,reportDuration]

    [VarDef,GoZProjectsPath,""]
    [VarDef, GoZBrushPath, ""]
	[If,[ZBrushInfo,6],//is MacOS
	 	[If,[StrFind,"Shared",publicPath]>-1,
		 	[VarSet,GoZProjectsPath,[StrExtract,publicPath,0,([StrFind,"Shared",publicPath]+6)]]
		 	[VarSet,GoZProjectsPath,[StrMerge,GoZProjectsPath,"Pixologic/GoZProjects/Default/"]]

		 	[VarSet,GoZBrushPath,[StrExtract,publicPath,0,([StrFind,"Shared",publicPath]+6)]]
		 	[VarSet,GoZBrushPath,[StrMerge,GoZBrushPath,"Pixologic/GoZBrush/"]]

            //[Note,[StrMerge, "\nThe GoZ Projects path is: \n    ", GoZProjectsPath],,reportDuration]
            //[Note,[StrMerge, "\nThe GoZ objects list path is: \n    ", GoZBrushPath],,reportDuration]
		 ]	 	
	 	//note that ZBrush paths on MacOS start with "!:"
	 	//this needs to be removed if passing paths to dynamic libraries etc. - see GetFullPath routine above
	 	
         ,//else Windows
		 [If,[StrFind,"Documents",publicPath]>-1,
		 	[VarSet,GoZProjectsPath,[StrExtract,publicPath,0,([StrFind,"Documents",publicPath]-1)]]
		 	[VarSet,GoZProjectsPath,[StrMerge,GoZProjectsPath,"Pixologic/GoZProjects/Default/"]]
		 	[RoutineCall,AdjustPath,GoZProjectsPath]//just as Notes don't display backslashes!

		 	[VarSet,GoZBrushPath,[StrExtract,publicPath,0,([StrFind,"Documents",publicPath]-1)]]
		 	[VarSet,GoZBrushPath,[StrMerge,GoZBrushPath,"Pixologic/GoZBrush/"]]
		 	[RoutineCall,AdjustPath,GoZBrushPath]//just as Notes don't display backslashes!

            //[Note,[StrMerge, "\nThe GoZ Projects path is: \n    ", GoZProjectsPath],,reportDuration]
            //[Note,[StrMerge, "\nThe GoZ objects list path is: \n    ", GoZBrushPath],,reportDuration]
		 ]
	]


    [VarDef,variablesFile,[StrMerge,GoZProjectsPath,"GoB_variables.zvr"]]  
    // load variables from GoB export
        /* File: Gob_variables.zvr
        0: fileExtension, 
        1: textureFormat, 
        2: diffSuffix,
        3: normSuffix, 
        4: dispSuffix, 
        5: gobVersion,
        6: gozProjectPath, 
        */

	[If,[FileExists,variablesFile],    
        [VarLoad,GoBList,variablesFile]
        [VarSet,fileExtension,[StrMerge,GoBList(0),""]]
        [VarSet,textureFormat,[StrMerge,GoBList(1),""]]
        [VarSet,diffSuffix,[StrMerge,GoBList(2),""]]
        [VarSet,normSuffix,[StrMerge,GoBList(3),""]]
        [VarSet,dispSuffix,[StrMerge,GoBList(4),""]]  
        [VarSet,gobVersion,[StrMerge,GoBList(5),""]]  
        [VarSet,gozProjectPath,[StrMerge,GoBList(6),""]]      
    , 
        [Note,[StrMerge,"\n\nGoB_variables.zvr not Found", "\naborting import"],,reportDuration]
        [Exit]
    ]   
    [Note,[StrMerge, "\CFFFFFFGoB Version: ",gobVersion, "\n"],,reportDuration]
       

    [RoutineDef,LoadTextures,
        [VarSet,diffTexture,[StrMerge,gozProjectPath,objectName,diffSuffix,textureFormat]]
        [VarSet,dispTexture,[StrMerge,gozProjectPath,objectName,dispSuffix,textureFormat]]
        [VarSet,normTexture,[StrMerge,gozProjectPath,objectName,normSuffix,textureFormat]]
        // import textures
        [If,[FileExists,diffTexture],
            [IPress,Tool:Texture Map:TextureMap]
            [FileNameSetNext,diffTexture] [IPress,Texture:Import]
            [Note, [StrMerge, "\n   Texture:   ", [StrMerge,objectName,diffSuffix,textureFormat]],, reportDuration]
        ]
        [If,[FileExists,dispTexture],
            [IPress,Tool:Displacement Map:DisplacementMap]
            [FileNameSetNext,dispTexture] [IPress,Alpha:Import]
            [Note, [StrMerge, "\n   Texture:   ", [StrMerge,objectName,dispSuffix,textureFormat]],, reportDuration]
        ]
        [If,[FileExists,normTexture],            
            [IPress,Tool:Normal Map:Normal Map]
            [FileNameSetNext,normTexture] [IPress,Texture:Import]
            [Note, [StrMerge, "\n   Texture:   ", [StrMerge,objectName,dispSuffix,textureFormat]],, reportDuration]
        ]
    ]


    //[IButton,ReadObjectList,"Read objects from GoZ_ObjectList.txt",
    [VarSet,objectlistFile,[StrMerge,GoZBrushPath,"GoZ_ObjectList.txt"]] 
    //[Note,[StrMerge, "\objectlistFile \n    ", objectlistFile],,reportDuration] 

    [If,[FileExists,objectlistFile],
        //create memory block from the file
        [MemCreateFromFile,GoB_ObjectList_InputMem,objectlistFile]
    ]

    
    [RoutineDef,CreateSubtoolList,
        [VarDef,subtoolName,""]                         // Define a new variable to store the current subtool name 
        [VarSet,totalSubtools,[SubToolGetCount]]        // create a variable to define the number of loop based on the subtools count
        [SubToolSelect,0]                               // select first subtool to loop over all subtools
        [VarSet,activeSubtool,[SubToolGetActiveIndex]]  // create a variable with the current subtool Index

        [Loop,totalSubtools,            //loop over subtools
            [SubToolSelect,[Val,activeSubtool]]
            [VarSet,subtoolName,[IGetTitle,"Tool:ItemInfo"]]        //get the subtool name
            [VarSet,subtoolName,[StrExtract,subtoolName,0,[StrLength,subtoolName]-2]]       // trim chars from the end.
            //[Note,[StrMerge,"\nactiveSubtool: ",activeSubtool, "\nSubtool Name: ",subtoolName, " ",[StrLength,subtoolName], "\nTarget Object: ",  objectName, " ",[StrLength,objectName]],,0]
            
            [VarSet,SubtoolList(activeSubtool),subtoolName]         //add subtools to list

            [VarInc, activeSubtool]     //adds 1 to the loop counter            
            [If,activeSubtool >= totalSubtools,
                [LoopExit]
            ]
        ]
    ]
    
    
    [VarDef,importAsSubtool, 0] // True:1 / False: 0 
    [VarSet,configCount,0]
    [VarDef,configLineStr,""]  

    [VarDef,configFile,[StrMerge,GoZBrushPath,"GoZ_Config.txt"]] 
    [If,[FileExists,configFile],
        //create memory block from the file
        [MemCreateFromFile,GoB_Config_InputMem,configFile]
    ]


    [If,[MemGetSize,GoB_Config_InputMem],
        [Loop,100,
            //read a line into a string variable
            [VarSet,lineBytes,[MemReadString,GoB_Config_InputMem,configLineStr,configCount,1]]
            //extract objects string
            [VarSet,configLine,[StrExtract,configLineStr,0,lineBytes]]
  
            [If, [StrFind, "IMPORT_AS_SUBTOOL = TRUE", configLine] == 0,
                [VarSet, importAsSubtool, 1]
                [LoopExit]            
            ]
            [If, [StrFind, "IMPORT_AS_SUBTOOL = FALSE", configLine] == 0,
                [VarSet, importAsSubtool, 0]
                [LoopExit]            
            ]    
            //next loop or exit if end of file
            [VarSet,configCount,configCount+lineBytes]
                //[Note,[StrMerge, "\nconfigCount: ", configCount],,reportDuration]
                [If,configCount >= [MemGetSize,GoB_Config_InputMem],
                    [LoopExit]
                ]
        ]
        //[Note,[StrMerge, "\nconfigFile   ", configFile, " \nlineBytes ", lineBytes, " \nconfigLine ",configLine, "\nimportAsSubtool: ", importAsSubtool],,0]
    ]    
    [MemDelete,GoB_Config_InputMem]        //all done, delete memblock
        

   [RoutineDef, FindSubtool,  
    // search for subtools with object name in subtoolList 
    // and return a list with the names of subtools
        [VarSet,count,0]
        [Loop,[VarSize,SubtoolList],   // search for subtools with object name in subtoolList 
            //[Note,[StrMerge,"\nStrLength: \n index:", count, " >length: ",[StrLength,SubtoolList(count)], " > Name: ", SubtoolList(count)],,reportDuration] 
            
            [If, ([StrFind,SubtoolList(count),objectName]==0) && ([StrLength,SubtoolList(count)]==[StrLength,objectName]),
                [VarSet, subtoolExists, objectName] //subtoolExists (str:objectName/ -1: for no subtool match
                [VarSet,subtoolCount, count] 
                [LoopExit]
            , //else
                [VarSet, subtoolExists, -1] //subtoolExists (str:objectName/ -1: for no subtool match
            ] 
            [VarInc, count]           
            [If,count >= [VarSize, SubtoolList],
                [LoopExit]
            ]
        ]
    , objectName, SubtoolList, subtoolExists
    ]

    [RoutineDef, setScale, 
        // set offset and scale to default, this has been transfered to the subtool.
        [ISet,Tool:Geometry:XYZ Size, [IGet,Tool:Geometry:XYZ Size] * [IGet,Tool:Export: Scale]]
        [ISet,Tool:Export:Scale,1]    
        //[Note,[StrMerge, "\n GoB scale transfered", ""],,reportDuration]  
    ]

    [RoutineDef, setOrigin, 
        // transfer export offset and scale to subtool offset, this is needed to correct origins that are not in the wrold center
        [ISet,Tool:Geometry:X Position, ([IGet,Tool:Geometry:X Position] + [IGet,Tool:Export:X Offset]) * [IGet,Tool:Export: Scale]]
        [ISet,Tool:Geometry:Y Position, ([IGet,Tool:Geometry:Y Position] + [IGet,Tool:Export:Y Offset]) * [IGet,Tool:Export: Scale]]
        [ISet,Tool:Geometry:Z Position, ([IGet,Tool:Geometry:Z Position] + [IGet,Tool:Export:Z Offset]) * [IGet,Tool:Export: Scale]]
        // set offset and scale to default, this has been transfered to the subtool.
        [ISet,Tool:Export:X Offset,0.0]
        [ISet,Tool:Export:Y Offset,0.0]
        [ISet,Tool:Export:Z Offset,0.0]    
        //[Note,[StrMerge, "\n GoB Origin transfered", ""],,reportDuration]  
    ]


    [RoutineDef, AddTool, 
        //create a new tool if option in GoZ is set to import as new tool
        [IKeyPress,13,[IPress,Tool:Plane3D]] //select simple brush to create new tool from it 
        [SubToolSelect,subtoolCount]
        [If,[FileExists, objectPath],
            [FileNameSetNext, objectPath] 
            [IPress, Tool:Import]                         
            [RoutineCall, LoadTextures]  
        ] 
        // new tool was created, frame it to the canvas otherwise it might not be visible
        [CanvasClick, 10, 10, 10, 20]
        [IPress, Transform: Edit] 
        [TransformGet, xPos, yPos, zPos, xSc, ySc, zSc, xRot, yRot, zRot ]
        [TransformSet, (Document:Width/2), (Document:Height/2), zPos,  xSc, ySc, zSc, xRot, yRot, zRot]
        
        [Note,[StrMerge, "\n\C00FF00 Created new tool: ",  objectName],,reportDuration]
    , objectName, objectPath]


    [RoutineDef, AddSubTool,        
        [VarDef, subtoolCount, 0]
        [VarSet,subtoolName,[IGetTitle, "Tool:ItemInfo"]]        //get the subtool name
        [VarSet,subtoolName,[StrExtract, subtoolName, 0,[StrLength, subtoolName]-2]]       // trim chars from the end.
        [If, [ToolGetSubToolID] == 0,
            [If,[FileExists, objectPath],
                [FileNameSetNext, objectPath] 
                [IPress, Tool:Import]                      
                [RoutineCall, LoadTextures]  
            ]
            [CanvasClick,10,10,10,20]
            [IPress,Transform: Edit]
        , //else
            [If, [StrFind,"PolyMesh3D",subtoolName] != -1, 
                [IPress,Tool:SubTool:Insert]
                [IPress,PopUp:Cube3D] 
            ,  //else                
                [IPress,Tool:SubTool:Insert]
                [IPress,PopUp:PolyMesh3D]
            ]     
            [If,[FileExists,objectPath],
                [FileNameSetNext,objectPath] 
                [IPress,Tool:Import]                            
                [RoutineCall, LoadTextures] 
            ] 
        ]    
        
        [Note,[StrMerge,"\n\C2200FF Created new Subtool:      \CFFFFFF", objectName] ,,reportDuration]
    , objectName, objectPath]


    [RoutineDef, UpdateSubTool,
        //[VarDef, subtoolCount, objectMemIndex]       // TODO: this needs to be set to the correct index, find it in the subtool List the object name
        [SubToolSelect,subtoolCount]
        [If,[FileExists,objectPath],
            [FileNameSetNext,objectPath] 
            [IPress,Tool:Import]                        
            [RoutineCall, LoadTextures]    
        ]         
        [Note,[StrMerge,"\n\CFFEE00 Updated Subtool:    \CFFFFFF",objectName],,reportDuration]  
    , objectName, objectPath, subtoolCount]


    [VarSet,subtoolCount,0] 
    [VarSet,objectMemIndex,0] 
    [VarDef,objectLineStr,""]  
    [VarDef,subtoolName,""]    
    [VarDef, SubtoolList(maxSubtools), ""]  
    [RoutineCall,CreateSubtoolList]
    [VarDef, subtoolExists, ""]             //subtoolExists (str:objectName/ -1: for no subtool match

    [If,[MemGetSize,GoB_ObjectList_InputMem],
        [Loop,maxSubtools,
            //read a line into a string variable
            [VarSet,lineBytes,[MemReadString,GoB_ObjectList_InputMem,objectLineStr,objectMemIndex,1]]
            //extract objects string
            [VarDef,objectName,""]
            [VarSet,objectName,[StrExtract,objectLineStr,[StrLength,gozProjectPath],lineBytes]]
            // call routines for import here          
            [VarDef,objectPath,""]
	        [If,[ZBrushInfo,6],//is MacOS 
                [VarSet,objectPath,[StrMerge,"!:",gozProjectPath,objectName,fileExtension]]
            , // else is Windows
                [VarSet,objectPath,[StrMerge,gozProjectPath,objectName,fileExtension]]
            ]             
            //[Note,[StrMerge, "\nobjectName \n    ", objectName],,0]
            //[Note,[StrMerge, "\nobjectPath \n    ", objectPath],,0]

            //find subtool
            [RoutineCall, FindSubtool, objectName, SubtoolList, subtoolExists]            
            //[Note,[StrMerge, "\n\n importAsSubtool: ", importAsSubtool, "\n toolid: ", [ToolGetSubToolID], "\n subtoolExists:  ",subtoolExists ],,reportDuration]                  

            // import as Tool
            [If, importAsSubtool == 0,                                   
                [RoutineCall, AddTool, objectName, objectPath] 
                //[RoutineCall, setOrigin] 
                //[RoutineCall, setScale] 
                // delete undo histroy after new tool has been added
                [IPress,Edit:Tool:DelUH] 
            ,

                // import as subtool
                [If, subtoolExists == -1, //subtoolExists (str:objectName/ -1: for no subtool match
                    [RoutineCall, AddSubTool, objectName, objectPath]  
                    //[RoutineCall, setOrigin] 
                    [IPress,Edit:Tool:DelUH]  
                ,

                    //update subtools
                    [If, subtoolExists == objectName, 
                        [RoutineCall, UpdateSubTool, objectName, objectPath, subtoolCount]
                    , //else
                        //does a exception exist?
                        [Note,[StrMerge, "\n GoB subtool already exists: ", subtoolExists, objectName],,reportDuration] 
                    ]
                ]
            ]

            //[RoutineCall, setOrigin] 
            
            //next loop or exit if end of file
            [VarSet, subtoolCount, subtoolCount + 1]
            [VarSet, objectMemIndex, objectMemIndex + lineBytes]

            [If, objectMemIndex >= [MemGetSize, GoB_ObjectList_InputMem],
            
                [IPress,Transform: Fit]
                [LoopExit]
            ]
        ]     
    ]
    [MemDelete,GoB_ObjectList_InputMem]        //all done, delete memblock
    

    // show summary of what was imorted
    [If, showFinalReport == 1,
        [Note,
            "\n\n\CFFFFFF GoB import finished!",
            none, //Optional path1 of an interface item to be pointed out (default:none), 
            finalReportreportDuration, //Display Duration (in seconds) (0:wait for user action(default), -1:combine with next note command),
            0x606060, //Popup background color (0x000000<->0xffffff, default:0x606060, 0:No Background), 
            48, //Prefered distance of the note from the specified interface item (default:48), 
            600, //Prefered Note width (in pixels, default:400), 
            0x000000, //optional marked windows fill color (0x000000<->0xffffff or (blue+(green*256)+(red*65536))(Omitted value:No fill)),
            1, //Frame horizontal size (1:Max width (default)), 
            1, //Frame vertical size (1:Max height (default)), 
            0, //Frame left side (0:left (default), .5:center, 1:right) Omit value for horizontal autocentering, 
            0, //Frame top side ( 0:top (default), .5:center, 1:bottom )Omit value for vertical auto-centering, 
            "IMAGE_GMenuIcons/zscript.psd" //Optional icon file name            
        ]
    ]
]/*End of ZScript*/





//[SubToolGetFolderName,4] //return the folder name that the 5th subtool was in, or an empty string if it wasn’t in a folder.
// [SubtoolGetFolderIndex] 

/* 
[IButton, “Subtool visible?”, ,
[VarSet,STStatus,[SubtoolGetStatus]]
[VarSet,STFolderIndex,[SubtoolGetFolderIndex]]

[If,(STFolderIndex > -1), //part of a folder
    [If,(STStatus&2), //head of the folder
        [If,(STStatus&1),
            [Note,“Visible head of folder”]
        ,
            [Note,“Invisible head of folder”] ]
        ,
        [If,(STStatus&1), //member of the folder
            [Note,“Visible in a folder”]
        ,
            [Note,“Invisible in a folder”] ] ] ] [If,(STFolderIndex == -1), //not part of a folder
            [If,(STStatus&1),
                [Note,“Visible”]
            ,
                [Note,“Invisible”]
        ]
    ]
] 
*/



/* 
[RoutineDef, SubToolIsVisible,
    [VarSet, isVisible, 0]
    [VarSet,actIndex,[SubToolGetActiveIndex]]
    [VarSet,st,[subtoolgetstatus,actIndex]]
    [VarSet,fInd,[subtoolgetfolderindex,actIndex]]
    
    [If,(fInd > -1),//it’s in a folder
        [VarSet,stFld,[subtoolgetstatus,fInd]]//get folder visibility
        [If,([Val,stFld]&0x2 == 0x2)&&([Val,st]&0x1 == 0x1),
            [VarSet,isVisible,1]
        ]
        , //else no folder
            [If,([Val,st]&0x1 == 0x1),
            [VarSet,isVisible,1]
        ]
    ]
, isVisible] 
*/
