/* Drop down/ Overlapping Content script

Description: 
This script lets you display content in tight areas on your page, by dropping it down into view when the mouse rolls over the anchor element. The content temporarily overlaps anything beneath it. Think of it as adding another dimension to your webpage to create more space. It's extremely handy for displaying search boxes, additional links etc in a tight area, such as the sidebar column of a page. The content to reveal/ overlap in each case is simply contained inside an arbitrary DIV on the page for easy customizing. A quick overview:

Drop Down Content can be revealed either via onclick of the anchor link, or onmouseover instead. Independent setting for each anchor link. 
Set whether Drop Down Content itself should automatically hide after the user rolls his mouse out of it. Global setting inside .js file. 
For the content within Drop Down Content, it can either be inline, or fetched from an external file on your server via Ajax instead. 

Drop Down Content supports four different position orientations:
"left-bottom", "right-bottom", "left-top", and "right-top". 

The  speed of the drop down reveal can also be customized. 
	**Updated: Dec 19th, 07': Added ability to dynamically populate a Drop Down content using an external file (Ajax feature)
	**Updated: Feb 29th, 08':
		1) Added ability to reveal drop down content via "click" of anchor link (instead of default "mouseover")
		2) Added ability to disable drop down content from auto hiding when mouse rolls out of it
		3) Added hidediv(id) public function to directly hide drop down div dynamically
				
<!--Example #1: -->
	<p>Demo #1: <a href="http://www.dynamicdrive.com" id="searchlink" rel="subcontent">Search DD</a></p>

	<DIV id="subcontent" style="position:absolute; visibility: hidden; border: 9px solid orange; background-color: white; width: 300px; padding: 8px;">
	
	<p><b>Search Dynamic Drive:</b></p>
	<form method="get" action="http://search.freefind.com/find.html" id="topform">
	<input name="query" maxlength="255" style="width: 150px" id="topsearchbox" alt="Search" /> 
	<input value="Search" class="topformbutton" type="submit" />
	</form>
	
	<div align="right"><a href="javascript:dropdowncontent.hidediv('subcontent')">Hide this DIV manually</a> | <a href="http://www.dynamicdrive.com">Dynamic Drive</a></div>
	
	
	</DIV>
	
<!--Example #2: content fetched via Ajax, activated onclick -->
	
	<p align="right" style="margin-top: 400px">Demo #2 (click): <a href="http://www.dynamicdrive.com/resources/" id="contentlink" rel="subcontent2">Additional Resources</a> </p>
	
	
	<DIV id="subcontent2" style="position:absolute; visibility: hidden; border: 9px solid black; background-color: lightyellow; width: 350px; height: 120px; padding: 4px;">
	
	<div style="width: 49%; float: left">
	<ul>
	<li><a href="http://www.dynamicdrive.com">Dynamic Drive</li>
	<li><a href="http://www.javascriptkit.com">JavaScript Kit</li>
	<li><a href="http://www.cssdrive.com">CSS Drive</li>
	<li><a href="http://www.codingforums.com">Coding Forums</li>
	</ul>
	</div>
	
	<div style="width: 49%; float: left">
	<ul>
	<li><a href="http://www.cnn.com">CNN</li>
	<li><a href="http://www.msnbc.com">MSNBC</li>
	<li><a href="http://www.news.bbc.co.uk">BBC News</li>
	<li><a href="http://www.slashdot.org">Slashdot</li>
	</ul>
	</div>
	
	<div align="right"><a href="javascript:dropdowncontent.hidediv('subcontent2')">Hide this DIV manually</a></div>
	
	</DIV>
	
	<script type="text/javascript">
	//Call dropdowncontent.init("anchorID", "positionString", glideduration, "revealBehavior") at the end of the page:
	
	dropdowncontent.init("searchlink", "right-bottom", 500, "mouseover")
	dropdowncontent.init("contentlink", "left-top", 300, "click")
	
	</script>
*/

var dropdowncontent={
	disableanchorlink: true, //when user clicks on anchor link, should link itself be disabled (always true if "revealbehavior" above set to "click")
 hidedivmouseout: [true, 200], //Set hiding behavior within Drop Down DIV itself: [hide_div_onmouseover?, miliseconds_before_hiding]
	ajaxloadingmsg: "Loading content. Please wait...", //HTML to show while ajax page is being feched, if applicable
	ajaxbustcache: true, //Bust cache when fetching Ajax pages?

	getposOffset:function(what, offsettype){
		return (what.offsetParent)? what[offsettype]+this.getposOffset(what.offsetParent, offsettype) : what[offsettype]
	},

	isContained:function(m, e){
		var e=window.event || e
		var c=e.relatedTarget || ((e.type=="mouseover")? e.fromElement : e.toElement)
		while (c && c!=m)try {c=c.parentNode} catch(e){c=m}
		if (c==m)
			return true
		else
			return false
	},

	show:function(anchorobj, subobj, e){
		if (!this.isContained(anchorobj, e)){
			var e=window.event || e
			if (e.type=="click" && subobj.style.visibility=="visible"){
				subobj.style.visibility="hidden"
				return
			}
			var horizontaloffset=(subobj.dropposition[0]=="left")? -(subobj.offsetWidth-anchorobj.offsetWidth) : 0 //calculate user added horizontal offset
			var verticaloffset=(subobj.dropposition[1]=="top")? -subobj.offsetHeight : anchorobj.offsetHeight //calculate user added vertical offset
			subobj.style.left=this.getposOffset(anchorobj, "offsetLeft") + horizontaloffset + "px"
			subobj.style.top=this.getposOffset(anchorobj, "offsetTop")+verticaloffset+"px"
			subobj.style.clip=(subobj.dropposition[1]=="top")? "rect(auto auto auto 0)" : "rect(0 auto 0 0)" //hide drop down box initially via clipping
			subobj.style.visibility="visible"
			subobj.startTime=new Date().getTime()
			subobj.contentheight=parseInt(subobj.offsetHeight)
			if (typeof window["hidetimer_"+subobj.id]!="undefined") //clear timer that hides drop down box?
				clearTimeout(window["hidetimer_"+subobj.id])
			this.slideengine(subobj, (subobj.dropposition[1]=="top")? "up" : "down")
		}
	},

	curveincrement:function(percent){
		return (1-Math.cos(percent*Math.PI)) / 2 //return cos curve based value from a percentage input
	},

	slideengine:function(obj, direction){
		var elapsed=new Date().getTime()-obj.startTime //get time animation has run
		if (elapsed<obj.glidetime){ //if time run is less than specified length
			var distancepercent=(direction=="down")? this.curveincrement(elapsed/obj.glidetime) : 1-this.curveincrement(elapsed/obj.glidetime)
			var currentclip=(distancepercent*obj.contentheight)+"px"
			obj.style.clip=(direction=="down")? "rect(0 auto "+currentclip+" 0)" : "rect("+currentclip+" auto auto 0)"
			window["glidetimer_"+obj.id]=setTimeout(function(){dropdowncontent.slideengine(obj, direction)}, 10)
		}
		else{ //if animation finished
			obj.style.clip="rect(0 auto auto 0)"
		}
	},

	hide:function(activeobj, subobj, e){
		if (!dropdowncontent.isContained(activeobj, e)){
			window["hidetimer_"+subobj.id]=setTimeout(function(){
				subobj.style.visibility="hidden"
				subobj.style.left=subobj.style.top=0
				clearTimeout(window["glidetimer_"+subobj.id])
			}, dropdowncontent.hidedivmouseout[1])
		}
	},

	hidediv:function(subobjid){
		document.getElementById(subobjid).style.visibility="hidden"
	},

	ajaxconnect:function(pageurl, divId){
		var page_request = false
		var bustcacheparameter=""
		if (window.XMLHttpRequest) // if Mozilla, IE7, Safari etc
			page_request = new XMLHttpRequest()
		else if (window.ActiveXObject){ // if IE6 or below
			try {
			page_request = new ActiveXObject("Msxml2.XMLHTTP")
			} 
			catch (e){
				try{
				page_request = new ActiveXObject("Microsoft.XMLHTTP")
				}
				catch (e){}
			}
		}
		else
			return false
		document.getElementById(divId).innerHTML=this.ajaxloadingmsg //Display "fetching page message"
		page_request.onreadystatechange=function(){dropdowncontent.loadpage(page_request, divId)}
		if (this.ajaxbustcache) //if bust caching of external page
			bustcacheparameter=(pageurl.indexOf("?")!=-1)? "&"+new Date().getTime() : "?"+new Date().getTime()
		page_request.open('GET', pageurl+bustcacheparameter, true)
		page_request.send(null)
	},

	loadpage:function(page_request, divId){
		if (page_request.readyState == 4 && (page_request.status==200 || window.location.href.indexOf("http")==-1)){
			document.getElementById(divId).innerHTML=page_request.responseText
		}
	},

 init:function(anchorid, pos, glidetime, revealbehavior){
		var anchorobj=document.getElementById(anchorid)
		var subobj=document.getElementById(anchorobj.getAttribute("rel"))
		var subobjsource=anchorobj.getAttribute("rev")
		if (subobjsource!=null && subobjsource!="")
			this.ajaxconnect(subobjsource, anchorobj.getAttribute("rel"))
		subobj.dropposition=pos.split("-")
		subobj.glidetime=glidetime || 1000
		subobj.style.left=subobj.style.top=0
		if (typeof revealbehavior=="undefined" || revealbehavior=="mouseover"){
			anchorobj.onmouseover=function(e){dropdowncontent.show(this, subobj, e)}
			anchorobj.onmouseout=function(e){dropdowncontent.hide(subobj, subobj, e)}
			if (this.disableanchorlink) anchorobj.onclick=function(){return false}
		}
		else
			anchorobj.onclick=function(e){dropdowncontent.show(this, subobj, e); return false}
		if (this.hidedivmouseout[0]==true) //hide drop down DIV when mouse rolls out of it?
			subobj.onmouseout=function(e){dropdowncontent.hide(this, subobj, e)}
	}
}
