// default node properties

var _cmNodeProperties =

{

	// theme prefix

	prefix:	'',



  	// main menu display attributes

  	//

  	// Note.  When the menu bar is horizontal,

  	// mainFolderLeft and mainFolderRight are

  	// put in <span></span>.  When the menu

  	// bar is vertical, they would be put in

  	// a separate TD cell.



  	// HTML code to the left of the folder item

  	mainFolderLeft: '',

  	// HTML code to the right of the folder item

  	mainFolderRight: '',

	// HTML code to the left of the regular item

	mainItemLeft: '',

	// HTML code to the right of the regular item

	mainItemRight:	'',



	// sub menu display attributes



	// HTML code to the left of the folder item

	folderLeft:		'',

	// HTML code to the right of the folder item

	folderRight:	'',

	// HTML code to the left of the regular item

	itemLeft:		'',

	// HTML code to the right of the regular item

	itemRight:		'',

	// cell spacing for main menu

	mainSpacing:	0,

	// cell spacing for sub menus

	subSpacing:		0,



	// optional settings

	// If not set, use the default



	// auto disappear time for submenus in milli-seconds

	delay:			500,



	// 1st layer sub menu starting index

	zIndexStart:	1000,

	// z-index incremental step for subsequent layers

	zIndexInc:		5,



	// sub menu header appears before the sub menu table

	subMenuHeader:	null,

	// sub menu header appears after the sub menu table

	subMenuFooter:	null,



	// submenu location adjustments

	//

	// offsetHMainAdjust for adjusting the first submenu

	// 		of a 'hbr' menu.

	// offsetVMainAdjust for adjusting the first submenu

	//		of a 'vbr' menu.

	// offsetSubAdjust for subsequent level of submenus

	//

	offsetHMainAdjust:	[0, 0],

	offsetVMainAdjust:	[0, 0],

	offsetSubAdjust:	[0, 0],



	// act on click to open sub menu

	// not yet implemented

	// 0 : use default behavior

	// 1 : hover open in all cases

	// 2 : click on main, hover on sub

	// 3 : click open in all cases (illegal as of 1.5)

	clickOpen:		0,



	// special effects on open/closing a sub menu

	effect:			null

};



// Globals

var _cmIDCount = 0;

var _cmIDName = 'cmSubMenuID';		// for creating submenu id



var _cmTimeOut = null;				// how long the menu would stay

var _cmCurrentItem = null;			// the current menu item being selected;



var _cmNoAction = new Object ();	// indicate that the item cannot be hovered.

var _cmNoClick = new Object ();		// similar to _cmNoAction but does not respond to mouseup/mousedown events

var _cmSplit = new Object ();		// indicate that the item is a menu split



var _cmMenuList = new Array ();		// a list of the current menus

var _cmItemList = new Array ();		// a simple list of items



var _cmFrameList = new Array ();	// a pool of reusable iframes

var _cmFrameListSize = 0;			// keep track of the actual size

var _cmFrameIDCount = 0;			// keep track of the frame id

var _cmFrameMasking = false;		// use the frame masking



// disable iframe masking for IE7

/*@cc_on

	@if (@_jscript_version >= 5.6)

		if (_cmFrameMasking)

		{

			var v = navigator.appVersion;

			var i = v.indexOf ("MSIE ");

			if (i >= 0)

			{

				if (parseInt (navigator.appVersion.substring (i + 5)) >= 7)

					_cmFrameMasking = false;

			}

		}

	@end

@*/



var _cmClicked = false;				// for onClick



// flag for turning on off hiding objects

//

// 0: automatic

// 1: hiding

// 2: no hiding

var _cmHideObjects = 0;



// Utility function to do a shallow copy a node property

function cmClone (nodeProperties)

{

	var returnVal = new Object ();

	for (v in nodeProperties)

		returnVal[v] = nodeProperties[v];

	return returnVal;

}



//

// store the new menu information into a structure to retrieve it later

//

function cmAllocMenu (id, menu, orient, nodeProperties, prefix)

{

	var info = new Object ();

	info.div = id;

	info.menu = menu;

	info.orient = orient;

	info.nodeProperties = nodeProperties;

	info.prefix = prefix;

	var menuID = _cmMenuList.length;

	_cmMenuList[menuID] = info;

	return menuID;

}



//

// request a frame

//

function cmAllocFrame ()

{

	if (_cmFrameListSize > 0)

		return cmGetObject (_cmFrameList[--_cmFrameListSize]);

	var frameObj = document.createElement ('iframe');

	var id = _cmFrameIDCount++;

	frameObj.id = 'cmFrame' + id;

	frameObj.frameBorder = '0';

	frameObj.style.display = 'none';

	frameObj.src = 'javascript:false';

	document.body.appendChild (frameObj);

	frameObj.style.filter = 'alpha(opacity=0)';

	frameObj.style.zIndex = 99;

	frameObj.style.position = 'absolute';

	frameObj.style.border = '0';

	frameObj.scrolling = 'no';

	return frameObj;

}



//

// make a frame resuable later

//

function cmFreeFrame (frameObj)

{

	_cmFrameList[_cmFrameListSize++] = frameObj.id;

}



//////////////////////////////////////////////////////////////////////

//

// Drawing Functions and Utility Functions

//

//////////////////////////////////////////////////////////////////////



//

// produce a new unique id

//

function cmNewID ()

{

	return _cmIDName + (++_cmIDCount);

}



//

// return the property string for the menu item

//

function cmActionItem (item, isMain, idSub, menuInfo, menuID)

{

	_cmItemList[_cmItemList.length] = item;

	var index = _cmItemList.length - 1;

	idSub = (!idSub) ? 'null' : ('\'' + idSub + '\'');



	var clickOpen = menuInfo.nodeProperties.clickOpen;

	var onClick = (clickOpen == 3) || (clickOpen == 2 && isMain);



	var param = 'this,' + isMain + ',' + idSub + ',' + menuID + ',' + index;



	var returnStr;

	if (onClick)

		returnStr = ' onmouseover="cmItemMouseOver(' + param + ',false)" onmousedown="cmItemMouseDownOpenSub (' + param + ')"';

	else

		returnStr = ' onmouseover="cmItemMouseOverOpenSub (' + param + ')" onmousedown="cmItemMouseDown (' + param + ')"';

	return returnStr + ' onmouseout="cmItemMouseOut (' + param + ')" onmouseup="cmItemMouseUp (' + param + ')"';

}



//

// this one is used by _cmNoClick to only take care of onmouseover and onmouseout

// events which are associated with menu but not actions associated with menu clicking/closing

//

function cmNoClickItem (item, isMain, idSub, menuInfo, menuID)

{

	// var index = _cmItemList.push (item) - 1;

	_cmItemList[_cmItemList.length] = item;

	var index = _cmItemList.length - 1;

	idSub = (!idSub) ? 'null' : ('\'' + idSub + '\'');



	var param = 'this,' + isMain + ',' + idSub + ',' + menuID + ',' + index;



	return ' onmouseover="cmItemMouseOver (' + param + ')" onmouseout="cmItemMouseOut (' + param + ')"';

}



function cmNoActionItem (item)

{

	return item[1];

}



function cmSplitItem (prefix, isMain, vertical)

{

	var classStr = 'cm' + prefix;

	if (isMain)

	{

		classStr += 'Main';

		if (vertical)

			classStr += 'HSplit';

		else

			classStr += 'VSplit';

	}

	else

		classStr += 'HSplit';

	return eval (classStr);

}



//

// draw the sub menu recursively

//

function cmDrawSubMenu (subMenu, prefix, id, nodeProperties, zIndexStart, menuInfo, menuID)

{

	var str = '<div class="' + prefix + 'SubMenu" id="' + id + '" style="z-index: ' + zIndexStart + ';position: absolute; top: 0px; left: 0px;">';

	if (nodeProperties.subMenuHeader)

		str += nodeProperties.subMenuHeader;



	str += '<table summary="sub menu" id="' + id + 'Table" cellspacing="' + nodeProperties.subSpacing + '" class="' + prefix + 'SubMenuTable">';



	var strSub = '';



	var item;

	var idSub;

	var hasChild;



	var i;



	var classStr;



	for (i = 5; i < subMenu.length; ++i)

	{

		item = subMenu[i];

		if (!item)

			continue;



		if (item == _cmSplit)

			item = cmSplitItem (prefix, 0, true);

		item.parentItem = subMenu;

		item.subMenuID = id;



		hasChild = (item.length > 5);

		idSub = hasChild ? cmNewID () : null;



		str += '<tr class="' + prefix + 'MenuItem"';

		if (item[0] != _cmNoClick)

			str += cmActionItem (item, 0, idSub, menuInfo, menuID);

		else

			str += cmNoClickItem (item, 0, idSub, menuInfo, menuID);

		str += '>'



		if (item[0] == _cmNoAction || item[0] == _cmNoClick)

		{

			str += cmNoActionItem (item);

			str += '</tr>';

			continue;

		}



		classStr = prefix + 'Menu';

		classStr += hasChild ? 'Folder' : 'Item';



		str += '<td class="' + classStr + 'Left">';



		if (item[0] != null)

			str += item[0];

		else

			str += hasChild ? nodeProperties.folderLeft : nodeProperties.itemLeft;



		str += '</td><td class="' + classStr + 'Text">' + item[1];



		str += '</td><td class="' + classStr + 'Right">';



		if (hasChild)

		{

			str += nodeProperties.folderRight;

			strSub += cmDrawSubMenu (item, prefix, idSub, nodeProperties, zIndexStart + nodeProperties.zIndexInc, menuInfo, menuID);

		}

		else

			str += nodeProperties.itemRight;

		str += '</td></tr>';

	}



	str += '</table>';



	if (nodeProperties.subMenuFooter)

		str += nodeProperties.subMenuFooter;

	str += '</div>' + strSub;

	return str;

}



//

// The function that builds the menu inside the specified element id.

//

// id				id of the element

// orient			orientation of the menu in [hv][ub][lr] format

// menu				the menu object to be drawn

// nodeProperties	properties for the theme

// prefix			prefix of the theme

//

function cmDraw (id, menu, orient, nodeProperties, prefix)

{

	var obj = cmGetObject (id);



	if (!prefix)

		prefix = nodeProperties.prefix;

	if (!prefix)

		prefix = '';

	if (!nodeProperties)

		nodeProperties = _cmNodeProperties;

	if (!orient)

		orient = 'hbr';



	var menuID = cmAllocMenu (id, menu, orient, nodeProperties, prefix);

	var menuInfo = _cmMenuList[menuID];



	// setup potentially missing properties

	if (!nodeProperties.delay)

		nodeProperties.delay = _cmNodeProperties.delay;

	if (!nodeProperties.clickOpen)

		nodeProperties.clickOpen = _cmNodeProperties.clickOpen;

	if (!nodeProperties.zIndexStart)

		nodeProperties.zIndexStart = _cmNodeProperties.zIndexStart;

	if (!nodeProperties.zIndexInc)

		nodeProperties.zIndexInc = _cmNodeProperties.zIndexInc;

	if (!nodeProperties.offsetHMainAdjust)

		nodeProperties.offsetHMainAdjust = _cmNodeProperties.offsetHMainAdjust;

	if (!nodeProperties.offsetVMainAdjust)

		nodeProperties.offsetVMainAdjust = _cmNodeProperties.offsetVMainAdjust;

	if (!nodeProperties.offsetSubAdjust)

		nodeProperties.offsetSubAdjust = _cmNodeProperties.offsetSubAdjust;

	// save user setting on frame masking

	menuInfo.cmFrameMasking = _cmFrameMasking;



	/* following has been changed by B.E */

    var vertical = orient.charAt (0) != 'h';

	var str = null;

	if (vertical)

	{

       str = '<table cellspacing="0" cellpadding="0" border="0" ><tr><td ';

       str += ' class="' + prefix + 'MenuOuter" >';

       str += '<table summary="main menu" cellpadding="0" border="0" ';

       str += ' class="' + prefix + 'Menu" cellspacing="' + nodeProperties.mainSpacing + '" >';  

    } 

	else 

	{

       str = '<table summary="main menu" cellpadding="0" border="0" ';

       str += ' cellspacing="0" class="' + prefix + 'MenuOuter" >';    

       str += '<tr>';

    }

    /* end */



	var strSub = '';



	// draw the main menu items

	var i;

	var item;

	var idSub;

	var hasChild;



	var classStr;



	for (i = 0; i < menu.length; ++i)

	{

		item = menu[i];



		if (!item)

			continue;



		item.menu = menu;

		item.subMenuID = id;



		/* modified to support tapestry theme studio */

        var noAction = (item == _cmSplit || item[0] == _cmNoAction || item[0] == _cmNoClick);

		if (vertical) 

		{

		   str += '<tr';

		}

        else

		{

           if(!noAction) str += '<td><table class="' + prefix + 'Menu" cellspacing="' + nodeProperties.mainSpacing + '" cellpadding="0" border="0"><tr';

		   else str += '<td '

        }

        

		str += ' class="' + prefix + 'MainItem"';



		hasChild = (item.length > 5);

		idSub = hasChild ? cmNewID () : null;



        if(noAction) str += cmNoActionItem (item) + '>';

		else str += cmActionItem (item, 1, idSub, menuInfo, menuID) + '>';

        /* end modified */



		if (item == _cmSplit)

			item = cmSplitItem (prefix, 1, vertical);



		if (item[0] == _cmNoAction || item[0] == _cmNoClick)

		{

			str += cmNoActionItem (item);

			str += vertical? '</tr>' : '</td>';

			continue;

		}



		/* modified to support tapestry theme studio */

        var verOrig = vertical;

        vertical = true;

        /* end modified */



		classStr = prefix + 'Main' + (hasChild ? 'Folder' : 'Item');



		str += vertical ? '<td' : '<span';

		str += ' class="' + classStr + 'Left">';



		str += (item[0] == null) ? (hasChild ? nodeProperties.mainFolderLeft : nodeProperties.mainItemLeft)

					 : item[0];

		str += vertical ? '</td>' : '</span>';



		str += vertical ? '<td' : '<span';

		str += ' class="' + classStr + 'Text">';

		str += item[1];



		str += vertical ? '</td>' : '</span>';



		str += vertical ? '<td' : '<span';

		str += ' class="' + classStr + 'Right">';



		str += hasChild ? nodeProperties.mainFolderRight : nodeProperties.mainItemRight;



		str += vertical ? '</td>' : '</span>';



		/* modified to support tapestry theme studio */

		vertical = verOrig;

        if (vertical)

		{

			str += '</tr>';

		}

		else

		{

			if(!noAction) str += '</tr></table>';

		}

        /* end modified */



		if (hasChild)

			strSub += cmDrawSubMenu (item, prefix, idSub, nodeProperties, nodeProperties.zIndexStart, menuInfo, menuID);

	}



	/* modified to support tapestry theme studio */

	if (vertical)

	{

        str += '</table></td></tr>';

    } 

	else 

	{

		str += '</tr>';

	}	 

	/* end modified */



	str += '</table>' + strSub;

	obj.innerHTML = str;

}



//

// The function builds the menu inside the specified element id.

//

// This function is similar to cmDraw except that menu is taken from HTML node

// rather a javascript tree.  This feature allows links to be scanned by search

// bots.

//

// This function basically converts HTML node to a javascript tree, and then calls

// cmDraw to draw the actual menu, replacing the hidden menu tree.

//

// Format:

//	<div id="menu">

//		<ul style="visibility: hidden">

//			<li><span>icon</span><a href="link" title="description">main menu text</a>

//				<ul>

//					<li><span>icon</span><a href="link" title="description">submenu item</a>

//					</li>

//				</ul>

//			</li>

//		</ul>

//	</div>

//

function cmDrawFromText (id, orient, nodeProperties, prefix)

{

	var domMenu = cmGetObject (id);

	var menu = null;

	for (var currentDomItem = domMenu.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling)

	{

		if (!currentDomItem.tagName)

			continue;

		var tag = currentDomItem.tagName.toLowerCase ();

		if (tag != 'ul' && tag != 'ol')

			continue;

		menu = cmDrawFromTextSubMenu (currentDomItem);

		break;

	}

	if (menu)

		cmDraw (id, menu, orient, nodeProperties, prefix);

}



//

// a recursive function that build menu tree structure

//

function cmDrawFromTextSubMenu (domMenu)

{

	var items = new Array ();

	for (var currentDomItem = domMenu.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling)

	{

		if (!currentDomItem.tagName || currentDomItem.tagName.toLowerCase () != 'li')

			continue;

		if (currentDomItem.firstChild == null)

		{

			items[items.length] = _cmSplit;

			continue;

		}

		var item = new Array ();

		var currentItem = currentDomItem.firstChild;

		var hasAction = false;

		for (; currentItem; currentItem = currentItem.nextSibling)

		{

			// scan for span or div tag

			if (!currentItem.tagName)

				continue;

			if (currentItem.className == 'cmNoClick')

			{

				item[0] = _cmNoClick;

				item[1] = getActionHTML (currentItem);

				hasAction = true;

				break;

			}

			if (currentItem.className == 'cmNoAction')

			{

				item[0] = _cmNoAction;

				item[1] = getActionHTML (currentItem);

				hasAction = true;

				break;

			}

			var tag = currentItem.tagName.toLowerCase ();

			if (tag != 'span')

				continue;

			if (!currentItem.firstChild)

				item[0] = null;

			else

				item[0] = currentItem.innerHTML;

			currentItem = currentItem.nextSibling;

			break;

		}

		if (hasAction)

		{

			items[items.length] = item;

			continue;

		}

		if (!currentItem)

			continue;

		for (; currentItem; currentItem = currentItem.nextSibling)

		{

			if (!currentItem.tagName)

				continue;

			var tag = currentItem.tagName.toLowerCase ();

			if (tag == 'a')

			{

				item[1] = currentItem.innerHTML;

				item[2] = currentItem.href;

				item[3] = currentItem.target;

				item[4] = currentItem.title;

				if (item[4] == '')

					item[4] = null;

			}

			else if (tag == 'span' || tag == 'div')

			{

				item[1] = currentItem.innerHTML;

				item[2] = null;

				item[3] = null;

				item[4] = null;

			}

			break;

		}



		for (; currentItem; currentItem = currentItem.nextSibling)

		{

			// scan for span tag

			if (!currentItem.tagName)

				continue;

			var tag = currentItem.tagName.toLowerCase ();

			if (tag != 'ul' && tag != 'ol')

				continue;

			var subMenuItems = cmDrawFromTextSubMenu (currentItem);

			for (i = 0; i < subMenuItems.length; ++i)

				item[i + 5] = subMenuItems[i];

			break;

		}

		items[items.length] = item;

	}

	return items;

}



//

// obtain the actual action item's action, which is inside a

// table.  The first row should be it

//

function getActionHTML (htmlNode)

{

	var returnVal = '<td></td><td></td><td></td>';

	var currentDomItem;

	// find the table first

	for (currentDomItem = htmlNode.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling)

	{

		if (currentDomItem.tagName && currentDomItem.tagName.toLowerCase () == 'table')

			break;

	}

	if (!currentDomItem)

		return returnVal;

	// skip over tbody

	for (currentDomItem = currentDomItem.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling)

	{

		if (currentDomItem.tagName && currentDomItem.tagName.toLowerCase () == 'tbody')

			break;

	}

	if (!currentDomItem)

		return returnVal;

	// get the first tr

	for (currentDomItem = currentDomItem.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling)

	{

		if (currentDomItem.tagName && currentDomItem.tagName.toLowerCase () == 'tr')

			break;

	}

	if (!currentDomItem)

		return returnVal;

	return currentDomItem.innerHTML;

}



//

// get the DOM object associated with the item

//

function cmGetMenuItem (item)

{

	if (!item.subMenuID)

		return null;

	var subMenu = cmGetObject (item.subMenuID);

	// we are dealing with a main menu item

	if (item.menu)

	{

		var menu = item.menu;

		// skip over table, tbody, tr, reach td

		subMenu = subMenu.firstChild.firstChild.firstChild.firstChild;

		var i;

		for (i = 0; i < menu.length; ++i)

		{

			if (menu[i] == item)

				return subMenu;

			subMenu = subMenu.nextSibling;

		}

	}

	else if (item.parentItem) // sub menu item

	{

		var menu = item.parentItem;

		var table = cmGetObject (item.subMenuID + 'Table');

		if (!table)

			return null;

		// skip over table, tbody, reach tr

		subMenu = table.firstChild.firstChild;

		var i;

		for (i = 5; i < menu.length; ++i)

		{

			if (menu[i] == item)

				return subMenu;

			subMenu = subMenu.nextSibling;

		}

	}

	return null;

}



//

// disable a menu item

//

function cmDisableItem (item, prefix)

{

	if (!item)

		return;

	var menuItem = cmGetMenuItem (item);

	if (!menuItem)

		return;

	if (item.menu)

		menuItem.className = prefix + 'MainItemDisabled';

	else

		menuItem.className = prefix + 'MenuItemDisabled';

	item.isDisabled = true;

}



//

// enable a menu item

//

function cmEnableItem (item, prefix)

{

	if (!item)

		return;

	var menuItem = cmGetMenuItem (item);

	if (!menuItem)

		return;

	if (item.menu)

		menu.className = prefix + 'MainItem';

	else

		menu.className = prefix + 'MenuItem';

	item.isDisabled = true;

}



//////////////////////////////////////////////////////////////////////

//

// Mouse Event Handling Functions

//

//////////////////////////////////////////////////////////////////////



//

// action should be taken for mouse moving in to the menu item

//

// Here we just do things concerning this menu item, w/o opening sub menus.

//

function cmItemMouseOver (obj, isMain, idSub, menuID, index, calledByOpenSub)

{

	if (!calledByOpenSub && _cmClicked)

	{

		cmItemMouseOverOpenSub (obj, isMain, idSub, menuID, index);

		return;

	}



	clearTimeout (_cmTimeOut);



	if (_cmItemList[index].isDisabled)

		return;



	var prefix = _cmMenuList[menuID].prefix;



	if (!obj.cmMenuID)

	{

		obj.cmMenuID = menuID;

		obj.cmIsMain = isMain;

	}



	var thisMenu = cmGetThisMenu (obj, prefix);



	// insert obj into cmItems if cmItems doesn't have obj

	if (!thisMenu.cmItems)

		thisMenu.cmItems = new Array ();

	var i;

	for (i = 0; i < thisMenu.cmItems.length; ++i)

	{

		if (thisMenu.cmItems[i] == obj)

			break;

	}

	if (i == thisMenu.cmItems.length)

	{

		//thisMenu.cmItems.push (obj);

		thisMenu.cmItems[i] = obj;

	}



	// hide the previous submenu that is not this branch

	if (_cmCurrentItem)

	{

		// occationally, we get this case when user

		// move the mouse slowly to the border

		if (_cmCurrentItem == obj || _cmCurrentItem == thisMenu)

		{

			var item = _cmItemList[index];

			cmSetStatus (item);

			return;

		}



		var thatMenuInfo = _cmMenuList[_cmCurrentItem.cmMenuID];

		var thatPrefix = thatMenuInfo.prefix;

		var thatMenu = cmGetThisMenu (_cmCurrentItem, thatPrefix);



		if (thatMenu != thisMenu.cmParentMenu)

		{

			if (_cmCurrentItem.cmIsMain)

				_cmCurrentItem.className = thatPrefix + 'MainItem';

			else

				_cmCurrentItem.className = thatPrefix + 'MenuItem';

			if (thatMenu.id != idSub)

				cmHideMenu (thatMenu, thisMenu, thatMenuInfo);

		}

	}



	// okay, set the current menu to this obj

	_cmCurrentItem = obj;



	// just in case, reset all items in this menu to MenuItem

	cmResetMenu (thisMenu, prefix);



	var item = _cmItemList[index];

	var isDefaultItem = cmIsDefaultItem (item);



	if (isDefaultItem)

	{

		if (isMain)

			obj.className = prefix + 'MainItemHover';

		else

			obj.className = prefix + 'MenuItemHover';

	}



	cmSetStatus (item);

}



//

// action should be taken for mouse moving in to the menu item

//

// This function also opens sub menu

//

function cmItemMouseOverOpenSub (obj, isMain, idSub, menuID, index)

{

	clearTimeout (_cmTimeOut);



	if (_cmItemList[index].isDisabled)

		return;



	cmItemMouseOver (obj, isMain, idSub, menuID, index, true);



	if (idSub)

	{

		var subMenu = cmGetObject (idSub);

		var menuInfo = _cmMenuList[menuID];

		var orient = menuInfo.orient;

		var prefix = menuInfo.prefix;

		cmShowSubMenu (obj, isMain, subMenu, menuInfo);

	}

}



//

// action should be taken for mouse moving out of the menu item

//

function cmItemMouseOut (obj, isMain, idSub, menuID, index)

{

	var delayTime = _cmMenuList[menuID].nodeProperties.delay;

	_cmTimeOut = window.setTimeout ('cmHideMenuTime ()', delayTime);

	window.defaultStatus = '';

}



//

// action should be taken for mouse button down at a menu item

//

function cmItemMouseDown (obj, isMain, idSub, menuID, index)

{

	if (_cmItemList[index].isDisabled)

		return;



	if (cmIsDefaultItem (_cmItemList[index]))

	{

		var prefix = _cmMenuList[menuID].prefix;

		if (obj.cmIsMain)

			obj.className = prefix + 'MainItemActive';

		else

			obj.className = prefix + 'MenuItemActive';

	}

}



//

// action should be taken for mouse button down at a menu item

// this is one also opens submenu if needed

//

function cmItemMouseDownOpenSub (obj, isMain, idSub, menuID, index)

{

	if (_cmItemList[index].isDisabled)

		return;



	_cmClicked = true;

	cmItemMouseDown (obj, isMain, idSub, menuID, index);



	if (idSub)

	{

		var subMenu = cmGetObject (idSub);

		var menuInfo = _cmMenuList[menuID];

		cmShowSubMenu (obj, isMain, subMenu, menuInfo);

	}

}



//

// action should be taken for mouse button up at a menu item

//

function cmItemMouseUp (obj, isMain, idSub, menuID, index)

{

	if (_cmItemList[index].isDisabled)

		return;



	var item = _cmItemList[index];



	var link = null, target = '_self';



	if (item.length > 2)

		link = item[2];

	if (item.length > 3 && item[3])

		target = item[3];



	if (link != null)

	{

		_cmClicked = false;

		window.open (link, target);

	}



	var menuInfo = _cmMenuList[menuID];

	var prefix = menuInfo.prefix;

	var thisMenu = cmGetThisMenu (obj, prefix);



	var hasChild = (item.length > 5);

	if (!hasChild)

	{

		if (cmIsDefaultItem (item))

		{

			if (obj.cmIsMain)

				obj.className = prefix + 'MainItem';

			else

				obj.className = prefix + 'MenuItem';

		}

		cmHideMenu (thisMenu, null, menuInfo);

	}

	else

	{

		if (cmIsDefaultItem (item))

		{

			if (obj.cmIsMain)

				obj.className = prefix + 'MainItemHover';

			else

				obj.className = prefix + 'MenuItemHover';

		}

	}

}



//////////////////////////////////////////////////////////////////////

//

// Mouse Event Support Utility Functions

//

//////////////////////////////////////////////////////////////////////



//

// move submenu to the appropriate location

//

function cmMoveSubMenu (obj, isMain, subMenu, menuInfo)

{

	var orient = menuInfo.orient;



	var offsetAdjust;



	if (isMain)

	{

		if (orient.charAt (0) == 'h')

			offsetAdjust = menuInfo.nodeProperties.offsetHMainAdjust;

		else

			offsetAdjust = menuInfo.nodeProperties.offsetVMainAdjust;

	}

	else

		offsetAdjust = menuInfo.nodeProperties.offsetSubAdjust;



	if (!isMain && orient.charAt (0) == 'h')

		orient = 'v' + orient.charAt (1) + orient.charAt (2);



	var mode = String (orient);

	var p = subMenu.offsetParent;

	var subMenuWidth = cmGetWidth (subMenu);

	var horiz = cmGetHorizontalAlign (obj, mode, p, subMenuWidth);

	if (mode.charAt (0) == 'h')

	{

		if (mode.charAt (1) == 'b')

			subMenu.style.top = (cmGetYAt (obj, p) + cmGetHeight (obj) + offsetAdjust[1]) + 'px';

		else

			subMenu.style.top = (cmGetYAt (obj, p) - cmGetHeight (subMenu) - offsetAdjust[1]) + 'px';

		if (horiz == 'r')

			subMenu.style.left = (cmGetXAt (obj, p) + offsetAdjust[0]) + 'px';

		else

			subMenu.style.left = (cmGetXAt (obj, p) + cmGetWidth (obj) - subMenuWidth - offsetAdjust[0]) + 'px';

	}

	else

	{

		if (horiz == 'r')

			subMenu.style.left = (cmGetXAt (obj, p) + cmGetWidth (obj) + offsetAdjust[0]) + 'px';

		else

			subMenu.style.left = (cmGetXAt (obj, p) - subMenuWidth - offsetAdjust[0]) + 'px';

		if (mode.charAt (1) == 'b')

			subMenu.style.top = (cmGetYAt (obj, p) + offsetAdjust[1]) + 'px';

		else

			subMenu.style.top = (cmGetYAt (obj, p) + cmGetHeight (obj) - cmGetHeight (subMenu) + offsetAdjust[1]) + 'px';

	}



	// IE specific iframe masking method

	/*@cc_on

		@if (@_jscript_version >= 5.5)

			if (menuInfo.cmFrameMasking)

			{

				if (!subMenu.cmFrameObj)

				{

					var frameObj = cmAllocFrame ();

					subMenu.cmFrameObj = frameObj;

				}



				var frameObj = subMenu.cmFrameObj;

				frameObj.style.zIndex = subMenu.style.zIndex - 1;

				frameObj.style.left = (cmGetX (subMenu) - cmGetX (frameObj.offsetParent)) + 'px';

				frameObj.style.top = (cmGetY (subMenu)  - cmGetY (frameObj.offsetParent)) + 'px';

				frameObj.style.width = cmGetWidth (subMenu) + 'px';

				frameObj.style.height = cmGetHeight (subMenu) + 'px';

				frameObj.style.display = 'block';

			}

		@end

	@*/

	if (horiz != orient.charAt (2))

		orient = orient.charAt (0) + orient.charAt (1) + horiz;

	return orient;

}



//

// automatically re-adjust the menu position based on available screen size.

//

function cmGetHorizontalAlign (obj, mode, p, subMenuWidth)

{

	var horiz = mode.charAt (2);

	if (!(document.body))

		return horiz;

	var body = document.body;

	var browserLeft;

	var browserRight;

	if (window.innerWidth)

	{

		// DOM window attributes

		browserLeft = window.pageXOffset;

		browserRight = window.innerWidth + browserLeft;

	}

	else if (body.clientWidth)

	{

		// IE attributes

		browserLeft = body.clientLeft;

		browserRight = body.clientWidth + browserLeft;

	}

	else

		return horiz;

	if (mode.charAt (0) == 'h')

	{

		if (horiz == 'r' && (cmGetXAt (obj) + subMenuWidth) > browserRight)

			horiz = 'l';

		if (horiz == 'l' && (cmGetXAt (obj) + cmGetWidth (obj) - subMenuWidth) < browserLeft)

			horiz = 'r';

		return horiz;

	}

	else

	{

		if (horiz == 'r' && (cmGetXAt (obj, p) + cmGetWidth (obj) + subMenuWidth) > browserRight)

			horiz = 'l';

		if (horiz == 'l' && (cmGetXAt (obj, p) - subMenuWidth) < browserLeft)

			horiz = 'r';

		return horiz;

	}

}



//

// show the subMenu w/ specified orientation

// also move it to the correct coordinates

//

function cmShowSubMenu (obj, isMain, subMenu, menuInfo)

{

	var prefix = menuInfo.prefix;



	if (!subMenu.cmParentMenu)

	{

		// establish the tree w/ back edge

		var thisMenu = cmGetThisMenu (obj, prefix);

		subMenu.cmParentMenu = thisMenu;

		if (!thisMenu.cmSubMenu)

			thisMenu.cmSubMenu = new Array ();

		thisMenu.cmSubMenu[thisMenu.cmSubMenu.length] = subMenu;

	}



	var effectInstance = subMenu.cmEffect;

	if (effectInstance)

		effectInstance.showEffect (true);

	else

	{

		// position the sub menu only if we are not already showing the submenu

		var orient = cmMoveSubMenu (obj, isMain, subMenu, menuInfo);

		subMenu.cmOrient = orient;



		var forceShow = false;

		if (subMenu.style.visibility != 'visible' && menuInfo.nodeProperties.effect)

		{

			try

			{

				effectInstance = menuInfo.nodeProperties.effect.getInstance (subMenu, orient);

				effectInstance.showEffect (false);

			}

			catch (e)

			{

				forceShow = true;

				subMenu.cmEffect = null;

			}

		}

		else

			forceShow = true;



		if (forceShow)

		{

			subMenu.style.visibility = 'visible';

			/*@cc_on

				@if (@_jscript_version >= 5.5)

					if (subMenu.cmFrameObj)

						subMenu.cmFrameObj.style.display = 'block';

				@end

			@*/

		}

	}



	if (!_cmHideObjects)

	{

		_cmHideObjects = 2;	// default = not hide, may change behavior later

		try

		{

			if (window.opera)

			{

				if (parseInt (navigator.appVersion) < 9)

					_cmHideObjects = 1;

			}

		}

		catch (e)

		{

		}

	}



	if (_cmHideObjects == 1)

	{

		if (!subMenu.cmOverlap)

			subMenu.cmOverlap = new Array ();

		cmHideControl ("IFRAME", subMenu);

		cmHideControl ("OBJECT", subMenu);

	}

}



//

// reset all the menu items to class MenuItem in thisMenu

//

function cmResetMenu (thisMenu, prefix)

{

	if (thisMenu.cmItems)

	{

		var i;

		var str;

		var items = thisMenu.cmItems;

		for (i = 0; i < items.length; ++i)

		{

			if (items[i].cmIsMain)

			{

				if (items[i].className == (prefix + 'MainItemDisabled'))

					continue;

			}

			else

			{

				if (items[i].className == (prefix + 'MenuItemDisabled'))

					continue;

			}

			if (items[i].cmIsMain)

				str = prefix + 'MainItem';

			else

				str = prefix + 'MenuItem';

			if (items[i].className != str)

				items[i].className = str;

		}

	}

}



//

// called by the timer to hide the menu

//

function cmHideMenuTime ()

{

	_cmClicked = false;

	if (_cmCurrentItem)

	{

		var menuInfo = _cmMenuList[_cmCurrentItem.cmMenuID];

		var prefix = menuInfo.prefix;

		cmHideMenu (cmGetThisMenu (_cmCurrentItem, prefix), null, menuInfo);

		_cmCurrentItem = null;

	}

}



//

// Only hides this menu

//

function cmHideThisMenu (thisMenu, menuInfo)

{

	var effectInstance = thisMenu.cmEffect;

	if (effectInstance)

		effectInstance.hideEffect (true);

	else

	{

		thisMenu.style.visibility = 'hidden';

		thisMenu.style.top = '0px';

		thisMenu.style.left = '0px';

		thisMenu.cmOrient = null;

		/*@cc_on

			@if (@_jscript_version >= 5.5)

				if (thisMenu.cmFrameObj)

				{

					var frameObj = thisMenu.cmFrameObj;

					frameObj.style.display = 'none';

					frameObj.style.width = '1px';

					frameObj.style.height = '1px';

					thisMenu.cmFrameObj = null;

					cmFreeFrame (frameObj);

				}

			@end

		@*/

	}



	cmShowControl (thisMenu);

	thisMenu.cmItems = null;

}



//

// hide thisMenu, children of thisMenu, as well as the ancestor

// of thisMenu until currentMenu is encountered.  currentMenu

// will not be hidden

//

function cmHideMenu (thisMenu, currentMenu, menuInfo)

{

	var prefix = menuInfo.prefix;

	var str = prefix + 'SubMenu';



	// hide the down stream menus

	if (thisMenu.cmSubMenu)

	{

		var i;

		for (i = 0; i < thisMenu.cmSubMenu.length; ++i)

		{

			cmHideSubMenu (thisMenu.cmSubMenu[i], menuInfo);

		}

	}



	// hide the upstream menus

	while (thisMenu && thisMenu != currentMenu)

	{

		cmResetMenu (thisMenu, prefix);

		if (thisMenu.className == str)

		{

			cmHideThisMenu (thisMenu, menuInfo);

		}

		else

			break;

		thisMenu = cmGetThisMenu (thisMenu.cmParentMenu, prefix);

	}

}



//

// hide thisMenu as well as its sub menus if thisMenu is not

// already hidden

//

function cmHideSubMenu (thisMenu, menuInfo)

{

	if (thisMenu.style.visibility == 'hidden')

		return;

	if (thisMenu.cmSubMenu)

	{

		var i;

		for (i = 0; i < thisMenu.cmSubMenu.length; ++i)

		{

			cmHideSubMenu (thisMenu.cmSubMenu[i], menuInfo);

		}

	}

	var prefix = menuInfo.prefix;

	cmResetMenu (thisMenu, prefix);

	cmHideThisMenu (thisMenu, menuInfo);

}



//

// hide a control such as IFRAME

//

function cmHideControl (tagName, subMenu)

{

	var x = cmGetX (subMenu);

	var y = cmGetY (subMenu);

	var w = subMenu.offsetWidth;

	var h = subMenu.offsetHeight;



	var i;

	for (i = 0; i < document.all.tags(tagName).length; ++i)

	{

		var obj = document.all.tags(tagName)[i];

		if (!obj || !obj.offsetParent)

			continue;



		// check if the object and the subMenu overlap



		var ox = cmGetX (obj);

		var oy = cmGetY (obj);

		var ow = obj.offsetWidth;

		var oh = obj.offsetHeight;



		if (ox > (x + w) || (ox + ow) < x)

			continue;

		if (oy > (y + h) || (oy + oh) < y)

			continue;



		// if object is already made hidden by a different

		// submenu then we dont want to put it on overlap list of

		// of a submenu a second time.

		// - bug fixed by Felix Zaslavskiy

		if(obj.style.visibility == 'hidden')

			continue;



		//subMenu.cmOverlap.push (obj);

		subMenu.cmOverlap[subMenu.cmOverlap.length] = obj;

		if (obj.id == "")

  		   obj.style.visibility = 'hidden';

	}

}



//

// show the control hidden by the subMenu

//

function cmShowControl (subMenu)

{

	if (subMenu.cmOverlap)

	{

		var i;

		for (i = 0; i < subMenu.cmOverlap.length; ++i)

			subMenu.cmOverlap[i].style.visibility = "";

	}

	subMenu.cmOverlap = null;

}



//

// returns the main menu or the submenu table where this obj (menu item)

// is in

//

function cmGetThisMenu (obj, prefix)

{

	var str1 = prefix + 'SubMenu';

	var str2 = prefix + 'Menu';

	while (obj)

	{

		if (obj.className == str1 || obj.className == str2)

			return obj;

		obj = obj.parentNode;

	}

	return null;

}



//

// A special effect function to hook the menu which contains

// special effect object to the timer.

//

function cmTimeEffect (menuID, show, delayTime)

{

	window.setTimeout ('cmCallEffect("' + menuID + '",' + show + ')', delayTime);

}



//

// A special effect function.  Called by timer.

//

function cmCallEffect (menuID, show)

{

	var menu = cmGetObject (menuID);

	if (!menu || !menu.cmEffect)

		return;

	try

	{

		if (show)

			menu.cmEffect.showEffect (false);

		else

			menu.cmEffect.hideEffect (false);

	}

	catch (e)

	{

	}

}



//

// return true if this item is handled using default handlers

//

function cmIsDefaultItem (item)

{

	if (item == _cmSplit || item[0] == _cmNoAction || item[0] == _cmNoClick)

		return false;

	return true;

}



//

// returns the object baring the id

//

function cmGetObject (id)

{

	if (document.all)

		return document.all[id];

	return document.getElementById (id);

}



//

// functions that obtain the width of an HTML element.

//

function cmGetWidth (obj)

{

	var width = obj.offsetWidth;

	if (width > 0 || !cmIsTRNode (obj))

		return width;

	if (!obj.firstChild)

		return 0;

	// use TABLE's length can cause an extra pixel gap

	//return obj.parentNode.parentNode.offsetWidth;



	// use the left and right child instead

	return obj.lastChild.offsetLeft - obj.firstChild.offsetLeft + cmGetWidth (obj.lastChild);

}



//

// functions that obtain the height of an HTML element.

//

function cmGetHeight (obj)

{

	var height = obj.offsetHeight;

	if (height > 0 || !cmIsTRNode (obj))

		return height;

	if (!obj.firstChild)

		return 0;

	// use the first child's height

	return obj.firstChild.offsetHeight;

}



//

// functions that obtain the coordinates of an HTML element

//

function cmGetX (obj)

{

	if (!obj)

		return 0;

	var x = 0;



	do

	{

		x += obj.offsetLeft;

		obj = obj.offsetParent;

	}

	while (obj);

	return x;

}



function cmGetXAt (obj, elm)

{

	var x = 0;



	while (obj && obj != elm)

	{

		x += obj.offsetLeft;

		obj = obj.offsetParent;

	}

	if (obj == elm)

		return x;

	return x - cmGetX (elm);

}



function cmGetY (obj)

{

	if (!obj)

		return 0;

	var y = 0;

	do

	{

		y += obj.offsetTop;

		obj = obj.offsetParent;

	}

	while (obj);

	return y;

}



function cmIsTRNode (obj)

{

	var tagName = obj.tagName;

	return tagName == "TR" || tagName == "tr" || tagName == "Tr" || tagName == "tR";

}



//

// get the Y position of the object.  In case of TR element though,

// we attempt to adjust the value.

//

function cmGetYAt (obj, elm)

{

	var y = 0;



	if (!obj.offsetHeight && cmIsTRNode (obj))

	{

		var firstTR = obj.parentNode.firstChild;

		obj = obj.firstChild;

		y -= firstTR.firstChild.offsetTop;

	}



	while (obj && obj != elm)

	{

		y += obj.offsetTop;

		obj = obj.offsetParent;

	}



	if (obj == elm)

		return y;

	return y - cmGetY (elm);

}



//

// extract description from the menu item and set the status text

//

function cmSetStatus (item)

{

	var descript = '';

	if (item.length > 4)

		descript = (item[4] != null) ? item[4] : (item[2] ? item[2] : descript);

	else if (item.length > 2)

		descript = (item[2] ? item[2] : descript);



	window.defaultStatus = descript;

}



//

// debug function, ignore :)

//

function cmGetProperties (obj)

{

	if (obj == undefined)

		return 'undefined';

	if (obj == null)

		return 'null';



	var msg = obj + ':\n';

	var i;

	for (i in obj)

		msg += i + ' = ' + obj[i] + '; ';

	return msg;

}



// utiltity object to simplify common tasks in effects.



function CMSpecialEffectInstance (effect, menu)

{

	effect.show = true;

	effect.menu = menu;

	menu.cmEffect = effect;

	this.effect = effect;

}



CMSpecialEffectInstance.prototype.canShow = function (changed)

{

	if (changed)

	{

		if (this.effect.show)

			return false;

		this.effect.show = true;

	}

	else if (!this.effect.show)

		return false;

	return true;

}



CMSpecialEffectInstance.prototype.canHide = function (changed)

{

	var effect = this.effect;

	if (changed)

	{

		if (!effect.show)

			return false;

		effect.show = false;

	}

	else if (effect.show)

		return false;

	return true;

}



//

// public function to be called to initate the display of the menu.

//

CMSpecialEffectInstance.prototype.startShowing = function ()

{

	var menu = this.effect.menu;

	menu.style.visibility = 'visible';

	/*@cc_on

		@if (@_jscript_version >= 5.5)

			if (menu.cmFrameObj)

			{

				var frameObj = menu.cmFrameObj;

				frameObj.style.display = 'block';

			}

		@end

	@*/

}



//

// public function to be called after showing effect is finished.

//

CMSpecialEffectInstance.prototype.finishShowing = function ()

{

}



//

// clean up after finish hiding effect.

//

CMSpecialEffectInstance.prototype.finishHiding = function ()

{

	var menu = this.effect.menu;

	menu.style.visibility = 'hidden';

	menu.style.top = '0px';

	menu.style.left = '0px';

	/*@cc_on

		@if (@_jscript_version >= 5.5)

			if (menu.cmFrameObj)

			{

				var frameObj = menu.cmFrameObj;

				frameObj.style.display = 'none';

				frameObj.style.top = '0px';

				frameObj.style.left = '0px';

				menu.cmFrameObj = null;

				cmFreeFrame (frameObj);

			}

		@end

	@*/

	menu.cmEffect = null;

	menu.cmOrient = null;

	this.effect.menu = null;

}



//

// this is the internal class to perform the sliding effect

//

function CMSlidingEffectInstance (menu, orient, speed)

{

	this.base = new CMSpecialEffectInstance (this, menu);



	menu.style.overflow = 'hidden';



	this.x = menu.offsetLeft;

	this.y = menu.offsetTop;



	if (orient.charAt (0) == 'h')

	{

		this.slideOrient = 'h';

		this.slideDir = orient.charAt (1);

	}

	else

	{

		this.slideOrient = 'v';

		this.slideDir = orient.charAt (2);

	}



	this.speed = speed;

	this.fullWidth = menu.offsetWidth;

	this.fullHeight = menu.offsetHeight;

	this.percent = 0;

	/*@cc_on

		@if (@_jscript_version >= 5.5)

			if (menu.cmFrameObj)

			{

				var frameObj = menu.cmFrameObj;

				this.frameX = frameObj.offsetLeft;

				this.frameY = frameObj.offsetTop;

				this.frameWidth = frameObj.offsetWidth;

				this.frameHeight = frameObj.offsetHeight;

			}

		@end

	@*/

}

	// public function to show the menu

CMSlidingEffectInstance.prototype.showEffect = function (changed)

{

	if (!this.base.canShow (changed))

		return;



	var percent = this.percent;

	if (this.slideOrient == 'h')

		this.slideMenuV ();

	else

		this.slideMenuH ();



	if (percent == 0)

	{

		this.base.startShowing ();

	}



	if (percent < 100)

	{

		this.percent += this.speed;

		cmTimeEffect (this.menu.id, this.show, 10);

	}

	else if (this.show)

	{

		this.base.finishShowing ();

	}

}



// public function to hide the menu

CMSlidingEffectInstance.prototype.hideEffect = function (changed)

{

	if (!this.base.canHide (changed))

		return;



	var percent = this.percent;

	if (this.slideOrient == 'h')

		this.slideMenuV ();

	else

		this.slideMenuH ();



	if (percent > 0)

	{

		this.percent -= this.speed;

		cmTimeEffect (this.menu.id, this.show, 10);

	}

	else if (!this.show)

	{

		this.menu.style.clip = 'auto';

		this.base.finishHiding ();

	}

}



// internal function to scroll a menu left/right

CMSlidingEffectInstance.prototype.slideMenuH = function ()

{

	var percent = this.percent;

	if (percent < 0)

		percent = 0;

	if (percent > 100)

		percent = 100;

	var fullWidth = this.fullWidth;

	var fullHeight = this.fullHeight;

	var x = this.x;

	var space = percent * fullWidth / 100;

	var menu = this.menu;



	if (this.slideDir == 'l')

	{

		menu.style.left = (x + fullWidth - space) + 'px';

		menu.style.clip = 'rect(0px ' + space + 'px ' + fullHeight + 'px 0px)';

	}

	else

	{

		menu.style.left = (x - fullWidth + space) + 'px';

		menu.style.clip = 'rect(0px ' + fullWidth + 'px ' + fullHeight + 'px ' + (fullWidth - space) + 'px)';

	}

	/*@cc_on

		@if (@_jscript_version >= 5.5)

			if (menu.cmFrameObj)

			{

				var frameObj = menu.cmFrameObj;

				if (this.slideDir == 'l')

					frameObj.style.left = (this.frameX + fullWidth - space) + 'px';

				frameObj.style.width = space + 'px';

			}

		@end

	@*/

}



// internal function to scroll a menu up/down

CMSlidingEffectInstance.prototype.slideMenuV = function ()

{

	var percent = this.percent;

	if (percent < 0)

		percent = 0;

	if (percent > 100)

		percent = 100;

	var fullWidth = this.fullWidth;

	var fullHeight = this.fullHeight;

	var y = this.y;

	var space = percent * fullHeight / 100;

	var menu = this.menu;



	if (this.slideDir == 'b')

	{

		menu.style.top = (y - fullHeight + space) + 'px';

		menu.style.clip = 'rect(' + (fullHeight - space) + 'px ' + fullWidth + 'px ' + fullHeight + 'px 0px)';

	}

	else

	{

		menu.style.top = (y + fullHeight - space) + 'px';

		menu.style.clip = 'rect(0px ' + fullWidth + 'px ' + space + 'px 0px)';

	}

	/*@cc_on

		@if (@_jscript_version >= 5.5)

			if (menu.cmFrameObj)

			{

				var frameObj = menu.cmFrameObj;

				if (this.slideDir == 'u')

					frameObj.style.top = (this.frameX - space) + 'px';

				frameObj.style.height = space + 'px';

			}

		@end

	@*/

}



//

// call

//		new CMSlidingEffect (speed)

// to create a new effect object.

//

function CMSlidingEffect (speed)

{

	if (!speed)

		speed = 10;

	else if (speed <= 0)

		speed = 10;

	else if (speed >= 100)

		speed = 100;

	this.speed = speed;

}



CMSlidingEffect.prototype.getInstance = function (menu, orient)

{

	return new CMSlidingEffectInstance (menu, orient, this.speed);

}



//

// this is the internal class to perform the sliding effect

//

function CMFadingEffectInstance (menu, showSpeed, hideSpeed)

{

	this.base = new CMSpecialEffectInstance (this, menu);



	menu.style.overflow = 'hidden';



	this.showSpeed = showSpeed;

	this.hideSpeed = hideSpeed;



	this.opacity = 0;

}



// public function to show the menu

CMFadingEffectInstance.prototype.showEffect = function (changed)

{

	if (!this.base.canShow (changed))

		return;



	var menu = this.menu;

	var opacity = this.opacity;



	this.setOpacity ();



	if (opacity == 0)

	{

		this.base.startShowing ();

	}



	if (opacity < 100)

	{

		this.opacity += 10;

		cmTimeEffect (menu.id, this.show, this.showSpeed);

	}

	else if (this.show)

	{

		this.base.finishShowing ();

	}

}



// public function to hide the menu

CMFadingEffectInstance.prototype.hideEffect = function (changed)

{

	if (!this.base.canHide (changed))

		return;



	var menu = this.menu;

	var opacity = this.opacity;



	this.setOpacity ();



	if (this.opacity > 0)

	{

		this.opacity -= 10;

		cmTimeEffect (menu.id, this.show, this.hideSpeed);

	}

	else if (!this.show)

	{

		this.base.finishHiding ();

	}

}



// internal functions

CMFadingEffectInstance.prototype.setOpacity = function ()

{

	this.menu.style.opacity = this.opacity / 100;

	/*@cc_on

		this.menu.style.filter = 'alpha(opacity=' + this.opacity + ')';

		//this.menu.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + this.opacity + ')';

	@*/

}



function CMFadingEffect (showSpeed, hideSpeed)

{

	this.showSpeed = showSpeed;

	this.hideSpeed = hideSpeed;

}



CMFadingEffect.prototype.getInstance = function (menu, orient)

{

	return new CMFadingEffectInstance (menu, this.showSpeed, this.hideSpeed);

}

