// supersedes nicknav.js



/*



We have two NavItemGroups - the menu at the top and the sidebar project box

Each NavItemGroup consists of one or more NavItems that move as a group.

Each NavItemGroup has the following properties:

- an axis of movement, either HORIZONTAL or VERTICAL;

- a startPosition, i.e. the horizontal or vertical offset of its first position

- a spacing, the distance it moves from one position to the next 

- its visibility, either "visible" or "hidden"

- its countdown (to being hidden); if zero then no countdown is in effect



Each NavItem is a moveable fragment of html.  It has

- a name, matching the id of the html

- an offset, used to fine tune its positioning

- dynamic, either true or false, indicating whether content changes with position

- behaviour, any of MOVE, HIDE or SHOW.  This defines the behaviour of the item when the

  group is activated.  MOVE is the default, but HIDE means that the item should be hidden

  and SHOW means that the item should be shown.  These states are reversed when the group

  ceases to be active.  HIDE is used for the fixed sidebar pointer that belongs to the page.



*/



var PROJECTBOX_MILLISECONDS = 1000



var HORIZONTAL = 0;

var VERTICAL = 1;

// TODO: startX and startY should come from stylesheet

function NavItemGroup(name, axis, spacing) {

	this.name = name;	// for use when tracing

	this.axis = axis;

	this.spacing = spacing;

	this.visibility = "hidden";

	this.countdown = 0;

	this.items = new Array();

	for (var i = 3; i < arguments.length; i++)

		this.items.push(arguments[i]);

}



var MENUS = "";	// declare here so can tell if not set; gets redeclared at foot of page

var RELATIVE_PATH_LEADIN = ""; // or "../" for sibling folder



var MOVE = 0;

var HIDE = 1;

var SHOW = 2;

function NavItem(behaviour, name, dynamic) {

	this.behaviour = behaviour;

	this.name = name;

	this.dynamic = dynamic;	// = content is dynamically generated, changes as item moves

	this.startX = -1;	// signal to showNavGroup to set value

	this.startY = -1;

}



var amount = 70;

//if (site_id == 2) NAVITEMS[0].spacing = 50; <- can't do this here as site_id not loaded yet

// therefore do it in js injected by TopMenu.ascx.cs

var NAVITEMS = new Array(	// TODO: 50 works for AT but not RHWL

	new NavItemGroup("TopSubMenu", HORIZONTAL, 70, // the items that appear below the top menu items

	//	new NavItem(SHOW, "MyTopMenu_navRollover01", false), 

		new NavItem(MOVE, "navRollover02", true)

		),

	new NavItemGroup("SideProjectBox", VERTICAL, 18, // the moving projectbox hides the sidebar pointer

		new NavItem(MOVE, "subNavRollover01", false), 

		new NavItem(HIDE, "subNavLine01", false),

		new NavItem(HIDE, "subNavDot01", false)

		),

	new NavItemGroup("SidePointer", VERTICAL, 18, // the pointer that identifies the current sidebar item

		new NavItem(MOVE, "subNavLine01", false),

		new NavItem(MOVE, "subNavDot01", false)

		)

	);

var TOPSUBMENU = 0;

var SIDEPROJECTBOX = 1;

var SIDEPOINTER = 2;

var TOPPROJECTBOX = 3;



// set to menu position in array when user clicks on a top menu item

var TOPMENUCLICKITEM = -1;



// these get set when mouseover on side menu, in case project is then selected

var ProjectMenuId = 0;

var ProjectItemId = 0;



function showNavGroup(groupNo, pos, content) {

	if (groupNo >= NAVITEMS.length) return;

	var i;

	var group = NAVITEMS[groupNo];

	stopCountdown(groupNo);

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

		var item = group.items[i];

		var obj = getStyleObject(item.name);

		// if startX and startY have not been set yet, do it now

		if (item.startX == -1)

			item.startX = toPixels(getElementStyle(item.name, 'left', 'left'));

		if (item.startY == -1)

			item.startY = toPixels(getElementStyle(item.name, 'top', 'top'));

		var newX = item.startX;

		var newY = item.startY;

		trace(item.name + ' start (' + newX + ',' + newY + ')');

		if (item.dynamic) getObject(item.name).innerHTML = content.toHTML();

		switch (item.behaviour) {

		case MOVE:

			// BUG: this only picks up gap before current item; what if earlier items have gaps?

			// e.g. both SEARCH and RHWL PROJECTS have gaps on ARTSTEAM sidebar

			if (group.axis == HORIZONTAL)

			{

				newX += (pos  * group.spacing) + content.gapBefore;

			}

			else

			{

				newY += (pos  * group.spacing) + content.gapBefore;

			}

			// alert("move " + item.name + " to (" + newX + "," + newY + ")");

			obj.left = newX;

			obj.top = newY;

			trace(item.name + ' to (' + newX + ',' + newY + ')');

			obj.visibility = "visible";

			break;

		case HIDE:

			obj.visibility = "hidden";

			break;

		case SHOW:

			obj.visibility = "visible";

			break;

		}

	}

}



function hideNavGroup(groupNo) {

	var i;

	var group = NAVITEMS[groupNo];

	trace('hideNavGroup ' + group.name);

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

		var item = group.items[i];

		var styleObject = getStyleObject(item.name);

		if (styleObject)

			styleObject.visibility = "hidden"; //(item.behaviour == HIDE ? "visible" : "hidden");

	}

	// no, no, no = out of memory!!!! positionSideBarPointer();

	if (groupNo == SIDEPROJECTBOX) positionSideBarPointer();

}



function startCountdown(groupNo) {

	var g = NAVITEMS[groupNo];

	if (g)

	{

		trace('startCountDown ' + g.name);

		NAVITEMS[groupNo].countdown = setTimeout("hideNavGroup(" + groupNo + ")", PROJECTBOX_MILLISECONDS);

	}

}



function stopCountdown(groupNo) {

	var g = NAVITEMS[groupNo];

	if (g)

	{

		var name = g.name;

		trace('stopCountDown ' + name);

		if (g.countdown != 0)

		{ 

			clearTimeout(g.countdown);

			trace('clearTimeOut ' + name);

		}

	}

}



function getProject(projectId)

{

	var f = document.forms[0];

	f.menu_id.value = ProjectMenuId;

	f.item_id.value = ProjectItemId;

	f.project_id.value = projectId;

	// We don't want a querystring to show in the url.

	// Because the project id and page are actually insufficient to determine

	// what to display (the project might belong to > 1 sector),

	// we really ought to be moving the parameters to hidden form fields but

	// this will be added later when the relevant handling code exists.

	var qPos = f.action.indexOf("?");

	if (qPos >= 0)

		f.action = f.action.substr(0, qPos);

	f.submit();

}

function getMenuItem(menuId, itemId, projectId)

{

	// this is like getProject but it is for use by the top Sub Menu, when there

	// is either no project or we want the first project in the project box.

	var f = document.forms[0];

	f.menu_id.value = menuId;

	f.item_id.value = itemId;

	f.project_id.value = projectId;

	var qPos = f.action.indexOf("?");

	if (qPos >= 0)

		f.action = f.action.substr(0, qPos);

	f.submit();

}

function ProjectBoxInnerHTML() {

	var sep = '<span class="subNavBreak">&nbsp;|&nbsp;</span>';

	var ret = "";

	for (var i=0; i < this.project.length; i++)

	{

		if (i>0) ret += sep;

		ret += projectSpan(this, i);

	}

	trace(ret);

	return ret;

}



// nb we do not pass individual project as we need the ordinal for the span style.

// Believe it or not, the styles do differ in that they have different padding values.

function projectSpan(pBox, i) {

	if (i >= pBox.project.length) return '';

	// class subNavItem01 for first, 03 for last, 02 for middle (s/b) just one

	var classNo;

	if (i == 0)

		classNo = "1";

	else if (i == pBox.project.length-1)

		classNo = "3";

	else

		classNo = "2";

	var myProject = pBox.project[i];

	var ret = '<span class="subNavItem0' + classNo + '"><a class="subNav" href="JavaScript:getProject(' + myProject.id + ');" alt="" onmouseover="return projectStatus(\'' + myProject.name.replace(/'/g, '\\\'') + '\')">' + myProject.name.replace(/ /g, "&nbsp;") + '</a>';

	if (myProject.location.length > 0)

		ret += '&nbsp;' + myProject.location.replace(/ /g, "&nbsp;") + '</span>';

	return ret; // .replace(/ /g, '&nbsp;');

}



function projectStatus(projectName)

{

	window.status = projectName;

	return true;

}

function Project(id, name, location) {

	this.id = id;

	this.name = name;

	this.location = location;

}



function ProjectBox(category, gapBefore) {

	this.category = category;

	this.gapBefore = gapBefore;

	// note that Jane sez every project box should have exactly 3 projects; we allow any # here

	this.project = new Array();

	for (var i = 2; i < arguments.length; i++)

		this.project.push(arguments[i]);

	// method

	this.toHTML = ProjectBoxInnerHTML;

}

/*

	<div class="subNavItem01">

		<a class="subNav" href="xxx.asp">our approach</a> 

		<br>

		<a class="subNav" href="xxx.asp">our teams</a> 

		<br>

		<a class="subNav" href="xxx.asp">clients</a>

	</div>

*/

function MenuInnerHTML() {

	if (this.menuItem.length == 1) return '';

	var ret = '<div class="subNavItem01">';

	var menu_id = this.menuItem[0].id;

	for (var i = 1; i < this.menuItem.length; i++) {

		var item = this.menuItem[i];

		if (!item.notOnTop)

		{

			if (i > 1) ret += '<br>';

			var project_id = 0;

			if (item.project.length > 0) 

			{

				project_id = item.project[0].id;

			}

			// use following if we decide to go back to using virtual url instead of submit

			ret += '<a class="subNav" href="' + item.url + '" onMouseOver="return subMenuMouseOver(this, ' + (i-1) + ');" onMouseOut="return subMenuMouseOut(this, ' + (i-1) + ');">' + item.name.replace(/ /g, "&nbsp;") + '</a>';

			// use following if we decide to go back to using submit instead of virtual url

			// ret += '<a class="' + item.cssClass + '" href="javascript:getMenuItem(' + menu_id + ', ' + item.id + ', ' + project_id + ')" onMouseOver="return subMenuMouseOver(this, ' + (i-1) + ');" onMouseOut="return subMenuMouseOut(this, ' + (i-1) + ');">' + item.name + '</a>';

		}

	}

	ret += '</div>';

	return ret;

}

function xMenuInnerHTML() {

	var ret = '<span class="navItem">';

	var menu_id = this.menuItem[0].id;

	for (var i = 1; i < this.menuItem.length; i++) {

		var item = this.menuItem[i];

		if (!item.notOnTop)

		{

			if (i > 1) ret += '<br>';

			var project_id = 0;

			if (item.project.length > 0) 

			{

				project_id = item.project[0].id;

			}

			// use following if we decide to go back to using virtual url instead of submit

			ret += '<a class="' + item.cssClass + '" href="' + item.url + '" onMouseOver="return subMenuMouseOver(this, ' + (i-1) + ');" onMouseOut="return subMenuMouseOut(this, ' + (i-1) + ');">' + item.name.replace(/ /g, "&nbsp;") + '</a>';

			// use following if we decide to go back to using submit instead of virtual url

			// ret += '<a class="' + item.cssClass + '" href="javascript:getMenuItem(' + menu_id + ', ' + item.id + ', ' + project_id + ')" onMouseOver="return subMenuMouseOver(this, ' + (i-1) + ');" onMouseOut="return subMenuMouseOut(this, ' + (i-1) + ');">' + item.name + '</a>';

		}

	}

	ret += '</span>';

	return ret;

}



function MenuItem(id, name, imageName, url, cssClass, gapBefore, notOnTop) 

{

	this.id = id;

	this.name = name;

	this.imageName = imageName;

	this.url = url;

	this.gapBefore = gapBefore;

	this.cssClass = cssClass;

	this.notOnTop = notOnTop;

	this.project = new Array;

	for (var i = 7; i < arguments.length; i++)

		this.project.push(arguments[i]);

}



function Menu() {

	this.menuItem = new Array;

	this.gapBefore = 0;	// not assigned right now; expected by showNavGroup

	for (var i = 0; i < arguments.length; i++)

		this.menuItem.push(arguments[i]);

	this.toHTML = MenuInnerHTML;

}



// Handlers for events in Rhwl.aspx, ArtsTeam.aspx





function sideBarMouseOver(o, i) {

	trace('sideBarMouseOver ' + i);

	if (MENUS == "") return false;	// page has not loaded yet!

	var menuItem = MENUS[SELECTEDMENU].menuItem[i+1];

	var pBox = menuItemProjectBox(menuItem);

	showNavGroup(1, i, pBox);

	// we do this so that if project is selected, postback also sets correct menu and item.

	// However, we defer setting the form hidden fields until we know that we are posting 

	// back as a consequence of having selected a project.

	// var f = document.forms[0];

	ProjectMenuId = MENUS[SELECTEDMENU].menuItem[0].id;

	ProjectItemId = menuItem.id;

	window.status = menuItem.name;

	//o.alt = pBox.category;

	//o.title = pBox.category;

	return true;

}



function menuItemProjectBox(item)

{

//	alert("new project box: " + item.name);

	var pBox = new ProjectBox(item.name, item.gapBefore);

	for (var i=0; i<item.project.length; i++)

	{

		pBox.project.push(item.project[i]);

	}

	return pBox;

}



function sideBarMouseOut() {

	trace('sideBarMouseOut');

	startCountdown(1);

	window.status = '';

	return true;

}



function topMenuMouseClick(o, i) {

	var menu = MENUS[i];

	var item = menu.menuItem[0]; // every menu should have a zero MenuItem element

	TOPMENUCLICKITEM = i;	// so we know which menuitem we are on in topsubmenu handler

	showNavGroup(TOPSUBMENU, i, menu);

	window.status = item.name;

}



function topMenuMouseOver(o, i) {

	trace('topMenuMouseOver ' + i);

	var menu = MENUS[i];

	var item = menu.menuItem[0]; // every menu should have a zero MenuItem element

	window.status = item.name;	

	topMenuMouseClick(o, i);	// NEW: mouse over should show menu items

	return true;

}



function topMenuMouseOut(o, i) {

	trace('topMenuMouseOut ' + i);

	var menu = MENUS[i];

	startCountdown(TOPSUBMENU);

	o.src = RELATIVE_PATH_LEADIN + "pics/" + menu.menuItem[0].imageName + "_01.gif"

	return true;

}



function topImageMouseOver(o, i) {

	trace('topImageMouseOver ' + i);

	var menu = MENUS[i];

	var item = menu.menuItem[0]; // every menu should have a zero MenuItem element

	o.src = RELATIVE_PATH_LEADIN + "pics/" + item.imageName + "_03.gif"

}



function topImageMouseOut(o, i) {

	trace('topMenuMouseOut ' + i);

	var menu = MENUS[i];

	o.src = RELATIVE_PATH_LEADIN + "pics/" + menu.menuItem[0].imageName + "_01.gif"

	window.status = '';

}



function subMenuMouseOver(o, i) {

	trace('subMenuMouseOver ' + i);

	stopCountdown(TOPSUBMENU);

	var menuItem = MENUS[TOPMENUCLICKITEM].menuItem[i+1];

	// The check to see if menuItem is instantiated fixes the error message that

	// would otherwise occur on the following line; however, for all subsequent

	// subMenuMouseOvers menuItem remains uninstantiated.

	// NB error is: name is null or not an object

	// if (!menuItem) return false;	// because sometimes it is null

	ProjectMenuId = MENUS[TOPMENUCLICKITEM].menuItem[0].id;

	ProjectItemId = menuItem.id;

	window.status = menuItem.name;		

	var pBox = menuItemProjectBox(menuItem);

	if (pBox.project.length > 0)

	{ 

		stopCountdown(TOPPROJECTBOX);

		showNavGroup(3, i, pBox);

	}

	else

		startCountdown(TOPPROJECTBOX);

	return true;

}



function subMenuMouseOut(o, i) {

	trace('subMenuMouseOut ' + i);

	//startCountdown(TOPSUBMENU);

	startCountdown(TOPPROJECTBOX);

	window.status = '';

	return true;

}



function topProjectBoxMouseOver()

{

	trace('topProjectBoxMouseOver');

	stopCountdown(TOPPROJECTBOX);

	stopCountdown(TOPSUBMENU);

}

function topProjectBoxMouseOut()

{

	trace('topProjectBoxMouseOut');

	startCountdown(TOPPROJECTBOX);

	startCountdown(TOPSUBMENU);

}



function sideProjectBoxMouseOver()

{

	trace('sideProjectBoxMouseOver');

	stopCountdown(SIDEPROJECTBOX);

}

function sideProjectBoxMouseOut()

{

	trace('projectBoxMouseOut');

	startCountdown(SIDEPROJECTBOX);

}



function toPixels(s)

{

	// given e.g. "128px" returns 128

	if (s.length > 2 && s.substr(s.length-2) == 'px') return s.substr(0, s.length-2)*1;

	if (s.length == 0) return 0;

	return s*1;

}

// to trace add this to bottom of masterlayup.aspx form

// <p align=right><textarea id="tracer" rows="40" cols="60"></textarea></p>



function trace(s)

{

	var t = document.getElementById("tracer");

	if (t != null)

		t.value = s + '\n' + t.value;

}

// should be injected by search.aspx

function showStageOptions(categoryList)

{

	id = categoryList.selectedIndex;

	flags = SEARCHFLAGS.substr(id,1);

	showSeating = (flags & 2);

	showStageType = (flags & 1);

	getObject("message").style.visibility = (showSeating || showStageType ? "visible": "hidden");

	getObject("seatingCapacitySection").style.visibility = showSeating ? "visible": "hidden";

	getObject("stageTypeSection").style.visibility = showStageType ? "visible": "hidden";

	// ensure that hidden drop downs have Any item selected

	if (!showSeating)

		getObject("Content_seating").selectedIndex = 0;

	if (!showStageType)

		getObject("Content_stageType").selectedIndex = 0;

}

