// Copyright (C) 1997-2004 Alias Systems Corp.
// 
// The information in this file is provided for the exclusive use of the
// licensees of Alias.  Such users have the right to use, modify,
// and incorporate this code into other products for purposes authorized
// by the Alias license agreement, without fee.
// 
// ALIAS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
// EVENT SHALL ALIAS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

//
//  Creation Date:	May 23, 1997
//
//  Procedure Name:
//	AEdiskCacheTemplate
//
//  Description Name;
//	Creates the attribute editor controls for the diskCache Node
//
//  Input Value:
//	nodeName 
//
//  Output Value:
//	None
// 

global proc int AEassignDiskCB( string $fileAttribute,
                                 string $filename,
                                 string $fileType )
{
    setAttr $fileAttribute -type "string" $filename;

	// This will force an update to display the effects
	// of the new cachefile.
	//
	currentTime `currentTime -q`;

    string $currentDir = `workspace -q -dir`;
    retainWorkingDirectory ($currentDir);

    return true;
}

global proc AEdiskCacheBrowser( string $cmd, string $cacheName )
{
	if( `exists fluidCacheIsSegmented`
	&&  fluidCacheIsSegmented( $cacheName ) )
	{
		string $expNode[] = `listConnections -d false ($cacheName+".segmentStartFrame")`;
		string $msg2;

		if( `nodeType $expNode[0]` == "expression" ) {
			$msg2 = ( "Please use the Expression Editor to modify the cache-swapping " +
					  "expression in node \"" + $expNode[0] + "\" instead." );
		}

		error( "Cannot browse for a cache file since disk cache " + $cacheName + " " +
			   "is segmented.  " + $msg2 );
		return;
	}

    string  $workspace = `workspace -q -fn`;
    setWorkingDirectory $workspace "diskCache" "data";
   
    fileBrowser ($cmd, "Assign Cache", "disk cache", 0);
}

global proc AEdeleteCache( string $startTime,
						   string $endTime,
						   string $samplingRate )
{
	string  $nodeName[];
	tokenize($startTime, ".", $nodeName);
	setAttr $startTime 0;
	setAttr $endTime   0;
	setAttr $samplingRate 1;
	string $cmd = "diskCache -delete \"" + $nodeName[0] + "\"";
	evalEcho($cmd);
	setAttr -type "string" ($nodeName[0]+".cacheName") "";
}

// Frame Layout does not handle the setting of heights properly on Mac 
// so added the expand callbacks where the heights can be set properly. 

global proc AEexpandDiskCacheLayout()
{
	if (`about -mac`)
	{
		if( `frameLayout -q -l diskCacheLayout` == "Fluid Initial State Attributes") {
			frameLayout -e -h 60 diskCacheLayout; 
		} else if( `frameLayout -q -l diskCacheLayout` == "Fluid Cache Attributes" ) {
			frameLayout -e -h 160 diskCacheLayout;
		} else if( `frameLayout -q -l diskCacheLayout` == "Hair Cache Attributes" ) {
			frameLayout -e -h 160 diskCacheLayout;
		} else if( `frameLayout -q -l diskCacheLayout` == "Jiggle Cache Attributes" ) {
			frameLayout -e -h 180 diskCacheLayout;
		}
	}
}

global proc AEexpandDiskCacheFrame()
{
	if (`about -mac`)
	{
		if( `frameLayout -q -l diskCacheLayout` == "Fluid Initial State Attributes") {
			frameLayout -e -h 200 diskCacheContentsFrame;
		} else if( `frameLayout -q -l diskCacheLayout` == "Fluid Cache Attributes" ) {
			frameLayout -e -h 200 diskCacheContentsFrame;
		}
	}
}

global proc AEdiskCacheNew( string $cacheType )
//
// Description:
//	
//	
{
	frameLayout -lv true -bv true -collapsable true -collapse false -ec AEexpandDiskCacheLayout diskCacheLayout;

		setUITemplate -pst attributeEditorTemplate;
		columnLayout -adj true;
			rowLayout -nc 3 diskNameLayout;
        		text cacheNameText;
		        textField diskNameField;
		            symbolButton -image "navButtonBrowse.xpm" browser;
				setParent ..;

			floatFieldGrp -l "Start Time" startTime; 
			floatFieldGrp -l "End Time" endTime;
			radioButtonGrp -l "Sampling Type" -nrb 2 
				-l1 "Over" -data1 0 
				-l2 "Under" -data2 1
				samplingType;
			intFieldGrp -l "Sampling Rate" samplingRate;

			rowLayout -nc 2 deleteCacheLayout;
				text -l " ";
				button -label "Delete Cache" -width 80 deleteCache;
				setParent ..;

		    setUITemplate -ppt;
			setParent ..;

		setParent ..;

	// Fluid Cache Contents
	//
	frameLayout -lv true -bv true -collapsable true -collapse false -ec AEexpandDiskCacheFrame diskCacheContentsFrame; 
		setUITemplate -pst attributeEditorTemplate;	
		columnLayout -adj true;
			checkBoxGrp -en1 false -l "Density" -l1 "" -ncb 1 diskContentsDensity;
			checkBoxGrp -en1 false -l "Velocity" -l1 "" -ncb 1 diskContentsVelocity;
			checkBoxGrp -en1 false -l "Temperature" -l1 "" -ncb 1 diskContentsTemperature;
			checkBoxGrp -en1 false -l "Fuel" -l1 "" -ncb 1 diskContentsFuel;
			checkBoxGrp -en1 false -l "Color" -l1 "" -ncb 1 diskContentsColor;
			checkBoxGrp -en1 false -l "Texture Coordinates" -l1 "" -ncb 1 diskContentsTexture;
			checkBoxGrp -en1 false -l "Falloff" -l1 "" -ncb 1 diskContentsFalloff;
			setParent ..;

		setUITemplate -ppt;
		setParent ..;

	AEdiskCacheReplace( $cacheType );
}

global proc AEdiskCacheReplace( string $cacheType )
//
// Description:
//	
//	
{
	string $type = `getAttr $cacheType`;
	int $isIC = $type == "mcfi";
	int $isPB = $type == "mcfp";
	int $isHair = $type == "mchp";
	int $isFluid = $isIC || $isPB;

	// Rename a few controls depending on the cache type
	//
	if( $isIC ) {
		frameLayout -e -l "Fluid Initial State Attributes" diskCacheLayout; 
		frameLayout -e -l "Cache Contents at Fluid Start Frame" diskCacheContentsFrame;
	} else if( $isPB ) {
		frameLayout -e -l "Fluid Cache Attributes" diskCacheLayout;
		frameLayout -e -l "Cache Contents at Current Time" diskCacheContentsFrame;
	} else if( $isHair ) {
		frameLayout -e -l "Hair Cache Attributes" diskCacheLayout;
	} else {
		frameLayout -e -l "Jiggle Cache Attributes" diskCacheLayout;
	}
		
	if (`about -mac`)
	{
		if( $isIC ) {
			frameLayout -e -h 60 diskCacheLayout; 
			frameLayout -e -h 200 diskCacheContentsFrame;
		} else if( $isPB ) {
			frameLayout -e -h 160 diskCacheLayout;
			frameLayout -e -h 200 diskCacheContentsFrame;
		} else if( $isHair ) {
			frameLayout -e -h 160 diskCacheLayout;
		} else {
			frameLayout -e -h 180 diskCacheLayout;
		}
	}

	// Now attach the controls to the right attrs on
	// the node.
	//
	string	$nameBits[];
	tokenize($cacheType, ".", $nameBits);
	string	$nodeName = $nameBits[0];

	string  $fileAttr 		= ( $nodeName + ".cacheName" );
	string  $startAttr 		= ( $nodeName + ".startTime" );
	string  $endAttr 		= ( $nodeName + ".endTime" );
	string  $sampTypeAttr 	= ( $nodeName + ".samplingType" );
	string  $sampRateAttr 	= ( $nodeName + ".samplingRate" ); 

	// Filename Attribute
	//
    connectControl -fileName diskNameField $fileAttr;
    string $command = "AEassignDiskCB " + " " + $fileAttr;
    button -e -c ("AEdiskCacheBrowser \"" + $command + "\" " + $nodeName ) browser;

	connectControl -index 2 startTime $startAttr;

	// Control the visibility of type-specific widgets.
	//
	floatFieldGrp -e -manage (!$isIC) startTime;
	floatFieldGrp -e -manage (!$isIC) endTime;
	radioButtonGrp -e -manage (!$isIC) samplingType;
	intFieldGrp -e -manage (!$isIC) samplingRate;
	rowLayout -e -manage (!$isFluid && !$isHair) deleteCacheLayout;

	// Connect the controls.
	//
	connectControl -index 2 endTime 		$endAttr;
	connectControl 			samplingType 	$sampTypeAttr;
	connectControl -index 2 samplingRate 	$sampRateAttr;

	// Disable whichever radio button isn't selected; 
	// we can't change it anyway.
	//
	int $sel = `radioButtonGrp -q -sl samplingType`;
	radioButtonGrp -e -enable1 ($sel==1) -enable2 ($sel==2)	samplingType;

	button -e -c ("AEdeleteCache " + 
				  $startAttr + " " + 
				  $endAttr + " " + 
				  $sampRateAttr ) deleteCache;

	// Fluid Cache Contents
	//
	int $showContents = ( $isIC || $isPB );
	// There will be a big blank area even though diskCacheContentsFrame is unmanaged,
	// on Mac. So, make sure to set its height properly so as to avoid this problem. 
	if (! $showContents && `about -mac`) 
		frameLayout -e -h 1 diskCacheContentsFrame;
	frameLayout -e -manage $showContents diskCacheContentsFrame;

	// Segmented bits
	// 
	int $isSegment = fluidCacheIsSegmented( $nodeName );
	textField -e -editable (!$isSegment) diskNameField;
	if( $isSegment ) {
		text -e -l "Segment File Name" cacheNameText;
	} else {
		text -e -l "Cache File Name" cacheNameText;
	}
	
	// Playback caches need to update at different times...
	//
	scriptJob -e "timeChanged" ( "updateCacheContents " + $nodeName )
		-rp -p diskCacheContentsFrame;


	updateCacheContents( $nodeName );
}

global proc AEdiskCachingNodeNew( string $cacheType, string $copyLocally ) 
{
	frameLayout -lv false -bv false -collapsable true -collapse false
		diskCacheNodeLayout;

		setUITemplate -pst attributeEditorTemplate;
		columnLayout -adj true; 
			checkBoxGrp -l "" -l1 "Copy Cache File Locally" copyLocally;
			setParent ..;

		setUITemplate -ppt attributeEditorTemplate;
		setParent ..;

	AEdiskCachingNodeReplace( $cacheType, $copyLocally );
}

global proc AEdiskCachingNodeReplace( string $cacheType, string $copyLocally ) 
{
	string $type = `getAttr $cacheType`;
	int $isIC = $type == "mcfi";

	string	$nameBits[];
	tokenize($cacheType, ".", $nameBits);
	string	$nodeName = $nameBits[0];
	int $isSegment = fluidCacheIsSegmented( $nodeName );

	// Only display the Copy Locally bits if we're a playback
	// cache and *not* a segmented playback cache.
	//
	frameLayout -e -manage (!$isIC && !$isSegment) diskCacheNodeLayout;

	checkBoxGrp -e -cc ( "setAttr " + $copyLocally + " #1 " )  
		copyLocally;

	scriptJob -attributeChange $copyLocally ( "updateCachingNodeContents " + $copyLocally )
		-rp -p diskCacheNodeLayout;

	updateCachingNodeContents( $copyLocally );
}

global proc updateCachingNodeContents( string $copyLocally )
{
	checkBoxGrp -e -v1 `getAttr $copyLocally` copyLocally;
}

global proc updateCacheContents( string $nodeName ) 
//
// Description:
//	Cases where we need to update the contents checkboxes
//	displayed in the AE:
//		1) When time changes, since playback caches can
//		   have different attrs cached at different times.
//		   
//		2) When a Set Initial State or an Append operation
//		   are performed on an existing cache, as this
//		   could change the contents displayed at the current 
//		   time as well.  
//		   
{
	// Make sure the object exists before using it
	// in a cmd that could fail.
	//
	string $ls[] = `ls ($nodeName + ".diskCache")`;
	if( size( $ls ) != 1 ) {
		return;
	}

	// Executing fluidCacheInfo below causes an attrChanged
	// message to be sent for .startTime, so if we're already
	// executing the scriptJob for that attrChanged message,
	// don't generate another one...
	//
	string $res[] = `listConnections ($nodeName + ".diskCache")`;
	if( size( $res ) != 1 ) {
		return;
	}

	string $fluid = $res[0];
	string $typeFlag = "";

	int $rightCacheType = false;

	float $currTime, $startTime, $endTime; 
	string $type = `getAttr ($nodeName + ".cacheType")`;
	if( $type == "mcfi" ) {
		// For initial states, contents info only matters at
		// startTime
		//
		$currTime = `getAttr ($fluid+".startTime")`;
		$typeFlag = " -ic ";
		$startTime = `fluidCacheInfo -sf -ic $fluid`;
		$endTime = $startTime;
		$rightCacheType = true;
	} else if( $type == "mcfp" ) {
		// For playback caches, contents info could be
		// different depending on current time.
		//
		$currTime = `currentTime -q`;
		$typeFlag = " -pb ";
		$startTime = `fluidCacheInfo -sf -pb $fluid`;
		$endTime = `fluidCacheInfo -ef -pb $fluid`;
		$rightCacheType = true;
	} 

	int $inRange = false;
	if( $currTime >= $startTime && $currTime <= $endTime ) {
		$inRange = true;
	}

	if( $rightCacheType ) {
		int $hasD, $hasV, $hasT, $hasF, $hasC, $hasTC;
		string $baseCmd = ( "fluidCacheInfo -t " + $currTime + 
							" -hd " + $typeFlag );

		$hasD  = eval( $baseCmd + "-at density " + $fluid );
		$hasV  = eval( $baseCmd + "-at velocity " + $fluid );
		$hasT  = eval( $baseCmd + "-at temperature " + $fluid );
		$hasF  = eval( $baseCmd + "-at fuel " + $fluid );
		$hasC  = eval( $baseCmd + "-at color " + $fluid );
		$hasTC = eval( $baseCmd + "-at coordinates " + $fluid );
		$hasFA = eval( $baseCmd + "-at falloff " + $fluid );
		

		// Then enable or disable just the corresponding check box.
		//
		checkBoxGrp -e -v1 $hasD diskContentsDensity;
		checkBoxGrp -e -v1 $hasV diskContentsVelocity;
		checkBoxGrp -e -v1 $hasT diskContentsTemperature;
		checkBoxGrp -e -v1 $hasF diskContentsFuel;
		checkBoxGrp -e -v1 $hasC diskContentsColor;
		checkBoxGrp -e -v1 $hasTC diskContentsTexture;
		checkBoxGrp -e -v1 $hasFA diskContentsFalloff;
	}
}

global proc AEdiskCacheTemplate ( string $nodeName )
{
	editorTemplate -beginScrollLayout;

	editorTemplate -callCustom AEdiskCacheNew AEdiskCacheReplace cacheType;

	editorTemplate -suppress enable;		
	editorTemplate -suppress cacheName;		
	editorTemplate -suppress cacheType;		
	editorTemplate -suppress hiddenCacheName;		
	editorTemplate -suppress segmentStartFrame;		

	editorTemplate -beginLayout "Caching Node" -collapse true;
	editorTemplate -addControl diskCache;
	editorTemplate -callCustom AEdiskCachingNodeNew AEdiskCachingNodeReplace cacheType copyLocally;
	editorTemplate -suppress copyLocally;
	editorTemplate -endLayout;

	AEdependNodeTemplate $nodeName;

	editorTemplate -addExtraControls;

	editorTemplate -endScrollLayout;
}
