// 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:  December 8/2000
//
// Description:
//
//		This file contains the procedures which create and manipulate the
//		Hypershade panel UI.
//												

global int $gRenderCreateBarIconsAndTextMinWidth = 70;
global int $gRenderCreateBarIconsAndTextMaxWidth = 342;
global string $gPreviousFilterBox = "";
global string $gPreviousFilterButton = "";
global int $gButtonsColumnWidth = 26;

// This script is sourced at startup by initScriptedPanels.mel. We will take
// this opportunity to ensure that the option vars related to node creation (ie
// with/without placement, as normal/projection/stencil...) exist.
//
initCreateNodeOptionVars();

// Initialize the optionVar which specifies which tab sections are to be shown,
// if it does not already exist.
//
if (!`optionVar -exists hyperShadePanelTabSectionsShown`)
{
	optionVar 
		-stringValue 
			hyperShadePanelTabSectionsShown 
			"showTopAndBottomTabs";
}

// Initialize the optionVar which specifies whether the create bar is to be 
// shown, if the optionVar does not already exist.
//
if (!`optionVar -exists hyperShadePanelCreateBarShown`)
{
	optionVar -intValue hyperShadePanelCreateBarShown true;
}

// Initialize the optionVar which specified how wide the create bar should be
// when in icons and text mode, if the optionVar does not already exist.
//
if (!`optionVar -exists hyperShadePanelCreateBarIconsAndTextWidth`)
{
	optionVar 
		-intValue 
			hyperShadePanelCreateBarIconsAndTextWidth 172;
}

// Initialize the optionVar which specifies whether to clear before graphing,
// if it does not already exist.
//
if (!`optionVar -exists hsClearBeforeGraphing`)
{
	optionVar -intValue hsClearBeforeGraphing true;
}

if (!`scriptedPanelType -exists hyperShadePanel`) 
//
// If you change this, you must also change the one in 
// initScriptedPanels.mel
//
{
	//
	//  Define the callbacks for the shader editor panel.
	//
	scriptedPanelType
		-createCallback		"createHyperShadePanel" 
		-initCallback		"initHyperShadePanel"
		-addCallback		"addHyperShadePanel"
		-removeCallback		"removeHyperShadePanel"
		-saveStateCallback	"saveStateHyperShadePanel"
		-deleteCallback		"deleteHyperShadePanel"
		-unique true
		hyperShadePanel;

}

global proc string hyperShadePanelName()
//
// Description:
//	This procedure returns the name of the panel containing the 
//	shader editor.
//	If there is no shader editor in existence, the behaviour of this
//	procedure is undefined.
//
//	ASSUMPTION: This procedure assumes there is a maximum of one 
//	shader editor open. 
//
{
	string $hyperShadePanels[] = 
		`getPanel -scriptType "hyperShadePanel"`;
	
	return $hyperShadePanels[0];
}

// ---------------------------------------------------------------------------
// 	Registry to record tabs and their associated libraryUI, graphUI and
// 	collectionUI components.
// 

global string $gHyperShadePanelLookupTable[];
global int $gHyperShadePanelLookupTableCreated = false;

proc createHyperShadePanelLookupTable()
{
	//
	// Description:
	//	This procedure initializes the string array
	//	$gHyperShadePanelLookupTable[] for use as a lookup table. The lookup
	//	table will contain information about the tabs of the hypershade panel,
	//	and the UI contained within them.
	//

	global string $gHyperShadePanelLookupTable[];
	global int $gHyperShadePanelLookupTableCreated;

	if (!$gHyperShadePanelLookupTableCreated)
	{
		string $columns[];

		$columns[0] = "tab";
		$columns[1] = "type";
		$columns[2] = "componentName";
		$columns[3] = "optionVar";
		$columns[4] = "tabLayout";

		lookupTable($gHyperShadePanelLookupTable, $columns);
		$gHyperShadePanelLookupTableCreated = true;
	}
}

proc registerTab(
	string $tab,
	string $type,
	string $libraryUI,
	string $optionVar,
    string $tabLayout)
{
	//
	// Description:
	//	This procedure enters information about the specified tab into the
	//	lookup table that contains information about all of the tabs in the
	//	hypershade panel.
	//

	if (	($type != "disk") 
		&& 	($type != "graph") 
		&& 	($type != "protected graph") 
		&& 	($type != "scene"))
	{
		error
			-showLineNumber true
			("Attempted to register unrecognized tab type.");
	}

	global string $gHyperShadePanelLookupTable[];
	string $row[];

	$row[0] = $tab;
	$row[1] = $type;
	$row[2] = $libraryUI;
	$row[3] = $optionVar;
	$row[4] = $tabLayout;

	lookupTableAddRow($gHyperShadePanelLookupTable, $row);
}

proc unregisterTab(
	string $tab)
{
	//
	// Description:
	//	This procedure removes information about the specified tab from the
	//	lookup table.
	//

	global string $gHyperShadePanelLookupTable[];

	lookupTableRemoveRow(
		$gHyperShadePanelLookupTable,
		"tab",
		$tab);
}

proc string lookupComponentName(
	string $tab)
{
	//
	// Description:
	//	This procedure uses the lookup table to look up the name of the
	//	UI component (ie libraryUI, collectionUI or graphUI) associated with 
	// 	the specified tab.
	//
	// Returns: 
	//	The name of the UI component associated with the specified tab.
	//

	global string $gHyperShadePanelLookupTable[];

	return lookupTableLookup(
		$gHyperShadePanelLookupTable,
		"tab",
		$tab,
		"componentName");
}

proc string lookupTabLayoutName(
    string $componentName)
{
    //
    // Description:
    //  This procedure uses the lookup table to look up the name of the
    //  tabLayout (firstPaneTabs or secondPaneTabs) associated with 
    //  the specified componentName.
    //

	global string $gHyperShadePanelLookupTable[];

	return lookupTableLookup(
		$gHyperShadePanelLookupTable,
		"componentName",
		$componentName,
		"tabLayout");
}

proc updateComponentNameInTabRegistry(
	string $tab, string $componentName)
{
	//
	// Description:
	//	This procedure edit the lookup table to update the 
    //  componentName for the specified tab.
	//
	//

	global string $gHyperShadePanelLookupTable[];

	lookupTableEdit(
		$gHyperShadePanelLookupTable,
		"tab",
		$tab,
		"componentName",
        $componentName);
}

proc string lookupTabOptionVar(
	string $tab)
{
	//
	// Description:
	//	This procedure uses the lookup table to look up the name of the
	//	optionVar which stores information about the specified tab. The
	//	information stored in these optionVars is used to recreate tabs with
	//	the same characteristics in subsequent Maya sessions, and also to
	//	recreate tabs when the panel is torn off into a window.
	//
	// Returns: 
	//	The name of the optionVar associated with the specified tab.
	//

	global string $gHyperShadePanelLookupTable[];

	return lookupTableLookup(
		$gHyperShadePanelLookupTable,
		"tab",
		$tab,
		"optionVar");
}

proc string lookupOptionVarTab(
	string $optionVar)
{
	//
	// Description:
	//	This procedure uses the lookup table to look up the name of the tab
	//	associated with the specified optionVar.
	//
	// Returns: 
	//	The name of the tab associated with the specified optionVar.
	//

	global string $gHyperShadePanelLookupTable[];

	return lookupTableLookup(
		$gHyperShadePanelLookupTable,
		"optionVar",
		$optionVar,
		"tab");
}

proc string lookupTabType(
	string $tab)
{
	//
	// Description:
	//	This procedure uses the lookup table to look up the type (disk, scene,
	//	graph, protected graph) of the specified tab.
	//
	// Returns: 
	//	The type of the specified tab.
	//

    if ($tab == "")
    {
        return "";
    }

	global string $gHyperShadePanelLookupTable[];

	return lookupTableLookup(
		$gHyperShadePanelLookupTable,
		"tab",
		$tab,
		"type");
}

proc int isDiskTab(
	string $tab)
{
	//
	// Description:
	//	This procedure is used to query whether the specified tab is a disk
	//	tab.
	//
	// Returns: 
	//	True if the tab is a disk tab, false if not.
	//

	global string $gHyperShadePanelLookupTable[];

	return (lookupTabType($tab) == "disk");
}

proc int isGraphTab(
	string $tab)
{
	//
	// Description:
	//	This procedure is used to query whether the specified tab is a graph
	//	tab.
	//
	// Returns: 
	//	True if the tab is a graph tab or protected graph tab, false if not.
	//

	global string $gHyperShadePanelLookupTable[];

	string $type = lookupTabType($tab);

	return (($type == "graph") || ($type == "protected graph"));
}

proc int isSceneTab(
	string $tab)
{
	//
	// Description:
	//	This procedure is used to query whether the specified tab is a scene
	//	tab.
	//
	// Returns: 
	//	True if the tab is a scene tab, false if not.
	//
    if ($tab == "")
    {
        return false;
    }

	global string $gHyperShadePanelLookupTable[];

	return (lookupTabType($tab) == "scene");
}

// ---------------------------------------------------------------------------
// 	Procedures to find out information about the current tab
// 
proc int activePaneIndex(
	string $panel)
{
	//
	// Description:
	//	This procedure determines what pane within the hypershade panel is the
	//	active pane.
	//
	// Returns: 
	//	The index of the active pane within the paneLayout called
	//	paneArrangement.
	//

	setParent $panel;
	string $paneLayout = `setParent paneArrangement`;

	// Determine what tab layout is currently active, and which tab layout the
	// tab is being moved to.
	//
	int $activePaneIndex;

	$activePaneIndex = `paneLayout -query -activePaneIndex $paneLayout`;

	return $activePaneIndex;
}

proc string activeTabLayout(
	string $panel)
{
	//
	// Description:
	//	This procedure determines the name of the tab layout in the active
	//	pane of the hypershade panel.
	//
	// Returns: 
	//	The name of the tab layout in the active pane of the hypershade panel.
	//

	// Remember the current parent so we can revert to it when we're done here.
	//
	string $oldParent = `setParent -query`;
	string $oldMenuParent = `setParent -menu -query`;

	setParent $panel;

	string $activeTabLayout; 

	string $tabSectionsShown = 
		`optionVar -query hyperShadePanelTabSectionsShown`;
	
	if ($tabSectionsShown == "showTopAndBottomTabs")
	{
		$activeTabLayout = `paneLayout -query -activePane paneArrangement`; 
	}
	else if ($tabSectionsShown == "showTopTabsOnly")
	{
		$activeTabLayout = "firstPaneTabs";
	}
	else // ($tabSectionsShown == "showBottomTabsOnly")
	{
		$activeTabLayout = "secondPaneTabs";
	}

	$activeTabLayout = `setParent $activeTabLayout`;

	// Revert to the original parent.
	//
	if ($oldParent != "NONE") setParent $oldParent;
	if ($oldMenuParent != "NONE") setParent -menu $oldMenuParent;

	return $activeTabLayout;
}

proc string activeTab(
	string $panel)
{
	//
	// Description:
	//	This procedure determines the name of the frontmost tab in the tab 
	//	layout in the active pane of the hypershade panel.
	//
	// Returns: 
	//	The name of the tab.
	//

	// Remember the current parent so we can revert to it when we're done here.
	//
	string $oldParent = `setParent -query`;
	string $oldMenuParent = `setParent -menu -query`;

	string $activeTabLayout = activeTabLayout($panel);

	setParent $activeTabLayout;
	
	string $activeTab;
    if (size(`tabLayout -q -childArray $activeTabLayout`) == 0)
    {
        // No tabs are under this tabLayout.  
        //
        $activeTab = ""; 
    }
    else
    {
	    $activeTab = `tabLayout -query -selectTab $activeTabLayout`;
	    $activeTab = `setParent $activeTab`;
    }

	// Revert to the original parent.
	//
	if ($oldParent != "NONE") setParent $oldParent;
	if ($oldMenuParent != "NONE") setParent -menu $oldMenuParent;

	return $activeTab;
}

proc string activeTabIndex(
	string $panel)
{
	//
	// Description:
	//	This procedure determines the index of the frontmost tab in the tab 
	//	layout in the active pane of the hypershade panel.
	//
	// Returns: 
	//	The index of the tab within the active tab layout.
	//

	string $activeTabLayout = activeTabLayout($panel);
	
	int $activeTabIndex;
	$activeTabIndex = `tabLayout -query -selectTabIndex $activeTabLayout`;

	return $activeTabIndex;
}

proc string activeTabLabel(
	string $panel)
{
	//
	// Description:
	//	This procedure determines the label of the frontmost tab in the tab 
	//	layout in the active pane of the hypershade panel.
	//
	// Returns: 
	//	The label of the tab.
	//

	// Remember the current parent so we can revert to it when we're done here.
	//
	string $oldParent = `setParent -query`;
	string $oldMenuParent = `setParent -menu -query`;

	setParent $panel;
	string $activeTabLayout = activeTabLayout($panel);
	int $activeTabIndex = activeTabIndex($panel);

	string $tabLabelArray[];
	$tabLabelArray = `tabLayout -query -tabLabel $activeTabLayout`;

	// Revert to the original parent.
	//
	if ($oldParent != "NONE") setParent $oldParent;
	if ($oldMenuParent != "NONE") setParent -menu $oldMenuParent;

	return $tabLabelArray[$activeTabIndex - 1];
}


proc string workAreaTab()
{
	//
	// Description:
	//	This procedure determines the name of the graph tab which is used as
	//	the designated work area (the tab to which graphs should be drawn if no
	//	other graph tab is a more obvious choice).
	//	The designated work area tab should be the only protected graph tab in
	//	the hypershade panel.
	//
	// Returns: 
	//	The name of the designated work area tab.
	//

	string $workAreaTab;
	$workAreaTab = `optionVar -q hyperShadePanelWorkAreaTab`;

	if ($workAreaTab == "")
	{
		error 
			-showLineNumber true 
			("Designated Work Area graph tab not found!");
	}

	return $workAreaTab;
}

proc int isGraphTabVisible(
	string $panel)
{
	//
	// Description:
	//	This procedure determines if a graph tab (work area) is visible within
	//	either of the two tab sections of the hypershade panel.
	//
	// Returns: 
	//	True if at least one of the two tab sections has a graph tab as the
	//	frontmost tab.
	//	False otherwise.
	//

	string $saveParent = `setParent -query`;
	string $saveParentMenu = `setParent -query -menu`;
	int    $result = false;

	// Determine the names of the tabs in the two tab sections
	//
	setParent $panel;
	$tabLayout = `setParent firstPaneTabs`;
	string $frontFirstPaneTab = 
		($tabLayout + "|" +`tabLayout -query -selectTab $tabLayout`);

	setParent $panel;
	$tabLayout = `setParent secondPaneTabs`;
	string $frontSecondPaneTab = 
		($tabLayout + "|" +`tabLayout -query -selectTab $tabLayout`);
	
	// Determine if a graph tab is currently frontmost in either tab section
	//
	if (	isGraphTab($frontFirstPaneTab)
		|| 	isGraphTab($frontSecondPaneTab))
	{
		$result = true;
	}
	else
	{
		$result =  false;
	}

	setParent $saveParent;
	setParent -menu $saveParentMenu;

	return $result;
}

proc string targetGraphTab(
	string $panel)
{
	//
	// Description:
	//	This procedure is called when the user is performing an action which
	//	should affect a graph tab (work area). For example, if the user has
	//	pressed the Show Up and Downstream Connections button, the resulting
	//	graph must be displayed in a graph tab.
	//	This procedure determines which graph tab would be the most appropriate
	//	graph tab in which to perform the action. The decision is made as
	//	follows: 
	//		If there is only one graph tab visible, it will be the target.
	//		Else if there are two graph tabs visible, the one in the active pane
	//		will be the target.
	//		Else the default work area tab will be the target.
	//
	// Returns: 
	//	The name of the graph tab which is the most appropriate target for an
	//	operation affecting a graph tab at the time this procedure is called.
	//

	// Determine which tab layout is currently active
	//
	int 	$activePaneIndex = activePaneIndex($panel);
	string 	$activeTabLayout;
	string 	$inactiveTabLayout;

	if ($activePaneIndex == 1) 
	{
		$activeTabLayout = "firstPaneTabs";
		$inactiveTabLayout = "secondPaneTabs";
	}
	else 
	{
		$inactiveTabLayout = "firstPaneTabs";
		$activeTabLayout = "secondPaneTabs";
	}

	// Determine the names of the tabs in the active and inactive tab sections
	//
	string $targetTab;

	setParent $panel;
	$tabLayout = `setParent $activeTabLayout`;
	string $frontActiveTab = 
		($tabLayout + "|" +`tabLayout -query -selectTab $tabLayout`);

	setParent $panel;
	$tabLayout = `setParent $inactiveTabLayout`;
	string $frontInactiveTab = 
		($tabLayout + "|" +`tabLayout -query -selectTab $tabLayout`);
	
	// Decide which graph tab should be the target 
	//
	if (isGraphTab($frontActiveTab))
	{
		// The frontmost tab in the active tab section is a graph tab.
		// Therefore we will consider it to be the target tab.
		//
		$targetTab = $frontActiveTab;
	}
	else if (isGraphTab($frontInactiveTab))
	{
		// The frontmost tab in the active tab section is not a graph tab, but
		// the frontmost tab in the inactive tab section is. We will consider
		// the graph tab in the inactive tab section to be the target tab.
		//
		$targetTab = $frontInactiveTab;
	}
	else
	{
		// Neither tab section has a graph tab frontmost. Therefore we will
		// consider the target tab to be the default work area tab.
		//
		$targetTab = workAreaTab();
	}

	return $targetTab;
}

proc string renderCreateBarUIName(
	string $panel)
{
	//
	// Description:
	//	This procedure determines and returns the name of the top level
	//	formLayout of the renderCreateBarUI. The name can then be used to call
	//	renderCreateBarUI procedures.
	//
	// Returns: 
	//	The name of the layout.
	//

	// Remember the current parent so we can revert to it when we're done here.
	//
	string $oldParent = `setParent -query`;
	string $oldMenuParent = `setParent -menu -query`;

	setParent $panel;
	string $createBarForm = hyperShadeCreateBarForm($panel); 
	string $childArray[] = `formLayout -query -childArray $createBarForm`;
	string $renderCreateBarUIName = $childArray[0];


	// Revert to the original parent.
	//
	if ($oldParent != "NONE") setParent $oldParent;
	if ($oldMenuParent != "NONE") setParent -menu $oldMenuParent;

	return $renderCreateBarUIName;
}

// ---------------------------------------------------------------------------
// 	Procedures to save/access information in option vars about the tab 
//	layouts and settings of individual tabs
// 
proc string tabLabel(
	string $tab)
{
	//
	// Description:
	//	This procedure determines the label of the specified tab.
	//
	// Returns: 
	//	The label of the specified tab.
	//

	// Remember the current parent so we can revert to it when we're done here.
	//
	string $oldParent = `setParent -query`;
	string $oldMenuParent = `setParent -menu -query`;

	string $tabLabel = "";

	setParent $tab;
	setParent ..;
	string $tabLayout = `setParent -query`;
	string $tabLabelArray[] = `tabLayout -query -tabLabel $tabLayout`;
	string $tabArray[] = `tabLayout -query -childArray $tabLayout`;

	int $i;

	for ($i = 0; ($i < size($tabArray)) && ($tabLabel == ""); $i++)
	{
		setParent $tabLayout;
		$tabArray[$i] = `setParent $tabArray[$i]`;

		if ($tabArray[$i] == $tab)
		{
			$tabLabel = $tabLabelArray[$i];
		}
	}

	// Revert to the original parent.
	//
	if ($oldParent != "NONE") setParent $oldParent;
	if ($oldMenuParent != "NONE") setParent -menu $oldMenuParent;

	return $tabLabel;
}

proc string generateUniqueTabOptionVarName()
{
	//
	// Description:
	//	This procedure is used to create a unique name for an optionVar in
	//	which information about a tab will be stored.
	//
	// Returns: 
	//	A unique name for an optionVar.
	//

	int $i = 1;
	string $optionVarName;

	do
	{
		$optionVarName = ("hyperShadeTab" + $i);
		$i++;
	}
	while (`optionVar -exists $optionVarName`);

	return $optionVarName;
}

proc updateTabOptionVar(
	string $optionVar,
	string $tab)
{
	//
	// Description:
	//	This procedure is called from updateTabOptionVar() and from
	//	createTabOptionVar(). It encapsulates some shared functionality of the
	//	two other procedures. 
	//	This procedure generates a unique name for a tab option var if no name
	//	is provided in $optionVar. This procedure looks up the type of the tab
	//	in the lookup table if the type is not specified in $type.
	//	This procedure then gathers all of the information about the specified
	//	tab which needs to be stored in the optionVar, and saves that
	//	information in the optionVar in a known format.
	//	

	if ($optionVar == "")
	{
		// No optionVar name was specified, so we create a new one.
		//
		$optionVar = generateUniqueTabOptionVarName();
	}

	//
	// Now we gather all of the information we need to store about the tab.
	//

	string $tabLabel = tabLabel($tab);
	string $type = lookupTabType($tab);
	string $component = lookupComponentName($tab);

	optionVar -intValue $optionVar 1;
	optionVar -stringValue ($optionVar + "Label") $tabLabel;
	optionVar -stringValue ($optionVar + "Type") $type;

	if ($type == "disk")
	{
		optionVar 
			-stringValue ($optionVar + "DirectoriesVisorName") 
			`libraryUIDirectoriesVisor($component)`;
		optionVar 
			-stringValue ($optionVar + "FilesVisorName") 
			`libraryUIFilesVisor($component)`;
		optionVar 
			-stringValue ($optionVar + "RootDirectory") 
			`libraryUIRootDirectory($component)`;
		optionVar 
			-stringValue ($optionVar + "CurrentDirectory") 
			`libraryUICurrentDirectory($component)`;
		optionVar 
			-intValue ($optionVar + "DirectoriesShown") 
			`libraryUIDirectoriesShown($component)`;
		optionVar 
			-intValue ($optionVar + "FilesShown") 
			`libraryUIFilesShown($component)`;
	}
	else if (($type == "graph") || ($type == "protected graph"))
	{
		optionVar 
			-stringValue ($optionVar + "HypershadeName") 
			`graphUIHypershadeName($component)`;
	}
	else if ($type == "scene")
	{
		optionVar 
			-stringValue ($optionVar + "HypershadeName") 
			`collectionUIHypershadeName($component)`;
		optionVar 
			-stringValue ($optionVar + "Filter") 
			`collectionUIFilter($component)`;
	}
	else
	{
		error
			-showLineNumber true
			("Unexpected tab type: " + $type);
	}
}

proc setTabLabel(
	string $tab,
	string $label)
{
	//
	// Description:
	//	This procedure sets the label of the specified tab.
	//

	// Remember the current parent so we can revert to it when we're done here.
	//
	string $oldParent = `setParent -query`;
	string $oldMenuParent = `setParent -menu -query`;

	setParent $tab;
	setParent ..;
	string $tabLayout = `setParent -query`;
	string $tabLabelArray[] = `tabLayout -query -tabLabel $tabLayout`;
	string $tabArray[] = `tabLayout -query -childArray $tabLayout`;

	int $i;
	string $shortTabName;
	int $found = false;

	for ($i = 0; ($i < size($tabArray)) && (!$found); $i++)
	{
		setParent $tabLayout;
		$shortTabName = $tabArray[$i];
		$tabArray[$i] = `setParent $tabArray[$i]`;

		if ($tabArray[$i] == $tab)
		{
			$found = true;
		}
	}

	if ($found)
	{
		tabLayout
			-edit
			-tabLabel $shortTabName $label
			$tabLayout;
	}

	// Save the new tab label so that it will be remembered the next time the
	// visor is opened.
	//
	string $optionVar = lookupTabOptionVar($tab);
	updateTabOptionVar($optionVar, $tab);

	// Revert to the original parent.
	//
	if ($oldParent != "NONE") setParent $oldParent;
	if ($oldMenuParent != "NONE") setParent -menu $oldMenuParent;
}

proc string tabTypeFromOptionVar(
	string $optionVar)
{
	//
	// Description:
	//	This procedure retrieves the type of the tab whose information is
	//	stored in the specified optionVar.
	//
	// Returns: 
	//	The type of the tab.
	//

	string $valueArray[];
	$valueArray = `optionVar -query $optionVar`;

	return $valueArray[0];
}

proc string tabLabelFromOptionVar(
	string $optionVar)
{
	//
	// Description:
	//	This procedure retrieves the label of the tab whose information is
	//	stored in the specified optionVar.
	//
	// Returns: 
	//	The label of the tab.
	//

	string $valueArray[];
	$valueArray = `optionVar -query $optionVar`;

	return $valueArray[1];
}

proc deleteOptionVar(
	string $optionVar)
{
	//
	// Description:
	//	This method is called from deleteTabOptionVar() or from
	//	deleteUnusedOptionVars(). 
	//	This method deletes the specified optionVar and the optionVars related
	//	to it.
	//	The specified optionVar actually serves no purpose except to act as a
	//	prefic for the related optionVars.
	//

	optionVar -remove $optionVar;
	optionVar -remove ($optionVar + "Label");
	optionVar -remove ($optionVar + "Type");
	optionVar -remove ($optionVar + "DirectoriesVisorName");
	optionVar -remove ($optionVar + "FilesVisorName");
	optionVar -remove ($optionVar + "RootDirectory"); 
	optionVar -remove ($optionVar + "CurrentDirectory"); 
	optionVar -remove ($optionVar + "DirectoriesShown");
	optionVar -remove ($optionVar + "FilesShown"); 
	optionVar -remove ($optionVar + "HypershadeName");
	optionVar -remove ($optionVar + "Filter");
}

proc deleteTabOptionVar(
	string $tab)
{
	//
	// Description:
	//	This procedure deletes the optionVar associated with the specified tab.
	//

	string $optionVar = lookupTabOptionVar($tab);
	deleteOptionVar($optionVar);
}

proc deleteUnusedTabOptionVars(
	string $panel)
{
	//
	// Description:
	//	This procedure is called the first time hypershade is opened each
	//	session.
	//	This procedure deletes all optionVars whose names indicate that they
	//	contain information about hypershade panel tabs, but which are not
	//	being used for some reason. This is done so that the user's userPrefs
	//	does not fill up with unused optionVars.
	//

	int $i;

	for ($i = 0; $i < 100; $i++)
	{
		string $optionVar = ("hyperShadeTab" + $i);
		if (`optionVar -exists $optionVar`)
		{
			if (lookupOptionVarTab($optionVar) == "")
			{
				deleteOptionVar($optionVar);
			}
		}
	}
}

proc updateTabLayoutOptionVar(
	string $panel,
	string $tabLayout)
{
	//
	// Description:
	//	This procedure should be called whenever a change is made to the tab
	//	layouts in the hypershade panel which we want to save to an optionVar
	//	in order to be able to recreate the same tab layout structure at a
	//	later time. For example, we would want to call this procedure if we had
	//	moved a tab left or right within the tab layout.
	//	This procedure writes out an option var which names all of the option
	//	vars describing properties of the tabs in the specified tab layout. 
	//	The tab option vars are named in order from left to right.
	//

	string $oldParent = `setParent -query`;
	setParent $panel;

	// Get the short name of the tab layout, since the caller may have passed
	// in the full path
	//
	string $tabLayoutPathTokens[];
	tokenize($tabLayout, "|", $tabLayoutPathTokens);
	$tabLayout = $tabLayoutPathTokens[size($tabLayoutPathTokens) - 1];

	string $tabLayoutOptionVar;

	if ($tabLayout == "firstPaneTabs")
	{
		$tabLayoutOptionVar = "hyperShadeFirstPaneTabs";
	}
	else if ($tabLayout == "secondPaneTabs")
	{
		$tabLayoutOptionVar = "hyperShadeSecondPaneTabs";
	}
	else
	{
		error
			-showLineNumber true
			("Unexpected tab layout name specified: " + $tabLayout + ".");
	}

	// Delete the existing optionVar for the tabs in this pane, because we are
	// going to rebuild it.
	//
	optionVar -remove $tabLayoutOptionVar;

    if (size(`tabLayout -q -childArray $tabLayout`) == 0)
    {
        // The tabLayout has no tabs in it.  Nothing to do.
        // 
	    if ($oldParent != "NONE") setParent $oldParent;
        return;
    }


	string $tabArray[] = `tabLayout -query -childArray $tabLayout`;

	//
	// Now that we have a list of the layouts associated with the tabs, we can
	// lookup the name of the optionVar associated with each and store it in
	// the optionVar which describes the ordering of the tabs.
	//

	string $tab;
	string $tabOptionVar;

	// For each tab in the tabLayout of the pane
	//
	for ($i = 0; $i < size($tabArray); $i++)
	{
		$tab = $tabArray[$i];
		setParent $panel;
		$tab = `setParent $tab`;

		// Lookup the optionVar which describes this tab
		//
		$tabOptionVar = lookupTabOptionVar($tab);

		if ($tabOptionVar == "")
		{
			global string $gHyperShadePanelLookupTable[];
			lookupTablePrint($gHyperShadePanelLookupTable);

			error
				-showLineNumber true
				("Expected lookup table to contain "
					+ "non-empty tab option var name.");
		}

		// Append the name of the optionVar to the optionVar describing the
		// tabs in this pane
		//
		optionVar -stringValueAppend $tabLayoutOptionVar $tabOptionVar;
	}

	if ($oldParent != "NONE") setParent $oldParent;
}

// ---------------------------------------------------------------------------
// 	UI creation procedures
// 

proc string createGraphTab(
	string $panel,
	string $tabLayout,
	string $tabLabel,
	int $protected)
{
	//
	// Description:
	//	This procedure is called when the user creates a new graph tab, or when
	//	the default tabs are being created (ie the first time the user uses the
	//	hypershade panel or as a result of a revert to default tabs). 
	//	This procedure creates a graph tab.
	//	If the $protected argument is true, this tab will be flagged as a
	//	protected graph. A protected graph is one which cannot be removed from
	//	the hypershade panel or moved from one tab layout to the other within
	//	the hypershade panel. 
	//
	// Returns: 
	//	The name of the newly created tab.
	//

	setParent $panel;
	setParent $tabLayout;
		string $tab = `formLayout`;
			// Create the graph UI. The second parameter is blank
			// because we want to have a new hypershade created,
			// rather than specifying an existing one to be used.
			//
			string $graphUI = 
				graphUI(
					$tab, 
					""); // hypershadeName
		setParent ..; // from $tab
	setParent ..; // from $tabLayout

	// Set the label on the tab
	//
	tabLayout
		-edit
		-tabLabel $tab $tabLabel
		$tabLayout;

	// Configure the graphUI
	//
	graphUISetPopupMenuScript(
		$graphUI, 
		("hyperShadePanelSceneAndGraphTabPopupMenu " + $panel));

	string $hypershadeName = graphUIHypershadeName($graphUI);

    // Create a callback to set the active pane when mouse is pressed.
    //
	hyperGraph -edit
		-focusCommand 
			("hyperShadePanelSetActiveTabLayout "
				+ $panel
				+ " "
				+ $tabLayout
                + " false")
		$hypershadeName;
	
	// Specify the callback to be called when the user clicks on the menu arrow
	// on the bottom of a node
	//
	hyperGraph 
		-edit
		-nodeMenuCommand 
			("hyperShadePanelSceneAndGraphTabPopupMenu " + $panel)
		$hypershadeName;

	string $optionVar = generateUniqueTabOptionVarName();
	if ($protected)
	{
		// A protected graph is one which cannot be removed or moved to the
		// other tab layout. It *can* be moved left and right within the tab
		// layout it is in.
		//
		registerTab($tab, "protected graph", $graphUI, $optionVar, $tabLayout);
	}
	else
	{
		registerTab($tab, "graph", $graphUI, $optionVar, $tabLayout);
	}
	updateTabOptionVar($optionVar, $tab);

	// Update the tab layout option var now that a new tab has been added
	//
	updateTabLayoutOptionVar($panel, $tabLayout);

	// If the graph tab is protected, it should be considered the designated
	// Work Area tab.
	//
	// ASSUMPTION:
	// We assume there will only ever be one protected tab, since we do not
	// allow the user to create one. If additional protected graph tabs are
	// created in the future, this code will need to change.
	//
	if ($protected)
	{
		optionVar -stringValue "hyperShadePanelWorkAreaTab" $tab;
	}

	// Return the name of the tab which was created.
	//
	return $tab;
}

proc string recreateGraphTab(
	string $panel,
	string $tabLayout,
	string $optionVar, 
	int $reuseEditors,
	int $protected)
{
	//
	// Description:
	//	This procedure is called when a graph tab is being recreated from an
	//	optionVar.
	//	This procedure creates a graph tab using the information stored in the
	//	specified optionVar.
	//	If the $protected argument is true, this tab will be flagged as a
	//	protected graph. A protected graph is one which cannot be removed from
	//	the hypershade panel or moved from one tab layout to the other within
	//	the hypershade panel. 
	//
	// Returns: 
	//	The name of the newly created tab.
	//

	string $tabLabel 
		= `optionVar -query ($optionVar + "Label")`;
	string $hypershadeName;

	if ($reuseEditors)
	{
		$hypershadeName = `optionVar -query ($optionVar + "HypershadeName")`;
	}

	setParent $panel;
	setParent $tabLayout;
		string $tab = `formLayout`;
			// Create the graph UI specifying that an existing hypershade
			// should be used.
			//
			string $graphUI = 
				graphUI(
					$tab, 
					$hypershadeName);
		setParent ..; // from $tab
	setParent ..; // from $tabLayout

	// Set the label on the tab
	//
	tabLayout
		-edit
		-tabLabel $tab $tabLabel
		$tabLayout;

	// Configure the graphUI according to saved state
	//
	graphUISetPopupMenuScript(
		$graphUI, 
		("hyperShadePanelSceneAndGraphTabPopupMenu " + $panel));

    // Create a callback to set the active pane when mouse is pressed.
    //
	string $hypershadeName = graphUIHypershadeName($graphUI);

	hyperGraph -edit
		-focusCommand 
			("hyperShadePanelSetActiveTabLayout "
				+ $panel
				+ " "
				+ $tabLayout
                + " false")
		$hypershadeName;

	// Specify the callback to be called when the user clicks on the menu arrow
	// on the bottom of a node
	//
	hyperGraph 
		-edit
		-nodeMenuCommand 
			("hyperShadePanelSceneAndGraphTabPopupMenu " + $panel)
		$hypershadeName;

	if ($protected)
	{
		registerTab($tab, "protected graph", $graphUI, $optionVar, $tabLayout);
	}
	else
	{
		registerTab($tab, "graph", $graphUI, $optionVar, $tabLayout);
	}

	// Update the tab layout option var now that a new tab has been added
	//
	updateTabLayoutOptionVar($panel, $tabLayout);

	// If the graph tab is protected, it should be considered the designated
	// Work Area tab.
	//
	// ASSUMPTION:
	// We assume there will only ever be one protected tab, since we do not
	// allow the user to create one. If additional protected graph tabs are
	// created in the future, this code will need to change.
	//
	if ($protected)
	{
		optionVar -stringValue "hyperShadePanelWorkAreaTab" $tab;
	}

	// Return the name of the tab which was created.
	//
	return $tab;
}

proc string createDiskTab(
	string $panel,
	string $tabLayout,
	string $tabLabel,
	string $directory)
{
	//
	// Description:
	//	This procedure is called when the user creates a new disk tab, or when
	//	the default tabs are being created (ie the first time the user uses the
	//	hypershade panel or as a result of a revert to default tabs). 
	//	This procedure creates a disk tab.
	//
	// Returns: 
	//	The name of the newly created tab.
	//

	setParent $panel;
	setParent $tabLayout;
		string $tab = `formLayout`;
			// Create the library UI. The second and third parameters are blank
			// because we want to have new directory and files visors created,
			// rather than specifying existing ones to be used.
			//
			string $libraryUI = 
				libraryUI(
					$tab, 
					"", 	// directoriesVisorName
					""); 	// filesVisorName
			libraryUISetRootDirectory($libraryUI, $directory);
		setParent ..; // from $tab
	setParent ..; // from $tabLayout

	// Set the label on the tab
	//
	tabLayout
		-edit
		-tabLabel $tab $tabLabel
		$tabLayout;
	
    // Create a callback to set the active pane when mouse is pressed.
    //
    {
        string $directoriesName = libraryUIDirectoriesVisor($libraryUI);

        hyperGraph -edit
            -focusCommand 
				("hyperShadePanelSetActiveTabLayout "
					+ $panel
					+ " "
					+ $tabLayout
                    + " false")
            $directoriesName;

        string $filesName = libraryUIFilesVisor($libraryUI);

        hyperGraph -edit
            -focusCommand 
				("hyperShadePanelSetActiveTabLayout "
					+ $panel
					+ " "
					+ $tabLayout 
                    + " false")
            $filesName;
    }

	// Configure the libraryUI
	//
	libraryUISetFilesPopupMenuScript(
		$libraryUI, 
		("hyperShadePanelDiskTabPopupMenu " + $panel));

	string $optionVar = generateUniqueTabOptionVarName();
	registerTab($tab, "disk", $libraryUI, $optionVar, $tabLayout);
	updateTabOptionVar($optionVar, $tab);

	// Update the tab layout option var now that a new tab has been added
	//
	updateTabLayoutOptionVar($panel, $tabLayout);

	// Return the name of the tab which was created.
	//
	return $tab;
}

proc string recreateDiskTab(
	string $panel,
	string $tabLayout,
	string $optionVar,
	int $reuseEditors)
{
	//
	// Description:
	//	This procedure is called when a disk tab is being recreated from 
	//	optionVars.
	//	This procedure creates a disk tab using the information stored in
	//	optionVars.
	//
	// Returns: 
	//	The name of the newly created tab.
	//

	string $tabLabel 
		= `optionVar -query ($optionVar + "Label")`;
	string $directoriesVisorName;
	string $filesVisorName;

	if ($reuseEditors)
	{
		$directoriesVisorName 
			= `optionVar -query ($optionVar + "DirectoriesVisorName")`;
		$filesVisorName 
			= `optionVar -query ($optionVar + "FilesVisorName")`;
	}

	setParent $panel;
	setParent $tabLayout;
		string $tab = `formLayout`;
			// Create the library UI specifying that our existing directory and
			// files visors should be used.
			//
			string $libraryUI = 
				libraryUI(
					$tab, 
					$directoriesVisorName,
					$filesVisorName);
		setParent ..; // from $tab
	setParent ..; // from $tabLayout

	// Set the label on the tab
	//
	tabLayout
		-edit
		-tabLabel $tab $tabLabel
		$tabLayout;

    // Create a callback to set the active pane when mouse is pressed.
    //
    {
        string $directoriesName = libraryUIDirectoriesVisor($libraryUI);

        hyperGraph -edit
            -focusCommand 
				("hyperShadePanelSetActiveTabLayout "
					+ $panel
					+ " "
					+ $tabLayout
                    + " false")
            $directoriesName;

        string $filesName = libraryUIFilesVisor($libraryUI);

        hyperGraph -edit
            -focusCommand 
				("hyperShadePanelSetActiveTabLayout "
					+ $panel
					+ " "
					+ $tabLayout
                    + " false")
            $filesName;
    }

	//
	// Configure the libraryUI according to saved state
	//
	// For some tabs we may not necessarily use the root directory and current
	// directory that have been stored in optionVars. In situations where the
	// tab label indicates that the tab is a "default" tab (ie one you would
	// get if you did Revert To Default Tabs), we will ensure the directories
	// point to the current installation of Maya. If we did not do this, we
	// would have situations where a user running a new installation of Maya
	// would still end up looking at shader libraries and such from a previous
	// installation.
	//

	// Initialize the root directory and current directory for the tab to be
	// the directories stored in optionVars.
	//
	string $rootDirectory = 
		`optionVar -query ($optionVar + "RootDirectory")`;
	string $currentDirectory = 
		`optionVar -query ($optionVar + "CurrentDirectory")`;

	// For disk tabs with particular labels, we will massage the directories to
	// be sure they are appropriate.
	//
	if ($tabLabel == "Projects")
	{
		string $projectsDir = `internalVar -userWorkspaceDir`;
		
		if ($rootDirectory != $projectsDir)
		{
			$rootDirectory = $projectsDir;
			$currentDirectory = $projectsDir;
		}
	}
	else if ($tabLabel == "Shader Library")
	{
		string $shaderLibraryDir = `getenv MAYA_SHADER_LIBRARY_PATH`;

		if (	($shaderLibraryDir != "")
			&&	($rootDirectory != $shaderLibraryDir))
		{
			$rootDirectory = $shaderLibraryDir;
			$currentDirectory = $shaderLibraryDir;
		}
	}


	// Set the root and current directories of the tab
	//
	libraryUISetRootDirectory($libraryUI, $rootDirectory);
	libraryUISetCurrentDirectory($libraryUI, $currentDirectory);

	if (`optionVar -query ($optionVar + "DirectoriesShown")`)
	{
		if (`optionVar -query ($optionVar + "FilesShown")`)
		{
			libraryUIShowDirectoriesAndFiles($libraryUI);
		}
		else
		{
			libraryUIShowDirectoriesOnly($libraryUI);
		}
	}
	else
	{
		libraryUIShowFilesOnly($libraryUI);
	}

	libraryUISetFilesPopupMenuScript(
		$libraryUI,
		("hyperShadePanelDiskTabPopupMenu " + $panel));


	registerTab($tab, "disk", $libraryUI, $optionVar, $tabLayout);

	// Update the tab layout option var now that a new tab has been added
	//
	updateTabLayoutOptionVar($panel, $tabLayout);

	// Return the name of the tab which was created.
	//
	return $tab;
}

proc string createSceneTab(
	string $panel,
	string $tabLayout,
	string $tabLabel,
	string $filter)
{
	//
	// Description:
	//	This procedure is called when the user creates a new scene tab, or when
	//	the default tabs are being created (ie the first time the user uses the
	//	hypershade panel or as a result of a revert to default tabs). 
	//	This procedure creates a scene tab.
	//
	// Returns: 
	//	The name of the newly created tab.
	//

	setParent $panel;
	setParent $tabLayout;
		string $tab = `formLayout`;
			// Create the collection UI. The second parameter is blank
			// because we want to have a new hypershade created,
			// rather than specifying an existing one to be used.
			//
			string $collectionUI = 
				collectionUI(
					$tab, 
					""); // hypershadeName
		setParent ..; // from $tab
	setParent ..; // from $tabLayout

	// Set the label on the tab
	//
	tabLayout
		-edit
		-tabLabel $tab $tabLabel
		$tabLayout;
	
    // Create a callback to set the active pane when mouse is pressed.
    //
    {
        string $hyperName = collectionUIHypershadeName($collectionUI);

        hyperGraph -edit
            -focusCommand 
				("hyperShadePanelSetActiveTabLayout "
					+ $panel
					+ " " 
					+ $tabLayout
                    + " false")
            -scrollUpDownNoZoom true
            -iconSize "mediumIcons"
			-viewOption "asIcons"
			// sortOption and reverseOption initialized below
            $hyperName;
		registerSortOption( $collectionUI, "byName" );
		registerReverseOption( $collectionUI, "false" );
    }

	// Configure the collectionUI
	//
	collectionUISetFilter($collectionUI, $filter);
	collectionUISetPopupMenuScript(
		$collectionUI, 
		("hyperShadePanelSceneAndGraphTabPopupMenu " + $panel));

	string $optionVar = generateUniqueTabOptionVarName();
	registerTab($tab, "scene", $collectionUI, $optionVar, $tabLayout);
	updateTabOptionVar($optionVar, $tab);

	// Update the tab layout option var now that a new tab has been added
	//
	updateTabLayoutOptionVar($panel, $tabLayout);

	//	create the appropriate filtering controls for the tab
	//
	string $implicitFilter = filteredCollection_RealFilterName( $filter );
	showFilter( $panel, $tab, $implicitFilter );

	// Return the name of the tab which was created.
	//
	return $tab;
}

proc refreshSceneTabContent(
	string $panel,
	string $tabLayout,
    string $tab,
	int $reuseEditors)
{
	//
	// Description:
	//	This procedure is called to refresh the scene tab content. 
    //  If the content of the tab is not yet created, we create it here.
	//

    // If it is not a scene tab, then don't do anything.
    //
    if (!isSceneTab($tab))
    {
        return;
    }

    if (size(`formLayout -q -childArray $tab`) > 0)
    {
        // The content of this tab has already been created.
        // We have nothing to do.
        //
        return;
    }

    // The content of this tab is not created yet, create it.
    //
    setParent $tab;

	string $hypershadeName;
    string $optionVar = lookupTabOptionVar($tab);
	if ($reuseEditors)
	{
		$hypershadeName = `optionVar -query ($optionVar + "HypershadeName")`;
	}

    // Create the graph UI specifying that an existing hypershade
    // should be used.
    //
    string $collectionUI = 
        collectionUI(
            $tab, 
            $hypershadeName);

    // The previous registration of the tab did not specify its its 
    // collectionUI.  Update the component of the tab in the tab registry.
    //
    updateComponentNameInTabRegistry($tab, $collectionUI);


    // Create a callback to set the active pane when mouse is pressed.
    //
    {
        string $hyperName = collectionUIHypershadeName($collectionUI);

        hyperGraph -edit
            -focusCommand 
				("hyperShadePanelSetActiveTabLayout "
					+ $panel
					+ " "
					+ $tabLayout
                    + " false")
            -scrollUpDownNoZoom true
            -iconSize "mediumIcons"
			-viewOption "asIcons"
			// sortOption and reverseOption initialized below
            $hyperName;
		registerSortOption( $collectionUI, "byName" );
		registerReverseOption( $collectionUI, "false" );
    }

	// Configure the collectionUI according to saved state
	//
	string $filter = `optionVar -query ($optionVar + "Filter")`;
	collectionUISetFilter(
		$collectionUI,
		$filter );
	collectionUISetPopupMenuScript(
		$collectionUI, 
		("hyperShadePanelSceneAndGraphTabPopupMenu " + $panel));

	//	create the appropriate filtering controls for the tab
	//
	string $implicitFilter = filteredCollection_RealFilterName( $filter );
	showFilter( $panel, $tab, $implicitFilter );
}

proc string recreateSceneTab(
	string $panel,
	string $tabLayout,
	string $optionVar,
	int $reuseEditors)
{
	//
	// Description:
	//	This procedure is called when a scene tab is being recreated from an
	//	optionVar.
	//	This procedure creates a scene tab using the information stored in the
	//	specified optionVar.
	//
	// Returns: 
	//	The name of the newly created tab.
	//

	string $tabLabel 
		= `optionVar -query ($optionVar + "Label")`;

	setParent $panel;
	setParent $tabLayout;
		string $tab = `formLayout`;
		setParent ..; // from $tab
	setParent ..; // from $tabLayout

	// Set the label on the tab
	//
	tabLayout
		-edit
		-tabLabel $tab $tabLabel
		$tabLayout;
	
    registerTab($tab, "scene", "" , $optionVar, $tabLayout);

	// Update the tab layout option var now that a new tab has been added
	//
	updateTabLayoutOptionVar($panel, $tabLayout);

    // If we need to reuseEditor, then we can create the content
    // of the tab right away.
    //
    if ($reuseEditors)
    {
        refreshSceneTabContent($panel, $tabLayout, $tab, $reuseEditors);
    }

	// Return the name of the tab which was created.
	//
	return $tab;
}


proc recreateTab(
	string $panel,
	string $tabLayout,
	string $optionVar,
	int $reuseEditors)
{
	//
	// Description:
	//	This procedure is called by initTabs() when a tab is being recreated 
	//	from an optionVar.
	//	This procedure determines what kind of tab is represented by the
	//	optionVar, then calls one of recreateGraphTab(), recreateDiskTab() or
	//	recreateSceneTab() to create the tab.
	//

	string $type = `optionVar -query ($optionVar + "Type")`;

	if ($type == "disk")
	{
		recreateDiskTab($panel, $tabLayout, $optionVar, $reuseEditors);
	}
	else if ($type == "graph")
	{
		recreateGraphTab(
			$panel, 
			$tabLayout, 
			$optionVar, 
			$reuseEditors,
			false);
	}
	else if ($type == "protected graph")
	{
		recreateGraphTab(
			$panel, 
			$tabLayout, 
			$optionVar, 
			$reuseEditors,
			true);
	}
	else if ($type == "scene")
	{
		recreateSceneTab($panel, $tabLayout, $optionVar, $reuseEditors);
	}
	else
	{
		error
			-showLineNumber true
			("Unexpected tab type in option var: " + $type );
	}
}


// Description:  This procedure is called to delete a scene tab as well as
//      the filterBox and filterButton associated with it. 
//      We assume that the input tab is a scene tab.
//
proc removeSceneTabFilterReference(string $panel, string $tab)
{
    // Delete the filterBox and filterButton associated with the scene.
    //
	string $collection = lookupComponentName( $tab );

	string $filterControls[] = collectionUIFilterControls( $collection );	
	string $filterBox = $filterControls[1];
	string $filterButton = $filterControls[2];

    setParent $panel;
    deleteUI $filterBox;
    deleteUI $filterButton;

    // Remove any reference to the filterBox and filterButton.
    //
    global string $gPreviousFilterBox; 
    global string $gPreviousFilterButton; 
    if ($gPreviousFilterBox == $filterBox)
    {
        $gPreviousFilterBox = "";
    }
    if ($gPreviousFilterButton == $filterButton)
    {
        $gPreviousFilterButton = "";
    }
}

// Description:  This procedure is called when we need to refresh
//      the sceneTabFilterForm to reflect the current pane and front
//      tab arrangement.
//
proc refreshSceneTabFilterForm(string $panel)
{
    // Check which is the top most pane. 
    //
    string $tabSectionsShown =
        `optionVar -query hyperShadePanelTabSectionsShown`;

    string $upperPane = "firstPaneTabs";

    if ($tabSectionsShown == "showBottomTabsOnly")
    {
        // When only the bottom pane is showing, the bottom pane is considered
        // the upper pane for the time being.
        //
        $upperPane = "secondPaneTabs";
    }

    setParent $panel;
    setParent $upperPane;

    // Check which tab is the front most tab in this upperPane.
    //
    string $upperPaneFrontMostTab = `tabLayout -query -selectTab $upperPane`;

    if ($upperPaneFrontMostTab != "")
    {
        $upperPaneFrontMostTab = `setParent $upperPaneFrontMostTab`;
    }

    if (isSceneTab($upperPaneFrontMostTab))
    {
        // If this front most tab is a scene tab, then show its filter in the
        // sceneTabFilterForm.
        //
        showCurrentFilterBoxAndButton($panel, $upperPaneFrontMostTab);
        control -edit -manage true sceneTabFilterForm;
    }
    else
    {
        // Dim the sceneTabFilterForm.
        //
        dimCurrentFilterBoxAndButton();
        control -edit -manage true sceneTabFilterForm;
        
    } 
}


proc moveTab(
	string $panel,
	string $direction)
{
	//
	// Description:
	//	This procedure moves a tab up, down, left or right within the
	//	hypershade panel. 
	//	This procedure acts on the currently active tab when the $direction is
	//	"left" or "right". When the $direction is "up" or "down", this
	//	procedure acts on the frontmost tab in the bottom or top tab layout
	//	respectively.
	//	Once the move has been completed, the tab is made the active tab so
	//	that it can easily be immediately moved again.
	//

	//	flag this as a "construction" operation.  This will prevent
	//	many unnecessary refreshes of the various tabs as they are
	//	moved around.
	//
	hyperShadeStartConstruction( $panel );

	setParent $panel;
	string $paneLayout = `setParent paneArrangement`;

	if ($direction == "up")
	{
		// Make the bottom tab layout active
		//
		paneLayout -edit -activePaneIndex 2 paneArrangement;
	}
	else if ($direction == "down")
	{
		// Make the top tab layout active
		//
		paneLayout -edit -activePaneIndex 1 paneArrangement;
	}

	// Determine what tab layout is currently active, and which tab layout the
	// tab is being moved to.
	//
	int 	$activePaneIndex = activePaneIndex($panel);
	string 	$activeTabLayout;

	if ($activePaneIndex == 1) 
	{
		$activeTabLayout = "firstPaneTabs";
	}
	else 
	{
		$activeTabLayout = "secondPaneTabs";
	}

	int 	$activeTabIndex = activeTabIndex($panel);

	if (($direction == "left") || ($direction == "right"))
	{
		int $numTabs = `tabLayout -query -numberOfChildren $activeTabLayout`;
		int $targetTabIndex;

		if (($direction == "left") && ($activeTabIndex > 1))
		{
			$targetTabIndex = $activeTabIndex - 1;
			tabLayout
				-edit
				-moveTab $activeTabIndex $targetTabIndex
				$activeTabLayout;

			// Bring the target tab to the front
			//
			tabLayout
				-edit
				-selectTabIndex $targetTabIndex
				$activeTabLayout;

			// Update the tab layout option vars now that a tab has been moved
			//
			updateTabLayoutOptionVar($panel, $activeTabLayout);
		}
		else if (($direction == "right") && ($activeTabIndex < $numTabs))
		{
			$targetTabIndex = $activeTabIndex + 1;
			tabLayout
				-edit
				-moveTab $activeTabIndex $targetTabIndex
				$activeTabLayout;

			// Bring the target tab to the front
			//
			tabLayout
				-edit
				-selectTabIndex $targetTabIndex
				$activeTabLayout;

			// Update the tab layout option vars now that a tab has been moved
			//
			updateTabLayoutOptionVar($panel, $activeTabLayout);
		}
	}
	else
	{
		string 	$activeTab 			= activeTab($panel);
	
		string 	$targetTabLabel 	= activeTabLabel($panel);
		int 	$targetPaneIndex;
		string 	$targetTabLayout;

		if ($activePaneIndex == 1) 
		{
			$targetTabLayout = "secondPaneTabs";
			$targetPaneIndex = 2;
		}
		else 
		{
			$targetTabLayout = "firstPaneTabs";
			$targetPaneIndex = 1;
		}

		string $recreatedTab;

		// Determine what kind of tab the current tab is (disk/graph/scene)
		//
		if (isDiskTab($activeTab))
		{
			string $libraryUI;
			$libraryUI = lookupComponentName($activeTab);

			// Store the information needed to recreate the tab into an 
			// optionVar
			//
			string $tabOptionVar = lookupTabOptionVar($activeTab);
			updateTabOptionVar($tabOptionVar, $activeTab);

			// Delete the libraryUI and the active tab.
			//
			unregisterTab($activeTab);
			libraryUIDelete(
				$libraryUI, 
				false); // don't delete the visors
			deleteUI $activeTab;

			// Recreate the libraryUI in the target tab.
			//
			$recreatedTab = recreateDiskTab(
				$panel, 
				$targetTabLayout,
				$tabOptionVar,
				true /* reuse editors */);
			
		}
		else if (isGraphTab($activeTab))
		{
			int $protected = (lookupTabType($activeTab) == "protected graph");
			string $graphUI;
			$graphUI = lookupComponentName($activeTab);

			// Store the information needed to recreate the tab into an 
			// optionVar
			//
			string $tabOptionVar = lookupTabOptionVar($activeTab);
			updateTabOptionVar($tabOptionVar, $activeTab);

			// Delete the libraryUI and the active tab.
			//
			unregisterTab($activeTab);
			graphUIDelete(
				$graphUI, 
				false); // don't delete the hypershade
			deleteUI $activeTab;

			// Recreate the libraryUI in the target tab.
			//
			$recreatedTab = recreateGraphTab(
				$panel, 
				$targetTabLayout,
				$tabOptionVar,
				true, /* reuse editors */
				$protected);
		}
		else if (isSceneTab($activeTab))
		{
			string $collectionUI;
			$collectionUI = lookupComponentName($activeTab);

			// Store the information needed to recreate the tab into an 
			// optionVar
			//
			string $tabOptionVar = lookupTabOptionVar($activeTab);
			updateTabOptionVar($tabOptionVar, $activeTab);

			// Delete the collectionUI and the active tab.
			//
            removeSceneTabFilterReference($panel, $activeTab);
			unregisterTab($activeTab);
			collectionUIDelete(
				$collectionUI, 
				false); // don't delete the hypershade
			deleteUI $activeTab;

			// Recreate the collectionUI in the target tab.
			//
			$recreatedTab = recreateSceneTab(
				$panel, 
				$targetTabLayout,
				$tabOptionVar,
				true /* reuse editors */);

		}

		// Bring the target tab to the front
		//
		tabLayout
			-edit
			-selectTab $recreatedTab
			$targetTabLayout;

        // Refresh the pane tabs.  
        // Keep the focus with the tab which is moved.
        //
        if ($targetPaneIndex == 1)
        {
            hyperShadePanelSetActiveTabLayout($panel, "secondPaneTabs", true); 
            hyperShadePanelSetActiveTabLayout($panel, "firstPaneTabs", true); 
        }
        else
        {
            hyperShadePanelSetActiveTabLayout($panel, "firstPaneTabs", true); 
            hyperShadePanelSetActiveTabLayout($panel, "secondPaneTabs", true); 
        }

		// Give the target tab layout focus so the user can move the tab
		// again without having to reselect it.
		//
		paneLayout -edit -activePaneIndex $targetPaneIndex paneArrangement;

		// Update the tab layout option vars now that a tab has been moved
		//
		updateTabLayoutOptionVar($panel, $activeTabLayout);
		updateTabLayoutOptionVar($panel, $targetTabLayout);
	}

    refreshSceneTabFilterForm($panel);

	//	Signal the end of the construction operation.  Specify
	//	that the HyperShade is still around, so the active tabs
	//	must be refreshed.
	//
	hyperShadeEndConstruction( $panel, 1 );

}

proc removeTab(
	string $tab)
{
	//
	// Description:
	//	This procedure removes the specified tab from the hypershade panel.
	//

	//	flag this as a "construction" operation.  This will prevent
	//	many unnecessary refreshes of the various tabs as they are
	//	removed.
	//
	string $panel = hyperShadePanelName();
	hyperShadeStartConstruction( $panel );

	// Delete the option var which describes this tab, so that it won't come
	// back the next time the user runs Maya
	//
	deleteTabOptionVar($tab);

	// Determine what kind of tab the current tab is (disk/graph/scene)
	//
	if (isDiskTab($tab))
	{
		string $libraryUI;
		$libraryUI = lookupComponentName($tab);

		// Delete the libraryUI and the active tab.
		//
		unregisterTab($tab);
		libraryUIDelete(
			$libraryUI, 
			true); // delete the visors
		deleteUI $tab;
	}
	else if (isGraphTab($tab))
	{
		string $graphUI;
		$graphUI = lookupComponentName($tab);

		// Delete the graphUI and the active tab.
		//
		unregisterTab($tab);
		graphUIDelete(
			$graphUI, 
			true); // delete the hypershade
		deleteUI $tab;
	}
	else if (isSceneTab($tab))
	{		
		string $collectionUI;
		$collectionUI = lookupComponentName($tab);

		// Delete the collectionUI and the active tab.
		//
        removeSceneTabFilterReference($panel, $tab);
		unregisterTab($tab);
		
        // Delete the $collectionUI if it exists.
        //
        if ($collectionUI != "")
        {
            // Remove the collectionUI's hyperShadeName from the
            // $gFilterUIViewList.
            //
            string $hypershadeName = collectionUIHypershadeName($collectionUI);
            global string $gFilterUIViewList[];
            
            // Bug 215233:
            // Before removing the view, we must update several lists,
            // deleting entries which correspond to the view so that the
            // active tab doesn't contain past content of previously
            // deleted tabs.
            // 
            // To do this, first identify the index of the view (since all the
            // arrays are index-matched).
            //
            // Note: These global variables are a subset of those listed in
            // filterUI.mel
            //
            int $i;
            int $matchedIndex = -1;
            for ($i=0 ; $i<size($gFilterUIViewList) ; $i++){
				if ($hypershadeName == $gFilterUIViewList[$i])
					$matchedIndex = $i;
			}
			if ($matchedIndex != -1){

				global string $gFilterUIPopupMenuList[];
				$gFilterUIPopupMenuList = AWRemoveStringsFromStringArray({$gFilterUIPopupMenuList[$matchedIndex]}, $gFilterUIPopupMenuList);
								
				global string $gFilterUIFieldList[];
				$gFilterUIFieldList = AWRemoveStringsFromStringArray({$gFilterUIFieldList[$matchedIndex]}, $gFilterUIFieldList);
				
				global string $gFilterUIFilterStatusControlList[];
				$gFilterUIFilterStatusControlList = AWRemoveStringsFromStringArray({$gFilterUIFilterStatusControlList[$matchedIndex]}, $gFilterUIFilterStatusControlList);
				
				global string $gFilterUIImplicitFilterList[];
				$gFilterUIImplicitFilterList= AWRemoveStringsFromStringArray({$gFilterUIImplicitFilterList[$matchedIndex]}, $gFilterUIImplicitFilterList);
				
				global string $gFilterUIRelatedFiltersProcedureList[];
				$gFilterUIRelatedFiltersProcedureList= AWRemoveStringsFromStringArray({$gFilterUIRelatedFiltersProcedureList[$matchedIndex]}, $gFilterUIRelatedFiltersProcedureList);
            }
            
            $gFilterUIViewList = AWRemoveStringsFromStringArray({$hypershadeName}, $gFilterUIViewList);
                        
            // Delete collectionUI.
            //
		    collectionUIDelete(
			    $collectionUI, 
			    true); // delete the hypershade
		}
		deleteUI $tab;

        // Figure out which tabLayout is active at the moment.
        //
        string $activeTabLayout = activeTabLayout($panel);

        // Refresh the active tab. 
        //
        hyperShadePanelSetActiveTabLayout($panel, $activeTabLayout, true);        
	}

    refreshSceneTabFilterForm($panel);

	//	Signal the end of the construction operation.  Specify
	//	that the HyperShade is still around, so the active tabs
	//	must be refreshed.
	//
	hyperShadeEndConstruction( $panel, 1 );

}

proc removeActiveTab(
	string $panel)
{
	//
	// Description:
	//	This procedure removes the active tab from the hypershade panel.
	//
	
	setParent $panel;
	string $paneLayout = `setParent paneArrangement`;

	// Determine what tab layout is currently active.
	//
	string $tabLayout;
	$tabLayout = activeTabLayout($panel);

	string 	$activeTab = activeTab($panel);

	if (`lookupTabType($activeTab)` == "protected graph")
	{
		// The active tab is marked as a protected graph, which means we don't
		// want to allow it to be deleted or moved between tab layouts.
		//
		return;
	}
	
	removeTab($activeTab);

	// Delete the option var which describes this tab, so that it won't come
	// back the next time the user runs Maya
	//
	deleteTabOptionVar($activeTab);

	// Determine what kind of tab the current tab is (disk/graph/scene)
	//
	if (isDiskTab($activeTab))
	{
		string $libraryUI;
		$libraryUI = lookupComponentName($activeTab);

		// Delete the libraryUI and the active tab.
		//
		unregisterTab($activeTab);
		libraryUIDelete(
			$libraryUI, 
			true); // delete the visors
		deleteUI $activeTab;
	}
	else if (isGraphTab($activeTab))
	{
		string $graphUI;
		$graphUI = lookupComponentName($activeTab);

		// Delete the graphUI and the active tab.
		//
		unregisterTab($activeTab);
		graphUIDelete(
			$graphUI, 
			true); // delete the hypershade
		deleteUI $activeTab;
	}
	else if (isSceneTab($activeTab))
	{
		string $collectionUI;
		$collectionUI = lookupComponentName($activeTab);

		// Delete the collectionUI and the active tab.
		//
        removeSceneTabFilterReference($panel, $activeTab);
		unregisterTab($activeTab);
		collectionUIDelete(
			$collectionUI, 
			true); // delete the hypershade
		deleteUI $activeTab;
	}

	// Update the tab layout option var now that the tab has been deleted
	//
	updateTabLayoutOptionVar($panel, $tabLayout);

    refreshSceneTabFilterForm($panel);
}

// Description:  This procedure is called to refresh the icon size
//      menu items. 
//
proc refreshIconSize(string $panel, string $activeTab)
{
    int $isSceneTab = isSceneTab($activeTab);

    string $oldParent = `setParent -q`;
    setParent $panel;

    menuItem -edit -enable $isSceneTab -radioButton false smallIcons;
    menuItem -edit -enable $isSceneTab -radioButton false mediumIcons;
    menuItem -edit -enable $isSceneTab -radioButton false largeIcons;
    menuItem -edit -enable $isSceneTab -radioButton false superIcons;

	// Enable/disable the buttons and update images
	setParent buttonsColumn;
	string $image1 = $isSceneTab ? "iconSmall.xpm" : "iconSmall_disabled.xpm";
	string $image2 = $isSceneTab ? "iconMedium.xpm" : "iconMedium_disabled.xpm";
	string $image3 = $isSceneTab ? "iconLarge.xpm" : "iconLarge_disabled.xpm";
	string $image4 = $isSceneTab ? "iconSuper.xpm" : "iconSuper_disabled.xpm";

	iconTextRadioButton -edit -image1 $image1 -enable $isSceneTab
		smallIconsColumnButton;
	iconTextRadioButton -edit -image1 $image2 -enable $isSceneTab
		mediumIconsColumnButton;
	iconTextRadioButton -edit -image1 $image3 -enable $isSceneTab
		largeIconsColumnButton;
	iconTextRadioButton -edit -image1 $image4 -enable $isSceneTab
		superIconsColumnButton;
	setParent ..; // from buttonsColumn

    if ($isSceneTab)
    {
        // For scene tab, find out which iconSize was used by this
        // tab, and set that radioButton to on.
        //
        string $collectionUI = lookupComponentName( $activeTab );
		string $iconSize = collectionUIIconSize( $collectionUI );
        if ($iconSize == "")
        {
            // If the user has not specified an icon size yet, then
            // we set the icon size to medium.
            //
            $iconSize = "mediumIcons";
        }
        menuItem -edit -radioButton true $iconSize;

		setParent buttonsColumn;
		string $iconSizeButton = $iconSize + "ColumnButton";
		iconTextRadioButton -edit -select $iconSizeButton;
		setParent ..; // from buttonsColumn
    }

    setParent $oldParent;
}

proc refreshViewOption(string $panel, string $activeTab)
{
    int $isSceneTab = isSceneTab($activeTab);

    string $oldParent = `setParent -q`;
    setParent $panel;

    menuItem -edit -enable $isSceneTab -radioButton false asIcons;
    menuItem -edit -enable $isSceneTab -radioButton false asList;

	// Enable/disable the buttons and update images
	setParent buttonsColumn;
	string $image1 = $isSceneTab ? "viewIcon.xpm" : "viewIcon_disabled.xpm";
	string $image2 = $isSceneTab ? "viewList.xpm" : "viewList_disabled.xpm";

	iconTextRadioButton -edit -image1 $image1 -enable $isSceneTab
		asIconsColumnButton;
	iconTextRadioButton -edit -image1 $image2 -enable $isSceneTab
		asListColumnButton;
	setParent ..; // from buttonsColumn

    if ($isSceneTab)
    {
        // For scene tab, find out which view option was used by this
        // tab, and set that radioButton to on.
        //
        string $collectionUI = lookupComponentName( $activeTab );        
		string $viewOption = collectionUIViewOption( $collectionUI );
        if ($viewOption == "")
        {
            // If the user has not specified a view option yet, then
            // we default to displaying icons (swatches).
            //
            $viewOption = "asIcons";
        }
        menuItem -edit -radioButton true $viewOption;

		setParent buttonsColumn;
		string $viewOptionButton = $viewOption + "ColumnButton";
		iconTextRadioButton -edit -select $viewOptionButton;
		setParent ..; // from buttonsColumn
    }
    setParent $oldParent;
}

proc refreshSortOption(string $panel, string $activeTab)
{
    int $isSceneTab = isSceneTab($activeTab);

    string $oldParent = `setParent -q`;
    setParent $panel;

    menuItem -edit -enable $isSceneTab -radioButton false byName;
    menuItem -edit -enable $isSceneTab -radioButton false byType;
    menuItem -edit -enable $isSceneTab -radioButton false byTime;

	// Enable/disable the buttons and update images
	setParent buttonsColumn;
	string $image1 = $isSceneTab ? "sortName.xpm" : "sortName_disabled.xpm";
	string $image2 = $isSceneTab ? "sortType.xpm" : "sortType_disabled.xpm";
	string $image3 = $isSceneTab ? "sortTime.xpm" : "sortTime_disabled.xpm";

	iconTextRadioButton -edit -image1 $image1 -enable $isSceneTab
		byNameColumnButton;
	iconTextRadioButton -edit -image1 $image2 -enable $isSceneTab
		byTypeColumnButton;
	iconTextRadioButton -edit -image1 $image3 -enable $isSceneTab
		byTimeColumnButton;
	setParent ..; // from buttonsColumn

    if ($isSceneTab)
    {
        // For scene tab, find out which sort option was used by this
        // tab, and set that radioButton to on.
        //
		string $collectionUI = lookupComponentName( $activeTab );
		string $sortOption = collectionUISortOption( $collectionUI );
        if ($sortOption == "")
        {
            // If the user has not specified a sort option yet, then
            // we set the sort option to alphabetical.
            //
            $sortOption = "byName";
        }
        menuItem -edit -radioButton true $sortOption;

		setParent buttonsColumn;
		string $sortOptionButton = $sortOption + "ColumnButton";
		iconTextRadioButton -edit -select $sortOptionButton;
		setParent ..; // from buttonsColumn
    }
    setParent $oldParent;
}

proc refreshReverseOption(string $panel, string $activeTab)
{
    int $isSceneTab = isSceneTab($activeTab);

    string $oldParent = `setParent -q`;
    setParent $panel;

	// Enable/disable the option
	//
	menuItem -edit -enable $isSceneTab reverseOrder;

	// Enable/disable the buttons and update images
	setParent buttonsColumn;
	string $image1 = $isSceneTab ? "reverseOrder.xpm" : "reverseOrder_disabled.xpm";

	iconTextCheckBox -edit -image1 $image1 -enable $isSceneTab
		reverseOrderColumnButton;
	setParent ..; // from buttonsColumn

    if ($isSceneTab)
    {
        // For scene tab, find out whether to reverse, and
		// set checkBox accordingly
        //
		string $collectionUI = lookupComponentName( $activeTab );
		string $reverseOption = collectionUIReverseOption( $collectionUI );
		if( $reverseOption == "true" ){
			menuItem -edit -checkBox true reverseOrder;

			setParent buttonsColumn;
			iconTextCheckBox -edit -value true reverseOrderColumnButton;
			setParent ..; // from buttonsColumn
		}else{ //$reverseOption == "false" or "" (not yet specified)
			menuItem -edit -checkBox false reverseOrder;

			setParent buttonsColumn;
			iconTextCheckBox -edit -value false reverseOrderColumnButton;
			setParent ..; // from buttonsColumn
		}
    }
    setParent $oldParent;
}

proc refreshToolbar(
	string $panel)
{
	setParent $panel;
	setParent toolbarForm;

	string $activeTab = activeTab($panel);

	// Enable the Clear Graph and Rearrange Graph buttons only if a graph tab
	// (work area) is visible.
	//
	int $enable;
	$enable = isGraphTabVisible($panel);

	iconTextButton
		-edit
		-enable $enable
		clearGraphButton;

	iconTextButton
		-edit
		-enable $enable
		rearrangeGraphButton;

	// The radio buttons which indicate which tab sections are shown need
	// to be kept in sync with the optionVar which stores that information.
	//
	if (`optionVar -query hyperShadePanelTabSectionsShown` 
			== "showTopTabsOnly")
	{
		iconTextRadioButton
			-edit
			-select
			showTopTabsOnlyButton;
	}
	else if (
		`optionVar -query hyperShadePanelTabSectionsShown` 
			== "showBottomTabsOnly")
	{
		iconTextRadioButton
			-edit
			-select
			showBottomTabsOnlyButton;
	}
	else
	{
		iconTextRadioButton
			-edit
			-select
			showTopAndBottomTabsButton;
	}
}

proc refreshCreateMenu(
	string $panel)
{
	//
	// Description:
	//	This procedure is called after a change is made which would require the
	//	hypershade panel Create menu to be updated to reflect a new state of 
	//	the UI. For example, when the user changes the state of the With
	//	Shading Group checkbox in the create render node dialog, the menu 
	//	needs to be refreshed so that the menu item which reflects the state of
	//	that checkbox is kept in sync. This procedure is not invoked 
	//	automatically when a change which affects the menus occurs, it must be
	//	explicitly called.
	//	This procedure refreshes the Create menu as appropriate considering the
	//	current state of the UI.
	//

	// Remember the current parent so we can revert to it when we're done here.
	//
	string $oldParent = `setParent -query`;
	string $oldMenuParent = `setParent -menu -query`;

	setParent $panel;

	string $menuPrefix = "hyperShadePanelMenu";
	string $menu = ($menuPrefix + "CreateMenu");

	// Since the Create menu is built each time it is opened, the menu
	// items it contains may not exist if it has not yet been opened.
	// We will only try to update the menu if the menu items actually 
	// exist.
	//
	if (	(`menu -exists $menu`)
		&&	(`menu -query -numberOfItems $menu` > 0))
	{
		setParent -menu $menu;

		// Update the create textures with placement checkbox
		//
		menuItem
			-edit
			-checkBox 
				`optionVar -query createTexturesWithPlacement`
			createIncludePlacementItem;

		// Update the normal/projection/stencil radiobuttons
		//
		menuItem 
			-edit
			-radioButton 
				(`optionVar -query create2dTextureType` == "normal")
			textureAsNormalItem;
		menuItem 
			-edit
			-radioButton 
				(`optionVar -query create2dTextureType` == "projection")
			textureAsProjectionItem;
		menuItem 
			-edit
			-radioButton 
				(`optionVar -query create2dTextureType` == "stencil")
			textureAsStencilItem;

		// Update the create materials with shading groups checkbox
		//
		menuItem
			-edit
			-checkBox 
				`optionVar -query createMaterialsWithShadingGroup`
			includeShadingGroupItem;
	}

	// Revert to the original parent.
	//
	if ($oldParent != "NONE") setParent $oldParent;
	if ($oldMenuParent != "NONE") setParent -menu $oldMenuParent;
}

proc refreshTabsMenu(
	string $panel)
{
	//
	// Description:
	//	This procedure is called after a change is made which would require the
	//	hypershade panel Tabs menu to be updated to reflect a new state of the 
	//	UI. For example, when the user presses one of the toolbar buttons which
	//	changes which tab sections are shown, the menus need to be refreshed so 
	//	that the menu items which indicate which tab sections are shown are
	//	properly updated. 
	//	This procedure is not invoked automatically when a change which affects 
	//	the menus occurs, it must be explicitly called.
	//	This procedure refreshes the Tabs menu as appropriate considering the
	//	current state of the UI.
	//

	// Remember the current parent so we can revert to it when we're done here.
	//
	string $oldParent = `setParent -query`;
	string $oldMenuParent = `setParent -menu -query`;

	setParent $panel;

	string $menuPrefix = "hyperShadePanelMenu";
	string $menu = ($menuPrefix + "TabsMenu");

	if (`menu -exists $menu`)
	{
		setParent -menu $menu;

		// Move Tab Up and Move Tab Down should be enabled if and only if both
		// tab sections are shown.
		//
		menuItem
			-edit
			-enable
				(`optionVar -query hyperShadePanelTabSectionsShown`
					== "showTopAndBottomTabs")
			tabsMoveTabUpItem;
		menuItem
			-edit
			-enable
				(`optionVar -query hyperShadePanelTabSectionsShown`
					== "showTopAndBottomTabs")
			tabsMoveTabDownItem;

		// The radio buttons which indicate which tab sections are shown need
		// to be kept in sync with the optionVar which stores that information.
		//
		menuItem 
			-edit
			-radioButton 
				(`optionVar -query hyperShadePanelTabSectionsShown` 
					== "showTopTabsOnly")
			tabsShowTopTabsOnlyItem;
		menuItem 
			-edit
			-radioButton 
				(`optionVar -query hyperShadePanelTabSectionsShown` 
					== "showBottomTabsOnly")
			tabsShowBottomTabsOnlyItem;
		menuItem 
			-edit
			-radioButton 
				(`optionVar -query hyperShadePanelTabSectionsShown` 
					== "showTopAndBottomTabs")
			tabsShowTopAndBottomTabsItem;
	}

	// Revert to the original parent.
	//
	if ($oldParent != "NONE") setParent $oldParent;
	if ($oldMenuParent != "NONE") setParent -menu $oldMenuParent;
}

proc refreshGraphMenu(
	string $panel)
{
	//
	// Description:
	//	This procedure is called after a change is made which would require the
	//	hypershade panel Graph menu to be updated to reflect a new state of the 
	//	UI. For example, when the user selects a new tab, the menus may need 
	//	to be refreshed so that menu items which apply only if the active tab 
	//	is a graph tab may be dimmed or undimmed. This procedure is not invoked
	//	automatically when a change which affects the menus occurs, it must be
	//	explicitly called.
	//	This procedure refreshes the Graph menu as appropriate considering the
	//	current state of the UI.
	//

	// Remember the current parent so we can revert to it when we're done here.
	//
	string $oldParent = `setParent -query`;
	string $oldMenuParent = `setParent -menu -query`;

	setParent $panel;

	string $menuPrefix = "hyperShadePanelMenu";
	string $menu = ($menuPrefix + "GraphMenu");

	if (`menu -exists $menu`)
	{
		setParent -menu $menu;

		// Enable some graph menu items only if a graph tab (work area) is 
		// visible
		//
		int $enable;
		$enable = isGraphTabVisible($panel);

		menuItem 
			-edit
			-enable $enable
			clearGraphItem;
		menuItem 
			-edit
			-enable $enable
			rearrangeGraphItem;
		menuItem 
			-edit
			-enable $enable
			showPreviousGraphItem;
		menuItem 
			-edit
			-enable $enable
			showNextGraphItem;
	}

	// Revert to the original parent.
	//
	if ($oldParent != "NONE") setParent $oldParent;
	if ($oldMenuParent != "NONE") setParent -menu $oldMenuParent;
}

global proc hyperShadePanelRefreshMenu(
	string $panel,
	string $menu)
{
	//
	// Description:
	//	This procedure is called whenever some procedure outside of this file
	//	needs to cause one of the hyperShadePanel menus to be updated.
	//	This procedure calls the appropriate local procedure to update the
	//	specified menu.
	//

	if ($menu == "Create")
	{
		refreshCreateMenu($panel);
	}
	else if ($menu == "Tabs")
	{
		refreshTabsMenu($panel);
	}
	else if ($menu == "Graph")
	{
		refreshGraphMenu($panel);
	}
	else 
	{
		// Somebody is trying to refresh a menu for which there is no refresh
		// procedure.
		//
		warning("Trying to refresh menu for which no refresh procedure exists");
	}
}

global proc hyperShadePanelRefreshCreateBar(
	string $panel)
{
	//
	// Description:
	//	This procedure is called when some procedure outside of this file has
	//	made a change to the state of Maya which requires the create bar
	//	contained within the hyperShadePanel to be updated.
	//	This procedure determines the name of the create bar and updates it.
	//
	renderCreateBarUIRefresh("MayaNodesTab");
	renderCreateBarUIRefresh("AllNodesTab");
}

global proc hyperShadePanelSetActiveTabLayout(
	string $panel,
    string $tabLayout,
    string $refreshFrontPane)
{
	//
	// Description:
	//	This procedure is invoked when the focus command on the hyper
    //  shade is run; this will occur when the mouse button is released
    //  in the view.
	//

	setParent paneArrangement;

    if ($tabLayout == "firstPaneTabs")
	{
        paneLayout -e -activePaneIndex 1 paneArrangement;
	}
    else if ($tabLayout == "secondPaneTabs")
	{
		if (`paneLayout -query -configuration paneArrangement` == "single")
		{
			paneLayout -e -activePaneIndex 1 paneArrangement;
		}
		else
		{
			paneLayout -e -activePaneIndex 2 paneArrangement;
		}
	}

	string $activeTab = activeTab( $panel );
		
    if ($activeTab == "")
    {
        // There is no tab in this tabLayout.  Nothing to do.
        //
        return;
    }

	//	When the HyperShade is created, hidden tabs are not
	//	enabled, so we must enable them when they become visible,
	//	i.e. now.
	//
	if( isSceneTab( $activeTab ) )
	{
		string $collectionUI = lookupComponentName( $activeTab );

        // If the $collectionUI is an empty string, then it means
        // we have not created the $collectionUI for this $activeTab.
        // So we create it.
        //
        if ($collectionUI == "")
        {
            refreshSceneTabContent( 
                $panel,
	            $tabLayout,
                $activeTab,
	            false);
		    $collectionUI = lookupComponentName( $activeTab );
        }
        else
        {
            // Since the tab content is not newly created, it 
            // needs to be refreshed to reflect the recent update
            // of bins being selected. 
            //
            if ($refreshFrontPane)
            {
                evalDeferred("refreshHyperShadePaneFrontTab "+$tabLayout+" false");
            }
        }
	}

    refreshSceneTabFilterForm($panel);
    refreshIconSize($panel, $activeTab);
	refreshViewOption($panel, $activeTab);
	refreshSortOption($panel, $activeTab);
	refreshReverseOption($panel, $activeTab);
	refreshToolbar($panel);
	refreshGraphMenu($panel);
}

proc int topTabsShown(
	string $panel)
{
	//
	// Description:
	//	This procedure determines whether the top tab section of the hypershade
	//	panel is being displayed.
	//
	// Returns: 
	//	True if the top tab section is being displayed, false otherwise.
	//
	string $tabSectionsShown = 
		`optionVar -query hyperShadePanelTabSectionsShown`;
	
	return (
			($tabSectionsShown == "showTopTabsOnly")
		||	($tabSectionsShown == "showTopAndBottomTabs"));
}

proc int bottomTabsShown(
	string $panel)
{
	//
	// Description:
	//	This procedure determines whether the bottom tab section of the 
	//	hypershade panel is being displayed.
	//
	// Returns: 
	//	True if the bottom tab section is being displayed, false otherwise.
	//
	string $tabSectionsShown = 
		`optionVar -query hyperShadePanelTabSectionsShown`;
	
	return (
			($tabSectionsShown == "showBottomTabsOnly")
		||	($tabSectionsShown == "showTopAndBottomTabs"));
}

proc showTopTabsOnly(
	string $panel)
{
	//
	// Description:
	//	This procedure causes the hypershade to reconfigure so that only the
	//	top tab section is visible.
	//

	setParent $panel;
	paneLayout
		-edit
		-configuration "single"
		-setPane firstPaneTabs 1
		-activePaneIndex 1
		paneArrangement;

	// Update the option var which remembers which tab sections are shown
	//
	optionVar 
		-stringValue 
			hyperShadePanelTabSectionsShown 
			"showTopTabsOnly";

	// Update the menus which are affected by this change
	//
    hyperShadePanelSetActiveTabLayout($panel, "firstPaneTabs", true);
	refreshTabsMenu($panel);
	refreshToolbar($panel);
}

proc showBottomTabsOnly(
	string $panel)
{
	//
	// Description:
	//	This procedure causes the hypershade to reconfigure so that only the
	//	bottom tab section is visible.
	//

	setParent $panel;
	paneLayout
		-edit
		-configuration "single"
		-setPane secondPaneTabs 1
		-activePaneIndex 1
		paneArrangement;

	// Update the option var which remembers which tab sections are shown
	//
	optionVar 
		-stringValue 
			hyperShadePanelTabSectionsShown 
			"showBottomTabsOnly";

	// Update the menus which are affected by this change
	//
    hyperShadePanelSetActiveTabLayout($panel, "secondPaneTabs", true);
	refreshTabsMenu($panel);
	refreshToolbar($panel);
}

proc showTopAndBottomTabs(
	string $panel)
{
	//
	// Description:
	//	This procedure causes the hypershade to reconfigure so that both the
	//	top and bottom tab sections are visible.
	//

	setParent $panel;

	int $activePaneIndex;

	// Determine whether it is the top or the bottom which is currently
	// visible, and thus which pane should be active once both are displayed.
	//
	if (topTabsShown($panel))
	{
		$activePaneIndex = 1;
	}
	else
	{
		$activePaneIndex = 2;
	}

	paneLayout
		-edit
		-configuration "horizontal2" // stacked
		-setPane firstPaneTabs 1
		-setPane secondPaneTabs 2
		-activePaneIndex 1
		paneArrangement;

	// Update the option var which remembers which tab sections are shown
	//
	optionVar 
		-stringValue 
			hyperShadePanelTabSectionsShown 
			"showTopAndBottomTabs";

	// Update the menus which are affected by this change
	//
    hyperShadePanelSetActiveTabLayout($panel, "firstPaneTabs", true);
    hyperShadePanelSetActiveTabLayout($panel, "secondPaneTabs", true);
	refreshTabsMenu($panel);
	refreshToolbar($panel);
}

proc selectTab(
	string $panel,
	string $tab)
{
	//
	// Description:
	//	This procedure selects the specified tab, bringing it to the front of
	//	its tab layout and making the pane in which it resides the active pane.
	//

	// Remember the current parent so we can revert to it when we're done here.
	//
	string $oldParent = `setParent -query`;
	string $oldMenuParent = `setParent -menu -query`;

	setParent $tab;
	string $tabLayout = `setParent ..`;
	string $tabPathTokens[];

	tokenize($tab, "|", $tabPathTokens);

	string $tabShortName = $tabPathTokens[size($tabPathTokens) - 1];
	string $tabLayoutShortName = $tabPathTokens[size($tabPathTokens) - 2];

	// If the tab to be selected is in a tab section which is not currently
	// shown, we will switch to show both tab sections so the user can see the
	// tab.
	//
	if (
			(	($tabLayoutShortName == "firstPaneTabs") 
			&& 	(!topTabsShown($panel)))
		||	(	($tabLayoutShortName == "secondPaneTabs") 
			&& 	(!bottomTabsShown($panel))))
	{
		showTopAndBottomTabs($panel);
	}

	// Select the tab
	//
	tabLayout
		-edit
		-selectTab $tabShortName
		$tabLayout;

	// Set the active pane to the layout which contains the selected tab
	//
	setParent $panel;

	if (
			($tabLayoutShortName == "firstPaneTabs")
		||	(!topTabsShown($panel)))
	{
		paneLayout
			-edit
			-activePaneIndex 1
			paneArrangement;
	}
	else
	{
		paneLayout
			-edit
			-activePaneIndex 2
			paneArrangement;
	}

	// Revert to the original parent.
	//
	if ($oldParent != "NONE") setParent $oldParent;
	if ($oldMenuParent != "NONE") setParent -menu $oldMenuParent;
}

proc revertToDefaultTabs(
	string $panel)
{
	//
	// Description:
	//	This procedure removes all tabs from the hypershade panel and creates
	//	the default set of tabs. 
	//

	//	flag this as a "construction" operation.  This will prevent
	//	many unnecessary refreshes of the various tabs as they are
	//	removed.
	//
	hyperShadeStartConstruction( $panel );


	setParent $panel;
	string $mainForm = `setParent mainForm`;
	formLayout -edit -manage false $mainForm;

	// Delete all tabs
	//
	int $i;
	string $tabArray[];
	string $tab;

    // Store previous activePane.
    //
    string $previousActivePane = `paneLayout -query -activePane  paneArrangement`;

    paneLayout -edit -activePane "firstPaneTabs" paneArrangement; 

	$tabArray = `tabLayout -query -childArray firstPaneTabs`;

	for ($i = 0; $i < size($tabArray); $i++)
	{
		setParent $panel;
		$tab = `setParent $tabArray[$i]`;
		removeTab($tab);
	}

    paneLayout -edit -activePane "secondPaneTabs" paneArrangement; 
	$tabArray = `tabLayout -query -childArray secondPaneTabs`;

	for ($i = 0; $i < size($tabArray); $i++)
	{
		setParent $panel;
		$tab = `setParent $tabArray[$i]`;
		removeTab($tab);
	}

    // Restore previous activePane.
    //
    paneLayout -edit -activePane $previousActivePane paneArrangement;

	formLayout -edit -manage true $mainForm;

	// Create the default tabs
	//
	createSceneTab(
		$panel,
		"firstPaneTabs",
		"Materials",
		"MaterialsAndShaderGlow");

	createSceneTab(
		$panel,
		"firstPaneTabs",
		"Textures",
		"Textures");

	createSceneTab(
		$panel,
		"firstPaneTabs",
		"Utilities",
		"Utilities");

	createSceneTab(
		$panel,
		"firstPaneTabs",
		"Lights",
		"LightsAndOpticalFX");

	createSceneTab(
		$panel,
		"firstPaneTabs",
		"Cameras",
		"Cameras");

	createSceneTab(
		$panel,
		"firstPaneTabs",
		"Shading Groups",
		"ShadingGroups");

	createSceneTab(
		$panel,
		"firstPaneTabs",
		"Bake Sets",
		"BakeSets");

	string $projectsDir = `internalVar -userWorkspaceDir`;

	createDiskTab(
		$panel,
		"firstPaneTabs",
		"Projects",
		$projectsDir);

	createGraphTab(
		$panel,
		"secondPaneTabs",
		"Work Area",
		true);

	string $shaderLibraryDir = `getenv MAYA_SHADER_LIBRARY_PATH`;

	if ($shaderLibraryDir != "")
	{
		optionVar -intValue hyperShadeShaderLibraryTabCreated 1;
		createDiskTab(
			$panel,
			"secondPaneTabs",
			"Shader Library",
			$shaderLibraryDir);
	}

	// If this is the first time the user has opened hypershade since 3.0, and
	// they have custom disk folders defined in their userPrefs, we will create
	// a tab for each of those custom disk folders.
	//
	if (	(!`optionVar -exists customFoldersConvertedForHypershade`)
		&&	(`optionVar -exists visorCustomDiskFolders`))
	{
		// Get from an optionVar the list of directories for which custom disk 
		// folders were created. Create a disk tab for each.
		//
		int 	$i;
		string 	$customFolderNameArray[];

		$customFolderNameArray = `optionVar -query visorCustomDiskFolders`;

		for ($i = 0; $i < size($customFolderNameArray); $i++)
		{
			// Tokenize the path stored in $customFolderNameArray[$i] so that
			// we can have a shorter name for the tab.
			//
			string $pathTokens[];
			tokenize $customFolderNameArray[$i] "/" $pathTokens;

			createDiskTab(
				$panel,
				"secondPaneTabs",
				$pathTokens[size($pathTokens) - 1],
				$customFolderNameArray[$i]);
		}

		if (`optionVar -exists customFoldersConvertedForVisor`)
		{
			// These custom disk folders have also already been added to Visor.
			// This means that we no longer need to keep the
			// visorCustomDiskFolders optionVar around.
			// We also don't need the customFoldersConvertedForVisor optionVar
			// anymore because it has served its purpose.
			//
			optionVar -remove visorCustomDiskFolders;
			optionVar -remove customFoldersConvertedForVisor;
		}
		else
		{
			// Set an optionVar to indicate that these custom disk folders have
			// already been added to Hypershade
			//
			optionVar -intValue customFoldersConvertedForHypershade true;
		}
	}

	// Update the tab layout option vars now that the tabs have been reverted
	//
	updateTabLayoutOptionVar($panel, "firstPaneTabs");
	updateTabLayoutOptionVar($panel, "secondPaneTabs");

	// Now that we have created all the tabs we need, we delete any option vars
	// which describe tabs that did not get used.
	//
	deleteUnusedTabOptionVars($panel);

    // Refresh the scene tab filter form in the toolbar.
    //
    refreshSceneTabFilterForm($panel);

	//	Signal the end of the construction operation.  Specify
	//	that the HyperShade is still around, so the active tabs
	//	must be refreshed.
	//
	hyperShadeEndConstruction( $panel, 1 );
}

proc initTabs(string $panel)
{
	//
	// Description:
	//	This procedure is called the first time the hypershade panel is opened
	//	during a Maya session.
	//	This procedure uses the optionVars which describe the contents of the
	//	hypershade panel tab layouts and tabs in order to recreate the
	//	hypershade panel as it appeared when it was last open.
	//	If no such optionVars exist, this procedure causes the default tabs to
	//	be created.
	//

	// Clear the lookup table because we are creating a fresh visor panel
	//
	global string $gHyperShadePanelLookupTable[];
	lookupTableReset($gHyperShadePanelLookupTable);

	// In Maya 4.0, trying to reuse editors was problematic because the
	// contents of the editor would be badly positioned when hypershade was
	// reopened with a reused editor. So we will not reuse editors for 4.0, but
	// may do so in the future.
	//
	int $reuseEditors = false;

	if (!`optionVar -exists hyperShadeFirstPaneTabs`)
	{
		// The option vars which should contain the names of the option vars
		// describing the tabs in the tab layouts do not exist.
		// This indicates that this is the first time the user is using
		// this version of Maya, or that their prefs have been deleted.
		// In this situation we want to fill the shader editor with what we
		// consider to be useful and appropriate default tabs.
		//
		revertToDefaultTabs($panel);
		return;
	}

	// If we get to here, it means the user already has option vars in their
	// prefs to describe the tabs they expect to see in their shader editor.
	// 
	// We will read ther user's preferred set of tabs from optionVars and 
	// create them.
	//
	int $i;

    // First Pane
    //

    // If the optionVar does not exists, it means that there is no
    // tab in it.  If it exists, recreate the tabs.
    //
    if (`optionVar -exists hyperShadeFirstPaneTabs` &&
        size(`optionVar -q hyperShadeFirstPaneTabs`) != 0)
    {
	    string $firstPaneTabVars[];
	    $firstPaneTabVars = `optionVar -query hyperShadeFirstPaneTabs`;

	    setParent $panel;
	
	    for ($i = 0; $i < size($firstPaneTabVars); $i++)
	    {
		    recreateTab(
			    $panel,
			    "firstPaneTabs",
			    $firstPaneTabVars[$i],
			    $reuseEditors);
	    }
    }

    // Second Pane
    //

    // If the optionVar does not exists, it means that there is no
    // tab in it.  If it exists, recreate the tabs.
    //
    if (`optionVar -exists hyperShadeSecondPaneTabs` &&
        size(`optionVar -q hyperShadeSecondPaneTabs`) != 0)
    {
		string $secondPaneTabVars[];
		$secondPaneTabVars = `optionVar -query hyperShadeSecondPaneTabs`;
	
		setParent $panel;
		
		for ($i = 0; $i < size($secondPaneTabVars); $i++)
		{
			recreateTab(
				$panel,
				"secondPaneTabs",
				$secondPaneTabVars[$i],
				$reuseEditors);
		}
	
		// If the shader library has never been added as a hypershade tab, we will
		// check to see if it exists and add it if it does.
		// In this way, the user will always get a shader library tab created for
		// them when they install the shader library, but if they delete that tab
		// it won't come back unless they revert to default tabs or delete their
		// userPrefs.
		//
		if (!`optionVar -exists hyperShadeShaderLibraryTabCreated`)
		{
			string $shaderLibraryDir = `getenv MAYA_SHADER_LIBRARY_PATH`;
	
			if ($shaderLibraryDir != "")
			{
				optionVar -intValue hyperShadeShaderLibraryTabCreated 1;
				createDiskTab(
					$panel,
					"secondPaneTabs",
					"Shader Library",
					$shaderLibraryDir);
			}
		}
    }

	// Now that we have created all the tabs we need, we delete any option vars
	// which describe tabs that did not get used.
	//
	deleteUnusedTabOptionVars($panel);

	// Update the toolbar and menus to reflect the currently active tab.
	//
	refreshToolbar($panel);
	refreshGraphMenu($panel);
}

global proc hyperShadePanelRootDirectoryBrowse()
{
	//
	// Description:
	//	This procedure is called when the user clicks on the browse button
	//	beside the root directory text field in the create new tab dialog for
	//	disk tabs.
	//	This procedure opens a file browser so the user can browse for the
	//	directory they want the tab to point at.
	//

	setParent hyperShadePanelCreateNewTabWindow;

	string $initialDirectory = `textField -query -fileName rootDirectoryField`;

	if (`filetest -d $initialDirectory`)
	{
		workspace -dir $initialDirectory;
	}
	else
	{
		string  $workspace = `workspace -query -fullName`;
		setWorkingDirectory($workspace, "", "");
	}

	fileBrowser("hyperShadePanelRefreshRootDirectoryBrowseField", "Open", "", 4);
}

global proc int hyperShadePanelRefreshRootDirectoryBrowseField(
	string $directory, 
	string $type)
{
	//
	// Description:
	//	This procedure is called by the file browser the user uses to choose a
	//	directory to which a new disk tab will point. 
	//	This procedure confirms that the user's selection is indeed a
	//	directory. If so, this procedure updates the root directory text field
	//	of the create new tab window.
	//
	// Returns: 
	//	1 if the $directory was a valid directory name, thereby causing the
	//	file browser to close.
	//	0 if the $directory was not a directory name, thereby causing the file
	//	browser to remain open.
	//

	if (`window -exists hyperShadePanelCreateNewTabWindow`)
	{
		if (`filetest -d $directory`)
		{
			setParent hyperShadePanelCreateNewTabWindow;
			textField
				-edit
				-fileName $directory
				rootDirectoryField;
			return 1;
		}
		else
		{
			confirmDialog
				-title "Invalid directory"
				-message 
					("The specified root directory is invalid.\n"
						+ "Please specify a valid directory.")
				-messageAlign center
				-button "Close";
			return 0;
		}
	}
	else
	{
		return 1;
	}
}

global proc hyperShadePanelCreateNewTabFinish(
	string $panel,
	int $dismiss)
{
	//
	// Description:
	//	This procedure is called when the user clicks on the Create button in
	//	the create new tab dialog. 
	//	This procedure examines the settings of the controls in the create new
	//	tab dialog to determine the details of the tab the user wants to
	//	create, and then creates the tab.
	//

	setParent hyperShadePanelCreateNewTabWindow;
	string 	$tabLabel;
	int 	$initialPlacementIndex;
	int 	$tabTypeIndex;
	string 	$tabLayout;

	$tabLabel = `textFieldGrp -query -text newTabNameGrp`;
    if ($tabLabel == "")
    {
        // Empty string is not allowed as tab label.
        //
        warning("The empty string is not a valid tab label.  Please enter a valid name as the tab label.");
        return;
    }

	$initialPlacementIndex = `radioButtonGrp -q -select initialPlacementGrp`;
	$tabTypeIndex = `radioButtonGrp -query -select tabTypeGrp`;

	if ($initialPlacementIndex == 1)
	{
		$tabLayout = "firstPaneTabs";
	}
	else
	{
		$tabLayout = "secondPaneTabs";
	}

	string $newTab = "";

	switch ($tabTypeIndex)
	{
		case 1: // Scene
			string $filter;
			$filter = `optionMenuGrp -query -value sceneTabFilterGrp`;

			//	Take the menu item text and figure out the internal name
			//	of this type of filtered collection.
			//	
			string $internalFilterName = filteredCollection_InternalName( $filter );

			//	flag this as a "construction" operation.  This will prevent
			//	many unnecessary refreshes of the various tabs as they are
			//	removed.
			//
			hyperShadeStartConstruction( $panel );

			$newTab = createSceneTab(
				$panel,
				$tabLayout,
				$tabLabel,
				$internalFilterName);
			break;
		case 2: // Disk
			string $rootDirectory = 
				`textField -query -text rootDirectoryField`;
			if (!`filetest -d $rootDirectory`)
			{
				confirmDialog
					-title "Invalid directory"
					-message 
						("The specified root directory is invalid.\n"
							+ "Please specify a valid directory.")
					-messageAlign center
					-parent hyperShadePanelCreateNewTabWindow
					-button "Close";
				return;
			}
			int $showFilesOnly = 
				`checkBoxGrp -query -value1 onlyShowFilesCheckBox`;
			
			if (`about -win`)
			{
				// The root directory must end in a "\" on NT otherwise weird 
				// things happen.
				//
				$rootDirectory = ($rootDirectory + "\\");
			}

			$newTab = createDiskTab(
				$panel,
				$tabLayout,
				$tabLabel,
				$rootDirectory);

			// Specify whether the new tab should show directories
			//
			if ($showFilesOnly)
			{
				string $libraryUI = lookupComponentName($newTab);
				libraryUIShowFilesOnly($libraryUI);
			}
			break;
		case 3: // Graph
			$newTab = createGraphTab(
				$panel,
				$tabLayout,
				$tabLabel,
				false);
			break;
		default:
			break;
	}

	// Update the tab layout option vars now that a tab has been added
	//
	updateTabLayoutOptionVar($panel, $tabLayout);

	if ($newTab != "")
	{
		// Bring the new tab to the front
		//
		selectTab($panel, $newTab);
	}

	if( $tabTypeIndex == 1 )
	{
		//	Signal the end of the construction operation.  Specify
		//	that the HyperShade is still around, so the active tabs
		//	must be refreshed.
		//
		//	Do this here because we want to refresh the panel that
		//	is active at the end of the operation.  
		//
		hyperShadeEndConstruction( $panel, 1 );
	}


	if ($dismiss)
	{
		// Close the create new tab dialog
		//
		deleteUI hyperShadePanelCreateNewTabWindow;
	}
}

global proc hyperShadePanelRefreshCreateNewTabWindow()
{
	//
	// Description:
	//	This procedure is called when the user changes the type of tab to be
	//	created in the create new tab dialog. 
	//	This procedure updates the UI of the create new tab dialog to show only
	//	the options which are applicable to a tab of the user's chosen type.
	//

	setParent hyperShadePanelCreateNewTabWindow;

	int $tabTypeIndex = `radioButtonGrp -query -select tabTypeGrp`;

	switch ($tabTypeIndex)
	{
		case 1: // Scene
			optionMenuGrp
				-edit
				-manage true
				sceneTabFilterGrp;
			rowLayout
				-edit
				-manage false
				directoryNameLayout;
			checkBoxGrp
				-edit
				-manage false
				onlyShowFilesCheckBox;
			break;
		case 2: // Disk
			optionMenuGrp
				-edit
				-manage false
				sceneTabFilterGrp;
			rowLayout
				-edit
				-manage true
				directoryNameLayout;
			checkBoxGrp
				-edit
				-manage true
				onlyShowFilesCheckBox;
			break;
		case 3: // Graph
			optionMenuGrp
				-edit
				-manage false
				sceneTabFilterGrp;
			rowLayout
				-edit
				-manage false
				directoryNameLayout;
			checkBoxGrp
				-edit
				-manage false
				onlyShowFilesCheckBox;
			break;
		default:
			break;
	}
}

proc createNewTab(
	string $panel)
{
	//
	// Description:
	//	This procedure is called when the user chooses Create New Tab... from
	//	the hypershade panel menu.
	//	This procedure builds and opens the create new tab dialog.
	//

	if (`window -exists hyperShadePanelCreateNewTabWindow`)
	{
		showWindow hyperShadePanelCreateNewTabWindow;
		return;
	}

	//
	// If we get to here, the create new tab window does not already exist, so 
	// we will create it.
	//
	int $windowWidth = 450;
	int $windowHeight = 200;
	
	window 
		-title "Create New Tab"
		-width $windowWidth
		-height $windowHeight
		-iconName "New Tab"
		hyperShadePanelCreateNewTabWindow;
	
	setUITemplate -pushTemplate DefaultTemplate;
	
	formLayout mainForm;
		scrollLayout
			-horizontalScrollBarThickness 0
			mainScroll;

			columnLayout scrollColumn;
				textFieldGrp
					-label "New Tab Name"
					newTabNameGrp;
				radioButtonGrp
					-label "Initial Placement"
					-numberOfRadioButtons 2
					-label1 "Top"
					-label2 "Bottom"
					-select 1 // Top is the default
					initialPlacementGrp;
				radioButtonGrp
					-label "Tab Type"
					-numberOfRadioButtons 3
					-label1 "Scene"
					-label2 "Disk"
					-label3 "Work Area"
					-changeCommand "hyperShadePanelRefreshCreateNewTabWindow"
					-select 1 // Scene is the default
					tabTypeGrp;
				separator -style "in";
				formLayout sceneTabOptionsWrap;
					optionMenuGrp
						-label "Show Nodes Which Are"
						sceneTabFilterGrp;

						string $sceneTabTypes[] = filteredCollection_ListTypes();
						string $st;
						for( $st in $sceneTabTypes )
						{
							menuItem -label $st;
						}

					setParent -menu ..; // from option menu
					formLayout
						-edit
						-af sceneTabFilterGrp left 0
						-af sceneTabFilterGrp right 0
						-af sceneTabFilterGrp top 0
						-af sceneTabFilterGrp bottom 0
						sceneTabOptionsWrap;
				setParent ..; // from sceneTabOptionsWrap
				formLayout diskTabOptionsWrap;
					rowLayout
						-numberOfColumns 3
						-columnWidth 2 225
						-columnWidth 3 25
						directoryNameLayout;
						text 
							-label "Root Directory";
						textField
							-width 150
							rootDirectoryField;
						symbolButton
							-width 10
							-image "navButtonBrowse.xpm" 
							-command "hyperShadePanelRootDirectoryBrowse"
							browseButton;
					setParent ..; // from directoryNameLayout
					checkBoxGrp
						-numberOfCheckBoxes 1
						-label1 "Only Show Files (Hide Directory Tree)"
						onlyShowFilesCheckBox;
					formLayout
						-edit
						-af directoryNameLayout left 0
						-af directoryNameLayout right 0
						-af directoryNameLayout top 0
						-an directoryNameLayout bottom
						-af onlyShowFilesCheckBox left 0
						-af onlyShowFilesCheckBox right 0
						-ac onlyShowFilesCheckBox top 0 directoryNameLayout
						-af onlyShowFilesCheckBox bottom 0
						diskTabOptionsWrap;
				setParent ..; // from diskTabOptionsWrap
			setParent ..; // from scrollColumn
		setParent ..; // from mainScroll

		formLayout 
			-numberOfDivisions 3
			buttonForm;

			button
				-label "Create"
				-command 
					("hyperShadePanelCreateNewTabFinish " 
						+ $panel
						+ " "
						+ "1")
				createButton;
			button
				-label "Apply"
				-command
					("hyperShadePanelCreateNewTabFinish " 
						+ $panel
						+ " "
						+ "0")
				applyButton;
			button
				-label "Close"
				-command "deleteUI hyperShadePanelCreateNewTabWindow"
				closeButton;

			formLayout
				-edit
				-af createButton left 0
				-ap createButton right 2 1
				-af createButton top 0
				-af createButton bottom 0

				-ap applyButton left 3 1
				-ap applyButton right 2 2
				-af applyButton top 0
				-af applyButton bottom 0

				-ap closeButton left 3 2
				-af closeButton right 0
				-af closeButton top 0
				-af closeButton bottom 0
				buttonForm;
		setParent ..; // from buttonForm

		formLayout
			-edit

			-af mainScroll left 0
			-af mainScroll right 0
			-af mainScroll top 0
			-ac mainScroll bottom 5 buttonForm

			-af buttonForm left 5
			-af buttonForm right 5
			-an buttonForm top
			-af buttonForm bottom 5
			
			mainForm;
	setParent ..; // from mainForm

	setUITemplate -popTemplate;

	hyperShadePanelRefreshCreateNewTabWindow;

	showWindow hyperShadePanelCreateNewTabWindow;
}

global proc hyperShadePanelRenameTabFinish(
	string $panel)
{
	//
	// Description:
	//	This procedure is called when the user clicks on the Rename button in
	//	the rename tab dialog. 
	//	This procedure examines the settings of the controls in the rename
	//	tab dialog to determine the new name for the tab, then renames the tab.
	//

	setParent hyperShadePanelRenameTabWindow;
	string 	$tabLabel;

	$tabLabel = `textFieldGrp -query -text newTabNameGrp`;

	setTabLabel(activeTab($panel), $tabLabel);
	deleteUI hyperShadePanelRenameTabWindow;
}

proc renameTab(
	string $panel)
{
	//
	// Description:
	//	This procedure is called when the user chooses Rename Tab... from
	//	the hypershade panel menu.
	//	This procedure builds and opens the rename tab dialog.
	//

	if (`window -exists hyperShadePanelRenameTabWindow`)
	{
		showWindow hyperShadePanelRenameTabWindow;
		return;
	}

	//
	// If we get to here, the rename tab window does not already exist, so 
	// we will create it.
	//
	
	int $windowWidth = 425;
	int $windowHeight = 110;

	window 
		-title "Rename Tab"
		-width $windowWidth
		-height $windowHeight
		-iconName "Rename Tab"
		hyperShadePanelRenameTabWindow;
	
	setUITemplate -pushTemplate DefaultTemplate;
	
	formLayout mainForm;
		columnLayout mainColumn;
			textFieldGrp 
				-label "Old Tab Name"
				-editable false
				-text `activeTabLabel($panel)`
				oldTabNameGrp;
			textFieldGrp 
				-label "New Tab Name"
				newTabNameGrp;
		setParent ..; // from mainColumn

		formLayout 
			-numberOfDivisions 2
			buttonForm;

			button
				-label "Rename"
				-command ("hyperShadePanelRenameTabFinish " + $panel)
				renameButton;
			button
				-label "Close"
				-command "deleteUI hyperShadePanelRenameTabWindow"
				closeButton;

			formLayout
				-edit
				-af renameButton left 5
				-ap renameButton right 2 1
				-af renameButton top 5
				-af renameButton bottom 5

				-ap closeButton left 3 1
				-af closeButton right 5
				-af closeButton top 5
				-af closeButton bottom 5
				buttonForm;
		setParent ..; // from buttonForm

		formLayout
			-edit

			-af mainColumn left 0
			-af mainColumn right 0
			-af mainColumn top 0
			-af mainColumn bottom 35

			-af buttonForm left 0
			-af buttonForm right 0
			-ac buttonForm top 0 mainColumn
			-af buttonForm bottom 0
			
			mainForm;
	setParent ..; // from mainForm

	setUITemplate -popTemplate;

	showWindow hyperShadePanelRenameTabWindow;
}

global proc string hyperShadePanelCreate(
	string $as,
	string $type)
{
	//
	// Description:
	//	This procedure is called when the user chooses to create a node from
	//	the hyperShadePanel Create menu.
	//	This procedure creates a node of the nodeType specified in $type, and
	//	using the $as argument to hook up the new node so that it may be
	//	properly filtered within the UI.
	//	Mostly this procedure calls renderCreateNode to perform the creation.
	//
	// Returns: 
	//	The name of the node which was created.
	//

	string $name;

	if ($as == "shader")
	{
		int $withShadingGroup = 
			`optionVar -query createMaterialsWithShadingGroup`;

		string $classification[] = `getClassification $type`;
		string $dest;

		if (substring($classification[0], 1, 19) == "shader/displacement") 
		{
			$dest = "displacementShader";
		} 
		else if (substring($classification[0], 1, 13) == "shader/volume") 
		{
			$dest = "volumeShader";
		} 
		else 
		{
			$dest = "surfaceShader";
		}
		
		string $name = 
			renderCreateNode( 
				"-asShader", 
				$dest, 
				$type, 
				"", 
				0, 
				0, 
				1,
				$withShadingGroup,
				0, 
				"");
	}
	else if ($as == "2dTexture")
	{
		int $asNormal;
		int $asProjection;
		int $asStencil;
		int $withPlacement;

		$asNormal = 
			(`optionVar -query create2dTextureType` == "normal");
		$asProjection = 
			(`optionVar -query create2dTextureType` == "projection");
		$asStencil = 
			(`optionVar -query create2dTextureType` == "stencil");
		$withPlacement = 
			(`optionVar -query createTexturesWithPlacement`);

		$name = 
			renderCreateNode(
				"-as2DTexture",
				"",
				$type,
				"", 
				$asProjection, 
				$asStencil,
				$withPlacement,
				0, 
				0, 
				"");
	}
	else if ($as == "3dTexture")
	{
		int $withPlacement;
		$withPlacement = (`optionVar -query createTexturesWithPlacement`);
		$name = 
			renderCreateNode(
				"-as3DTexture", 
				"",
				$type,
				"",
				0, 
				0,
				$withPlacement,
				0,
				0,
				"");
	}
	else if ($as == "otherTexture")
	{
		$name = `renderCreateNode "-asTexture" "" $type "" 0 0 0 0 0 ""`;
	}
	else if ($as == "light")
	{
		$name = `renderCreateNode "-asLight" "" $type "" 0 0 0 0 0 ""`;
	}
	else if ($as == "utility")
	{
		$name = `renderCreateNode "-asUtility" "" $type "" 0 0 0 0 0 ""`;
	}
	else if ($as == "camera")
	{
		string $cameraNames[];
		$cameraNames = `camera`;
		$name = $cameraNames[0];
	}
	else if ($as == "node")
	{
		$name = `createNode $type`;
	}

	return $name;
}

proc string smallUIName (string $nodeName)
{
	// In most cases we can just take the given name and
	// add spaces to make it more appealing.  For a few
	// larger names we will override the name with a
	// shorter version.  This makes the whole window smaller.
	//
	string $labelName;

	switch ($nodeName) {
		case "psdFileTex":
			$labelName = "PSD File" ;
			break ;
		default:
			$labelName = interToUI($nodeName);
			break;
	}	
	
 	return $labelName;
}

global proc buildCreateSubMenu(
	string $classification, 
	string $callback)
{
	//
	// Description:
	//	This procedure is called from buildMainMenu().
	//	This procedure builds a menu which allows the user to create nodes of
	//	the specified classification.
	//	The specified callback script is the one which is called to do the
	//	creation of a node of a particular type.
	//

	// some of mental ray shaders are registered as both 
	// rendernode/mentalray/material and shaders/surface
	// For those node, this function is called twice : 
	// once with $classification = shader/surface, 
	// once with $classification = rendernode/mentalray/material
	// We want to create buttons/menus in mental ray section

	string $types[];
	string $mentalrayClassfication = "rendernode/mentalray";

	if( startsWith($classification, $mentalrayClassfication) ) 
	{
		$types = `listNodeTypes $classification`;
	}
	else
	{
		$types = `listNodeTypes -ex $mentalrayClassfication $classification`;
	}


	for($type in $types) 
	{
		// Check whether node should appear in this UI, based on 
		// certain variables			
		if (!shouldAppearInNodeCreateUI($type)) {
			continue;
		}

		string $typeString = smallUIName( $type );
		menuItem 
			-label $typeString
			-annotation 
				("Create a new " 
					+ $typeString 
					+ " node")
			-command ($callback + " " + $type ); 
	}
}

proc buildCreateNodesSubMenu(
	string $types[], 
	string $callback)
{
	//
	// Description:
	//	This procedure is called from buildMainMenu().
	//	This procedure builds menu items to create nodes of the nodeTypes
	//	specified in $types[].
	//	The specified callback script is the one which is called to do the
	//	creation of a node of a particular type.
	//

	for($type in $types) 
	{
		string $typeString = `interToUI $type`;
		menuItem 
			-label $typeString
			-annotation 
				("Create a new " 
					+ $typeString 
					+ " node")
			-command ($callback + "(\"" + $type + "\")");
	}
}

proc buildMainMenu(
	string $panel,
	int $isPopupMenu)
//
// Description:
//	This procedure is called when the hypershade panel is first opened.
//	This procedure creates menus in the top menubar of the hypershade panel. 
//
{
	string $menuPrefix;

	if ($isPopupMenu)
	{
		$menuPrefix = "hyperShadePopupMenu";
	}
	else
	{
		$menuPrefix = "hyperShadePanelMenu";
	}

	// Build the File menu
	//
	if ($isPopupMenu)
	{
		menuItem
			-subMenu true
			-label "File" 
			-tearOff true 
			($menuPrefix + "FileMenu");
	}
	else
	{
		menu 
			-label "File" 
			-tearOff true 
			($menuPrefix + "FileMenu");
	}

		menuItem 
			-label "Import..." 
			-annotation "Import a shading network or other file"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"import\")");
		menuItem -divider true;
		menuItem 
			-label "Export Selected Network"
			-annotation "Export the selected shading network or other items"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"exportSelectedNetwork\")");
	
	// Build the Edit menu
	//
	if ($isPopupMenu)
	{
		setParent -menu ..;
		menuItem
			-postMenuCommand 
				("hyperShadePanelBuildEditMenu " 
					+ $panel 
					+ " " 
					+ $menuPrefix 
					+ "EditMenu")
			-subMenu true
			-label "Edit" 
			-allowOptionBoxes true 
			-tearOff true 
			($menuPrefix + "EditMenu");
	}
	else
	{
		menu
			-postMenuCommand 
				("hyperShadePanelBuildEditMenu " 
					+ $panel 
					+ " " 
					+ $menuPrefix 
					+ "EditMenu")
			-label "Edit" 
			-allowOptionBoxes true 
			-tearOff true 
			($menuPrefix + "EditMenu");
	}

	// Build the View menu
	//
	if ($isPopupMenu)
	{
		setParent -menu ..;
		menuItem
			-subMenu true
			-label "View" 
			-tearOff true 
			($menuPrefix + "ViewMenu");
	}
	else
	{
		menu 
			-label "View" 
			-tearOff true 
			($menuPrefix + "ViewMenu");
	}

		menuItem 
			-label "Frame All"
			-annotation "Frame All: Reset the view to frame all nodes/files"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"frameAll\")");
		menuItem 
			-label "Frame Selected"
			-annotation 
				"Frame Selection: Reset the view to frame selected nodes/files"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"frameSelected\")");

		menuItem -divider true;

        radioMenuItemCollection;
            $menuItemName = "asIcons";
		    menuItem 
			    -label "as Icons" 
                -radioButton off
			    -command 
				    ("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \""+$menuItemName+"\")")
                    $menuItemName;

            $menuItemName = "asList";
		    menuItem 
			    -label "as List" 
                -radioButton off
			    -command 
				    ("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \""+$menuItemName+"\")")
                    $menuItemName;             
			
		menuItem -divider true;

        radioMenuItemCollection;
            $menuItemName = "smallIcons";
		    menuItem 
			    -label "as Small Swatches" 
                -radioButton off
			    -command 
				    ("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \""+$menuItemName+"\")")
                    $menuItemName;

            $menuItemName = "mediumIcons";
		    menuItem 
			    -label "as Medium Swatches" 
                -radioButton off
			    -command 
				    ("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \""+$menuItemName+"\")")
                    $menuItemName;
        
            $menuItemName = "largeIcons";
		    menuItem 
			    -label "as Large Swatches" 
                -radioButton off
			    -command 
				    ("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \""+$menuItemName+"\")")
                    $menuItemName;       

            $menuItemName = "superIcons";
		    menuItem 
			    -label "as Extra Large Swatches" 
                -radioButton off
			    -command 
				    ("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \""+$menuItemName+"\")")
                    $menuItemName;       

		menuItem -divider true;

        radioMenuItemCollection;
            $menuItemName = "byName";
		    menuItem 
			    -label "by Name" 
                -radioButton off
			    -command 
				    ("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \""+$menuItemName+"\")")
                    $menuItemName;

            $menuItemName = "byType";
		    menuItem 
			    -label "by Type" 
                -radioButton off
			    -command 
				    ("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \""+$menuItemName+"\")")
                    $menuItemName;
        
            $menuItemName = "byTime";
		    menuItem 
			    -label "by Time" 
                -radioButton off
			    -command 
				    ("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \""+$menuItemName+"\")")
                    $menuItemName;

		menuItem -divider true;

		$menuItemName = "reverseOrder";
		menuItem 
			-label "reverse order" 
            -checkBox false
			-command 
				("hyperShadePanelMenuCommand(\"" 
				+ $panel 
				+ "\", \""+$menuItemName+"\")")
                $menuItemName;
        
		
	// Build the Create menu
	//
	if ($isPopupMenu)
	{
		setParent -menu ..;
		menuItem
			-subMenu true
			-label "Create" 
			-allowOptionBoxes true
	/*		-postMenuCommand (
				"hyperShadePanelBuildCreateMenu " 
				+ $panel 
				+ " " 
				+ $menuPrefix 
				+ "CreateMenu")
			-postMenuCommandOnce true*/
			-tearOff true 
			($menuPrefix + "CreateMenu");
	}
	else
	{
		menu 
			-label "Create" 
			-allowOptionBoxes true 
		/*	-postMenuCommand (
				"hyperShadePanelBuildCreateMenu " 
				+ $panel 
				+ " " 
				+ $menuPrefix 
				+ "CreateMenu")
			-postMenuCommandOnce false*/
			-tearOff true 
			($menuPrefix + "CreateMenu");
	}

	hyperShadePanelBuildCreateMenu($panel, $menuPrefix);
	// Build the Tabs menu
	//
	if ($isPopupMenu)
	{
		setParent -menu ..;
		menuItem
			-subMenu true
			-label "Tabs" 
			-tearOff true 
			($menuPrefix + "TabsMenu");
	}
	else
	{
		menu 
			-label "Tabs" 
			-tearOff true 
			($menuPrefix + "TabsMenu");
	}

		menuItem 
			-label "Create New Tab..."
			-annotation ("Create New Tab: Add a new tab to the Hypershade")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"createNewTab\")");
		menuItem -divider true;
		menuItem 
			-label "Move Tab Up" 
			-annotation 
				("Move Tab Up: Move the frontmost bottom tab to the top")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"moveTabUp\")")
			tabsMoveTabUpItem;
		menuItem 
			-label "Move Tab Down"
			-annotation 
				("Move Tab Down: Move the frontmost top tab to the bottom")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"moveTabDown\")")
			tabsMoveTabDownItem;
		menuItem 
			-label "Move Tab Left" 
			-annotation 
				("Move Tab Left: Move the active tab left within its tab "
					+ "section")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"moveTabLeft\")");
		menuItem 
			-label "Move Tab Right" 
			-annotation 
				("Move Tab Right: Move the active tab right within its tab "
					+ "section")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"moveTabRight\")");
		menuItem -divider true;
		menuItem 
			-label "Rename Tab..." 
			-annotation 
				("Rename Tab: Rename the current tab")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"renameTab\")");
		menuItem -divider true;
		menuItem 
			-label "Remove Tab"
			-annotation 
				("Remove Tab: Remove the active tab from Hypershade")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"removeTab\")");
		menuItem 
			-label "Revert to Default Tabs" 
			-annotation 
				("Revert to Default Tabs: Remove all tabs from Hypershade and "
					+ "create default tabs to replace them")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"revertToDefaultTabs\")");
		menuItem -divider true;
			
		radioMenuItemCollection;
		menuItem 
			-label "Show Top Tabs Only"
			-radioButton 
				(`optionVar -q hyperShadePanelTabSectionsShown` 
					== "showTopTabsOnly")
			-annotation
				("Show Top Tabs Only: Hide the bottom tab section")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"showTopTabsOnly\")")
			tabsShowTopTabsOnlyItem;
		menuItem 
			-label "Show Bottom Tabs Only"
			-radioButton 
				(`optionVar -q hyperShadePanelTabSectionsShown` 
					== "showBottomTabsOnly")
			-annotation
				("Show Bottom Tabs Only: Hide the top tab section")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"showBottomTabsOnly\")")
			tabsShowBottomTabsOnlyItem;
		menuItem 
			-label "Show Top And Bottom Tabs"
			-radioButton 
				(`optionVar -q hyperShadePanelTabSectionsShown` 
					== "showTopAndBottomTabs")
			-annotation
				("Show Both: Show both tab sections")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"showTopAndBottomTabs\")")
			tabsShowTopAndBottomTabsItem;
		menuItem -divider true;
		string $currentTabMenu = 
			`menuItem 
				-label "Current Tab" 
				-subMenu true
				currentTabMenu`;
			setParent -menu ..;
		menuItem
			-edit
			-postMenuCommand 
				("hyperShadePanelBuildTabOptionsMenu " 
					+ $panel
					+ " "
					+ $currentTabMenu)
			$currentTabMenu;

	// Build the Graph menu
	//
	if ($isPopupMenu)
	{
		setParent -menu ..;
		menuItem
			-subMenu true
			-label "Graph" 
			-tearOff true 
			($menuPrefix + "GraphMenu");
	}
	else
	{
		menu 
			-label "Graph" 
			-tearOff true 
			($menuPrefix + "GraphMenu");
	}

		menuItem 
			-label "Graph Materials on Selected Objects"
			-annotation 
				("Graph Materials on Selected Objects: "
					+ "Graph the shading network currently applied to the "
					+ "selected objects")
			-command 
				("hyperShadePanelGraphCommand(\"" 
					+ $panel 
					+ "\", \"graphMaterials\")");
		menuItem -divider true;
		menuItem 
			-label "Clear Graph"
			-annotation "Clear View: Clear the active graph tab"
			-command 
				("hyperShadePanelGraphCommand(\"" 
					+ $panel 
					+ "\", \"clearGraph\")")
			clearGraphItem;
		menuItem -divider true;
		menuItem 
			-label "Input and Output Connections"
			-annotation 
				("Show Input and Output Connections: Display entire network for "
					+ "selected nodes")
			-command 
				("hyperShadePanelGraphCommand(\"" 
					+ $panel 
					+ "\", \"showUpAndDownstream\")");
		menuItem 
			-label "Input Connections"
			-annotation 
				("Show Input Connections: Display network affecting selected "
					+ "nodes")
			-command 
				("hyperShadePanelGraphCommand(\"" 
					+ $panel 
					+ "\", \"showUpstream\")");
		menuItem 
			-label "Output Connections"
			-annotation 
				("Show Output Connections: Display network affected by selected nodes")
			-command 
				("hyperShadePanelGraphCommand(\"" 
					+ $panel 
					+ "\", \"showDownstream\")");
		menuItem -divider true;
		menuItem
			-label "Show Previous Graph"
			-annotation
				("Show Previous Graph: Display the shading network graphed"
					+ " before the current one.")
			-command 
				("hyperShadePanelGraphCommand(\"" 
					+ $panel 
					+ "\", \"showPreviousGraph\")")
			showPreviousGraphItem;
		menuItem
			-label "Show Next Graph"
			-annotation
				("Show Next Graph: Display the shading network graphed"
					+ " after the current one.")
			-command 
				("hyperShadePanelGraphCommand(\"" 
					+ $panel 
					+ "\", \"showNextGraph\")")
			showNextGraphItem;
		menuItem -divider true;
		menuItem 
			-label "Add Selected to Graph"
			-annotation 
				("Add Selected to Graph: Add the selected nodes to the "
					+ "active graph tab")
			-command 
				("hyperShadePanelGraphCommand(\"" 
					+ $panel 
					+ "\", \"addSelected\")");
		menuItem 
			-label "Remove Selected from Graph"
			-annotation 
				("Remove Selected from Graph: Remove the selected nodes from "
					+ "the active graph tab (without deleting them)")
			-command 
				("hyperShadePanelGraphCommand(\"" 
					+ $panel 
					+ "\", \"removeSelected\")");
		menuItem -divider true;
		menuItem 
			-label "Rearrange Graph"
			-annotation 
				("Rearrange Graph: Automatically re-arrange layout of the "
					+ "active graph tab")
			-command 
				("hyperShadePanelGraphCommand(\"" 
					+ $panel 
					+ "\", \"rearrangeGraph\")")
			rearrangeGraphItem;

		if ($isPopupMenu)
		{
			// Enable some graph menu items only if a graph tab (work area) is 
			// visible
			//
			int $enable;
			$enable = isGraphTabVisible($panel);

			menuItem 
				-edit
				-enable $enable
				clearGraphItem;
			menuItem 
				-edit
				-enable $enable
				rearrangeGraphItem;
			menuItem 
				-edit
				-enable $enable
				showPreviousGraphItem;
			menuItem 
				-edit
				-enable $enable
				showNextGraphItem;
		}

	
	// Build the Window menu
	//
	if ($isPopupMenu)
	{
		setParent -menu ..;
		menuItem
			-subMenu true
			-label "Window" 
			-tearOff true 
			($menuPrefix + "WindowMenu");
	}
	else
	{
		menu 
			-label "Window" 
			-tearOff true 
			($menuPrefix + "WindowMenu");
	}

		menuItem -label "Attribute Editor..."
			-annotation 
				("Attribute Editor: Edit the attributes of the selected object")
			-c ("showEditor `select`");
		menuItem -label "Attribute Spread Sheet"
			-annotation 
				("Attribute Spread Sheet: "
					+ "Edit the attributes of the selected object(s)")
			-c ("SpreadSheetWindow");
		menuItem -divider true;
		menuItem 
			-label "Connection Editor..." 
			-annotation 
				("Connection Editor: " 
					+ "Make connections between node attributes")
			-command ("connectWindow");
		menuItem 
			-label "Connect Selected..." 
			-annotation
				("Connect Selected: Make connections involving "
					+ "the selected node's attributes")
			-command 
				("string $sel[] = `ls -sl`; connectWindowWith $sel[0] $sel[1]");

	// Build the Options menu
	//
	if ($isPopupMenu)
	{
		setParent -menu ..;
		menuItem
			-subMenu true
			-label "Options" 
			-tearOff true 
			($menuPrefix + "OptionsMenu");
	}
	else
	{
		menu 
			-label "Options" 
			-tearOff true 
			($menuPrefix + "OptionsMenu");
	}
		string $createBarMenu = 
			`menuItem 
				-label "Create Bar" 
				-subMenu true
				createBarMenu`;
			setParent -menu ..;
		menuItem
			-edit
			-postMenuCommand 
				("hyperShadePanelBuildCreateBarOptionsMenu " 
					+ $panel
					+ " "
					+ $createBarMenu)
			$createBarMenu;
		menuItem -divider true;

        int $value = `optionVar -q hsBinsSortShadingNodesOnly`;
        string $hsBinsSortShadingNodesOnlyItem = `menuItem
            -label "Bins Sort Shading Node Only"
            -checkBox $value 
            hsBinsSortShadingNodesOnlyItem`;
        setParent -menu ..;
        menuItem
            -edit
			-command 
				("optionVar -intValue hsBinsSortShadingNodesOnly "
					+ "`menuItem -query -checkBox " 
					+ $hsBinsSortShadingNodesOnlyItem+"`")
		    $hsBinsSortShadingNodesOnlyItem;
	
		menuItem -divider true;

		string $displayMenu = 
			`menuItem 
				-label "Display (Work Area Only)" 
				-subMenu true
				displayMenu`;
			setParent -menu ..;
		menuItem
			-edit
			-postMenuCommand 
				("hyperShadePanelBuildDisplayOptionsMenu " 
					+ $panel
					+ " "
					+ $displayMenu)
			$displayMenu;
		menuItem -divider true;

		int $keepSwatchesAtCurrentResolution = `optionVar -query keepSwatchesAtCurrentResolution`;
        string $keepSwatchesAtCurrentResolutionItem = 
            `menuItem 
                -label "Keep Swatches at Current Resolution" 
                -annotation 
                    ("Keep Swatches at Current Resolution: Reuse the existing "
                        + "rendering of swatches to make display updates "
                        + "quicker")
                -checkBox $keepSwatchesAtCurrentResolution
                keepSwatchesAtCurrentResolution`;
		menuItem 
			-edit
			-command 
				("optionVar "
					+ "-intValue keepSwatchesAtCurrentResolution "
					+ "`menuItem -query -checkBox " 
					+ $keepSwatchesAtCurrentResolutionItem
					+ "`; hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"keepSwatchesAtCurrentResolution\")")
			$keepSwatchesAtCurrentResolutionItem; 

		int $isClearBeforeSet = `optionVar -query hsClearBeforeGraphing`;
        string $clearBeforeItem = 
            `menuItem 
                -label "Clear Before Graphing" 
                -annotation 
                    ("Clear all nodes from the work area before graphing.")
                -checkBox $isClearBeforeSet
                clearBeforeItem`;
		menuItem 
			-edit
			-command 
				("optionVar "
					+ "-intValue hsClearBeforeGraphing "
					+ "`menuItem -query -checkBox " 
					+ $clearBeforeItem
                    + "`")
			$clearBeforeItem;

	// Add support for the Context Sensitive Help Menu.
	//
	addContextHelpProc $panel "hyperShadePanelBuildContextHelpItems";
			
	// Set the menu bar visibility
	//
	int $menusOkayInPanels = `optionVar -q allowMenusInPanels`;
	panel -e -mbv $menusOkayInPanels $panel;
}

// ---------------------------------------------------------------------------
// 	Global procedures
// 

global proc hyperShadePanelBuildContextHelpItems(
	string $nameRoot, 
	string $menuParent)
{
	//
	// Description:
	//	This procedure is called as the Help menu for this panel is being
	//	built.
	//	This procedure builds the menu item which provides help on the
	//	Hypershade.
	//	$nameRoot is the name to use as the root of all item names
	//	$menuParent is the name of the parent of this menu
	//

	menuItem -label "Help on Hypershade..."
		-enableCommandRepeat false
		-command "showHelp Hypershade";
	menuItem -label "Help on Shader Library..."
		-enableCommandRepeat false
		-command "showHelp ShaderLibrary";
}

global proc hyperShadePanelBuildEditMenu(
	string $panel, 
	string $parent)
{
	//
	// Description:
	//	This procedure is called every time the Edit menu is opened.
	//	This procedure builds the Edit menu. 
	//

	menu -edit -deleteAllItems $parent;

	setParent -menu $parent;

	menuItem 
		-label "Delete"
		-annotation "Delete: Delete the selected node(s)"
		-command 
			("hyperShadePanelMenuCommand(\"" 
				+ $panel 
				+ "\", \"delete\")");

	menuItem 
		-label "Delete Unused Nodes"
		-annotation 
			("Delete Unused Nodes: Delete all shading nodes not "
				+ "assigned to surfaces")
		-command 
			("hyperShadePanelMenuCommand(\"" 
				+ $panel 
				+ "\", \"deleteUnusedNodes\")");

	menuItem 
		-label "Delete Duplicate Shading Networks"
		-annotation 
			("Delete Duplicate Shading Networks: Delete all shading networks "
				+ "that duplicate the selected network")
		-command 
			("removeDuplicateShadingNetworks( 1 )");

	menuItem -label "Delete All by Type" -subMenu true;

		menuItem 
			-label "Shading Groups and Materials"
			-annotation "Delete all Shading Groups and Materials"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"deleteShadingGroupsAndMaterials\")");

		menuItem 
			-label "Textures"
			-annotation "Delete all Textures"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"deleteTextures\")");

		menuItem 
			-label "Lights"
			-annotation "Delete all Lights"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"deleteLights\")");

		menuItem 
			-label "Utilities"
			-annotation "Delete all Utility nodes"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"deleteUtilities\")");

		menuItem 
			-label "Cameras and Image Planes"
			-annotation "Delete all Cameras and Image Planes"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"deleteCamerasAndImagePlanes\")");

		menuItem 
			-label "Bake Sets"
			-annotation "Delete all Bake Sets"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"deleteBakeSets\")");

		setParent -menu ..;

	menuItem 
		-label "Revert Selected Swatches"
		-annotation 
			("Revert Selected Swatches: Revert to default swatches for "
				+ "selected nodes")
		-command 
			("hyperShadePanelMenuCommand(\"" 
				+ $panel 
				+ "\", \"revertSelectedSwatches\")");

	menuItem -divider true;

	menuItem -label "Select All by Type" -subMenu true;

		menuItem 
			-label "Shading Groups and Materials"
			-annotation "Select All Shading Groups and Materials"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"selectShadingGroupsAndMaterials\")");

		menuItem 
			-label "Textures"
			-annotation "Select All Textures"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"selectTextures\")");

		menuItem 
			-label "Lights"
			-annotation "Select All Lights"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"selectLights\")");

		menuItem 
			-label "Utilities"
			-annotation "Select All Utility nodes"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"selectUtilities\")");

		menuItem 
			-label "Cameras and Image Planes"
			-annotation "Select All Cameras and Image Planes"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"selectCamerasAndImagePlanes\")");

		menuItem 
			-label "Bake Sets"
			-annotation "Select All Bake Sets"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"selectBakeSets\")");

		setParent -menu ..;

	menuItem -divider true;

    menuItem -label "Select Objects with Materials"
             -command "hyperShade -objects \"\"";

    menuItem -label "Select Materials from Objects"
             -command "hyperShade -smn \"\"";

	menuItem -divider true;

	menuItem -label "Duplicate" -subMenu true;

		menuItem 
			-label "Shading Network"
			-annotation 
				("Duplicate Shading Network: Duplicate selected node(s) "
					+ "including the input connection network(s)")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"duplicateShadingNetwork\")");

		menuItem 
			-label "Without Network"
			-annotation 
				("Duplicate Without Network: Duplicate only the selected "
					+ "node(s)")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"duplicateWithoutNetwork\")");

		menuItem 
			-label "With Connections to Network"
			-annotation 
				("Duplicate With Connections to Network: Duplicate "
					+ "selected node(s); connect new one(s) to input "
					+ "connection network")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"duplicateWithConnections\")");

		setParent -menu ..;

	menuItem -divider true;

	menuItem 
		-label 
			("Convert to File Texture (Maya Software)")
		-annotation 
			("Convert to File Texture: Create file texture(s) matching "
				+ "materials of selected object(s); select "
				+ "texture/material and surface(s)")
		-command 
			("hyperShadePanelMenuCommand(\"" 
				+ $panel 
				+ "\", \"convertToFileTexture\")");

	menuItem 
		-label "Convert to File Texture Option Box" 
		-optionBox true 
		-command 
			("hyperShadePanelMenuCommand(\"" 
				+ $panel 
				+ "\", \"convertToFileTextureOptionBox\")");

	menuItem 
		-label "Convert PSD to Layered Texture" 
		-annotation ("Convert To LT Network: Converts Psd file texture to layered texture network")
		-command "hypergraphConvertSelectedPsdNodesToLT";
		
	menuItem 
		-label "Convert PSD to File Texture" 
		-annotation ("Convert To File Network: Converts Psd file texture to file texture network")
		-command "hypergraphConvertSelectedPsdNodesToFile";

	menuItem -divider true;
	
	menuItem -l "Create PSD Network..."
			-annotation "PSD Texture: Create a PSD file for texturing..."
		        -c "photoShopPaintTex" 
			createPsdTextureItem;
	menuItem -l "Edit PSD Network..."
			-annotation "PSD Texture: Edit a PSD file for texturing..."
		        -c "photoshopEditTexture" 
			editPsdTextureItem;
	menuItem -l "Update PSD Networks"
			-annotation "PSD Texture: Update PSD texture nodes..."
		        -c "psdUpdateTextures" 
			updatePsdTextureItem;

	menuItem -divider true;
	
	menuItem 
		-label "Edit Texture"
		-annotation (getRunTimeCommandAnnotation ("EditTexture"))
		-command "EditTexture";

	menuItem 
		-label "Test Texture"
		-annotation (getRunTimeCommandAnnotation ("TestTexture"))
		-command "TestTexture";

	menuItem 
		-label "Test Texture Option Box" 
		-optionBox true 
		-annotation (getRunTimeCommandAnnotation ("TestTextureOptions"))
		-command "TestTextureOptions";

	menuItem 
		-label "Render Texture Range"
		-annotation (getRunTimeCommandAnnotation ("RenderTextureRange"))
		-command "RenderTextureRange";

	menuItem 
		-label "Render Texture Range Option Box" 
		-optionBox true 
		-annotation (getRunTimeCommandAnnotation ("RenderTextureRangeOptions"))
		-command "RenderTextureRangeOptions";

}

global proc hyperShadePanelBuildCreateMenu(string $panel, string $parent)
{
	//
	// Description:
	//	This procedure is called every time the Create menu is opened.
	//	This procedure builds the Create menu.
	//

//	menu -edit -deleteAllItems $parent;

//	setParent -menu $parent;	

	menuItem -label "Materials" -tearOff true -subMenu true; 
		buildCreateSubMenu(
			"shader/surface",
			"hyperShadePanelCreate \"shader\"");
	setParent -menu ..;

	menuItem -label "Volumetric Materials" -tearOff true -subMenu true; 
		buildCreateSubMenu(
			"shader/volume",
			"hyperShadePanelCreate \"shader\"");
	setParent -menu ..;

	menuItem -divider true;

	menuItem -label "2D Textures" -tearOff true -subMenu true;
		buildCreateSubMenu(
			"texture/2D",
			"hyperShadePanelCreate \"2dTexture\"");
		menuItem -divider true;
		radioMenuItemCollection;
		menuItem -label "2D Normal"
			-annotation "2D Normal: Create 2D textures"
			-radioButton 
				(`optionVar -query create2dTextureType` == "normal")
			-command 
				("optionVar "
					+ "-stringValue create2dTextureType \"normal\";"
					+ "refreshCreateNodeUI();")
			textureAsNormalItem;
		menuItem -label "2D Projection"
			-annotation "2D Projection: Create 2D projection textures"
			-radioButton 
				(`optionVar -query create2dTextureType` == "projection")
			-command 
				("optionVar "
					+ "-stringValue create2dTextureType \"projection\";"
					+ "refreshCreateNodeUI();")
			textureAsProjectionItem;
		menuItem -label "2D Stencil"
			-annotation "2D Stencil: Create 2D stencil textures"
			-radioButton 
				(`optionVar -query create2dTextureType` == "stencil")
			-command 
				("optionVar "
					+ "-stringValue create2dTextureType \"stencil\";"
					+ "refreshCreateNodeUI();")
			textureAsStencilItem;
	setParent -menu ..;

	menuItem -label "3D Textures" -tearOff true -subMenu true;
		buildCreateSubMenu(
			"texture/3D",
			"hyperShadePanelCreate \"3dTexture\"");
	setParent -menu ..;

	menuItem -label "Environment Textures" -tearOff true -subMenu true;
		buildCreateSubMenu(
			"texture/environment",
			"hyperShadePanelCreate \"3dTexture\"");
	setParent -menu ..;

	buildCreateSubMenu(
		"texture/other",
		"hyperShadePanelCreate \"otherTexture\"");

	menuItem -divider true;

	menuItem -label "General Utilites" -tearOff true -subMenu true;
		buildCreateSubMenu(
			"utility/general",
			"hyperShadePanelCreate \"utility\"");
	setParent -menu ..;
	menuItem -label "Switch Utilites" -tearOff true -subMenu true;
		buildCreateSubMenu(
			"utility/switch",
			"hyperShadePanelCreate \"utility\"");
	setParent -menu ..;
	menuItem -label "Color Utilites" -tearOff true -subMenu true;
		buildCreateSubMenu(
			"utility/color",
			"hyperShadePanelCreate \"utility\"");
	setParent -menu ..;
	menuItem -label "Particle Utilites" -tearOff true -subMenu true;
		buildCreateSubMenu(
			"utility/particle",
			"hyperShadePanelCreate \"utility\"");
	setParent -menu ..;
	menuItem -label "Glow" -tearOff true -subMenu true;
		string $nodes[1];
		$nodes[0] = "opticalFX";
		buildCreateNodesSubMenu(
			$nodes,
			"hyperShadePanelCreate \"utility\"");
	setParent -menu ..;

	menuItem -divider true;

	menuItem -label "Lights" -tearOff true -subMenu true;
		buildCreateSubMenu(
			"light",
			"hyperShadePanelCreate \"light\"");
	setParent -menu ..;
	
	menuItem 
		-label "Camera"
		-annotation "Create a new Camera"
		-command ("hyperShadePanelCreate \"camera\" \"\"");
	if (`licenseCheck -m "edit" -typ "complete"`)
	{
		menuItem -label "Image Plane"
			-annotation "Create a new Image Plane"
			-command ("hyperShadePanelCreate \"node\" \"imagePlane\"");
	}

	menuItem -divider true;

	// We will only show custom shader UI 
	// if mental ray plugin is loaded.
	//
	if (`pluginInfo -query -loaded Mayatomr`)
	{
		mrHyperShadeCreateMenu_BuildMenu();
		menuItem -divider true;
	}

	menuItem
		-label "Create Render Node..."
		-annotation "Open Create Render Node window"
		-command 
			("hyperShadePanelMenuCommand(\""
				+ $panel 
				+ "\", \"createNewNode\")");
	menuItem -divider true;

	menuItem -label "Create Options" -subMenu true;

		$includeShadingGroupItem = 
			`menuItem 
				-label "Include Shading Group with Materials"
				-checkBox true
				-annotation 
					("Include Shading Group: If on, new materials are "
						+ "created with an associated shading group")
				includeShadingGroupItem`;
		menuItem
			-edit
			-checkBox 
				`optionVar -query createMaterialsWithShadingGroup` 
			-command 
				("optionVar -intValue createMaterialsWithShadingGroup "
					+ "`menuItem -query -checkBox " 
					+ $includeShadingGroupItem
					+ "`; refreshCreateNodeUI();")
			$includeShadingGroupItem;

		$createIncludePlacementItem = 
			`menuItem 
				-label "Include Placement with Textures"
				-checkBox true
				-annotation 
					("Include Placement: If on, new textures are created "
						+ "with an associated placement node")
				createIncludePlacementItem`;
		menuItem
			-edit
			-checkBox 
				`optionVar -query createTexturesWithPlacement` 
			-command 
				("optionVar -intValue createTexturesWithPlacement "
					+ "`menuItem -query -checkBox " 
					+ $createIncludePlacementItem
					+ "`; refreshCreateNodeUI();")
			$createIncludePlacementItem;

	//setParent ..;
	setParent -menu ..;
}

global proc hyperShadePanelBuildCreateBarOptionsMenu(
	string $panel,
	string $menuParent)
{
	//
	// Description:
	//	This procedure is called every time the Create-> Create Bar menu
	//	item in the hypershade panel menu is selected.
	//	This procedure creates the menu items which will appear in that menu.
	//

	setParent $panel;
	setParent -menu $menuParent;
	menu
		-edit
		-deleteAllItems
		$menuParent;

		string $renderCreateBarUI = renderCreateBarUIName($panel);
		int $managed = renderCreateBarUIIsManaged($renderCreateBarUI); 

		menuItem
			-label "Show Create Bar"
			-checkBox $managed
			-command
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"toggleRenderCreateBar\")");
		
		menuItem -divider true;

		radioMenuItemCollection;

		string $style = `optionVar -query renderCreateBarStyle`;

		menuItem 
			-label "Display Icons and Text"
			-radioButton ($style == "iconsAndText")
			-annotation
				("Display Icons and Text: Configure the Create Bar to display "
					+ "icons and text")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"createBarDisplayIconsAndText\")");
		menuItem 
			-label "Display Icons Only"
			-radioButton ($style == "iconsOnly")
			-annotation
				("Display Icons Only: Configure the Create Bar to display "
					+ "only icons (no text)")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"createBarDisplayIconsOnly\")");

	setParent -menu ..;
}

global proc hyperShadePanelShapeDisplay()
{
	if( `optionVar -q hsNoShapes` )
	{
	}
}
		

global proc hyperShadePanelBuildDisplayOptionsMenu(
	string $panel,
	string $menuParent)
{
	//
	// Description:
	//	This procedure is called every time the Options->Display menu
	//	item in the hypershade panel menu is selected.
	//	This procedure creates the menu items which will appear in that menu.
	//

	setParent $panel;
	setParent -menu $menuParent;
	menu
		-edit
		-deleteAllItems
		$menuParent;

		radioMenuItemCollection;

		if( !`optionVar -exists hsShapeDisplay` )
		{
			optionVar -intValue hsShapeDisplay 2;
		}
		int $shapeDisplay = `optionVar -query hsShapeDisplay`;

		menuItem 
			-label "No Shapes"
			-radioButton ($shapeDisplay == 0)
			-annotation
				"Display No Shapes: Do not graph any shape nodes attached to shading nodes or shading groups"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"displayNoShapes\")");
		menuItem 
			-label "All Shapes Except Shading Group Members"
			-radioButton ($shapeDisplay == 1)
			-annotation
				"Display All Shapes Except Shading Group Members: Display only shapes that are connected to shading nodes in the graph"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"displayInterestingShapes\")");
		menuItem 
			-label "All Shapes"
			-radioButton ($shapeDisplay == 2)
			-annotation
				"Display All Shapes: Display any shapes connected to shading nodes or shading groups (including shading group members)"
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"displayAllShapes\")");


		menuItem -divider true;

		if( !`optionVar -exists hsTransformDisplay` )
		{
			optionVar -intValue hsTransformDisplay 1;
		}
		int $transformDisplay = `optionVar -query hsTransformDisplay`;

		menuItem
			-label "Transforms"
			-checkBox $transformDisplay
			-command
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"toggleTransformDisplay\")");

	setParent -menu ..;
}



global proc hyperShadePanelBuildTabOptionsMenu(
	string $panel,
	string $menuParent)
{
	//
	// Description:
	//	This procedure is called every time the Tabs->Current Tab Options menu
	//	item in the hypershade panel menu is selected.
	//	This procedure creates the menu items which will appear in that menu,
	//	such that they are the appropriate ones for the active tab type.
	//

	setParent $panel;
	setParent -menu $menuParent;
	menu
		-edit
		-deleteAllItems
		$menuParent;

	string $activeTab = activeTab($panel);

	if (isDiskTab($activeTab))
	{
		string $libraryUI = lookupComponentName($activeTab);
		int $onlyDirectoriesShown = false;
		int $onlyFilesShown = false;
		int $bothShown = false;

		if (
				libraryUIDirectoriesShown($libraryUI)
			&&	libraryUIFilesShown($libraryUI))
		{
			$bothShown = true;
		}
		else if (libraryUIDirectoriesShown($libraryUI))
		{
			$onlyDirectoriesShown = true;
		}
		else if (libraryUIFilesShown($libraryUI))
		{
			$onlyFilesShown = true;
		}
		
		radioMenuItemCollection;
		menuItem 
			-label "Show Directories Only"
			-radioButton $onlyDirectoriesShown
			-annotation
				("Show Directories Only: Hide the section of the active tab "
					+ "which displays files")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"showDirectoriesOnly\")");
		menuItem 
			-label "Show Files Only"
			-radioButton $onlyFilesShown
			-annotation
				("Show Files Only: Hide the section of the active tab "
					+ "which displays directories")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"showFilesOnly\")");
		menuItem 
			-label "Show Both"
			-radioButton $bothShown
			-annotation
				("Show Both: Show both sections of the active tab "
					+ "(directories and files)")
			-command 
				("hyperShadePanelMenuCommand(\"" 
					+ $panel 
					+ "\", \"showDirectoriesAndFiles\")");
		menuItem -divider true;
		menuItem
			-label "Refresh File Listing"
			-annotation
				("Refresh File Listing: Refresh the display of files on disk "
					+ "to reflect newly added or removed files")
			-command
				("hyperShadePanelMenuCommand(\""
					+ $panel 
					+ "\", \"refreshFileListing\")");
		menuItem
			-label "Refresh Selected Swatches"
			-annotation
				("Refresh Selected Swatches: Refresh the selected swatches "
					+ "to reflect changes made to the files")
			-command
				("hyperShadePanelMenuCommand(\""
					+ $panel 
					+ "\", \"refreshSelectedSwatches\")");
		menuItem
			-label "Refresh All Swatches"
			-annotation
				("Refresh All Swatches: Refresh all swatches "
					+ "to reflect changes made to the files")
			-command
				("hyperShadePanelMenuCommand(\""
					+ $panel 
					+ "\", \"refreshAllSwatches\")");
		menuItem -divider true;
		menuItem
			-label "Generate Swatch Files for Current Images"
			-annotation
				("Generate Swatch Files for Current Images: "
					+ "Save the swatches of the currently displayed files "
					+ "to disk so this directory can be opened faster")
			-command
				("hyperShadePanelMenuCommand(\""
					+ $panel 
					+ "\", \"saveSwatchesToDisk\")");
	}
	else
	{
		menuItem
			-label "No options available"
			-enable false;
	}

	setParent -menu ..;
}

global proc hyperShadePanelGraphCommand(
	string $panel,
	string $command)
{
	// Determine which graph tab (work area) would be the most appropriate
	// tab to perform this operation in. This will be called the target tab.
	//
	string $targetTab;

	$targetTab = targetGraphTab($panel);

	// Get the name of the hypershade in the target graph tab so that we
	// can graph into it.
	//
	string $graphUI;

	$graphUI = lookupComponentName($targetTab);

	// Select the tab so the user can see the graph.
	//
	selectTab($panel, $targetTab);

	if ($command == "graphMaterials")
	{
		if (size(`ls -sl`) != 0)
		{
			graphUIGraphMaterials($graphUI);
		}
		else
		{
			warning("Nothing is selected.");
		}
	}
	else if ($command == "clearGraph")
	{
		graphUIClearGraph($graphUI);
	}
	else if ($command == "showUpAndDownstream")
	{
		if (size(`ls -sl`) != 0)
		{
			graphUIShowUpAndDownstream($graphUI);
		}
		else
		{
			warning("Nothing is selected.");
		}
	}
	else if ($command == "showUpstream")
	{
		if (size(`ls -sl`) != 0)
		{
			graphUIShowUpstream($graphUI);
		}
		else
		{
			warning("Nothing is selected.");
		}
	}
	else if ($command == "showDownstream")
	{
		if (size(`ls -sl`) != 0)
		{
			graphUIShowDownstream($graphUI);
		}
		else
		{
			warning("Nothing is selected.");
		}
	}
	else if ($command == "rearrangeGraph")
	{
		graphUIRearrangeGraph($graphUI);
	}
	else if ($command == "showPreviousGraph")
	{
		graphUIShowPreviousGraph($graphUI);
	}
	else if ($command == "showNextGraph")
	{
		graphUIShowNextGraph($graphUI);
	}
	else if ($command == "addSelected")
	{
		graphUIAddSelected($graphUI);
	}
	else if ($command == "removeSelected")
	{
		graphUIRemoveSelected($graphUI);
	}

	refreshToolbar($panel);
	refreshGraphMenu($panel);
}

global proc hyperShadePanelMenuCommand(
	string $panel,
	string $command)
{
	//
	// Description:
	//	This procedure is called whenever a menu item is chosen from the
	//	hypershade panel menu.
	//	This procedure is the single global procedure entry point to all
	//	functionality invoked by the menu items. This avoids cluttering the
	//	global procedure namespace with a global procedure for each menu item.
	//	This procedure causes the expected action to be performed. Typically
	//	this will mean calling some local procedure within this file to perform
	//	the action the user expects when they choose the menu item.
	//

	if ($command == "")
	{
	}
	else if ($command == "import")
	{
		Import;
	}
	else if (
			($command == "importSelectedSceneFiles")
		||	($command == "importSelectedImageFilesAsNormal")
		||	($command == "importSelectedImageFilesAsProjection")
		||	($command == "importSelectedImageFilesAsStencil"))
	{
		string $activeTab = activeTab($panel);
		if (isDiskTab($activeTab))
		{
			string $libraryUI;
			$libraryUI = lookupComponentName($activeTab);

			string $filesVisor;
			$filesVisor = libraryUIFilesVisor($libraryUI);

			string $filesToImport[];
			$filesToImport = `visor -query -selectedGadgets $filesVisor`;

			int $asProjection;
			int $asStencil;
			int $withPlacement;

			if ($command == "importSelectedImageFilesAsNormal")
			{
				$asProjection = false;
				$asStencil = false;
			}
			else if ($command == "importSelectedImageFilesAsProjection")
			{
				$asProjection = true;
				$asStencil = false;
			}
			else if ($command == "importSelectedImageFilesAsStencil")
			{
				$asProjection = false;
				$asStencil = true;
			}

			$withPlacement =
				(`optionVar -query createTexturesWithPlacement`);

			int $i;

			for ($i = 0; $i < size($filesToImport); $i++)
			{
				string $fileTypesArray[] = 
					`file -query -type $filesToImport[$i]`;
				string $fileType = $fileTypesArray[0];

				if (
						($command == "importSelectedSceneFiles") 
					&& 	(	($fileType == "mayaBinary") 
						|| 	($fileType == "mayaPLE")
						|| 	($fileType == "mayaAscii")))
				{
					file -import $filesToImport[$i];
					print("// Imported: " + $filesToImport[$i] + "\n");
				}
				else if ($fileType == "image")
				{
					importImageFile(
						$filesToImport[$i], 
						$asProjection,
						$asStencil,
						$withPlacement);
				}
			}
		}
	}
	else if ($command == "exportSelectedNetwork")
	{
		global string		$gv_operationMode;
		string				$filetype;
		string				$ws = `workspace -q -fn`;

		// Old projects saved their shaders in a directory called "lights".
		// New projects save both lights and shaders in a directory called
		// "shaders". We have to continue to specify that the shading network
		// be stored in whatever directory is used to store lights, just in
		// case this is an old project.
		//
		setWorkingDirectory $ws "image" "lights";

		if (`optionVar -exists defaultFileExportActiveType`) 
		{
			$filetype = `optionVar -q defaultFileExportActiveType`;
		}
		else 
		{
			$filetype = "mayaBinary";
		}

		$gv_operationMode = "ExportActive";
		
		// Open the file browser to export the selection
		//
		fileBrowser "pv_performAction" "Export Selection" $filetype 1;
	}
	else if ($command == "toggleRenderCreateBar")
	{
		string $renderCreateBarUI = renderCreateBarUIName($panel);
		int $manage = !(renderCreateBarUIIsManaged($renderCreateBarUI)); 
		renderCreateBarUIManage($renderCreateBarUI, $manage);
		optionVar -intValue hyperShadePanelCreateBarShown $manage;

		int $iconsAndTextWidth = 
			`optionVar -query hyperShadePanelCreateBarIconsAndTextWidth`;

		int $createBarWidth;
		
		$createBarWidth = $iconsAndTextWidth;

		if (!$manage)
		{
			$createBarWidth = 1;
		}

		global int $gButtonsColumnWidth;
		int $paneLeftPosnYesCreateBar = $createBarWidth + $gButtonsColumnWidth;
		setParent $panel;
		formLayout
			-edit
			-af paneArrangement	left $paneLeftPosnYesCreateBar
			-af buttonsColumn	left $createBarWidth
			mainForm;

		refreshCreateMenu($panel);
	}
	else if ($command == "createBarDisplayIconsAndText")
	{
		string $style = `optionVar -query renderCreateBarStyle`;

		if ($style != "iconsAndText")
		{
			// The UI is not already showing icons and text, so we will change
			// it so that it is.
			//
			optionVar -stringValue renderCreateBarStyle "iconsAndText";
			string $renderCreateBarUI = renderCreateBarUIName($panel);

			// Delete the existing icons only UI
			//
			deleteUI $renderCreateBarUI;

			// Hide the section of the hyperShadePanel which contains the
			// create bar until it has finished building
			//
			setParent $panel;
			int $iconsAndTextWidth = 
				`optionVar -query hyperShadePanelCreateBarIconsAndTextWidth`;

			formLayout
				-edit
				-af paneArrangement	left 1
				mainForm;

			// Build the new create bar
			//
            string $createBarForm = hyperShadeCreateBarForm($panel); 
            $createBarForm = `setParent $createBarForm`;
			renderCreateBarUI($createBarForm);

			// Show the create bar again
			//
			formLayout
				-edit
				-af paneArrangement	left $iconsAndTextWidth
				mainForm;
		}
	}
	else if ($command == "createBarDisplayIconsOnly")
	{
		string $style = `optionVar -query renderCreateBarStyle`;

		if ($style != "iconsOnly")
		{
			// The UI is not already showing icons only, so we will change
			// it so that it is.
			//
			optionVar -stringValue renderCreateBarStyle "iconsOnly";
			string $renderCreateBarUI = renderCreateBarUIName($panel);

			// Delete the existing icons only UI
			//
			deleteUI $renderCreateBarUI;

			// Hide the section of the hyperShadePanel which contains the
			// create bar until it has finished building
			//
			setParent $panel;
			formLayout
				-edit
				-af paneArrangement	left 1
				mainForm;

			// Build the new create bar
			//
            string $createBarForm = hyperShadeCreateBarForm($panel); 
            $createBarForm = `setParent $createBarForm`;
			renderCreateBarUI($createBarForm);

			
            int $iconsAndTextWidth = 
                `optionVar -query hyperShadePanelCreateBarIconsAndTextWidth`;
			// Show the create bar again
			//
			formLayout
				-edit
				-af paneArrangement	left $iconsAndTextWidth
				mainForm;
		}
	}
	else if( $command == "displayNoShapes" )
	{
		optionVar -intValue hsShapeDisplay 0;
	}
	else if( $command == "displayInterestingShapes" )
	{
		optionVar -intValue hsShapeDisplay 1;
	}
	else if( $command == "displayAllShapes" )
	{
		optionVar -intValue hsShapeDisplay 2;
	}
	else if( $command == "toggleTransformDisplay" )
	{
		if( !`optionVar -exists hsTransformDisplay` )
		{
			optionVar -intValue hsTransformDisplay 1;
		}
		int $curVal = `optionVar -q hsTransformDisplay`;
		int $newVal;
		if( $curVal )
		{
			$newVal = 0;
		}
		else
		{
			$newVal = 1;
		}

		optionVar -intValue hsTransformDisplay $newVal;
	}
	else if ($command == "createNewNode")
	{
		createRenderNode("-all", "", "");
	}
	else if ($command == "duplicateShadingNetwork")
	{
		hyperShade -duplicate;
	}
	else if ($command == "duplicateWithoutNetwork")
	{
		duplicate;
	}
	else if ($command == "duplicateWithConnections")
	{
		duplicate -inputConnections;
	}
	else if ($command == "deleteShadingGroupsAndMaterials")
	{
		string $cmd;
		string $items[];
		string $item;

		$cmd = "delete ";
		$items = `lsThroughFilter DefaultShadingGroupsAndMaterialsFilter`;
		
		if (size($items) > 0)
		{
			for ($item in $items)
			{
				$cmd = ($cmd + " " + $item);
			}
			eval $cmd;
		}
	}
	else if ($command == "deleteTextures")
	{
		string $cmd;
		string $items[];
		string $item;

		$cmd = "delete ";
		$items = `lsThroughFilter DefaultTexturesFilter`;
		
		if (size($items) > 0)
		{
			for ($item in $items)
			{
				$cmd = ($cmd + " " + $item);
			}
			eval $cmd;
		}
	}
	else if ($command == "deleteLights")
	{
		string $cmd;
		string $items[];
		string $item;

		$cmd = "delete ";
		$items = `lsThroughFilter DefaultAllLightsFilter`;
		
		if (size($items) > 0)
		{
			for ($item in $items)
			{
				$cmd = ($cmd + " " + $item);
			}
			eval $cmd;
		}
	}
	else if ($command == "deleteUtilities")
	{
		string $cmd;
		string $items[];
		string $item;

		$cmd = "delete ";
		$items = `lsThroughFilter DefaultRenderUtilitiesFilter`;
		
		if (size($items) > 0)
		{
			for ($item in $items)
			{
				$cmd = ($cmd + " " + $item);
			}
			eval $cmd;
		}
	}
	else if ($command == "deleteCamerasAndImagePlanes")
	{
		string $cmd;
		string $items[];
		string $item;

		$cmd = "delete ";
		$items = `lsThroughFilter DefaultCameraShapesImagePlanesFilter`;
		
		if (size($items) > 0)
		{
			for ($item in $items)
			{
				$cmd = ($cmd + " " + $item);
			}
			eval $cmd;
		}
	}
	else if ($command == "deleteBakeSets")
	{
		string $cmd;
		string $items[];
		string $item;

		$cmd = "delete ";
		$items = `lsThroughFilter DefaultBakeSetsFilter`;
		
		if (size($items) > 0)
		{
			for ($item in $items)
			{
				$cmd = ($cmd + " " + $item);
			}
			eval $cmd;
		}
	}
	else if ($command == "selectShadingGroupsAndMaterials")
	{
		select 
			-noExpand 
			-replace
			`lsThroughFilter DefaultShadingGroupsAndMaterialsFilter`;
	}
	else if ($command == "selectTextures")
	{
		select 
			-noExpand
			-replace 
			`lsThroughFilter DefaultTexturesFilter`;
	}
	else if ($command == "selectLights")
	{
		select 
			-noExpand
			-replace 
			`lsThroughFilter DefaultAllLightsFilter`; 
	}
	else if ($command == "selectUtilities")
	{
		select 
			-noExpand 
			-replace
			`lsThroughFilter DefaultRenderUtilitiesFilter`; 
	}
	else if ($command == "selectCamerasAndImagePlanes")
	{
		select 
			-noExpand
			-replace 
			`lsThroughFilter DefaultCameraShapesImagePlanesFilter`; 
	}
	else if ($command == "selectBakeSets")
	{
		select 
			-noExpand
			-replace 
			`lsThroughFilter DefaultBakeSetsFilter`; 
	}
	else if ($command == "revertSelectedSwatches")
	{
		hyperShade -resetSwatch;
	}
	else if ($command == "convertToFileTexture")
	{
		performConvertSolidTx false false;
	}
	else if ($command == "convertToFileTextureOptionBox")
	{
		performConvertSolidTx true false;
	}
	else if ($command == "delete")
	{
		delete;	
	}
	else if ($command == "deleteUnusedNodes")
	{
		MLdeleteUnused;	
	}
	else if ($command == "createNewTab")
	{
		createNewTab($panel);
	}
	else if ($command == "moveTabUp")
	{
		moveTab($panel, "up");
	}
	else if ($command == "moveTabDown")
	{
		moveTab($panel, "down");
	}
	else if ($command == "moveTabLeft")
	{
		moveTab($panel, "left");
	}
	else if ($command == "moveTabRight")
	{
		moveTab($panel, "right");
	}
	else if ($command == "renameTab")
	{
		renameTab($panel);
	}
	else if ($command == "showTopTabsOnly")
	{
		showTopTabsOnly($panel);
	}
	else if ($command == "showBottomTabsOnly")
	{
		showBottomTabsOnly($panel);
	}
	else if ($command == "showTopAndBottomTabs")
	{
		showTopAndBottomTabs($panel);
	}
	else if ($command == "removeTab")
	{
		string $confirm = 
			`confirmDialog
				-title "Confirm Remove Current Tab"
				-message 
					("Are you sure you want to remove the \""
						+ activeTabLabel($panel)
						+ "\" tab?")
				-button "Yes"
				-button "No"
				-defaultButton "No"
				-cancelButton "No"`;
		if ($confirm == "Yes")
		{
			removeActiveTab($panel);
		}
	}
	else if ($command == "revertToDefaultTabs")
	{
		string $confirm = 
			`confirmDialog
				-title "Confirm Revert to Default Tabs"
				-message 
					("This operation will remove all tabs from the\n"
						+ "Hypershade layout except Materials, Textures\n"
						+ "Utilities, Lights, Cameras, Bake Sets, Projects, Work Area\n"
						+ "and Shader Library (if installed).\n"
						+ "Are you sure you want to revert to default tabs?\n")
				-button "Yes"
				-button "No"
				-defaultButton "No"
				-cancelButton "No"`;
		if ($confirm == "Yes")
		{
			revertToDefaultTabs($panel);
		}
	}
	else if ($command == "showDirectoriesOnly")
	{
		string $activeTab = activeTab($panel);
		if (isDiskTab($activeTab))
		{
			string $libraryUI = lookupComponentName($activeTab);
			libraryUIShowDirectoriesOnly($libraryUI);
			string $tabOptionVar = lookupTabOptionVar($activeTab);
			updateTabOptionVar($tabOptionVar, $activeTab);
		}
	}
	else if ($command == "showFilesOnly")
	{
		string $activeTab = activeTab($panel);
		if (isDiskTab($activeTab))
		{
			string $libraryUI = lookupComponentName($activeTab);
			libraryUIShowFilesOnly($libraryUI);
			string $tabOptionVar = lookupTabOptionVar($activeTab);
			updateTabOptionVar($tabOptionVar, $activeTab);
		}
	}
	else if ($command == "showDirectoriesAndFiles")
	{
		string $activeTab = activeTab($panel);
		if (isDiskTab($activeTab))
		{
			string $libraryUI = lookupComponentName($activeTab);
			libraryUIShowDirectoriesAndFiles($libraryUI);
			string $tabOptionVar = lookupTabOptionVar($activeTab);
			updateTabOptionVar($tabOptionVar, $activeTab);
		}
	}
	else if ($command == "refreshFileListing")
	{
		string $activeTab = activeTab($panel);
		if (isDiskTab($activeTab))
		{
			string $libraryUI = lookupComponentName($activeTab);
			libraryUIRefreshFileListing($libraryUI);
		}
	}
	else if ($command == "refreshSelectedSwatches")
	{
		string $activeTab = activeTab($panel);
		if (isDiskTab($activeTab))
		{
			string $libraryUI = lookupComponentName($activeTab);
			libraryUIRefreshSelectedSwatches($libraryUI);
		}
	}
	else if ($command == "refreshAllSwatches")
	{
		string $activeTab = activeTab($panel);
		if (isDiskTab($activeTab))
		{
			string $libraryUI = lookupComponentName($activeTab);
			libraryUIRefreshAllSwatches($libraryUI);
		}
	}
	else if ($command == "saveSwatchesToDisk")
	{
		string $activeTab = activeTab($panel);
		if (isDiskTab($activeTab))
		{
			string $libraryUI = lookupComponentName($activeTab);
			libraryUISaveSwatchesToDisk($libraryUI);
		}
	}
	else if ($command == "frameSelected")
	{
		string $activeTab = activeTab($panel);
		string $component = lookupComponentName($activeTab);
		string $editor;

		if (isGraphTab($activeTab))
		{
			$editor = graphUIHypershadeName($component);
		}
		else if (isSceneTab($activeTab))
		{
			$editor = collectionUIHypershadeName($component);
		}
		else if (isDiskTab($activeTab))
		{
			$editor = libraryUIFilesVisor($component);
		}

		hyperGraph -edit -frame $editor;
	}
	else if ($command == "frameAll")
	{
		string $activeTab = activeTab($panel);
		string $component = lookupComponentName($activeTab);
		string $editor;

		if (isGraphTab($activeTab))
		{
			$editor = graphUIHypershadeName($component);
		}
		else if (isSceneTab($activeTab))
		{
			$editor = collectionUIHypershadeName($component);
		}
		else if (isDiskTab($activeTab))
		{
			$editor = libraryUIFilesVisor($component);
		}

		hyperGraph -edit -frameGraph $editor;
	}
	else if ($command == "keepSwatchesAtCurrentResolution")
	{
		hyperShade 
			-fixRenderSize `optionVar -query keepSwatchesAtCurrentResolution`;
	}

	else if ($command == "smallIcons" || $command == "mediumIcons" || $command == "largeIcons" || $command == "superIcons") 
	{
		string $activeTab = activeTab($panel);
		string $component = lookupComponentName($activeTab);
		string $editor;
		if (isSceneTab($activeTab))
		{
			$editor = collectionUIHypershadeName($component);
		    hyperGraph -edit -iconSize $command $editor;
            registerIconSize($component, $command);

			// Refresh both menu and icon
			refreshIconSize( $panel, $activeTab );

		}
        else
        {
            warning("The currently active tab is not a scene tab.  This icon size change operation is not implemented for this tab.");
        }

	}
	else if ($command == "asIcons" || $command == "asList")
	{
		string $activeTab = activeTab($panel);
		string $component = lookupComponentName($activeTab);
		string $editor;
		if (isSceneTab($activeTab))
		{
			$editor = collectionUIHypershadeName($component);
			hyperGraph -edit -viewOption $command $editor;
			registerViewOption($component, $command);

			// Refresh both menu and icon
			refreshViewOption( $panel, $activeTab );

		}
		else
        {
            warning("The currently active tab is not a scene tab.  The list view functionality is not implemented for this tab.");
        }
	}
	else if ($command == "byName" || $command == "byType" || $command == "byTime")
	{
		string $activeTab = activeTab($panel);
		string $component = lookupComponentName($activeTab);
		if (isSceneTab($activeTab))
		{
			// Register this in the colletionUIlookupTable 
			registerSortOption($component, $command);

			// Refresh both menu and icon
			refreshSortOption( $panel, $activeTab );

			// Need to refresh the command action of the current visor.
			// First, remove any folders in the HyperShade.
			//
			string $hypershadeName = lookupHypershadeName( $component );
			string $fl[] = `visor -q -fl $hypershadeName`;
			string $f;
			for( $f in $fl )
			{
				visor -deleteFolder $f $hypershadeName;
			}

			// Second, create a new folder that orders nodes
			// according to our sorting method.
			// Account for both the sort and reverse flag.
			//
			string $filter = collectionUIAdvancedFilter( $component );
			string $reverse = collectionUIReverseOption( $component );
			string $cmd = "lsThroughFilter -na " + $filter
				+ " -sort " + $command
				+ " -reverse " + $reverse;
			visor
				-addFolder 
				-name "foobar"
				-type command
				-cmd $cmd
				$hypershadeName;
		}
		else
        {
            warning("The currently active tab is not a scene tab. The sort order functionality is not implemented for this tab.");
        }
	}
	else if ($command == "reverseOrder")
	{
		string $activeTab = activeTab($panel);
		string $component = lookupComponentName($activeTab);
		if (isSceneTab($activeTab))
		{
			// Reverse the current option and register this in the
			// colletionUIlookupTable
			//
			string $reverse = collectionUIReverseOption( $component );
			$reverse = ($reverse == "true") ? "false" : "true";
			registerReverseOption($component, $reverse);

			// Refresh both menu and icon
			refreshReverseOption( $panel, $activeTab );
			
			// Need to refresh the command action of the current visor.
			// First, remove any folders in the HyperShade.
			//
			string $hypershadeName = lookupHypershadeName( $component );
			string $fl[] = `visor -q -fl $hypershadeName`;
			string $f;
			for( $f in $fl )
			{
				visor -deleteFolder $f $hypershadeName;
			}

			// Second, create a new folder that orders nodes
			// according to our sorting method.
			// Account for both the sort and reverse flag.
			//
			string $filter = collectionUIAdvancedFilter( $component );
			string $sort = collectionUISortOption( $component );
			string $cmd = "lsThroughFilter -na " + $filter
				+ " -sort " + $sort
				+ " -reverse " + $reverse;
			visor
				-addFolder 
				-name "foobar"
				-type command
				-cmd $cmd
				$hypershadeName;
		}
		else
        {
            warning("The currently active tab is not a scene tab. The sort order functionality is not implemented for this tab.");
        }
	}

	else
	{
		error
			-showLineNumber true
			("Command not yet implemented: " + $command);
	}
}

global proc hyperShadePanelGraphNodeNetwork(
	string $panel,
	string $hypershade,
	string $node)
{
	//
	// Description:
	//	This procedure is called from the RMB popup menu of a node in a
	//	scene or graph tab in the shader editor.
	//	This method determines what tab the RMB menu is being invoked from,
	//	what tab the graph should be displayed in, and displays the graph.
	//

	//
	// To determine what tab the RMB is being invoked from is a bit ugly. We
	// will search up the parent structure from the hypershade which has been
	// provided, looking for firstPaneTabs or secondPaneTabs. We keep track of
	// the layout we just came from so that when we find firstPaneTabs or
	// secondPaneTabs we know what tab contained the hypershade.
	//

	setParent $panel;
	string $firstPaneTabs = `setParent firstPaneTabs`;
	setParent $panel;
	string $secondPaneTabs = `setParent secondPaneTabs`;

	string $parent = `hyperGraph -query -parent $hypershade`;
	string $child;

	setParent $parent;

	while (($parent != $firstPaneTabs) && ($parent != $secondPaneTabs))
	{
		$child = $parent;
		$parent = `setParent ..`;
		if ($parent == "") break;
	}

	if (($parent != $firstPaneTabs) && ($parent != $secondPaneTabs))
	{
		error
			-showLineNumber true
			("hyperShadePanelGraphNodeNetwork invoked from outside "
				+ "of Hypershade.");
	}

	// When we get to here, the name of the tab from which the menu was invoked
	// is stored in $child. To make things a little easier to understand, we
	// will store that name in $activeTab.
	//
	string $activeTab = $child;
	string $tabType = lookupTabType($activeTab);
	
	if (($tabType == "graph") || ($tabType == "protected graph"))
	{
		// The user is already in a graph, so we will graph the network in this
		// graph.
		//
		if (`optionVar -query hsClearBeforeGraphing` == 1)
		{
			hyperShade -clearWorkArea $hypershade;
		}

		hyperShade -shaderNetwork $node $hypershade;

		if (`optionVar -query hsClearBeforeGraphing` == 1)
		{
			hyperGraph -edit -frameGraph $hypershade;
		}
	}
	else if ($tabType == "scene")
	{
		// The user is in a scene graph, so we will graph the network in the
		// protected graph (default Work Area)
		//
		string $protectedGraphTab = workAreaTab();

		// Get the name of the hypershade in the protected graph tab so that we
		// can graph into it.
		//
		string $graphUI;
		string $hypershadeName;

		$graphUI = lookupComponentName($protectedGraphTab);
		$hypershadeName = graphUIHypershadeName($graphUI);

		if (`optionVar -query hsClearBeforeGraphing` == 1)
		{
			hyperShade -clearWorkArea $hypershadeName;
		}

		hyperShade -shaderNetwork $node $hypershadeName;
		hyperGraph -edit -frameGraph $hypershadeName;

		// Select the tab we have just graphed into so the user can see the
		// graph.
		//
		selectTab($panel, $protectedGraphTab);
	}
}

global proc hyperShadePanelSceneAndGraphTabPopupMenu(
	string $panel,
	string $hypershade,
	string $popupMenuName)
{
	//
	// Description:
	//	This procedure is called when the user RMB clicks in a scene or graph
	//	tab hypershade editor.
	//	This procedure builds the menu items which will appear in the popup
	//	menu.
	//	If the cursor is over a node, this procedure calls
	//	sceneAndGraphTabNodePopupMenu() to build the node-specific menu items.
	//

	if (!`popupMenu -e -exists $popupMenuName`) return;

	// Delete the existing menu items from the popup menu.
	//
	popupMenu -edit -deleteAllItems $popupMenuName;
	setParent -menu $popupMenuName;

	string $node = `hyperGraph -query -feedbackNode $hypershade`;
	string $gadget = `hyperGraph -query -feedbackGadget $hypershade`;

	if ($gadget == "Outputs")
	{
		hypergraphOutputsMenu($hypershade, $popupMenuName, $node);
		return;
	}

	if ($node != "")
	{
		menuItem 
			-label "Graph Network" 
			-radialPosition "S"
			-command 
				("hyperShadePanelGraphNodeNetwork "
					+ $panel 
					+ " "
					+ $hypershade 
					+ " "
					+ $node);

		buildHypergraphNodePopupMenuItems($hypershade, $node);

		menuItem -divider true;

		string $nodeType = `nodeType $node`;
		menuItem 
			-label ("Help on \"" + $nodeType + "\"")	
			-enableCommandRepeat false
			-command ("showHelp -docs \"Nodes/" + $nodeType + ".html\"");
	}
	else
	{
		// There is no node under the cursor.
		//
		buildMainMenu(
			$panel, 
			true); // popup menu
	}
}

global proc hyperShadePanelDiskTabPopupMenu(
	string $panel,
	string $editor,
	string $popupMenu)
{
	//
	// Description:
	//	This procedure is called when the user RMB clicks in a disk tab visor.
	//	This procedure builds the menu items which will appear in the popup
	//	menu.
	//	The contents of the menu can vary based on the type of file the cursor
	//	is positioned over.
	//

	if (!`popupMenu -e -exists $popupMenu`) return;

	// Delete the existing menu items from the popup menu.
	//
	popupMenu -edit -deleteAllItems $popupMenu;
	setParent -menu $popupMenu;

	// Determine what file is under the mouse pointer, if any
	//
	string $filePath = `hyperGraph -query -feedbackNode $editor`;

	if ($filePath != "")
	{
		buildHypergraphFilePopupMenuItems($editor, $popupMenu, $filePath);
	}
	else
	{
		// There is no file under the cursor.
		//
		buildMainMenu(
			$panel, 
			true); // popup menu
	}
}

proc framePane(
	string $panel,
    string $paneTabsName,
	string $frameOperation)
{
	//
	// Description:
	//	This procedure is called from frame() when
	//	the user presses a hotkey to frame the contents of a tab in the
	//	hypershade panel.
	//	This procedure determines for the pane specified by the given 
    //  $paneTabsName what tab the user's cursor is over, and
	//	performs a frame all or frame selected operation on the component UI in
	//	that tab as requested by the $frameOperation.
	//

	setParent $panel;
	string $paneTabs = `setParent $paneTabsName`;

	string $paneTab = `tabLayout -query -selectTab $paneTabs`;

    if ($paneTab == "")
    {
        // No tab is in this pane.  Do nothing.
        //
        return;
    }

    $paneTab = `setParent $paneTab`;

	string $paneHypergraph;

	string $componentName;

	$componentName = lookupComponentName($paneTab);

	if (isDiskTab($paneTab))
	{
		$paneHypergraph = libraryUIFilesVisor($componentName);
	}
	else if (isGraphTab($paneTab))
	{
		$paneHypergraph = graphUIHypershadeName($componentName);
	}
	else if (isSceneTab($paneTab))
	{
		$paneHypergraph = collectionUIHypershadeName($componentName);
	}

	if (`hyperGraph -query -isHotkeyTarget $paneHypergraph`)
	{
		if ($frameOperation == "all")
		{
			hyperGraph
				-edit
				-frameGraph
				$paneHypergraph;
		}
		else if ($frameOperation == "selected")
		{
			hyperGraph
				-edit
				-frame
				$paneHypergraph;
		}

		// Set focus to the tab layout which received the frame command
		//
		hyperShadePanelSetActiveTabLayout($panel, $paneTabsName, false);
	}
}

proc frame(
	string $panel,
	string $frameOperation)
{
	//
	// Description:
	//	This procedure is called from frameAll() or frameSelected() when
	//	the user presses a hotkey to frame the contents of a tab in the
	//	hypershade panel.
	//	This procedure determines what tab the user's cursor is over, and
	//	performs a frame all or frame selected operation on the component UI in
	//	that tab as requested by the $frameOperation.
	//

    framePane($panel, "firstPaneTabs", $frameOperation);
    framePane($panel, "secondPaneTabs", $frameOperation);
}

global proc hyperShadePanelFrameAll(
	string $panel)
{
	//
	// Description:
	//	This procedure is typically called from fitPanel() in fitPanel.mel when
	//	the user presses a hotkey to frame the contents of a tab in the
	//	hypershade panel.
	//	This procedure calls frame() to perform the operation.
	//
	frame($panel, "all");
}

global proc hyperShadePanelFrameSelected(
	string $panel)
{
	//
	// Description:
	//	This procedure is typically called from fitPanel() in fitPanel.mel when
	//	the user presses a hotkey to frame the selected items in a tab in the
	//	hypershade panel.
	//	This procedure calls frame() to perform the operation.
	//
	frame($panel, "selected");
}

global proc hyperShadePanelRebuildCreateBarUI(
	string $panel)
{
	//
	// Description:
	//	This procedure is called when the contents of the hypershade create bar
	//	no longer accurately reflect what can be created. Usually this is
	//	because a plugin has been loaded or unloaded. 
	//	This procedure deletes the UI in the create bar and rebuilds it.
	//

	// Get the name of the layout containing the create bar UI
	//
	string $renderCreateBarUI = renderCreateBarUIName($panel);

	int $managed = renderCreateBarUIIsManaged($renderCreateBarUI); 

	// Determine the current width of the create bar so that it can
	// be restored if we decide to collapse it during rebuilding.
	//
	int $iconsAndTextWidth = 
		`optionVar -query hyperShadePanelCreateBarIconsAndTextWidth`;

	int $createBarWidth = `optionVar -query hyperShadePanelCreateBarShown` ?
					  $iconsAndTextWidth : 1;

	global int $gButtonsColumnWidth;
	int $spacer = 3;
	int $paneLeftPosnNoCreateBar = $spacer + $gButtonsColumnWidth;
	int $paneLeftPosnYesCreateBar = $createBarWidth + $gButtonsColumnWidth;


	// Hide the section of the hyperShadePanel which contains the
	// create bar until it has finished building
	//
	if ($managed)
	{
		// The create bar is currently being displayed.
		// In order to update it without things looking bad in the process, 
		// we will collapse the pane which contains the create bar and 
		// expand it after we are finished.
		//
		setParent $panel;
		formLayout
			-edit
			-af paneArrangement	left $paneLeftPosnNoCreateBar
			mainForm;
	}

	// Delete the existing UI
	//
	deleteUI $renderCreateBarUI;

	// Build the new create bar
	//
    string $createBarForm = hyperShadeCreateBarForm($panel); 
    $createBarForm = `setParent $createBarForm`;
	renderCreateBarUI($createBarForm);

	// Show the create bar again, if it was being shown before
	//
	if ($managed)
	{
		formLayout
			-edit
			-af paneArrangement	left $paneLeftPosnYesCreateBar
			mainForm;
	}
}

proc pluginChange(
	string $panel,
	string $changeType,
	string $plugin)
{
	//
	// Description:
	//	This procedure is called from hyperShadePanelLoadPluginCallback() or
	//	from hyperShadePanelUnloadPluginCallback(). If this method is being
	//	called because a plugin has been loaded, $changeType should be
	//	"loadPlugin". If this method is being called because a plugin is
	//	about to be unloaded, $changeType should be "unloadPlugin". There
	//	are no other valid values for $changeType.
	//	This method determines if the create bar UI needs to be updated as a
	//	result of the loading or unloading of the specified plugin, and if so,
	//	deletes and rebuilds the create bar UI.
	//

	// Get a list of all node types loaded by the plugin
	//
	string $pluginNodeTypeArray[] = `pluginInfo -query -dependNode $plugin`;

	string $nodeType;

	for ($nodeType in $pluginNodeTypeArray)
	{
		// Determine the classification(s) of each node type. Note that nodes
		// can have multiple classifications.
		//
		string $classificationArray[] = `getClassification $nodeType`;
		string $classification;

		for ($classification in $classificationArray)
		{
			string $tokenArray[];
			int $numTokens = tokenize($classification, "/", $tokenArray);

			if (	($tokenArray[0] == "texture")
				||	($tokenArray[0] == "shader")
				||	($tokenArray[0] == "light")
				||	($tokenArray[0] == "utility")
				||	($tokenArray[0] == "imageplane")
				||	($tokenArray[0] == "postprocess")
				||	( $numTokens>=2 && $tokenArray[0] == "rendernode" && $tokenArray[1] == "mentalray") )
			{
				// The node type is classified as something which appears
				// within the create bar, so we need to refresh
				// that window.
				//
				// Note that the above list needs to be kept in sync with the
				// types of nodes which appear in the create bar.
				//
				if ($changeType == "loadPlugin")
				{
					hyperShadePanelRebuildCreateBarUI($panel);
					return;
				}
				else if ($changeType == "unloadPlugin")
				{
					// The plugin is being unloaded, but is not yet gone. We
					// want to refresh the create bar but not until
					// after the plugin has finished unloading. If we don't
					// wait until the plugin has finished unloading, then the
					// refreshed create bar will still contain the node types
					// defined by the plugin.
					// 
					// To make sure the plugin has finished unloading before we
					// refresh the create bar, we will defer the evaluation of 
					// the refresh command until idle time.
					//
					evalDeferred(
						"hyperShadePanelRebuildCreateBarUI " 
						+ $panel);

					return;
				}
			}
		}
	}
}

global proc hyperShadePanelLoadPluginCallback(
	string $panel,
	string $pluginName)
{
	//
	// Description:
	//	This procedure is called when a plugin has been loaded.
	//	This procedure calls pluginChange(), which will update the create bar
	//	if necessary as a result of the newly loaded plugin.
	//

	pluginChange($panel, "loadPlugin", $pluginName);
}

global proc hyperShadePanelUnloadPluginCallback(
	string $panel,
	string $pluginName)
{
	//
	// Description:
	//	This procedure is called when a plugin is about to be unloaded.
	//	This procedure calls pluginChange(), which will update the create bar
	//	if necessary as a result of the unloading of the plugin.
	//
	pluginChange($panel, "unloadPlugin", $pluginName);
}

proc rebuildIconOnlyCreateBar(string $panel)
{
    //
    // Description:  This procedure is called to rebuild the iconsOnly
    // style create bar in hyper shade if the style is currently
    // "iconsOnly".
    //

    string $style = `optionVar -query "renderCreateBarStyle"`;

    if ($style == "iconsOnly")
    {
        setParent $panel;
        string $createBarTabLayout = `setParent createBarTabLayout`;
        refreshCreateBarTabLayout( $createBarTabLayout);
    }
}

global proc hyperShadePanelDecreaseCreateBarSize(
	string $panel)
{
	// 
	// Description:
	//	This procedure is called when the user presses the "<<" button shown 
	//	at the bottom of the create bar when it is in icons and text mode.
	//	This procedure decreases the width of the create bar and redraws it, 
	//	unless the new width would be less than a predefined minimum width.
	//
	global int $gRenderCreateBarIconsAndTextMinWidth;
	global int $gButtonsColumnWidth;

	int $createBarWidth;

	$createBarWidth = 
		`optionVar -query hyperShadePanelCreateBarIconsAndTextWidth`;
	
	$createBarWidth -= 34;

	if ($createBarWidth < $gRenderCreateBarIconsAndTextMinWidth)
	{
		// The new width would be smaller than the minimum, so we clamp it to
		// the minimum.
		//
		$createBarWidth = $gRenderCreateBarIconsAndTextMinWidth;

		// Also disable the "<<" button since we aren't going to allow the
		// create bar to get any narrower than it currently is.
		//
		button 
			-edit
			-enable false
			decreaseCreateBarSizeButton;
	}

	// Save the new width of the create bar in the option var which represents
	// it.
	//
	optionVar 
		-intValue hyperShadePanelCreateBarIconsAndTextWidth $createBarWidth;
	
	// Adjust the width of the form layout which contains the create bar.
	//
	setParent $panel;
	int $paneLeftPosnYesCreateBar = $createBarWidth + $gButtonsColumnWidth;
	formLayout
		-edit
		-af buttonsColumn left $createBarWidth
		-af paneArrangement	left $paneLeftPosnYesCreateBar
		mainForm;

	// Ensure the ">>" button is enabled since the create bar is now definitely
	// narrower than the maximum allowable size.
	//
	button 
		-edit
		-enable true
		increaseCreateBarSizeButton;

    // Rebuild the iconOnly style create bar after the width of
    // the create bar is decreased.
    //
    rebuildIconOnlyCreateBar($panel);
}

global proc hyperShadePanelIncreaseCreateBarSize(
	string $panel)
{
	// 
	// Description:
	//	This procedure is called when the user presses the ">>" button shown 
	//	at the bottom of the create bar when it is in icons and text mode.
	//	This procedure increases the width of the create bar and redraws it, 
	//	unless the new width would be greater than a predefined maximum width.
	//

	global int $gRenderCreateBarIconsAndTextMaxWidth;
	global int $gButtonsColumnWidth;

	int $createBarWidth;

	$createBarWidth = 
		`optionVar -query hyperShadePanelCreateBarIconsAndTextWidth`;
	
	$createBarWidth += 34;

	if ($createBarWidth > $gRenderCreateBarIconsAndTextMaxWidth)
	{
		// The new width would be larger than the maximum, so we clamp it to
		// the maximum.
		//
		$createBarWidth = $gRenderCreateBarIconsAndTextMaxWidth;

		// Also disable the ">>" button since we aren't going to allow the
		// create bar to get any wider than it currently is.
		//
		button 
			-edit
			-enable false
			increaseCreateBarSizeButton;
	}

	// Save the new width of the create bar in the option var which represents
	// it.
	//
	optionVar 
		-intValue hyperShadePanelCreateBarIconsAndTextWidth $createBarWidth;
	
	// Adjust the width of the form layout which contains the create bar.
	//
	setParent $panel;
	int $paneLeftPosnYesCreateBar = $createBarWidth + $gButtonsColumnWidth;

	formLayout
		-edit
		-af paneArrangement	left $paneLeftPosnYesCreateBar
		-af buttonsColumn left $createBarWidth
		mainForm;

	// Ensure the "<<" button is enabled since the create bar is now definitely
	// wider than the minimum allowable size.
	//
	button 
		-edit
		-enable true
		decreaseCreateBarSizeButton;

    // Rebuild the iconOnly style create bar after the width of
    // the create bar is increased.
    //
    rebuildIconOnlyCreateBar($panel);
}

// ---------------------------------------------------------------------------
// 	Scripted panel support
// 

global proc createHyperShadePanel(string $panel) 
{
	//
	// Description:
	//	This procedure is called the first time the shader editor is opened.
	//	This procedure creates the various UI entities that the shader
	//	editor will use, except for those UI entities which are controls.
	//
}

// Description: Copy the bin list from the render globals attribute to 
// the mel global variable.
//
proc initHyperShadeBinList()
{
    if( !`optionVar -exists hsBinsSortShadingNodesOnly` )
    {
        optionVar -intValue hsBinsSortShadingNodesOnly 1;
    }
}

global proc initHyperShadePanel(string $panel)
{
    // Copy the bin list from the render globals attribute to 
    // the mel global variable.
    //
    initHyperShadeBinList();

	// This is called when the file changes to make sure that everything
	// is up-to-date with the new file.  
	//
    if (`exists hyperShadeUpdateBinsUISceneOpenCallback`)
    {
        hyperShadeUpdateBinsUISceneOpenCallback();
    }

	// Create the lookup table which will keep track of the tabs, their types,
	// and their associated components.
	//
	createHyperShadePanelLookupTable();
}

global int $gHypershadePluginCallbacksRegistered = false;

// Description:  This procedure is called to create the content for
//      the toolbarForm.
//
proc createToolbarFormContent(string $panel, string $toolbarForm)
{
    string $oldParent = `setParent -q`;

            setParent $toolbarForm;

			int $iconSize = 26;
			iconTextButton
				-image1 "navButtonUnconnected.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Toggle the Create Bar On/Off"
				-command 
					("hyperShadePanelMenuCommand(\"" 
						+ $panel 
						+ "\", \"toggleRenderCreateBar\")")
				toggleRenderCreateBarButton;

			separator -horizontal false -style single separator1;

			iconTextButton
				-image1 "hsPrevGraph.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Show Previous Graph"
				-command
					("hyperShadePanelGraphCommand(\""
						+ $panel
						+ "\", \"showPreviousGraph\")")
				showPreviousGraphButton;

			iconTextButton
				-image1 "hsNextGraph.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Show Next Graph"
				-command
					("hyperShadePanelGraphCommand(\""
						+ $panel
						+ "\", \"showNextGraph\")")
				showNextGraphButton;

			separator -horizontal false -style single separator2;

			iconTextButton
				-image1 "hsClearView.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Clear Graph"
				-command 
					("hyperShadePanelGraphCommand(\"" 
						+ $panel 
						+ "\", \"clearGraph\")")
				clearGraphButton;

			iconTextButton
				-image1 "hsRearrange.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Rearrange Graph"
				-command 
					("hyperShadePanelGraphCommand(\"" 
						+ $panel 
						+ "\", \"rearrangeGraph\")")
				rearrangeGraphButton;

			iconTextButton
				-image1 "hsGraphMaterial.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Graph Materials on Selected Objects"
				-command 
					("hyperShadePanelGraphCommand(\"" 
						+ $panel 
						+ "\", \"graphMaterials\")")
				graphMaterialsButton;

			separator -horizontal false -style single separator3;

			iconTextButton
				-image1 "hsUpStreamCon.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Input Connections"
				-command 
					("hyperShadePanelGraphCommand(\"" 
						+ $panel 
						+ "\", \"showUpstream\")")
				showUpstreamButton;

			iconTextButton
				-image1 "hsUpDownStreamCon.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Input and Output Connections"
				-command 
					("hyperShadePanelGraphCommand(\"" 
						+ $panel 
						+ "\", \"showUpAndDownstream\")")
				showUpAndDownstreamButton;

			iconTextButton
				-image1 "hsDownStreamCon.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Output Connections"
				-command 
					("hyperShadePanelGraphCommand(\"" 
						+ $panel 
						+ "\", \"showDownstream\")")
				showDownstreamButton;

			separator -horizontal false -style single separator4;

            // Filter for the hyper shade tab.  
            //   . If we have "Show Top and Bottom Tabs", then the 
            //     filter is for the current active tab among the top tabs.
            //   . If we have "Show Top Tabs Only" or 
            //     "Show Bottom Tabs Only", then the filter is for
            //     the currently active tab. 
            //
            string $sceneTabFilterForm = `formLayout sceneTabFilterForm`;
            setParent ..;  // from sceneTabFilterForm

			iconTextRadioCollection;
			iconTextRadioButton
				-image1 "hsShowTopTabsOnly.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Show Top Tabs Only"
				-onCommand 
					("hyperShadePanelMenuCommand(\"" 
						+ $panel 
						+ "\", \"showTopTabsOnly\")")
				showTopTabsOnlyButton;

			iconTextRadioButton
				-image1 "hsShowBottomTabsOnly.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Show Bottom Tabs Only"
				-onCommand 
					("hyperShadePanelMenuCommand(\"" 
						+ $panel 
						+ "\", \"showBottomTabsOnly\")")
				showBottomTabsOnlyButton;

			iconTextRadioButton
				-image1 "hsShowTopAndBottomTabs.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Show Top and Bottom Tabs"
				-onCommand 
					("hyperShadePanelMenuCommand(\"" 
						+ $panel 
						+ "\", \"showTopAndBottomTabs\")")
				showTopAndBottomTabsButton;
				
			separator -horizontal false -style single separator5;
				
			formLayout
				-edit
				-af toggleRenderCreateBarButton top 0 
				-af toggleRenderCreateBarButton bottom 0 
				-af toggleRenderCreateBarButton left 0
				-an toggleRenderCreateBarButton right 

				-af separator1 top 0 
				-af separator1 bottom 0 
				-ac separator1 left 0 toggleRenderCreateBarButton 
				-an separator1 right 

				-af showPreviousGraphButton top 0 
				-af showPreviousGraphButton bottom 0 
				-ac showPreviousGraphButton left 0 separator1
				-an showPreviousGraphButton right 

				-af showNextGraphButton top 0 
				-af showNextGraphButton bottom 0 
				-ac showNextGraphButton left 0 showPreviousGraphButton
				-an showNextGraphButton right 

				-af separator2 top 0 
				-af separator2 bottom 0 
				-ac separator2 left 0 showNextGraphButton 
				-an separator2 right 

				-af clearGraphButton top 0 
				-af clearGraphButton bottom 0 
				-ac clearGraphButton left 0 separator2
				-an clearGraphButton right 

				-af rearrangeGraphButton top 0 
				-af rearrangeGraphButton bottom 0 
				-ac rearrangeGraphButton left 0 clearGraphButton
				-an rearrangeGraphButton right 

				-af graphMaterialsButton top 0 
				-af graphMaterialsButton bottom 0 
				-ac graphMaterialsButton left 0 rearrangeGraphButton
				-an graphMaterialsButton right 

				-af separator3 top 0 
				-af separator3 bottom 0 
				-ac separator3 left 0 graphMaterialsButton 
				-an separator3 right 

				-af showUpstreamButton top 0 
				-af showUpstreamButton bottom 0 
				-ac showUpstreamButton left 0 separator3
				-an showUpstreamButton right 

				-af showUpAndDownstreamButton top 0 
				-af showUpAndDownstreamButton bottom 0 
				-ac showUpAndDownstreamButton left 0 showUpstreamButton
				-an showUpAndDownstreamButton right 

				-af showDownstreamButton top 0 
				-af showDownstreamButton bottom 0 
				-ac showDownstreamButton left 0 showUpAndDownstreamButton
				-an showDownstreamButton right 

				-af separator4 top 0 
				-af separator4 bottom 0 
				-ac separator4 left 0 showDownstreamButton
				-an separator4 right 

				-af sceneTabFilterForm top 0 
				-af sceneTabFilterForm bottom 0 
				-ac sceneTabFilterForm left 0 separator4
				-an sceneTabFilterForm right
				
				-af separator5 top 0 
				-af separator5 bottom 0 
				-ac separator5 left 0 sceneTabFilterForm
				-an separator5 right
				
				-af showTopAndBottomTabsButton top 0 
				-af showTopAndBottomTabsButton bottom 0 
				-ac showTopAndBottomTabsButton left 0 separator5
				-an showTopAndBottomTabsButton right

				-af showBottomTabsOnlyButton top 0 
				-af showBottomTabsOnlyButton bottom 0 
				-ac showBottomTabsOnlyButton left 0 showTopAndBottomTabsButton
				-an showBottomTabsOnlyButton right

				-af showTopTabsOnlyButton top 0 
				-af showTopTabsOnlyButton bottom 0 
				-ac showTopTabsOnlyButton left 0 showBottomTabsOnlyButton
				-an showTopTabsOnlyButton right
				
				toolbarForm;

    setParent $oldParent;
}

// Description:  This procedure is called to create the content for
//      the buttonsColumn.
//
proc createButtonsColumnContent(string $panel, string $buttonsColumn)
{
    string $oldParent = `setParent -q`;

            setParent $buttonsColumn;

			int $iconSize = 26;

			// Buttons for View as Icons/List
			iconTextRadioCollection;
			iconTextRadioButton
				-image1 "viewIcon.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "View as Icons"
				-onCommand 
					("hyperShadePanelMenuCommand(\"" 
						+ $panel 
						+ "\", \"asIcons\")")
				asIconsColumnButton;

			iconTextRadioButton
				-image1 "viewList.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "View as List"
				-onCommand 
					("hyperShadePanelMenuCommand(\"" 
						+ $panel 
						+ "\", \"asList\")")
				asListColumnButton;

			separator -height $iconSize -visible false separator1;

			// Buttons for View as Small/Medium/Large Swatches
			iconTextRadioCollection;
			iconTextRadioButton
				-image1 "iconSmall.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "View as Small Swatches"
				-onCommand 
					("hyperShadePanelMenuCommand(\"" 
						+ $panel 
						+ "\", \"smallIcons\")")
				smallIconsColumnButton;

			iconTextRadioButton
				-image1 "iconMedium.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "View as Medium Swatches"
				-onCommand 
					("hyperShadePanelMenuCommand(\"" 
						+ $panel 
						+ "\", \"mediumIcons\")")
				mediumIconsColumnButton;

			iconTextRadioButton
				-image1 "iconLarge.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "View as Large Swatches"
				-onCommand 
					("hyperShadePanelMenuCommand(\"" 
						+ $panel 
						+ "\", \"largeIcons\")")
				largeIconsColumnButton;

			iconTextRadioButton
				-image1 "iconSuper.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "View as Extra Large Swatches"
				-onCommand 
					("hyperShadePanelMenuCommand(\"" 
						+ $panel 
						+ "\", \"superIcons\")")
				superIconsColumnButton;

			separator -height $iconSize -visible false separator2;

			// Buttons for Sort by Name/Type/Time, and Reverse Order
			iconTextRadioCollection;
			iconTextRadioButton
				-image1 "sortName.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Sort by Name"
				-onCommand 
					("hyperShadePanelMenuCommand(\"" 
						+ $panel 
						+ "\", \"byName\")")
				byNameColumnButton;

			iconTextRadioButton
				-image1 "sortType.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Sort by Type"
				-onCommand 
					("hyperShadePanelMenuCommand(\"" 
						+ $panel 
						+ "\", \"byType\")")
				byTypeColumnButton;

			iconTextRadioButton
				-image1 "sortTime.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Sort by Time"
				-onCommand 
					("hyperShadePanelMenuCommand(\"" 
						+ $panel 
						+ "\", \"byTime\")")
				byTimeColumnButton;

			iconTextCheckBox
				-image1 "reverseOrder.xpm"
				-width $iconSize
				-height $iconSize
				-annotation "Sort in reverse order"
				-changeCommand
					("hyperShadePanelMenuCommand(\""
						+ $panel
						+ "\", \"reverseOrder\")")
				reverseOrderColumnButton;
			
			// Layout
			//
			formLayout
				-edit
				-af asIconsColumnButton top 0 
				-an asIconsColumnButton bottom
				-af asIconsColumnButton left 0
				-af asIconsColumnButton right 0

				-ac asListColumnButton top 0 asIconsColumnButton
				-an asListColumnButton bottom
				-af asListColumnButton left 0
				-af asListColumnButton right 0

				-ac separator1 top 0 asListColumnButton
				-an separator1 bottom
				-af separator1 left 0
				-af separator1 right 0

				-ac smallIconsColumnButton top 0 separator1
				-an smallIconsColumnButton bottom
				-af smallIconsColumnButton left 0
				-af smallIconsColumnButton right 0

				-ac mediumIconsColumnButton top 0 smallIconsColumnButton
				-an mediumIconsColumnButton bottom
				-af mediumIconsColumnButton left 0
				-af mediumIconsColumnButton right 0

				-ac largeIconsColumnButton top 0 mediumIconsColumnButton
				-an largeIconsColumnButton bottom
				-af largeIconsColumnButton left 0
				-af largeIconsColumnButton right 0

				-ac superIconsColumnButton top 0 largeIconsColumnButton
				-an superIconsColumnButton bottom
				-af superIconsColumnButton left 0
				-af superIconsColumnButton right 0

				-ac separator2 top 0 superIconsColumnButton
				-an separator2 bottom
				-af separator2 left 0
				-af separator2 right 0

				-ac byNameColumnButton top 0 separator2
				-an byNameColumnButton bottom
				-af byNameColumnButton left 0
				-af byNameColumnButton right 0

				-ac byTypeColumnButton top 0 byNameColumnButton
				-an byTypeColumnButton bottom
				-af byTypeColumnButton left 0
				-af byTypeColumnButton right 0

				-ac byTimeColumnButton top 0 byTypeColumnButton
				-an byTimeColumnButton bottom
				-af byTimeColumnButton left 0
				-af byTimeColumnButton right 0

				-ac reverseOrderColumnButton top 0 byTimeColumnButton
				-an reverseOrderColumnButton bottom
				-af reverseOrderColumnButton left 0
				-af reverseOrderColumnButton right 0
				
				buttonsColumn;

    setParent $oldParent;
}


// Description:  This procedure is called to create the content of
// the createBarWrapForm.
//
proc createCreateBarWrapFormContent(
    string $panel, string $createBarWrapForm, int $createBarWidth)
{   
    string $oldParent = `setParent -q`;

            setParent $createBarWrapForm;
            string $createAndOrganizeForm = `formLayout createAndOrganizeForm`;


			setParent ..; // from $createAndOrganizeForm

			// The createBarSizeButtonsFormWrap exists so that the
			// createBarSizeButtonsForm can be unmanaged/managed in order to 
			// hide/show the create bar size buttons.
			//
			formLayout createBarSizeButtonsFormWrap;
				formLayout -numberOfDivisions 2 createBarSizeButtonsForm;
				
					button
						-label "<<"
						-height 15
						-annotation "Decrease Create Bar size"
						-command 
							("hyperShadePanelDecreaseCreateBarSize " + $panel)
						decreaseCreateBarSizeButton;

					button
						-label ">>"
						-height 15
						-annotation "Increase Create Bar size"
						-command 
							("hyperShadePanelIncreaseCreateBarSize " + $panel)
						increaseCreateBarSizeButton;

		            global int $gRenderCreateBarIconsAndTextMinWidth;
		            global int $gRenderCreateBarIconsAndTextMaxWidth;
            
		            if ($createBarWidth == $gRenderCreateBarIconsAndTextMaxWidth)
		            {
			            // Disable the ">>" button since we aren't going to allow the
			            // create bar to get any wider than it currently is.
			            //
			            button 
				            -edit
				            -enable false
				            increaseCreateBarSizeButton;
		            }
		            else if ($createBarWidth == $gRenderCreateBarIconsAndTextMinWidth)
		            {
			            // Disable the "<<" button since we aren't going to allow the
			            // create bar to get any narrower than it currently is.
			            //
			            button 
				            -edit
				            -enable false
				            decreaseCreateBarSizeButton;
		            }
					
					formLayout
						-edit

						-af	decreaseCreateBarSizeButton top 0
						-af	decreaseCreateBarSizeButton bottom 0
						-af	decreaseCreateBarSizeButton left 0
						-ap	decreaseCreateBarSizeButton right 0 1

						-af	increaseCreateBarSizeButton top 0
						-af	increaseCreateBarSizeButton bottom 0
						-ap	increaseCreateBarSizeButton left 0 1
						-af	increaseCreateBarSizeButton right 0

						createBarSizeButtonsForm;

				setParent ..; // from createBarSizeButtonsForm

				formLayout
					-edit
					-af createBarSizeButtonsForm top 0
					-af createBarSizeButtonsForm bottom 0
					-af createBarSizeButtonsForm left 0
					-af createBarSizeButtonsForm right 0
					createBarSizeButtonsFormWrap;

			setParent ..; // from createBarSizeButtonsFormWrap

			formLayout
				-edit

				-af	createAndOrganizeForm top 0
				-ac	createAndOrganizeForm bottom 0 createBarSizeButtonsFormWrap
				-af	createAndOrganizeForm left 0
				-af	createAndOrganizeForm right 0

				-an	createBarSizeButtonsFormWrap top
				-af	createBarSizeButtonsFormWrap bottom 0
				-af	createBarSizeButtonsFormWrap left 0
				-af	createBarSizeButtonsFormWrap right 0

				createBarWrapForm;

        // Create the CreateAndOrganizeForm content.
        //
        hyperShadeCreateAndOrganizeUI($panel, $createAndOrganizeForm);

    
    setParent $oldParent;
}



global proc addHyperShadePanel(string $panel) 
{
	//
	// Description:
	//	This procedure is called when the hypershade panel is first opened. 
	//	This procedure creates all of the UI for the hypershade panel.
	//

	global int $gButtonsColumnWidth;

	// Make sure the filteredCollection stuff is initialized.
	//
	filteredCollection();

	// Show the wait cursor
	//
	waitCursor -state on;

	// Flag this as a construction operation, to prevent many unnecessary
	// refreshes as the tabs are being created.
	//
	hyperShadeStartConstruction( $panel );

	buildMainMenu(
		$panel, 
		false); // not a popup menu


	formLayout -manage false mainForm;

		string $toolbarForm = `formLayout toolbarForm`;
		setParent ..; // from toolbarForm

		separator -horizontal true -style single separator3;

		string $createBarWrapForm = `formLayout createBarWrapForm`;
		setParent ..; // from createBarWrapForm

		string $buttonsColumn = `formLayout -width $gButtonsColumnWidth
			buttonsColumn`;
		setParent ..; // from columnLayout

		// This variable will define the width of the box around the pane in
		// hypershade which currently has focus. It needs to be larger on NT
		// than on IRIX because it is more difficult to see it on NT.
		//
		int $activeFrameThickness = 2;

		if (`about -win`)
		{
			// Unfortunately, it seems there is a bug in paneLayout on NT as
			// changing this value does not appear to have any effect.
			//
			$activeFrameThickness = 4;
		}

		string $paneLayout = 
			`paneLayout
				-configuration "horizontal2" // stacked
				-separatorThickness 5
				-activeFrameThickness $activeFrameThickness
				-activePaneIndex 1
				paneArrangement`;

			string $firstPaneTabs = `tabLayout 
                -selectCommand 
                    ("hyperShadePanelSetActiveTabLayout "
                        + $panel
                        + " firstPaneTabs true")
				firstPaneTabs`;
			setParent ..; // from firstPaneTabs;
				
			string $secondPaneTabs = `tabLayout 
				-selectCommand 
					("hyperShadePanelSetActiveTabLayout "
						+ $panel
						+ " secondPaneTabs false")
				secondPaneTabs`;
			setParent ..; // from secondPaneTabs;
					
		setParent ..; // from paneArrangement

		int $iconsAndTextWidth = 
			`optionVar -query hyperShadePanelCreateBarIconsAndTextWidth`;

		int $createBarWidth = 1;

		if (`optionVar -query hyperShadePanelCreateBarShown`)
		{
			$createBarWidth = $iconsAndTextWidth;
		}

		int $spacer = 3;
		int $paneLeftPosnNoCreateBar = $spacer + $gButtonsColumnWidth;
		int $paneLeftPosnYesCreateBar = $createBarWidth + $gButtonsColumnWidth;

		// Main layout done here
		//
		formLayout
			-edit

			-af toolbarForm top 0
			-an toolbarForm bottom
			-af toolbarForm left 0
			-af toolbarForm right 0

			-ac separator3	top		0 toolbarForm
			-an separator3	bottom
			-af separator3	left	0
			-af separator3	right	0

			-ac createBarWrapForm top 		1 separator3
			-af createBarWrapForm bottom 	1
			-af createBarWrapForm left 		1
			-ac createBarWrapForm right		1 buttonsColumn

			-ac buttonsColumn top		1 separator3
			-af buttonsColumn bottom	1
			-af buttonsColumn left		`max $spacer $createBarWidth`
			-ac buttonsColumn right		1 paneArrangement

			-ac paneArrangement	top		1 separator3
			-af paneArrangement	bottom	1
			-af paneArrangement	left    `max $paneLeftPosnNoCreateBar $paneLeftPosnYesCreateBar`
			-af paneArrangement	right	1

			mainForm;

	setParent ..; // from mainForm

    // Create the content of the toolbarForm.
    //
    createToolbarFormContent($panel, $toolbarForm);

    // Create the createBarWrapForm content.
    //
    createCreateBarWrapFormContent(
        $panel, $createBarWrapForm, $createBarWidth);

	// Create the buttonsColumn content.
	//
	createButtonsColumnContent( $panel, $buttonsColumn );

    // Finished creating the content of the mainForm, manage the
    // form to show the content.
    //
    formLayout -edit -manage true mainForm;


	optionVar -stringValue "hyperShadePanelWorkAreaTab" "";

	// Create the tabs
	//
	initTabs($panel);

    // Refresh the PaneTabs' active tab.
    //
    hyperShadePanelSetActiveTabLayout($panel, "firstPaneTabs", true); 
    hyperShadePanelSetActiveTabLayout($panel, "secondPaneTabs", true); 

	// If the user has specified in a previous session that only the top or
	// bottom tab section is to be displayed, we will continue to do so.
	//
	string $tabSectionsShown = 
		`optionVar -query hyperShadePanelTabSectionsShown`; 
	
	if ($tabSectionsShown == "showTopTabsOnly")
	{
		showTopTabsOnly($panel);
	}
	else if ($tabSectionsShown == "showBottomTabsOnly")
	{
		showBottomTabsOnly($panel);
	}

	// Refresh the toolbar since it is affected by the currently active tab
	//
	refreshToolbar($panel);

	// Hide the wait cursor
	//
	waitCursor -state off;

	// Establish callbacks which will be called when plugins are
	// loaded/unloaded. The callbacks will find out what plugin was loaded and 
	// will update the create bar if necessary.
	//
	global int $gHypershadePluginCallbacksRegistered;

	if (!$gHypershadePluginCallbacksRegistered)
	{
		loadPlugin 
			-addCallback 
				("hyperShadePanelLoadPluginCallback \"" + $panel + "\"") ;
		unloadPlugin 
			-addCallback
				("hyperShadePanelUnloadPluginCallback \"" + $panel + "\"") ;
		$gHypershadePluginCallbacksRegistered = true;
	}

	// Signal the end of the construciton operation
	//
	hyperShadeEndConstruction( $panel, 1 );
}

proc deleteEditors(
	string $tabLayout)
{
	//
	// Description:
	//	This procedure is called from removeHyperShadePanel(). 
	//	This procedure determines all the hypergraph editors that are being
	//	used within the specified tab layout and deletes them, since the 
	//	hypershade is going away.
	//

	string $tabArray[] = `tabLayout -query -childArray $tabLayout`;
	string $tab;

	// Delete all hypergraph editors being used by this panel
	//
	for ($i = 0; $i < size($tabArray); $i++)
	{
		$tab = $tabArray[$i];
		$tab = ($tabLayout + "|" + $tab);

		string $tabType = lookupTabType($tab);
		string $component = lookupComponentName($tab);

        // If the conponent is an empty string, it means the
        // content of this tab was never constructed, then we
        // do no need to do anything.
        //
        if ($component == "")
        {
            continue;
        }

		string $hypergraph;

		if ($tabType == "scene")
		{
			string $hypershade = collectionUIHypershadeName($component);
			
			// Be sure to properly delete the collection, including
			// its filters and such.
			//
			collectionUIDelete( $component, 0 );

			hyperGraph -edit -unParent $hypershade;
			deleteUI $hypershade;
		}
		else if ($tabType == "disk")
		{
			string $filesVisor = libraryUIFilesVisor($component);
			string $directoriesVisor = 
				libraryUIDirectoriesVisor($component);
			hyperGraph -edit -unParent $filesVisor;
			deleteUI $filesVisor;
			hyperGraph -edit -unParent $directoriesVisor;
			deleteUI $directoriesVisor;
		}
		else if ($tabType == "graph" || $tabType == "protected graph")
		{
			string $hypershade = graphUIHypershadeName($component);
			hyperGraph -edit -unParent $hypershade;
			deleteUI $hypershade;
		}
	}
}

global proc removeHyperShadePanel(string $panel) 
{
	//
	// Description:
	//	This procedure is called when the hypershade is being destroyed
	//	or reparented. 
	//	This procedure ensures that all hypergraph/hypershade/visor editors
	//	used by the various tabs get deleted.
	//

	// Flag this as a construction operation, to prevent many unnecessary 
	// refreshes as the tabs are deleted.
	//
	hyperShadeStartConstruction( $panel );

	string $tabLayout;

	setParent $panel;
	$tabLayout = `setParent firstPaneTabs`;
	deleteEditors($tabLayout);

	setParent $panel;
	$tabLayout = `setParent secondPaneTabs`;
	deleteEditors($tabLayout);

    // Set the previous filterBox and filterButton value to "".
    //
    global string $gPreviousFilterBox; 
    global string $gPreviousFilterButton; 
    $gPreviousFilterBox = "";
    $gPreviousFilterButton = "";

	// Unregister the callbacks which are being called when plugins are
	// loaded/unloaded.
	//
	global int $gHypershadePluginCallbacksRegistered;

	if ($gHypershadePluginCallbacksRegistered)
	{
		loadPlugin 
			-removeCallback 
				("hyperShadePanelLoadPluginCallback \"" + $panel + "\"") ;
		unloadPlugin 
			-removeCallback
				("hyperShadePanelUnloadPluginCallback \"" + $panel + "\"") ;
		$gHypershadePluginCallbacksRegistered = false;
	}

	// Signal end of the construction process
	//
	hyperShadeEndConstruction( $panel, 0 );
}

global proc string saveStateHyperShadePanel(string $panel) 
{
	//
	// Description:
	//	This procedure is a required procedure for a scripted panel.
	//  It is meant to return a string which, when executed, will set the
	//  panel's state. Because the hypershade panel is far too complicated to
	//  have its state recorded in a single string, we use other mechanisms to
	//  remember the state of the hypershade panel. As a result, we will return
	//  only an empty string from this procedure.
	//

	string $stateStr = "";
	return $stateStr;
}

global proc deleteHyperShadePanel(string $panel) 
{
	//
	//  Description:
	//    Final deletion of the panel.  Clean up any resources that need to be
	//    freed.
	//
}

global proc hyperShadePanel(string $panel)
{
	global string $gMainPane;

	// Instantiate a new hyperShadePanel
	//
	setParent $gMainPane;
	scriptedPanel -unParent -type hyperShadePanel $panel;
}
			
			
			
//-----------------------------------------------------------------------------
//
//	FILTER CONTROLS
//	---------------
//
//	This section provides functions for adding general HyperGraph-style
//	filtering to the HyperShade tabs.  Each tab has two controls that
//	implement filtering:
//
//	1) a text box for entering regular expressions that specify the
//	   names of nodes that should be displayed in the tab.
//
//	2) a "Show" button that has a popup menu that specifies some
//	   node type-based filters to be applied in addition to the
//	   name-based filtering.
//
//	The filter controls are created and managed by the code in
//	filterUI.mel.
//
//-----------------------------------------------------------------------------


proc string[] findTabFilterControls( 
	string $tab)
{
	//
	// Description:
	//	Locates the parent layout for a tab, as well as
	//	the relevant filtering controls for it.
	//

	// returns 4 controls:
	//
	//	1) formLayout that contains the HyperShade editor
	//	   and its filter controls
	//	2) hyperShade editor
	//	3) filter box
	//	4) filter "Show" button
	//
	string $collection = lookupComponentName( $tab );

	string $filterControls[] = collectionUIFilterControls( $collection );	
	string $hs = $filterControls[0];
	string $filterBox = $filterControls[1];
	string $filterButton = $filterControls[2];

	string $res[];
	$res[0] = $collection;
	$res[1] = $hs;
	$res[2] = $filterBox;
	$res[3] = $filterButton;
	return $res;
}

proc setTabFilterControls( 
	string $tab, 
	string $filterBox, 
	string $filterButton)
{
	//
	// Description: 
	//	Records the names of the filter controls for the
	//	specified tab.
	//
	string $collection = lookupComponentName( $tab );

	collectionUISetFilterControls( $collection,
								   $filterBox,
								   $filterButton );
}

// Description:  This procedure is called to show the given $tab's 
//      filterBox and filterButton.
// 
global proc showCurrentFilterBoxAndButton(string $panel, string $tab)
{
	string $controls[] = `findTabFilterControls( $tab )`;
	string $filterBox = $controls[2];
	string $filterButton = $controls[3];
	
    setParent $panel;

    // Hide the previous filterBox and filterButton.
    //
    global string $gPreviousFilterBox;
    global string $gPreviousFilterButton;
    if ($gPreviousFilterBox != "" && $filterBox != $gPreviousFilterBox)
    {
        control -e -vis false $gPreviousFilterBox; 
        control -e -vis false $gPreviousFilterButton; 
    }

    // Show the current filterBox and filterButton. Must also enable in case they are dimmed.
    //
	control -e -vis true -enable true $filterBox;
	control -e -vis true -enable true $filterButton;

    $gPreviousFilterBox = $filterBox;
    $gPreviousFilterButton = $filterButton;
}

// Description:  This procedure is called to dim the given $tab's 
//      filterBox and filterButton.
// 
global proc dimCurrentFilterBoxAndButton()
{
    // Dim the previous filterBox and filterButton.
    //
    global string $gPreviousFilterBox;
    global string $gPreviousFilterButton;
    if ($gPreviousFilterBox != "")
    {
        control -e -enable false $gPreviousFilterBox; 
        control -e -enable false $gPreviousFilterButton; 
    }
}

global proc showFilter( 
	string $panel, 
	string $tab, 
	string $implicit)
{
	//
	// Description:
	//	Creates the user-defined filtering controls for the given tab.
	//	The specified implicit filter will be applied before the
	//	user-specified filtering.
	//

	//	build the filtering controls
	//
	addFilter( $panel, $tab, $implicit );

	//	lay out the controls
	//
	string $controls[] = `findTabFilterControls( $tab )`;
	string $layout = $controls[0];
	string $hs = $controls[1];
	string $filterBox = $controls[2];
	string $filterButton = $controls[3];


	string $oldParent = `setParent -q`;
	setParent $layout;

    // Put the hyperShadeEditor in layout.
    //
	formLayout -edit
		-attachForm		$hs				"bottom"	0
		-attachForm	    $hs				"top"		0 
		-attachForm		$hs				"left"		0
		-attachForm		$hs				"right"		0
	$layout;

    // Put the filterBox and filterButton in the sceenTabForm.
    //
    setParent $panel;

    showCurrentFilterBoxAndButton($panel, $tab);

	control -e -en 1 $filterBox;

	formLayout -edit
   		-attachForm     $filterBox		"top"		0
   		-attachForm     $filterBox		"left"		0
   		-attachForm  	$filterBox		"bottom"    0
   		-attachNone		$filterBox		"right" 
	sceneTabFilterForm;

	control -e -en 1 $filterButton;

	formLayout -edit
   		-attachForm     $filterButton	"top"		0
   		-attachControl  $filterButton   "left"		5 $filterBox
   		-attachForm     $filterButton   "bottom"    0
   		-attachForm     $filterButton   "right"     0
	sceneTabFilterForm;

	setParent $oldParent;

}			

global proc addFilter( 
	string $panel, 
	string $tab, 
	string $implicit )
{
	//
	// Description:
	//	Creates filter controls for the specified tab and hooks
	//	them up to the HyperShade view.
	//

	//	see if the controls have already been created
	//
	string $controls[] = `findTabFilterControls( $tab )`;
	string $collection = $controls[0];
	string $hs = $controls[1];
	string $filterBox = $controls[2];
	string $filterButton = $controls[3];

	if( !`button -ex $filterButton` )
	{
		//	controls do not exist, so build them in the
		//  sceneTabFilterForm.	
		//
		string $oldParent = `setParent -q`;
		setParent $panel;
        string $filterUIParent = `setParent sceneTabFilterForm`;

		//	create the filter box for specifying node name
		//	wildcards.
		//
		$filterBox = filterUICreateField($hs, $filterUIParent);

		//	create the "Show" button that will contain a popup
		//	menu for node type-based filtering
		//
		$filterButton = `button -l "Show"`;

		//	create the popup "Show" menu
		//
		string $m = `popupMenu -parent $filterButton -button 1`;
		string $filterMenu = filterUICreateMenuSub($hs, $m, 0);

		//	set the implicit filter - this is determined by the type
		//	of the tab.  If a user creates a "Materials" tab, then
		//	the implicit filter will show only materials, and the
		//	user-defined name and type filters will be applied on
		//	top of that.
		//
		filterUISetImplicitFilter( $hs, $implicit );

		//	set the related filters for this tab
		//
		string $internalName = 
			filteredCollection_InternalFromFilter( $implicit );

		string $relatedFilters[] = 
			filteredCollection_RelatedFilters( $internalName );

		if( (size($relatedFilters) == 1) && ($relatedFilters[0] == "ALL") )
		{
			// means all filters are related, so specify no related filter proc
			//
			filterUISetRelatedFiltersProcedure($hs, "");
		}
		else
		{
			string $relatedProc = 
				("filteredCollection_RelatedFilters " + $internalName);
			filterUISetRelatedFiltersProcedure( $hs, $relatedProc );
		}

		//	register the controls in the lookup table
		//
		setTabFilterControls( $tab, $filterBox, $filterButton );
		setParent $oldParent;
	}
}


//------------------------------------------------------------------------
//
//	The following procedures are for enabling and disabling 
//	HyperShade tabs during construction operations.  This helps
//	to speed up the UI by avoiding unnecessary refreshes while
//	the UI is in a transient state.
//

proc string[] listSceneTabs( 
	string $panel, 
	int $active )
{
	//
	// Description:
	//	Lists the names of the scene tabs in the HyperShade.  If the
	//	$active flag it true, only lists the tabs that are 
	//	currently active.

	string $oldParent = `setParent -q`;
	setParent $panel;

	string $tabs[] = {};

	//	go through the top and bottom panes
	//
	string $pane;
	for( $pane in { "firstPaneTabs", "secondPaneTabs" } )
	{
		if( `layout -ex $pane` )
		{
			string $tabLayout = `setParent $pane`;

			//	get the tab layout children
			//
			string $tabArray[];
			if( $active )
			{
				string $active = `tabLayout -query -selectTab $tabLayout`;
				$tabArray = { $active };
			}
			else
			{
				$tabArray = `tabLayout -query -childArray $tabLayout`;
			}

			//	store the scene tabs
			//
			for ($i = 0; $i < size($tabArray); $i++)
			{
				string $tab = $tabArray[$i];
				$tab = ($tabLayout + "|" + $tab);
				
				if( isSceneTab($tab) )
				{
					$tabs[size($tabs)] = $tab;
				}
			}
		}
	}

	setParent $oldParent;
	return $tabs;
}

proc enableTabs( 
	string $panel, 
	int $enable )
{
	//
	// Description:
	//	Enables or disables all scene tabs in the HyperShade.
	//
	string $allTabs[] = listSceneTabs($panel,0);
	string $t;

	for( $t in $allTabs )
	{
		string $collectionUI = lookupComponentName( $t );
		collectionUIEnableFilter( $collectionUI, $enable );
	}
}

proc enableActiveTabs( 
	string $panel, 
	int $enable )
{
	//
	// Description:
	//	Enables or disables all active scene tabs in the HyperShade.
	//
	string $activeTabs[] = listSceneTabs($panel,1);
	string $t;

	for( $t in $activeTabs )
	{
		string $collectionUI = lookupComponentName( $t );
		collectionUIEnableFilter( $collectionUI, $enable );
	}
}	

//	global variable indicates whether HyperShade is in a
//	transient state or not.
//
global int $hsInConstruction = 0;

global proc hyperShadeStartConstruction( 
	string $panel)
{
	//
	// Description:
	//	Signals that the HyperShade is about to start 
	//	constructing, destroying, or moving tabs.  This
	//	causes many refresh messages to be sent to the
	//	tabs, so we would like to prevent them from doing
	//	unnecessary work during this time.  We do this by
	//	disabling the filters on the tabs.
	//
	global int $hsInConstruction;
	$hsInConstruction = 1;

	enableTabs( $panel, 0 );
}

global proc hyperShadeEndConstruction( 
	string $panel, 
	int $stillAround)
{
	//
	// Description:
	//	Signals the end of a HyperShade tab construction, destruction, or
	//	move operation.  If the HyperShade panel itself is still around
	//	after this operation, then we need to refresh the active tabs.
	//	Other tabs will be refreshed when the user clicks on them.
	//
	global int $hsInConstruction;
	$hsInConstruction = 0;

	if( $stillAround )
	{
		enableActiveTabs( $panel, 1 );
	}
}

global proc int hyperShadeIsInConstruction( string $panel )
{
	//
	// Description: 
	//	Indicates whether or not the HyperShade is in the 
	//	middle of a construction operation.  The filtering
	//	functions in collectionUI.mel use this function
	//	to decide whether or not they should obey requests
	//	to refresh the contents of the tabs.
	//
	global int $hsInConstruction;
	return $hsInConstruction;
}

proc string paneActiveTab(
	string $panel, string $tabLayout)
{
	//
	// Description:
	//	This procedure determines the name of the frontmost tab in the tab 
	//	layout in the active pane of the hypershade panel.
	//
	// Returns: 
	//	The name of the tab.
	//

	// Remember the current parent so we can revert to it when we're done here.
	//
	string $oldParent = `setParent -query`;
	string $oldMenuParent = `setParent -menu -query`;

    setParent $panel;
	string $tab;

    if (size(`tabLayout -q -childArray $tabLayout`) == 0)
    {
        // No tab in this tabLayout.  
        //
        $tab = "";
    }
    else
    {
        $tabLayout = `setParent $tabLayout`;
    	
	    $tab = `tabLayout -query -selectTab $tabLayout`;
	    $tab = `setParent $tab`;
    }

	// Revert to the original parent.
	//
	if ($oldParent != "NONE") setParent $oldParent;
	if ($oldMenuParent != "NONE") setParent -menu $oldMenuParent;

	return $tab;
}

// Description:  This procedure returns the active scene tab
//      in hyper shade.
//
global proc string hyperShadePaneSceneTabsCurrentView(string $tabLayout)
{
	string $panel = hyperShadePanelName();
    setParent $panel;
    
    string $tab = paneActiveTab($panel, $tabLayout);

    // If the tabLayout has no tabs in it, then there is no view.
    //
    if ($tab == "")
    {
        return "";
    }
    
    // If the active tab is not a scene tab, then there is no scene
    // tab being viewed at the moment for this tabLayout.  Return "".
    //
    if (!isSceneTab($tab))
    {
        return "";
    }
    
    string $controls[] = `findTabFilterControls($tab)`;
    string $view = $controls[1];
    return $view;
}

// Description:  This procedure is called to return the name of
//      the hyper shade createAndOrganizeForm
//
global proc string hyperShadeCreateAndOrganizeFormName()
{
    string $oldParent = `setParent -q`;

	string $panel = hyperShadePanelName();
    setParent $panel;
    setParent createAndOrganizeForm;
    string $result = `setParent -q`; 

    setParent $oldParent;

    return $result;
}

global proc hyperShadeEditTexture( string $node )
{
	string $cmd = "getAttr ";
	$cmd += $node;
	$cmd += ".fileTextureName";

    string $fileName = eval($cmd);
	if ( $fileName == "" ) {
		error (" No file is assigned to " + $node );
		return;
	}

	if (`about -linux`) {
		int $sequence  = 0;	// single image
		int $editImage = 1;
		launchImageApp($fileName, $sequence, $editImage);
	}
	else {
		launchImageEditor -eif $fileName;
	}
}

global proc EditTexture()
{
	// Need to run a test to make sure something is selected
	string $node[] = `ls -selection`;
	if (`size ($node)` < 1) {
		error "Nothing selected - Select a texture node and try again.";
	}
	else if (`size ($node)` > 1) {
		warning "More than 1 node selected - Only sample the first will be processed";
	}

	// Need to run a test on the selected node to make sure we can sample it
	if (!(isClassified($node[0], "texture"))) {
		error "Selected node cannot be processed. Only textures nodes with outputs are acceptable.";
	}
	
	//Check whether node is of PSD type or file type
	if( ((nodeType ($node[0])) != "psdFileTex" ) && ((nodeType ($node[0])) != "file" ) )
	{
		error "Selected node cannot be processed. Only PSD type or file type nodes are acceptable.";
	}

	hyperShadeEditTexture( $node[0] );

}

// Description:  This procedure is called from the C++ code after
//      the icon size type has been changed.  We want to refresh
//      the hyper shade UI to show the new icon size.
//
global proc refreshHyperShadeAfterIconSizeChange(string $iconSizeName)
{
    string $panel = hyperShadePanelName(); 
    hyperShadePanelMenuCommand($panel, $iconSizeName);
}

// Description:  This procedure is called to activate the tabLayout
//      corresponding to the specified collectionUI.
//
global proc activateCorrespondingTabLayout(string $collectionUI)
{
    string $panel = hyperShadePanelName(); 

    string $correspondingTabLayout = lookupTabLayoutName($collectionUI);
    string $currentlyActiveTabLayout = activeTabLayout($panel);

    // Check to see if the corresponding tab is already active.
    //
    if ($correspondingTabLayout != $currentlyActiveTabLayout)
    {
        hyperShadePanelSetActiveTabLayout( $panel, $correspondingTabLayout, false); 
    }
}
