/* ---------------------------------------------------------------- */
// 2007.08.12 10:03PM  d.binette

/* ---------------------------------------------------------------- */
// Assets is the folder containing the support files
// for the bubble
// find our own path, and set it as the asset directory
// get the invokers page name so we can find it in the menu and open to there.
var CurrentPageNode = null;
var CurrentPageName;
if (parent && parent.document)
	CurrentPageName = basename(parent.document.URL);
else
	CurrentPageName = basename(this.document.URL);

var Assets = '';

{
	var scripts = document.getElementsByTagName('script');
	var index = scripts.length - 1;
	var me = scripts[index].src;
	var n = me.lastIndexOf('/');
	if (n>=0)
		Assets = (me.substr(0,n+1));

	bubblehead();
}
/* ---------------------------------------------------------------- */
// convenience function to output all headers and setup for running
/* ---------------------------------------------------------------- */

function bubblehead()
{
    str = "<link rel='stylesheet' href='" + Assets + "menu.css' type='text/css' />\r\n";
    document.write(str);
};

/* ---------------------------------------------------------------- */

// end of bubble
bubble.prototype.end = function()
{
    document.write(this);
}


/* ---------------------------------------------------------------- */
// Node object
function Node(id, pid, name, url, title, target, open)
{
	this.id              = id;                 // id for this node
	this.pid             = pid;                // parent ID
	this.name            = name;               // label
	this.url             = url;                // url
	this.title           = title;              // tooltip and status bar
	this.target          = target;             // for targetting frames
	this._isopen         = open || false;      // 'is open'
	this._islastsibling  = false;              // 'last sibling'
	this._haschildren    = false;              // 'has children'
	this._ai             = 0;
	this._p;									// parent
};

/* ---------------------------------------------------------------- */
// Tree object
function bubble(objName)
{
	this.config =
	    {target				: '_top'
		,useStatusText		: true
		,closeSameLevel	    : true
		,inOrder            : true
		,autoToolTip        : true
	};

	this.obj          = objName;
	this.aNodes       = [];
	this.aIndent      = [];
	this.root         = new Node(-1);
	this.completed    = false;
    this.AutoNodeID   = 0;
    this.MenuItem     = { 'root' : -1 };
};

/* ---------------------------------------------------------------- */
// Adds a new node to the node array
bubble.prototype.add = function(miName, miParent, name, url, title, target, open)
{
    if (this.AutoNodeID == 0)
    {   miName   = 'main';
        miParent = 'root';
    }

    if (miName != '')
        this.MenuItem[miName] = this.AutoNodeID;

    if (miParent == '' )
    {   miParent = this.AutoNodeID ? 'main' : 'root';
    }

    if (this.config.autoToolTip && title == null)
    {   title = url;
    }

    if (url && CurrentPageName == basename(url))
    {   CurrentPageNode = this.AutoNodeID;
    }

    pid = this.MenuItem[miParent];

	this.aNodes[this.aNodes.length] = new Node(this.AutoNodeID, pid, name, url, title, target, open);
    ++this.AutoNodeID;
};

/* ---------------------------------------------------------------- */
// Open/close all nodes
bubble.prototype.openAll = function()
{
	return this.oAll(true);
};

/* ---------------------------------------------------------------- */
bubble.prototype.closeAll = function()
{
	return this.oAll(false);
};

/* ---------------------------------------------------------------- */
// if ANY nodes are open, close them all
// if all nodes are closed, open them all
bubble.prototype.togOpenAll = function()
{
	for (var n=0; n<this.aNodes.length; ++n)
	{
	    if (this.aNodes[n]._isopen)
		{   return this.oAll(false);
		}
	}
	return this.oAll(true);
}

/* ---------------------------------------------------------------- */

bubble.prototype.search = function(pat)
{
	if (pat && pat > '')
	{	this.closeAll();
		rePat = new RegExp(pat, "i") // case insensitive
		for (var n=0; n<this.aNodes.length; ++n)
		{	if (this.aNodes[n].name.match(rePat))
				this.openTo(n,true);
		}
	}
};

/* ---------------------------------------------------------------- */

bubble.prototype.asksearch = function()
{
	var pat = prompt("Menu Search\r\nEnter what you want to find and the menu will open to that place. ","");
	if (pat > '')
	{	this.search(pat);
	}
	return false;
};

/* ---------------------------------------------------------------- */
// Outputs the tree to the page
bubble.prototype.toString = function()
{
	var str = '';//"\r\n";
	str += "<div class=\"bubble\">\r\n";
	str += this.addNode(this.root);
	str += "</div>\r\n";
	this.completed = true;
	return str;
};

/* ---------------------------------------------------------------- */
// Creates the tree structure
bubble.prototype.addNode = function(pNode)
{
	var str = '';
	var n=0;

	if (this.config.inOrder)
	    n = pNode._ai;

	for (n; n<this.aNodes.length; ++n)
	{
		if (this.aNodes[n].pid == pNode.id)
		{
			var cn = this.aNodes[n];
			cn._p  = pNode;
			cn._ai = n;
			this.setCS(cn);

			if (!cn.target && this.config.target)
			    cn.target = this.config.target;

			if (cn._haschildren)
			    cn.url = null;

			str += this.node(cn, n);

			if (cn._ls)
			    break;
		}
	}
	return str;
};

/* ---------------------------------------------------------------- */

bubble.prototype.invoke = function(nodeId)
{
    var cn = this.aNodes[nodeId];

    return true;
}

/* ---------------------------------------------------------------- */
// Creates the node url and text
bubble.prototype.node = function(node, nodeId)
{
	var str = '';

	if (this.root.id == node.pid)
    {	////////////////////////////////////////////////////////////////////
		// searchbox
		str += '<div class="parent">' + "\r\n";
		str += '<img width=18 height=18 src="' + Assets + 'arrow.gif">';
		//str += '<img width=18 height=18 src="' + Assets + 'empty.gif" alt="" />';

		str += '<a href="#"';
		str += ' onclick="return ' + this.obj + '.asksearch();"';
		str += ' title="click to search"> Search</a>';
        ////////////////////////////////////////////////////////////////////
		str += ' <a href="#" onclick="return ' + this.obj + '.togOpenAll();" > ';
    }
	else
	{
	    if (node._haschildren)
		    str += '<div class="parent">' +"\r\n"
		else
		    str += '<div class="child">' +"\r\n"

		str += this.indent(node, nodeId);
	}


	if (node.url)
	{
		str += '<a id="s' + this.obj + nodeId + '" class="node" ';

        ////////////////////////////////////////////////////////////////////
		// a clickable end user link
		str += 'href="' + node.url + '"' ;
		str += 'onclick="return ' + this.obj + '.invoke(' + nodeId + ')"  ';
        ////////////////////////////////////////////////////////////////////

		if (node.target)
		    str += ' target="' + node.target + '"';

		if (node.title)
		    str += ' title="' + node.title + '"';

		if (this.config.useStatusText)
		    str += ' onmouseover="window.status=\'' + node.name + '\';return true;" onmouseout="window.status=\'\';return true;" ';

		str += ">\r\n";
	}

	else

    if (node._haschildren && node.pid != this.root.id)
	{   str += '<a href="#" onclick="return ' + this.obj + '.o(' + nodeId + ');" class="title"';

		if (node.title)
		    str += ' title="' + node.title + '"';

		if (this.config.useStatusText)
		    str += ' onmouseover="window.status=\'' + node.name + '\';return true;" onmouseout="window.status=\'\';return true;" ';

		str += ">\r\n";
	}


	str += node.name;
	if (node.url || node._haschildren || this.root.id == node.pid)
	    str += "</a>\r\n";

	str += "</div>\r\n";


	if (this.root.id == node.pid)
	{	str += "<br>\r\n";
	}


	if (node._haschildren)
	{
		str += '<div id="d' + this.obj + nodeId + '" class="clip" style="display:'
		    + ((this.root.id == node.pid || node._isopen) ? 'block' : 'none') + ';">';

		str += this.addNode(node);
		str += "</div>\r\n";
	}


	str +="<br>\r\n";
	this.aIndent.pop();

    return str;
};

/* ---------------------------------------------------------------- */
// Adds the empty and lines
bubble.prototype.indent = function(node, nodeId)
{
	var str = '';
	if (this.root.id != node.pid)
	{
		for (var n=1; n<this.aIndent.length; ++n)
		{	str += '<img width=18 height=18 src="' + Assets + 'empty.gif" alt="" />';
	    }

		this.aIndent.push(node._islastsibling ? 0 : 1);

		if (node._haschildren)
		{
			str += '<a href="#" onclick="return ' + this.obj + '.o(' + nodeId + ');">' + "\r\n";
			str += '<span id="j' + this.obj + nodeId + '" /> <img width=18 height=18 src="' + Assets + 'arrow.gif">';
			str += '</a>';
		}
		else
		{   if (strBeginsWith(node.name,'<hr'))
		        str += '<img width=18 height=18 src="' + Assets + 'empty.gif" alt="" />';
		    else
		        str += '<img width=18 height=18 src="' + Assets + 'dot.gif" alt="" />';
		}
		str += "\r\n";
    }
	return str;
};

/* ---------------------------------------------------------------- */
// Checks if a node has any children and if it is the last sibling
bubble.prototype.setCS = function(node)
{
	var lastId;
	for (var n=0; n<this.aNodes.length; ++n)
	{
		if (this.aNodes[n].pid == node.id)
		    node._haschildren = true;

		if (this.aNodes[n].pid == node.pid)
		    lastId = this.aNodes[n].id;
	}
	if (lastId==node.id)
	    node._islastsibling = true;
};

/* ---------------------------------------------------------------- */
// Toggle Open or close
bubble.prototype.o = function(id)
{
	var cn = this.aNodes[id];
	this.nodeStatus(!cn._isopen, id, cn._islastsibling);

	cn._isopen = !cn._isopen;

	if (this.config.closeSameLevel)
	    this.closeLevel(cn);

	return false;
};

/* ---------------------------------------------------------------- */
// Open or close all nodes
bubble.prototype.oAll = function(status)
{
	for (var n=0; n<this.aNodes.length; ++n)
	{
		if (this.aNodes[n]._haschildren && this.aNodes[n].pid != this.root.id)
		{
			this.nodeStatus(status, n, this.aNodes[n]._islastsibling);
			this.aNodes[n]._isopen = status;
		}
		else
		if (status == false)
			this.aNodes[n]._isopen = status;
	}
	return false;
};

/* ---------------------------------------------------------------- */
// Opens the tree to a specific node
bubble.prototype.openTo = function(nId, bFirst)
{
	if (!bFirst)
	{
		for (var n=0; n<this.aNodes.length; ++n)
		{
			if (this.aNodes[n].id == nId)
			{
				nId=n;
				break;
			}
		}
	}

	var cn=this.aNodes[nId];

	if (cn.pid==this.root.id || !cn._p)
	    return;

	cn._isopen = true;
	if (this.completed && cn._haschildren)
	    this.nodeStatus(true, cn._ai, cn._islastsibling);

	this.openTo(cn._p._ai, true);
	return false;
};

/* ---------------------------------------------------------------- */
// Closes all children of a node
bubble.prototype.closeAllChildren = function(node)
{
	for (var n=0; n<this.aNodes.length; ++n)
	{
		if (this.aNodes[n].pid == node.id && this.aNodes[n]._haschildren)
		{
			if (this.aNodes[n]._isopen)
			    this.nodeStatus(false, n, this.aNodes[n]._islastsibling);

			this.aNodes[n]._isopen = false;

			this.closeAllChildren(this.aNodes[n]);
		}
	}
};

/* ---------------------------------------------------------------- */
// Closes all nodes on the same level as certain node
bubble.prototype.closeLevel = function(node)
{
	for (var n=0; n<this.aNodes.length; ++n)
	{
		if (this.aNodes[n].pid == node.pid && this.aNodes[n].id != node.id && this.aNodes[n]._haschildren)
		{
			this.nodeStatus(false, n, this.aNodes[n]._islastsibling);
			this.aNodes[n]._isopen = false;
			this.closeAllChildren(this.aNodes[n]);
		}
	}
};

/* ---------------------------------------------------------------- */
// Change the status of a node(open or closed)
bubble.prototype.nodeStatus = function(status, id, bottom)
{
	eDiv	= document.getElementById('d' + this.obj + id);
	eJoin	= document.getElementById('j' + this.obj + id);
	eDiv.style.display = (status) ? 'block': 'none';
};

/* ---------------------------------------------------------------- */
// add array methods that may be not implemented by the browser
if (!Array.prototype.last)
{
	Array.prototype.last = function array_last()
	{
		return  this[this.length-1];
	}
};

if (!Array.prototype.pop)
{
	Array.prototype.pop = function array_pop()
	{
		lastElement = this.last();
		this.length = Math.max(this.length-1,0);
		return lastElement;
	}
};

if (!Array.prototype.push)
{
	Array.prototype.push = function array_push()
	{
		for (var n=0; n < arguments.length; ++n)
		{	this[this.length]=arguments[n];
		}
		return this.length;
	}
};

/* ---------------------------------------------------------------- */

function strEndsWith(str,pat)
{
    return str.toLowerCase().substr(str.length - pat.length) == pat.toLowerCase();
}

/* ---------------------------------------------------------------- */

function strBeginsWith(str,pat)
{  return str.toLowerCase().substr(0,pat.length) == pat.toLowerCase();
};

/* ---------------------------------------------------------------- */

function basename(filename)
{
    if (filename > '')
    {   pos = filename.lastIndexOf('/');
        //if (pos > 0)
            return filename.substring(pos + 1);
    }
    return '';
};

/* ---------------------------------------------------------------- */
// bubble obj is the created bubble object
// menu is the menu specification
// Change the status of a node(open or closed)
bubble.prototype.play = function(menu)
{
	var id = this.obj;
	var el = document.getElementById(id);

	// get tree lines, one per line
	var line = menu.replace(/\r\n/g,"\n").split("\n");

	for (i=0; i<line.length; i = i + 1)
	{
		// get each field
		field = line[i].split(',');

		if (field.length < 2)
		{	continue;
		}

		// replace null fields with ''
		for(f=0; f<field.length; ++f)
		{	if (field[f] == null)
				field[f] = '';

			// trim off leading and trailing spaces
			field[f] = field[f].replace(/^\s+/, '').replace(/\s+$/, '');

			field[f] = field[f].replace(/'+/, '&#146;');
		}

		if (field.length == 1)	this.add(field[0]); // miName
		if (field.length == 2)	this.add(field[0],field[1]); // miParent
		if (field.length == 3)	this.add(field[0],field[1],field[2]); // name (label)
		if (field.length == 4)	this.add(field[0],field[1],field[2],field[3]); // url
		if (field.length == 5)	this.add(field[0],field[1],field[2],field[3],field[4]); // tooltip
		if (field.length == 6)	this.add(field[0],field[1],field[2],field[3],field[4],field[5]); // target
		if (field.length == 7)	this.add(field[0],field[1],field[2],field[3],field[4],field[5],field[6]); // open
	}
	el.innerHTML = this;
	if (CurrentPageNode != null)
	{	this.openTo(CurrentPageNode,true);
	}
	el.style.display = 'block';
};

/* ---------------------------------------------------------------- */

var MainMenu =
" main  , root   , All Tutorials\n"
+" over  , main   , Intro To YahELite      ,                             , Overview - How to Log in\n"
+"       , over   , Overview               ,/tutorial/overview.php       , An overview of YahELite\n"
+"       , over   , Getting Started        ,/tutorial/start.php          , Login and Connect\n"
+"       , over   , Menus: Basic or Expert ,/tutorial/compare.php        , Basic or Expert which level are you?\n"
+"       , over   , Change User Levels     ,/tutorial/changelevels.php   , Change the visual complexity\n"
+"       , over   , Captcha Verification   ,/tutorial/captcha.php        , Captcha - Keeping Bots out of chat\n"
+" chat  , main   , Chat Window            ,                             , Customize your Chat Experience\n"
+"       , chat   , Appearance             ,/tutorial/appearance.php     , Control the Chat Window Appearance\n"
+"       , chat   , Avatars                ,/tutorial/avatar.php         , Avatars - Eye Candy only for chat clients\n"
+"       , chat   , Rainbow Text Blends    ,/tutorial/blend.php          , Create and use text blends\n"
+"       , chat   , Layout                 ,/tutorial/layout.php         , Change the layout\n"
+"       , chat   , Show Posted URLS       ,/tutorial/showurls.php       , Show all the URLs that have been posted\n"
+"       , chat   , Tabbars                ,/tutorial/tabbar.php         , Use tabbar to reduce window clutter\n"
+"       , chat   , Tattoos                ,/tutorial/tattoo.php         , Tattoos - Eye candy for all to see\n"
+"       , chat   , User Buttons           ,/tutorial/buttons.php        , Post text into the room with user defined buttons\n"   
+"       , chat   , Wallpapers             ,/tutorial/wallpaper.php      , Wallpaper - Eye candy only you see\n"
+" file  , main   , File Sharing           ,                             , Sharing Files\n"
+"       , file   , Receiving Files        ,/tutorial/receivefiles.php\n"
+"       , file   , Sharing Files          ,/tutorial/fileshare.php\n"
+" buds  , main   , Managing Friends       ,                             , Add Friends to Your List-Remove yourself from ex-friend's lists\n"
+"       , buds   , Add A Friend           ,/tutorial/buddyadd.php       , Add a friend to YOUR buddy list\n"
+"       , buds   , Away Status            ,/tutorial/status.php         , Set online status \n"
+"       , buds   , Buddy List             ,/tutorial/buddylist.php      , View your Buddy List\n"
+"       , buds   , Remove Yourself        ,/tutorial/unbud.php          , Remove Yourself from your ex-friends list\n"
+" room  , main   , Maneuvering in Chat    ,                             , How to use the Join Room Command and View yahoo Room Lists\n"
+"       , room   , Change Rooms           ,/tutorial/joinroom.php       , How to use the change rooms using the recent rooms window\n"
+"       , room   , Goto Friends           ,/tutorial/goto.php           , How to go to your friends in chat\n"
+"       , room   , Join Room Command      ,/tutorial/join.php           , How to use the Join Command to get to a room\n"
+"       , room   , Yahoo Room Lists       ,/tutorial/roomlist.php       , How to see all the Yahoo roomnames\n"
+" peac  , main   , Peace in Chat          ,                             , Filters - Auto ignores\n"
+"       , peac   , Overview of Peace      ,/tutorial/peace.php          , Peace - Overview\n"
+"       , peac   , Censored Text          ,/tutorial/censored.php       , Censoring the text you see on your screen\n"
+"       , peac   , Ignore Manually        ,/tutorial/ignore.php         , Ignore - Manually\n"
+"       , peac   , Ignore Accidental      ,/tutorial/ignore_oops.php    , OOPS how did they get ignored - unignore\n"
+"       , peac   , Ignore Temporary       ,/tutorial/ignore_temp.php    , Temporarily ignore chatters\n"
+"       , peac   , Ignore Wildcard        ,/tutorial/wildcard.php       , Auto ignore using wildcards\n"
+"       , peac   , Spam Filters           ,/tutorial/nospam.php         , Controlling Spam\n"
+" cams  , main   , Voice and Cams         ,                             , Using Cams and Voice in Chat\n"
+"       , cams   , Use Voice              ,/tutorial/yahvox.php         , How to use YahVox\n"
+"       , cams   , View Webcams           ,/tutorial/yahsee.php         , How to view and use Cams\n"
+"       , cams   , Fixing voice/cam       ,/tutorial/ycabby.php         , yCabby - troubleshooting voice and cams\n"
+" misc  , main   , Miscellanous Topics    ,                             , Update YahELite - Use Replacements To Fix Typos\n"
+"       , misc   , Updating YahELite      ,/tutorial/update.php         , How to update YahELite\n"
+"       , misc   , Using Replacements     ,/tutorial/replace.php        , Tired of Typos? Make a replacement macro\n"
+" adv1  , main   , Advanced Topics        ,                             , Learn about using Commands and Extensions\n"
+"       , adv1   , Using Commands         ,/tutorial/command.php        , Use commands to start and stop features and programs\n"
+"       , adv1   , Extensions             ,/tutorial/extension.php      , Use extensions with YahELite\n"
+" name  , main   , Banned/Deactivation    ,                             , Help! Yahoo won't let me log in!\n"
+"       , name   , Banned Names           ,/tutorial/banned.php         , My Name is Banned - What can I do?\n"
+"       , name   , Deactivated Names      ,/tutorial/deactivated.php         , My Name is DEACTIVATED - What can I do?\n"

+" oth1  , main   , Other Chat Topics      ,                             , Yahoo Glitches - Workarounds - Banned Names - IP addresses\n"
+"       , oth1   , Yahoo's IP Message     ,/tutorial/ip.php             , Why does yahoo record IP addresses\n"
+"       , oth1   , Yahoo Glitches         ,/tutorial/workarounds.php    , What was yahoo thinking!\n"
+"       , oth1   , Yahoo Edit Profile     ,/tutorial/yahoochangeprofile.php , Hints for changing your profile\n"
+"       , oth1   , ROFL                   ,/tutorial/abbreviations.php  , Chat acronyms ROFL LOL BRB etc.\n"
+"       , main   , <hr size=4>\n"
+"       , main   , DeepSpace              ,/tutorial/deepspace.php\n"
+"       , main   , Deeps Toys             ,/deep/yahelite/files.php\n"
+"       , main   , Friends                ,/tutorial/friends.php\n"
+"       , main   , Gallery                ,/gallery\n"
+"       , main   , Geek Gloves            ,/tutorial/geekgloves.php\n"
+"       , main   , Geek Scarf             ,/tutorial/geekscarf.php\n"
+"       , main   , YahELite               ,/deep/yahelite\n"
;
/* ---------------------------------------------------------------- */
/* end */
