// 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.

//
//  Alias Script File
//  MODIFY THIS AT YOUR OWN RISK
//
//  Creation Date:   29 July 1996
//
//  Description:
//      This implements the plugin-manager utility window
//
//  Procedures:
//     pluginWin, updatePluginWin, browsePlugin, displayPluginInfo, 
//     loadPluginCallback
//

global int $pluginListSize = 0;
global string $defaultPluginBrowseDir = "";
global string $pluginWindowName = "pluginManagerWindow";
global int $ignoreUpdateCallback = false;
global int $pluginRefreshNeeded = false;
global string $winLyt ="windowLyt";



/////////////////////////////////////////////////////////////////
// Helper Functions: these are not exported to the application //
/////////////////////////////////////////////////////////////////

proc string getDir( string $path ) 
//
//  Procedure Name:
//      getDir
//
//  Description:
//      strips the file name off of a path
//
//  Return Value:
//      the directory name
//	
{
	string $dir = match( "^.*/", $path );

	int $sz = size( $dir );
	// Strip off trailing '/'
	//
	if ( ( $sz > 1 ) && ( substring( $dir, $sz, $sz ) == "/" ) ) {
		$dir = substring( $dir, 1, ($sz - 1) );
	} 
	return $dir;
}

proc string getFile( string $path ) 
//
//  Procedure Name:
//      getFile
//
//  Description:
//      returns the final file name in a path
//
//  Return Value:
//      the file name
//	
{
	string $file = match( "[^/]*$", $path );
	return $file;
}

/////////////////////////////////////////////////////////////
// Plugin List code.  Maintain a list of plugin info using //
// the available single dimensional arrays in MEL          //
/////////////////////////////////////////////////////////////

//
//  Procedure Name:
//      pluginListEntry
//
//  Description:
//      gets info about the plugin at the given index
//
//  Return Value:
//      the contents of the given field
//
proc string pluginListEntry( int $index, string $field ) 
{
	global string $pluginManagerList[];
	int $numElements = 4;
	
	if ( $field == "path" ) {
		$name = $pluginManagerList[$numElements * $index]; 
		return $name;
	} else if ( $field == "fileName" ) { 
		$path = $pluginManagerList[$numElements * $index];
		$name = getFile( $path );
		return $name;
	} else if ( $field == "loadedWidget" ) { 
		$name = $pluginManagerList[($numElements * $index) + 1]; 
		return $name;
	} else if ( $field == "autoloadWidget" ) { 
		$name = $pluginManagerList[($numElements * $index) + 2]; 
		return $name;
	} else if ( $field == "infoWidget" ) { 
		$name = $pluginManagerList[($numElements * $index) + 3]; 
		return $name;
	}
	return "";
}
 

proc setPluginListEntry( int $index, string $path, string $loadedWiget,
						 string $autoWidget, string $infoWidget )
//
//  Procedure Name:
//      setPluginListEntry
//
//  Description:
//      Set information about the plugin at the given index
//
//  Return Value:
//      none
//	
{
	global string $pluginManagerList[];
	int $numElements = 4;
	
	$pluginManagerList[$numElements * $index] = $path;
	$pluginManagerList[($numElements * $index) + 1] = $loadedWiget;
	$pluginManagerList[($numElements * $index) + 2] = $autoWidget;
	$pluginManagerList[($numElements * $index) + 3] = $infoWidget;
}

proc int removePluginListEntries (string $path)
//
//  Procedure Name:
//      removePluginListEntries
//
//  Description:
//      Remove all entries associated in the directory given by $path
//
{
	global string $pluginManagerList[];
	global int $pluginListSize;
	int $numElements = 4;
	
	int $i, $j;
	int $numRemoved = 0;

	for ($i = 0; $i < $pluginListSize; $i++)
		if (getDir (pluginListEntry ($i, "path")) == $path)
			$numRemoved++;
		else if ($numRemoved != 0)
			for ($j = 0; $j < $numElements; $j++)
				$pluginManagerList[($i - $numRemoved) * $numElements + $j] =
					$pluginManagerList[$i * $numElements + $j];
	$pluginListSize -= $numRemoved;
	return $numRemoved;
}

proc int isPathInSearchPath( string $path ) 
//
//  Procedure Name:
//      isPathInSearchPath
//
//  Description:
//      determines if the given path is in our plugin search path
//
//  Return Value:
//      whether it is in the path
//
{
	global string $verifiedPluginPath[];

	return stringArrayCount( $path, $verifiedPluginPath ) > 0;
}

proc int isPluginInUI( string $path ) 
//
//  Procedure Name:
//      isPluginInUI
//
//  Description:
//      determines if the given plugin is listed in our UI already
//
//  Return Value:
//      whether it is in the UI
//
{
	global int $pluginListSize;

	for ($i = 0; $i < $pluginListSize; ++$i) 
	{
		if ( pluginListEntry ($i, "path") == $path ) 
		{
			return true;
		}
	}

	return false;
}

proc addSinglePlugin( string $path, string $parent )
//
//  Procedure Name:
//      addSinglePlugin
//
//  Description:
//      adds a single plugin, creating the widgets
//
{ 
	global int $pluginListSize;
	global int $ignoreUpdateCallback;

	// Make sure the path is using forward slashes regardless of the platform
	$path = convert($path);
	setParent $parent; 
	string $name = getFile( $path );

	text -l $name ("PlugNameTxt" + (string)$pluginListSize);
	string $loadedCheck = `checkBox -align "left" -l "loaded" ("plugLoadedChk" + (string)$pluginListSize)`; 
	string $autoBox = `checkBox -align "left" -l "auto load" ("plugAutoLoadChk" + (string)$pluginListSize)`;
	string $symButt = `symbolButton -image "info.xpm" ("plugInfoBtn" + (string)$pluginListSize)`;

	// Store the widget name so that we can update this widget later
	//
	setPluginListEntry( $pluginListSize, $path, $loadedCheck, $autoBox, $symButt );
	

	// Add callbacks to controls
	//
	checkBox -edit -onCommand (
		"waitCursor -state on;						\
		$ignoreUpdateCallback = true;				\
		catch( `loadPlugin \"" + $path + "\"`);		\
		updatePluginUI( \"" + $pluginListSize + "\" );		\
		$ignoreUpdateCallback = false;				\
		waitCursor -state off;"  ) 
		-offCommand  ( "unloadPluginWithCheck( \"" + $path + "\" );" ) $loadedCheck;

	checkBox -edit -onCommand ("pluginInfo -edit -autoload true \""
		+ $path + "\";" ) -offCommand 
		("pluginInfo -edit -autoload false \"" + $path + "\";" ) $autoBox;
	symbolButton -edit -command ("displayPluginInfo \"" + $path + "\";" ) $symButt; 

	// Move to the next list item 
    $pluginListSize++;
}

proc addDirectory( string $dirName, string $parent, int $index )
//
//  Procedure Name:
//      addDirectory
//
//  Description:
//      adds a new directory, creating the layout widget
//
{
	string $tempString[];

	// Create a new layout widget
	//
	setParent $parent;
	string $dir = getFile( getDir( $dirName ) ); 
 
	string $frameName = "PluginFrameLyt" + (string)$index;
	string $par;
	if (`frameLayout -exists $frameName`) {
		setParent $frameName;
	} else {
		string $labelStr;
		$labelStr = $dirName;
		frameLayout 
			-mw 10 -mh 10
			-borderStyle "etchedIn"
			-borderVisible true 
			-collapse false -collapsable true
		    -label $labelStr -labelVisible true $frameName;
	}
	string $rowColName = "PluginRowColLyt" + (string)$index;
	if(`about -mac`)
	{
		$par = `rowColumnLayout  -cat 1 "left" 2 -columnWidth 1 200
			-columnWidth 2 70
			-columnWidth 3 105 -columnWidth 4 25 -nc 4 $rowColName`;
	} else {
		$par = `rowColumnLayout -cal 1 "left" -columnWidth 1 125
			-columnWidth 2 70
			-columnWidth 3 105 -columnWidth 4 25 -nc 4 $rowColName`; 
	}

	// Read the directory, retaining a file count
	//
	string $dirList[];
	string $pattern = "*.so";
	if ( `about -windows` ) {
		$pattern = "*.mll";
	}else if( `about -mac` ){
		$pattern = "*.lib";
	}
	
	if( `about -mac` ){
		catch( $dirList = `getFileList -folder $dirName -filespec $pattern` );
	}else { 
		catch( $dirList = `getFileList -folder ( $dirName + "/" ) -filespec $pattern` );
	}

	int $fileCount = size( $dirList );
	for ( $fileName in $dirList ) {
		string $path = $dirName + "/" + $fileName;
		addSinglePlugin( $path, $par );
	}
} 

proc rescanDirectory( string $dirName, string $parent, int $index)
//
//  Procedure Name:
//      rescanDirectory
//
//  Description:
//      rescans a directory, creating layout widgets for any new plug-ins and
//      removing layout widgets for removed plug-ins
{
	string $frame = "PluginFrameLyt" + (string) $index;
	string $children[] = `frameLayout -q -childArray $frame`;

	string $child;

	for ($child in $children)
		deleteUI $child;
	removePluginListEntries ($dirName);
	addDirectory ($dirName, $parent, $index);
}

//////////////////////
// Global Functions //
//////////////////////

global proc updatePluginWin()
//
//  Procedure Name:
//      updatePluginWin
//
//  Description:
//      refreshes the values in the plugin window 
//
//  Return Value:
//      None
//
{
	global string $verifiedPluginPath[];
	global int    $isPluginPathVerified;
	global string $pluginWinParentWidget;
	global string $pluginWinSingleParent;
	global string $pluginWindowName;
	global int    $pluginRefreshNeeded;

	// Make sure the window exists
	//
	if (!`window -exists $pluginWindowName`) {
		return;
	}

	if(`window -q -visible $pluginWindowName` )
	{
		return;
	}

	// Make sure that our path array is set up
	//
	if ( !$isPluginPathVerified ) 
	{
		// We will read the environment variable and check to see that all paths
		// are valid
		//
		string $pathEnvVar = getenv("MAYA_PLUG_IN_PATH");

		string $pathArray[];
		if (`about -nt`) {
			tokenize( $pathEnvVar, ";", $pathArray );
		}
		else {
			tokenize( $pathEnvVar, ":", $pathArray );
		}
		
		// Check that the paths are valid
		//
		int $index = 0;
		for ($path in $pathArray) {
			string $oldPath = `pwd`;
			// Expand the environment variables in the path
			//
			string $expandedPath;
			if (`about -nt` || `about -mac`) {
				$expandedPath = $path;
			}
			else {
				$expandedPath = system( "echo " + $path );
				// Strip the newline
				$expandedPath = strip ($expandedPath);
			}

			if ( 0 == `chdir $expandedPath` ) 
			{
				// Avoid addind duplicate paths to the search list
				if( !isPathInSearchPath( $expandedPath ) )
				{
					$verifiedPluginPath[$index] = $expandedPath;
					++$index;
				}
				chdir $oldPath;
			}
		} 

		// The UI hasn't been built yet
		//
		waitCursor -state on;
 
		int $index = 1;
		for ( $path in $verifiedPluginPath ) {
			addDirectory( $path, $pluginWinParentWidget, $index );
			$index++;
		}
		// Put in the misc section
		//
		setParent $pluginWinParentWidget;
		frameLayout 
			-borderStyle "etchedIn"
			-borderVisible true -collapse false -collapsable true 
		    -label "Other Registered Plugins" -labelVisible true
			-mw 10 -mh 10
			"PluginFrameLytMisc";
		if(`about -mac`) {
			$pluginWinSingleParent = `rowColumnLayout  -cat 1 "left" 2 -columnWidth 1 200 
				-columnWidth 2 70 -columnWidth 3 105 -columnWidth 4 25 -nc 4
				PluginRowColLytMisc`;
		} else {
			$pluginWinSingleParent = `rowColumnLayout -cal 1 "left" -columnWidth 1 125 
				-columnWidth 2 70 -columnWidth 3 105 -columnWidth 4 25 -nc 4
				PluginRowColLytMisc`;
		}

		$isPluginPathVerified = true;
		$pluginRefreshNeeded = true;

		waitCursor -state off;
	}

	if( $pluginRefreshNeeded )
	{
		updatePluginList();
	}
}

global proc updatePluginCallback()
{
	global int $ignoreUpdateCallback;
	global int $pluginRefreshNeeded;
	global string $pluginWindowName;

	int $visible = `window -q -visible $pluginWindowName`;

	if( $visible )
	{
 		if( !$ignoreUpdateCallback )  
		{
			updatePluginList();
		}
	}
	else
	{
		$pluginRefreshNeeded = true;
	}
}

global proc updatePluginList()
{
	global string $pluginWinSingleParent;
	global int    $pluginListSize;
	global string $pluginWindowName;
	global int $ignoreUpdateCallback;
	global int $pluginRefreshNeeded;

	// Make sure that all registered (i.e loaded)  plugins appear in UI
	// 
	string $knownPlugins[] = `pluginInfo -q -listPluginsPath`;
 
	string $dir; 
	for ( $plugin in $knownPlugins ) 
	{  
		$path = `pluginInfo -query -path $plugin`;
		$dir = getDir( $path );
		if ( !isPathInSearchPath( $dir ) ) {
			// We don't know this path, so this is a singleton plugin
			//
			 if ( !isPluginInUI( $plugin ) ) {
				addSinglePlugin( $path, $pluginWinSingleParent );
			}
		}
	}

	// Now, we need to make sure that the check boxes in the UI reflect the current
	// state
	//

	for ($i=0; $i < $pluginListSize; ++$i) 
	{
		updatePluginUI( $i );
	}

	$pluginRefreshNeeded = false;
} 

global proc updatePluginUI( int $i )
{

	string $path = pluginListEntry( $i, "path" );
	string $loadedWidgName = pluginListEntry( $i, "loadedWidget" );
	string $autoWidgName = pluginListEntry( $i, "autoloadWidget" );
	string $infoWidgName = pluginListEntry( $i, "infoWidget" );

	int $details[] = `pluginInfo -query -settings $path`;
	int $isLoaded = $details[0];
	int $auto = $details[1];
	int $registered = $details[2];

	if ( $isLoaded != ( `checkBox -query -value $loadedWidgName` ) ) 
	{
		checkBox -edit -value $isLoaded $loadedWidgName;
	} 			

	// Check autoload status
	//
	checkBox -edit -value $auto $autoWidgName;

		if ( $registered ) 
	{ 
		// We have valid info for the plugin
		// 
		symbolButton -edit -enable 1 $infoWidgName; 
	} 
	else 
	{ 
		// We don't have information about the given plugin in our database
		// as it has never been loaded.  Therefore, we will dim the info button
		// 
		symbolButton -edit -enable 0 $infoWidgName;
	}
}

global proc int loadPluginCallback( string $theFile, string $fileType )
//
//  Procedure Name:
//      loadPluginCallback
//
//  Description:
//      this is used by the file browser for actually loading the plugin, and
//      also remembers the last directory from which a plug-in was loaded.
//
//  Return Value:
//      None
//	
{
	global string $defaultPluginBrowseDir;
	$defaultPluginBrowseDir = `getDir $theFile`;
	// Set the file rule - this makes sure that future calls to browse
	// start from the same place
	if ( catch( `loadPlugin $theFile` ) ) {
 		warning ( "Could not load " + $theFile + " as a plug-in" );
 		return false;
 	} 
	return true;
}

global proc browsePlugin() 
//
//  Procedure Name:
//      browsePlugin
//
//  Description:
//      this is a UI equivalent to loadPlugin.  It puts up a file requestor. 
//      It keeps track of the directory it used last and maintains it
//      separately from the workspace directory. It starts in the user's home
//      directory.
//
//  Return Value:
//      None
//	
{  
	global string $defaultPluginBrowseDir;
	global string $gDefaultFileBrowserDir;

	// Note: every time Maya is restarted, the file rule is reset. This is
	// intentional - the default location is Maya's starting point. Change
	// this if the default changes.
	if ($defaultPluginBrowseDir == "") {
			global string $verifiedPluginPath[];
			if (size ($verifiedPluginPath) > 0)
				$defaultPluginBrowseDir =  $verifiedPluginPath[0];
			else
				$defaultPluginBrowseDir =  pwd ();
	}
	$gDefaultFileBrowserDir = $defaultPluginBrowseDir;

	string $prevDir = `workspace -query -directory`;
	workspace -directory $defaultPluginBrowseDir;
	fileBrowser ( "loadPluginCallback", "Load Plug-in", "plug-in", 0 );
	workspace -directory $prevDir;
}

global proc displayPluginInfo( string $path ) 
//
//  Procedure Name:
//      displayPluginInfo
//
//  Description:
//      opens a window and displays information about the given plugin
//
//  Return Value:
//      None
//
{
	global string $pluginInfoWinName;
	global string $pluginInfoWinPath;
	global string $pluginInfoWinVendor;
	global string $pluginInfoWinAutoLoad;
	global string $pluginInfoWinLoaded;
	global string $pluginInfoWinAPIVerson;
	global string $pluginInfoWinVerson;
	global string $pluginInfoWinFeatures; 
	int	$numHtCount = 0;

	string $name = `pluginInfo -query -name $path`;
	if ( catch( $path = `pluginInfo -query -path $name` ) ) {
		warning "Plug-in information not in database";
	}

	string $winName = "PluginInfoWin";

	if (!`window -exists $winName`) {
		window -t "Plug-in Information"  -wh 340 280 $winName;
		formLayout windowLyt;
			scrollLayout -cr true scrollLayout;
				formLayout scrollWindowLyt; 
					columnLayout -adjustableColumn true infoLyt;
						rowLayout -nc 2 -cw2 100 340 -adjustableColumn 2;
						text -label "Name: " -align "left" nameTxt;
						$pluginInfoWinName = `text -align "left" nameValTxt`;
						setParent ..;

						rowLayout -nc 2 -cw2 100 340 -adjustableColumn 2;
						text -label "Path: " -align "left" pathTxt;
						$pluginInfoWinPath = `text -align "left" pathValTxt`;
						setParent ..;

						rowLayout -nc 2 -cw2 100 340 -adjustableColumn 2;
						text -label "Vendor: " -align "left" vendTxt; 
						$pluginInfoWinVendor = `text -align "left" vendValTxt`;
						setParent ..;

						rowLayout -nc 2 -cw2 100 340 -adjustableColumn 2;
						text -label "Plug-in Version: " -align "left" versionTxt; 
						$pluginInfoWinVerson = `text -align "left" versValTxt`;
						setParent ..;

						rowLayout -nc 2 -cw2 100 340 -adjustableColumn 2;
						text -label "For API Version: " -align "left" apiVersionTxt; 
						$pluginInfoWinAPIVerson = `text -align "left" apiVersValTxt`;
						setParent ..;

						rowLayout -nc 2 -cw2 100 340 -adjustableColumn 2;
						text -label "Auto Load: " -align "left" autoTxt; 
						$pluginInfoWinAutoLoad = `text -align "left" autoValTxt`; 
						setParent ..;

						rowLayout -nc 2 -cw2 100 340 -adjustableColumn 2;
						text -label "Is Loaded: " -align "left" isLoadedTxt; 
						$pluginInfoWinLoaded = `text -align "left" isLoadedValTxt`; 
						setParent ..;
					setParent ..;
			
					frameLayout -borderVisible true
						-collapsable false -label "Plug-in Features" 
						-labelVisible true pluginFeaturesLyt;
						if(`about -mac`) {
							$pluginInfoWinFeatures = `textField  featuresTxt`;
						} else {
							$pluginInfoWinFeatures = `text -align "left" featuresTxt`; 
						}
					setParent ..;

				formLayout -e	-af infoLyt "left" 0
								-af infoLyt "right" 0 
								-af infoLyt "top" 0
								scrollWindowLyt; 

				formLayout -e	-af pluginFeaturesLyt "left" 0 
								-af pluginFeaturesLyt "right" 0
								-af pluginFeaturesLyt "bottom" 0 
								-ac infoLyt "bottom" 0 pluginFeaturesLyt
								scrollWindowLyt;  
				setParent ..;
			setParent ..;

		$closeInfoBtn = `button -l "Close" closeInfoBtn`;

		formLayout -e -af $closeInfoBtn "left" 5
					  -af $closeInfoBtn "right" 5
					  -af $closeInfoBtn "bottom" 5
					  -an $closeInfoBtn "top"
					  windowLyt;

		formLayout -e -af scrollLayout "top" 0
					  -af scrollLayout "left" 0
					  -af scrollLayout "right" 0
					  -ac scrollLayout "bottom" 5 $closeInfoBtn
					  windowLyt;

		button -edit -command "deleteUI PluginInfoWin" $closeInfoBtn;

		setParent ..; // close the formLayout
	}  

	// Update all of the fields
	//
	text -edit -label $name $pluginInfoWinName;
	text -edit -label $path $pluginInfoWinPath;
	text -edit -label `pluginInfo -query -vendor $name` $pluginInfoWinVendor;
	text -edit -label `pluginInfo -query -version $name` $pluginInfoWinVerson;
	text -edit -label `pluginInfo -query -apiVersion $name` $pluginInfoWinAPIVerson;
	if ( `pluginInfo -query -autoload $name` ) {
		text -edit -label "Yes" $pluginInfoWinAutoLoad;
	} else {
		text -edit -label "No" $pluginInfoWinAutoLoad; 
	} 
	if ( `pluginInfo -query -loaded $name` ) {
		text -edit -label "Yes" $pluginInfoWinLoaded;
	} else {
		text -edit -label "No" $pluginInfoWinLoaded; 
	} 

	if(`about -mac`){
		$numHtCount += 1;
	}
	// Build list of plugin features starting with commands
	//
	string $featureStr = "";
	string $commands[] = `pluginInfo -query -command $name`;
	if ( size( $commands ) > 0 ) {
		$featureStr = "  Commands:\n";
		if(`about -mac`) {
			$numHtCount += 1; 
		}
		if(`about -mac`) {
			$numHtCount += size( $commands );
		}		
		for ( $command in $commands ) {
			$featureStr = ( $featureStr + "      " + $command ); 
			if ( $command != $commands[ size( $commands ) - 1 ] ) {
				$featureStr = $featureStr + "\n";
			}
		} 
	}

	// Build list of context commands
	//
	string $tools[] = `pluginInfo -query -tool $name`; 
	if ( size( $tools ) > 0 ) {
		if ( $featureStr != "" ) {
			$featureStr = $featureStr + "\n\n";
			if(`about -mac`){
					$numHtCount += 2;
			}
		} 
		$featureStr = $featureStr + "  Tools:\n";
		if(`about -mac`) {
					$numHtCount += 1;
		}
		if(`about -mac`) {
			$numHtCount += size( $tools );
		}	
		for ( $tool in $tools ) {
			$featureStr = ( $featureStr + "      " + $tool );  
			if ( $tool != $tools[ size( $tools ) - 1 ] ) {
				$featureStr = $featureStr + "\n";
			}
		}
	} 

	// Build list of dependency nodes
	//
	string $nodes[] = `pluginInfo -query -dependNode $name`;
	if ( size( $nodes ) > 0 ) { 
		if ( $featureStr != "" ) {
			$featureStr = $featureStr + "\n\n";
			if(`about -mac`) {
					$numHtCount += 2;
			}
		} 
		$featureStr = $featureStr + "  Dependency Nodes:\n";
		if(`about -mac`){
			$numHtCount += 1;
		}
		if(`about -mac`) {
			$numHtCount += size( $nodes );
		}
		for ( $node in $nodes ) {
			$featureStr = ( $featureStr + "      " + $node );  
			if ( $node != $nodes[ size( $nodes ) - 1 ] ) {
				$featureStr = $featureStr + "\n";
			}
		}
	} 

	// Build list of dependency graph data types
	//
	string $data[] = `pluginInfo -query -data $name`; 
	if ( size( $data ) > 0 ) { 
		if ( $featureStr != "" ) {
			$featureStr = $featureStr + "\n\n";
			if(`about -mac`) {
				$numHtCount += 2;
			}
		} 
		$featureStr = $featureStr + "  Dependency Graph Data Types:\n";
		if(`about -mac`) {
			$numHtCount += 1;
		}
		if(`about -mac`) {
			$numHtCount += size( $data );
		}	
		for ( $datum in $data ) {
			$featureStr = ( $featureStr + "      " + $datum );  
			if ( $datum != $data[ size( $data ) - 1 ] ) {
				$featureStr = $featureStr + "\n";
			}
		}
	}

	// Build list of file translators
	//
	string $translators[] = `pluginInfo -query -translator $name`;
	if ( size( $translators ) > 0 ) {
		if ( $featureStr != "" ) {
			$featureStr = $featureStr + "\n\n";
			if(`about -mac`) {
				$numHtCount += 2;
			}
		}
		$featureStr = $featureStr + "  File Translators:\n";
		if(`about -mac`) {
			$numHtCount += 1;
		}
		if(`about -mac`) {
			$numHtCount += size( $translators );
		}	
		for ( $translator in $translators ) {
			$featureStr = ( $featureStr + "      " + $translator );
			if ( $translator != $translators[ size( $translators ) - 1 ] ) {
				$featureStr = $featureStr + "\n";
			}
		}
	}

	// Build list of ik solvers
	//
	string $ikSolvers[] = `pluginInfo -query -iksolver $name`;
	if ( size( $ikSolvers ) > 0 ) {
		if ( $featureStr != "" ) {
			$featureStr = $featureStr + "\n\n";
			if(`about -mac`){
					$numHtCount += 2;
			}
		}
		$featureStr = $featureStr + "  Ik Solvers:\n";
		if(`about -mac`){
					$numHtCount += 1;
		}
		if(`about -mac`)
			$numHtCount += size( $ikSolvers );
			
		for ( $ikSolver in $ikSolvers ) {
			$featureStr = ( $featureStr + "      " + $ikSolver );
			if ( $ikSolver != $ikSolvers[ size( $ikSolvers ) - 1 ] ) {
				$featureStr = $featureStr + "\n";
			}
		}
	}

	// Build list of input devices
	//
	string $devices[] = `pluginInfo -query -device $name`;
	if ( size( $devices ) > 0 ) {
		if ( $featureStr != "" ) {
			$featureStr = $featureStr + "\n\n";
			if(`about -mac`){
					$numHtCount += 2;
			}
		}
		$featureStr = $featureStr + "  Input Devices:\n";
		if(`about -mac`){
					$numHtCount += 1;
		}
		if(`about -mac`)
			$numHtCount += size( $devices );
			
		for ( $device in $devices ) {
			$featureStr = ( $featureStr + "      " + $device );
			if ( $device != $devices[ size( $devices ) - 1 ] ) {
				$featureStr = $featureStr + "\n";
			}
		}
	}

	// Build list of drag and drop behaviors
	//
	string $behaviors[] = `pluginInfo -query -dragAndDropBehavior $name`;
	if ( size( $behaviors ) > 0 ) {
		if ( $featureStr != "" ) {
			$featureStr = $featureStr + "\n\n";
		}
		$featureStr = $featureStr + "  Drag and Drop Behaviors:\n";
		for ( $behavior in $behaviors ) {
			$featureStr = ( $featureStr + "      " + $behavior );
			if ( $behavior != $behaviors[ size( $behaviors ) - 1 ] ) {
				$featureStr = $featureStr + "\n";
			}
		}
	}

	if(`about -mac`) {
		$numHtCount += 1;
	}

	if(`about -mac`) {
		int	$totalHeight = $numHtCount * 15;
		
		textField -edit -text $featureStr  $pluginInfoWinFeatures;
		textField -edit  -h $totalHeight  $pluginInfoWinFeatures;
		textField -edit  -ed false  $pluginInfoWinFeatures;
	} else {
		text -edit -label $featureStr $pluginInfoWinFeatures;
	}

	showWindow $winName;
}

global proc updatePluginDirectories()
//
//  Procedure Name:
//      updatePluginDirectories
//
//  Description:
//      rescans the plugin directory.
//
//  Return Value:
//      None
//
{
	global string $verifiedPluginPath[];
	global string $pluginWinParentWidget;
	global int $pluginListSize;
	global int $ignoreUpdateCallback;
	global string $winLyt;

	$pluginListSize = 0;

	waitCursor -state on;
	formLayout -e -vis 0 $winLyt;

	int $index = 1;
	for ( $path in $verifiedPluginPath ) {
		rescanDirectory( $path, $pluginWinParentWidget, $index );
		$index++;
	}
	for ($i=0; $i < $pluginListSize; ++$i) 
	{
		updatePluginUI( $i );
	}
	updatePluginList();

	formLayout -e -vis 1 $winLyt;
	waitCursor -state off;
}

global proc pluginWin()  
//
//  Procedure Name:
//      pluginWin
//
//  Description:
//      opens up a window which allows the user to load/unload plugins.
//
//  Return Value:
//      None
//	
{   
	global string $verifiedPluginPath[];
	global string $pluginManagerList[];
	global int    $isPluginPathVerified;
	global int	  $pluginWinCallbackInstalled = false;
	global string $pluginWindowName;
	global string $pluginWinParentWidget;


	if (!`window -exists $pluginWindowName`) { 
		// We have to build the window from scratch, so we will rescan
		// the directories
		//

		clear $verifiedPluginPath;
		$isPluginPathVerified = false;
		$pluginListSize = 0;
		clear $pluginManagerList;


		// Create the UI
		//
		if(`about -mac`) {
			window -t "Plug-in Manager" -in "Plug-ins"
			-menuBar true
			-retain -wh 450 411 $pluginWindowName;
		} else {
		window -t "Plug-in Manager" -in "Plug-ins"
			-menuBar true
			-retain -wh 384 411 $pluginWindowName;
		}
		menu -label "Help" -helpMenu true;
			menuItem -label "Help on Plug-in Manager..."
				-enableCommandRepeat false
				-command "showHelp PluginWindow";
			
		// This form layout becomes the default layout for the window
		//
		formLayout windowLyt; 
			tabLayout -cr true -scr true -tv false scrollLyt; 
		        // The following layout will get deleted a rebuilt if new
		        // paths or plugins are loaded
		        //
				$pluginWinParentWidget = `columnLayout -adj true parentLyt`;
		        setParent ..; 
			setParent ..;
		    $browseBtn = `button -l "Browse" browseBtn`; 
		    $refreshBtn = `button -l "Refresh" refreshBtn`; 
		    $closeBtn = `button -l "Close" closeBtn`; 

		// Arrange controls in the form
		//
		// Attach button 
		formLayout -e
            -af $browseBtn "left" 5
			-ap $browseBtn "right" 3 33 
			-af $browseBtn "bottom" 5
			-an $browseBtn "top"

            -ac $refreshBtn "left" 1 $browseBtn
			-ap $refreshBtn "right" 1 63
			-af $refreshBtn "bottom" 5
			-an $refreshBtn "top"

			-ac $closeBtn "left" 2 $refreshBtn
			-af $closeBtn "right" 5
			-af $closeBtn "bottom" 5
			-an $closeBtn "top"
			windowLyt;

		// Attach scroll layout 
		formLayout -e 
			-af scrollLyt "top" 0 
			-af scrollLyt "left" 0 
            -af scrollLyt "right" 0 
			-ac scrollLyt "bottom" 5 $browseBtn 
			windowLyt;

		button -edit -command "browsePlugin" $browseBtn;
		button -edit -command "updatePluginDirectories" $refreshBtn;
		button -edit -command "window -e -vis 0 pluginManagerWindow" $closeBtn;

		setParent ..;

		// Tell updatePluginWin the check path and build UI
		//
		$isPluginPathVerified = false;

		// Add a callback to the plugin database so that the window gets
		// updated
		//
		if ( !$pluginWinCallbackInstalled ) {
			pluginInfo -changedCommand "updatePluginCallback();";
			$pluginWinCallbackInstalled = true;
		}
	}

	// Now build and show the contents
	updatePluginWin();
	showWindow $pluginWindowName;
} 

global proc unloadPluginWithCheck( string $path )
//
//  Description:
//      unload the plugin, or warn if it is being used
//
{ 
	global string $pluginWindowName;

	if(`about -mac`)
	{
		string $result;
		$result = `confirmDialog -ma left -title "Plug-in Warning"
			-message ( 
					"Unloading of plug-ins during a session\n"+
					"is not permitted on this platform.\n" +
					"To run Maya without a particular plug-in\n"+
					"loaded, make sure \"auto load\" \n"+
					"is unchecked and restart Maya." )
			-button "OK" -defaultButton "OK"
			-parent $pluginWindowName`;

			// This will turn the check box back on
			updatePluginList();
			return;
	}

	if ( `pluginInfo -query -unloadOk $path` ) {
		waitCursor -state on;
		unloadPlugin `pluginInfo -query -name $path`; 
		waitCursor -state off;
	} else {
		string $serviceList[] = `pluginInfo -query -serviceDescriptions $path`;
		string $services = "";
		for ( $service in $serviceList  ){
			$services = ( $services + "- " + $service + "\n" );
		}
		string $pluginName = `pluginInfo -query -name $path`;
		int $isUnlimitedPlugin = false;
		string $result;
		if(!strcmp($pluginName,"Fur") || !strcmp($pluginName,"CpClothPlugin") || !strcmp($pluginName,"mayalive"))
		{
			$isUnlimitedPlugin = true;
			$result = `confirmDialog -ma left -title "Plug-in In Use Warning"
			-message ( "Services provided by this plug-in are\n" + 
					   "currently in use.\n\n" +
					   "Forcefully unloading this plug-in opens\n" +
					   "the \"File->Save Scene As...\" dialog box to save this scene\n"+
					   "and creates a new empty scene.\n\n"  +
  				        "The following services are in use:\n" + $services ) 
			-button "Force" -button "Cancel" -defaultButton "Cancel"
			-cancelButton "Cancel" -dismissString "Cancel"
			-parent $pluginWindowName`;
		}
		else
		{
			$result = `confirmDialog -ma left -title "Plug-in In Use Warning"
				-message ( "Services provided by this plug-in are\n" + 
						   "currently in use.\n\n" +
						   "Unloading this plug-in may cause problems\n" +
						   "with your scene.  To unload this plug-in\n" +
						   "safely, remove all objects that reference\n" +
					       "the plug-in and flush the undo queue either\n" +
						   "with \"file -new\" or the \"flushUndo\" command.\n\n" +
					       "The following services are in use:\n" + $services ) 
				-button "Force" -button "Cancel" -defaultButton "Cancel"
				-cancelButton "Cancel" -dismissString "Cancel"
				-parent $pluginWindowName`;
		}
		if ( $result == "Force" ) {
			if( $isUnlimitedPlugin == true)
			{
                SaveSceneAs;
                waitCursor -state on;
                if ( !strcmp($pluginName,"mayalive") ) {
					global int $liveUnloading;
                	$liveUnloading = 1;
					mlResetAllDeletable;
					file -f -new;
                 	evalDeferred -lp "unloadPlugin -f mayalive";
                }
                else {
					file -f -new;
                    unloadPlugin -force `pluginInfo -query -name $path`;
                }       
                waitCursor -state off;			
			}
			else
			{
				waitCursor -state on;
				unloadPlugin -force `pluginInfo -query -name $path`;
				waitCursor -state off;
			}
		}
		else {
			// This will turn the check box back on
			updatePluginList();
		}
	}
}
