// UTILITY FUNCTIONS, ALSO USED IN EXTERNAL FILES
//------------------------------------------------------------------------------

function addEvent(obj, type, fn) // - requires above EventCache var
{
	if(obj.addEventListener)					// standards
		{
		if(obj == window && type == 'load')
			{obj.addEventListener('DOMContentLoaded', fn, false);}	// using faster modern DOM loaded event
		else
			{obj.addEventListener(type, fn, false);}
		}
	else										// IE
		{
		obj["e"+type+fn] = fn;
		obj[type+fn] = function() {obj["e"+type+fn]( window.event );}
		obj.attachEvent("on"+type, obj[type+fn]);
		}
}

function removeEvent(obj, type, fn)
{
	if(obj.removeEventListener)							// standards
		{obj.removeEventListener(type, fn, false);}
	else												// IE
		{
		obj.detachEvent("on"+type, obj[type+fn]);
		obj[type+fn] = null;
		}
}

function purge(obj)									// recursively attempt to do some IE garbage collection on unload
{
	if(obj)
		{elem = obj}
	else
		{elem = window}

    var a = elem.attributes, i, Z, n;
    if (a)
    	{
        Z = a.length-1;
        for(var i=Z; i>=0;i--)
        	{
            n = a[i].name;
            if (typeof elem[n] === 'function')
            	{elem[n] = null;}
	        }
	    }

    a = elem.childNodes;
    if (a)
    	{
        Z = a.length-1;
        for(var i=Z; i>=0;i--)
        	{purge(elem.childNodes[i]);}
	    }
}

function findThis(e)
{
	if(!e)
		{var e = window.event;}

	if(e.target)			// standards
		{var obj = e.target;}
	else if(e.srcElement)	// IE
		{var obj = e.srcElement;}

	return obj;
}

function preventDef(e)
{
	e = e || event;

	if(e.preventDefault)			// standards
		{e.preventDefault();}
	else
		{e.returnValue = false;}	// IE
}

function stopProp(e)
{
	e = e || event;

	if (e.stopPropagation)			// standards
		{e.stopPropagation();}
	else
		{e.cancelBubble = true;}	// IE
}

function DOMfind(selector, DOMtype)
{
	if (document.querySelectorAll)
		{
		if(DOMtype == 'id')
			{return document.querySelector(selector)}
		else
			{return document.querySelectorAll(selector)}
		}

	if(DOMtype == 'tag')
		{return document.getElementsByTagName(selector)}

	if(DOMtype == 'id')
		{selector = selector.replace('#', '')
		return document.getElementById(selector)}

	if(document.getElementsByClassName && DOMtype == 'DOMclass')
		{selector = selector.replace('.', '')
		return document.getElementsByClassName(selector)}

	if(DOMtype == 'DOMclass')
		{
		selector = selector.replace('.', '')

		var children = document.body.getElementsByTagName('*');
		var elems = [];
		var A = children.length;
		for (var i=0; i<A; i++)
			{
			if(children[i].className == selector || children[i].className.match(selector + ' ') || children[i].className.match(' ' + selector))
				{elems.push(children[i]);}
			}

		return elems;
		}
}

function insertAfter(refNode,newNode)
	{refNode.parentNode.insertBefore(newNode,refNode.nextSibling);}

function newClass(elem, newclass)
	{
	if (document.documentElement.classList)		// new HTML5 API
		{elem.classList.add(newclass)}

	else if(!(elem.className.match(newclass)))
		{elem.className = elem.className + ' ' + newclass}
	}

function removeClass(elem, remclass)
	{
	if (document.documentElement.classList)		// new HTML5 API
		{elem.classList.remove(remclass)}
	else
		{elem.className = elem.className.replace(remclass,'');}
	}

function createXMLHttpRequest()		// generic asynchronous requests
{
	try {return new XMLHttpRequest();} catch(e) {}
	try {return new ActiveXObject("Msxml2.XMLHTTP.6.0");} catch (e) {}
	return null;
}

function parseQ(para)			// parse querystring for value attached to 'para'meter
{
	para = para.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");

	var regexS = "[\\?&]"+para+"=([^&#]*)";
	var regex = new RegExp(regexS);
	var results = regex.exec(window.location.search);

	if(results == null)
		{return "";}
	else
		{return results[1];}
}

addEvent(window, 'load', initShowHide);		// expand/collapse functionality; used in FAQ, Product Description
addEvent(window, 'load', initSearchvalues);	// removes 'Search' text from inside site / carehomes search boxes when focused
addEvent(window, 'load', ajaxTabs); 		// used to provide AJAX loading on tabbed content
addEvent(window, 'load', bubbleText);		// used on Carehomes homeInfo portlet to show/hide info bubbles
addEvent(window, 'load', ajaxAddShort);		// used on Carehomes M57 Tools module to update user's shortlist

if(document.all && !window.opera)
	{addEvent(window, 'unload', purge);}	// attempt to do some IE garbage collection on unload

//-------------------------------------

function initShowHide()
{
	if(DOMfind('.FAQcategorySelector', 'DOMclass'))
		{
		var FAQcats = DOMfind('.FAQcategorySelector', 'DOMclass');	//---- FAQ category holder
		var A = FAQcats.length-1

		for(var i=A; i>=0;i--)
			{
			var FAQkids = FAQcats[i].childNodes;
			var B = FAQkids.length

			for(var j=0; j<B; j++)
				{
				var kid = FAQkids[j];
				if(kid.nodeType == 1 && kid.nodeName == 'OL')										// --- find FAQ category lists
					{
					kid.parentNode.FAQlist = [];
					var qscount = 0;
					var Z = kid.childNodes.length

					for(var k=0; k<Z; k++)
						{
						var grandkid = kid.childNodes[k];

						if(grandkid.nodeType == 1 && grandkid.nodeName == 'LI')
							{
							kid.parentNode.FAQlist.push(grandkid);
							qscount++;
							if(qscount > 3)		// --- ignore first three questions
								{newClass(grandkid, 'hidden')}
							}
						}
					}

				else if(kid.nodeType == 1 && kid.nodeName == 'P' && kid.className.match('seeAll') && qscount > 3)	// --- find See All holder where we have more than 3 questions
					{
					var C = kid.childNodes.length-1

					for(var k=C; k>=0; k--)
						{
						if(kid.childNodes[k].nodeType == 1 && kid.childNodes[k].nodeName == 'SPAN')
							{
							var clickspan = kid.childNodes[k];
							kid.clickspan = clickspan;
							removeClass(clickspan, 'hidden');
							newClass(clickspan, 'collapsed');
							break;
							}
						}
					addEvent(kid, 'click', toggleShowHideCats);
					}
				}
			}
		}

	if(DOMfind('.FAQ', 'DOMclass'))											//---- FAQ question lists
		{
		var FAQqs = DOMfind('.FAQ', 'DOMclass');
		var A = FAQqs.length-1

		for(var i=A; i>=0; i--)
			{
			var FAQqskids = FAQqs[i].childNodes;
			var dtcount = 0;
			var Z = FAQqskids.length

			for(var j=0; j<Z; j++)
				{
				var kid = FAQqskids[j];

				if(kid.nodeType == 1 && kid.nodeName == 'DT')
					{
					dtcount++;
					addEvent(kid, 'click', toggleShowHide);

					if(dtcount == 1 && i == 0)		// --- first question
						{newClass(kid, 'expanded')}
					else
						{newClass(kid, 'collapsed')}

					var grandkids = kid.childNodes;
					var Y = grandkids.length

					for(var k=0; k<Y; k++)
						{
						if (grandkids[k].nodeType == 1 && grandkids[k].nodeName == 'SPAN')
							{
							kid.clickspan = grandkids[k];

							if(dtcount == 1 && i == 0)
								{grandkids[k].innerHTML = 'Hide'}
							else
								{grandkids[k].innerHTML = 'Show'}
							break;
							}
						}
					}

				else if(kid.nodeType == 1 && kid.nodeName == 'DD')
					{
					if(dtcount == 1 && i == 0)		// --- first answer
						{newClass(kid, 'expanded')}
					else
						{newClass(kid, 'collapsed')}
					}
				}
			}
		}

	if(DOMfind('.detailListing', 'DOMclass'))					//---- products / services listing div
		{
		var detailLs = DOMfind('.detailListing', 'DOMclass');
		var A = detailLs.length-1

		for(var i=A; i>=0; i--)
			{
			newClass(detailLs[i], 'collapsed');
			detailLs[i].prodItems = [];
			var detailLskids = detailLs[i].childNodes;
			var B = detailLskids.length-1

			for(var j=B; j>=0; j--)
				{
				var kid = detailLskids[j];

				if(kid.nodeType == 1 && kid.nodeName == 'H2')
					{
					addEvent(kid, 'click', toggleWholeList);

					var grandkids = kid.childNodes;
					var C = grandkids.length-1

					for(var k=C; k>=0; k--)
						{
						if(grandkids[k].nodeType == 1 && grandkids[k].nodeName == 'SPAN')
							{
							kid.clickspan = grandkids[k]
							break;
							}
						}
					break;
					}

				else if(kid.nodeType == 1 && kid.nodeName == 'DL')
					{
					newClass(kid, 'collapsed');

					var prodIts = kid.childNodes;
					var dtcount = 0;
					var Z = prodIts.length

					for(var k=0; k<Z; k++)
						{
						if(prodIts[k].nodeType == 1 && prodIts[k].nodeName == 'DT')
							{
							var prdt = prodIts[k];
							dtcount++;
							detailLs[i].prodItems.push(prdt);

							addEvent(prdt, 'click', toggleShowHide);

							if(dtcount == 1)
								{newClass(prdt, 'expanded')}
							else
								{newClass(prdt, 'collapsed')}

							var dtkids = prdt.childNodes;
							var Y = dtkids.length

							for(var m=0; m<Y; m++)
								{
								if (dtkids[m].nodeType == 1 && dtkids[m].nodeName == 'SPAN' && dtkids[m].className.match('showhide'))
									{
									prdt.clickspan = dtkids[m];

									if(dtcount == 1)
										{dtkids[m].innerHTML = 'Hide'}
									else
										{dtkids[m].innerHTML = 'Show'}
									break;
									}
								}
							}

						else if(prodIts[k].nodeType == 1 && prodIts[k].nodeName == 'DD')
							{
							detailLs[i].prodItems.push(prodIts[k]);

							if(dtcount == 1)
								{newClass(prodIts[k], 'expanded')}
							else
								{newClass(prodIts[k], 'collapsed')}
							}
						}
					}
				}
			}
		}
}

function toggleShowHideCats()
{
	var FAQlist = this.parentNode.FAQlist;
	var Z = FAQlist.length;
	var clickspan = this.clickspan;

	if(clickspan.className.match('collapsed'))
		{
		for(var i=0; i<Z; i++)
			{removeClass(FAQlist[i], 'hidden')}
		clickspan.className = 'expanded';
		clickspan.innerHTML = 'Hide other questions';
		}
	else
		{
		for(var i=0; i<Z; i++)
			{
			if(i > 2)
				{newClass(FAQlist[i], 'hidden')}
			}
		clickspan.className = 'collapsed';
		clickspan.innerHTML = 'See all questions';
		}
}

function toggleShowHide()
{
	if(this.nextSibling.nodeType == 1)
		{var ans = this.nextSibling}
	else
		{var ans = this.nextSibling.nextSibling}

	if(this.className.match('collapsed'))
		{
		checkState(this, 'collapsed');
		checkState(ans, 'collapsed');
		this.clickspan.innerHTML = 'Hide';
 		}
	else
		{
		checkState(this, 'expanded');
		checkState(ans, 'expanded');
		this.clickspan.innerHTML = 'Show';
		}
}

function toggleWholeList()
{
	var detailLs = this.parentNode;

	if(detailLs.className.match('collapsed'))
		{
		checkState(detailLs, 'collapsed');
		this.clickspan.innerHTML = 'Hide all';
		detailLs.action = 'expand'
		}
	else
		{
		checkState(detailLs, 'expanded');
		this.clickspan.innerHTML = 'Show all';
		detailLs.action = 'collapse'
		};

	var A = detailLs.prodItems.length-1

	for(var i=A; i>=0; i--)
		{
		if(detailLs.action == 'expand')
			{
			checkState(detailLs.prodItems[i], 'collapsed');
			if(detailLs.prodItems[i].nodeType == 1 && detailLs.prodItems[i].nodeName == 'DT')
				{detailLs.prodItems[i].clickspan.innerHTML = 'Hide'}
			}
		else
			{
			checkState(detailLs.prodItems[i], 'expanded');
			if(detailLs.prodItems[i].nodeType == 1 && detailLs.prodItems[i].nodeName == 'DT')
				{detailLs.prodItems[i].clickspan.innerHTML = 'Show'}
			}
		};
}

function checkState(elem, currState)
{
	if(currState == 'expanded')
		{elem.className = elem.className.replace('expanded', 'collapsed')}
	else
		{elem.className = elem.className.replace('collapsed', 'expanded')}
}

//-------------------------------------

function initSearchvalues()
{
	if(DOMfind('#searchSite', 'id'))
		{
		var srch = DOMfind('#searchSite', 'id')
		addEvent(srch, 'focus', emptySearch)
		}

	if(DOMfind('#carehomeSrch', 'id'))
		{
		var srch = DOMfind('#carehomeSrch', 'id')
		addEvent(srch, 'focus', emptySearch)
		}

	if(DOMfind('#locationSrch', 'id'))
		{
		var srch = DOMfind('#locationSrch', 'id')
		addEvent(srch, 'focus', emptySearch)
		}
}

function emptySearch()
{
	this.value = ''
}

//-----------------------------------------------------

function ajaxTabs()
{
	if(DOMfind('#tabbedContent', 'id'))
		{
		var tabLinks = DOMfind('.bupaTab', 'DOMclass')
		var A = tabLinks.length
		var baselink = tabLinks[0].href
		var qStrng = baselink.indexOf('?');
		var newbaselink = baselink.substring(0, qStrng);

		for(var i=0; i<A; i++)
			{
			var tlink = tabLinks[i]
			tlink.ajLink = newbaselink + '?tab=' + i;
			tlink.allTabs = tabLinks
			addEvent(tlink, 'click', intercept)
			addEvent(tlink, 'click', preventDef)
			}
		}
}

function intercept()
{
	var thistab = this

	var request = createXMLHttpRequest()
	var cont  = DOMfind('#tabbedContent', 'id')

	request.open('GET', this.ajLink + '&ajaxFetch=true', true)

// request.open('GET', 'POC.html?' + '&ajaxFetch=true&nocache=', true)	// POC version

	request.onreadystatechange = function()
		{
		if (request.readyState == 4 && request.status == 200)
			{
			cont.innerHTML = request.responseText

			var tabs = thistab.allTabs
			var Z = tabs.length-1

			for(var i=Z; i>=0;i--)
				{
				// forcing repaint in IE
				/*@cc_on

					newClass(tabs[i].parentNode, 'redraw')
					removeClass(tabs[i].parentNode, 'redraw')

				@*/

				tabs[i].parentNode.parentNode.id = ''
				}

			thistab.parentNode.parentNode.id = 'current'

			// re-initialising functions that trigger on page load
			bubbleText()
			ajaxAddShort()
			restartGmap()
			}
		}
	request.send(null)

	var jsonReq = createXMLHttpRequest()

	jsonReq.open('GET', thistab.ajLink + '&jsonFetch=true', true)  // fetch JSON for Flash SWF parameters

// jsonReq.open('GET', 'JSONempty.txt?' + '&jsonFetch=true&nocache=', true)	// POC version

	jsonReq.onreadystatechange = function()
		{
		if (jsonReq.readyState == 4 && jsonReq.status == 200)
			{
			if(jsonReq.responseText && jsonReq.responseText.match('{'))
				{
				var regex = /<!--.+?-->/g;
				responseText = jsonReq.responseText.replace(regex,'');	// clean up Jahia's dodgy JSON output

				if(typeof JSON === 'object')					// check for native JSON
					{var flashParams = JSON.parse(responseText)}
				else
					{var flashParams = nnJSON.decode(responseText)}

				var Z = flashParams.flashinstances.length-1

				for(var i=Z; i>=0;i--)
					{restartSWF(flashParams.flashinstances[i])}
				}
			}
		}
	jsonReq.send(null)
}

function restartGmap()	// recursive function; repeats until Google Map is available
{
	if(recall)
		{clearTimeout(recall)}

	if(typeof(loadGmap) != 'undefined')
		{loadGmap();}
	else
		{
		if(!recall)
			{var recall = setTimeout(restartGmap(), 100)}
		}
}

function restartSWF(instance)	// recursive function; repeats until required id is available
{
	if(recall)
		{clearTimeout(recall)}

	if(DOMfind('#' + instance.flashid, 'id'))
		{
		var flashplayerpath = instance.flashPlayerPath;
		var flashvars = {title:'Bupa Advert', src:flashplayerpath, type:'video', preview:'#'};

		var source = instance.source;
		if (source == 'xml')
			{flashvars = {title:'Bupa Advert', xml:flashplayerpath, type:'video', preview:'#'};}

		var params = {};
		params.play = 'true';
		params.quality = 'high';
		params.scale = 'exactfit';
		params.bgcolor = '#ffffff';
		params.wmode= 'opaque';
		params.allowfullscreen = 'true';

		var attributes = {};

		var flash = swfobject.embedSWF(instance.flashpath, instance.flashid, instance.flashwidth, instance.flashheight, instance.flashver, false, flashvars, params, attributes)
		}
	else
		{
		if(!recall)
			{var recall = setTimeout(function(){restartSWF(instance)}, 100)}
		}
}

//--------------------------------------------------------

function bubbleText()
{
	if(DOMfind('.extraInfo', 'DOMclass'))
		{
		var bubPointer = document.createElement('img')
		bubPointer.src = '/bupastatic/images/icons/bubblePointer.png'
		bubPointer.className = 'pointer'
		bubPointer.alt = ''

		var bubClose = document.createElement('img')
		bubClose.src = '/bupastatic/images/icons/close.gif'
		bubClose.className = 'closer'
		bubClose.alt = ''

		var bubHeadTxt = document.createTextNode('Quick help')

		var bubHead = document.createElement('h4')
		bubHead.appendChild(bubHeadTxt)
		bubHead.appendChild(bubClose)

		var infLinks = DOMfind('.extraInfo', 'DOMclass')
		var bubbles = DOMfind('.bubbleText', 'DOMclass')
		var ddInc = -1

		var A = bubbles.length

		for(var i=0; i<A; i++)
			{
			var thisBbl = bubbles[i]
			var newPoint = bubPointer.cloneNode(true)
			thisBbl.insertBefore(newPoint, thisBbl.firstChild)

			var B = thisBbl.childNodes.length

			for(var j=0; j<B; j++)
				{
				var thisInner = thisBbl.childNodes[j]

				if(thisInner.nodeName == 'DIV')
					{
					var newHead = bubHead.cloneNode(true)
					thisInner.insertBefore(newHead, thisInner.firstChild)
					thisHead = thisInner.firstChild
					thisHead.lastChild.bubble = thisBbl
					addEvent(thisHead.lastChild, 'click', hideBubble)
					addEvent(thisHead.lastChild, 'click', stopProp)

					break;
					}
				}

			if(infLinks[i].nodeName == 'DT')
				{
				switch(ddInc)
					{
					case -1:
						infLinks[i].offset = 0
						break

					case 0:
						infLinks[i].offset = 1.7
						break

					case 1:
						infLinks[i].offset = 4.5
						break

					case 2:
						infLinks[i].offset = 7.55
						break
					}
				ddInc++
				}

			infLinks[i].bubble = bubbles[i]
			addEvent(infLinks[i], 'click', showBubble)
			addEvent(infLinks[i], 'click', stopProp)

			newClass(infLinks[i], 'jsAvail')
			}
		}
}

function showBubble()
{
	// fix for buggy IE z-index and redraw

	/*@cc_on

		var prevClicked = DOMfind('.IEredraw', 'DOMclass')
		var A = prevClicked.length

		for(var i=0; i<A; i++)
			{removeClass(prevClicked[i], 'IEredraw')}

		newClass(this, 'IEredraw')
		newClass(this.bubble.parentNode, 'IEredraw')

		stopProp()

	@*/

	if(this.offset)
		{this.bubble.style.top = this.offset + 'em'}

	var bubbles = DOMfind('.bubbleText', 'DOMclass')
	var A = bubbles.length

	for(var i=0; i<A; i++)
		{removeClass(bubbles[i], 'onScreen')}

	newClass(this.bubble, 'onScreen')
}

function hideBubble()
{
	// fix for buggy IE redraw

	/*@cc_on

		removeClass(this, 'IEredraw')
		removeClass(this.bubble.parentNode, 'IEredraw')

	@*/

	removeClass(this.bubble, 'onScreen')
}

//-------------------------------------

function ajaxAddShort()
{
	if(DOMfind('.addToList', 'DOMclass'))
		{
		var addShrts = DOMfind('.addToList', 'DOMclass')
		var Z = addShrts.length-1

		for(var i=Z; i>=0;i--)
			{
			addS = addShrts[i]

			var kids = addS.childNodes
			var Y = kids.length-1

			for(var j=Y; j>=0;j--)
				{
				if(kids[j].nodeName == 'A')
					{
					addS.link = kids[j]
					break
					}
				}
			addEvent(addS, 'click', updateShortlist)
			addEvent(addS.link, 'click', preventDef)
			}
		}
}

function updateShortlist()
{
	var request = createXMLHttpRequest()
	var thisAdd = this

	var ran = Math.floor(Math.random()*10000)

	request.open("GET", this.link.href + '&noCache=' + ran, true)
	request.onreadystatechange = function()
		{
		if (request.readyState == 4 && request.status == 200)
			{
			var response = request.responseText;
			if(response.match('success'))
				{
				thisAdd.className = 'addedToList'
				thisAdd.replaceChild(document.createTextNode('Added to shortlist'), thisAdd.link)
				removeEvent(thisAdd, 'click', updateShortlist)
				}
			else
				{
				newClass(thisAdd, 'error')
				thisAdd.replaceChild(document.createTextNode('Sorry, you can only add up to 20 care homes to your shortlist. There are ' + response + ' care homes in your shortlist already. Please deselect some care homes from your list below, or remove some from your shortlist before proceeding.'), thisAdd.link)
				removeEvent(thisAdd, 'click', updateShortlist)
				}
			}
		}
	request.send(null)
}