
Try = Object.extend(Try,{
  again: function() {
	var fn = function () {};
	var attempts = 12;
	var delay = 250;
	var hideerror = true;
	if (typeof arguments[0] == "string")
	{
		var str = arguments[0];
		fn = function () { eval(str); }
	} else
		fn = arguments[0];
	if (typeof arguments[1] != "undefined" && arguments[2] != null)
		attempts = arguments[1];
	if (typeof arguments[2] != "undefined" && arguments[2] != null)
		delay = arguments[2];
	if (typeof arguments[3] != "undefined" && arguments[3] != null)
		hideerror = arguments[3];
	Try.repeatagain(fn, 1, attempts, delay, hideerror);
  },
  repeatagain : function(fn, attempt, attempts, delay, hideerror) {
	try { fn(); }
	catch (e)
	{
		attempt++;
		if (attempt == attempts && !hideerror)
			fn();
		else if (attempt <= attempts)
			setTimeout(function () { Try.repeatagain(fn, attempt, attempts, delay, hideerror); }, delay);
	}
  }
});

// faster getElementsByClassName, written by Leo
var getElementsByClassNameFaster = function(needle, context) {
		if (document.evaluate) {
			var q = ".//*[contains(concat(' ', @class, ' '), ' " + needle + " ')]";
			var results=[];
			var query = document.evaluate(q, (context!=null ? context : document), null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
			for (var i = 0, length = query.snapshotLength; i < length; i++) results.push(query.snapshotItem(i));
			return results;
		}
		else {//compressing to make it faster. Things are the way they are for a good reason, don't poke around.
			var a = (context!=null ? context : document).getElementsByTagName("*"),l=a.length,r=[],i,j;
			for (i=j=0;i<l;i++) {
				var ai=a[i],c = " " + ai.className + " ";
				if (c.indexOf(" " + needle + " ") != -1) {r[j++] = ai;}
			}
			return r;
		}//end
	}

/*******************************************************************************************
*  fix: remove the spans surrounding the ul in the unordered list response for autocompleter
*********************************************************************************************/
if(Prototype.Version != '1.3.0'){
	Object.extend(Ajax.Autocompleter.prototype,{
	  onComplete: function(request) {
		this.updateChoices(request.responseText.replace(/^<span.*?\>/, "").replace(/<\/span>$/, "") );
	  }
	});
}

function sitehost()
{
	return location.href.replace(/(https?:\/\/.*?)\/.*/gi, "$1").toLowerCase();
}

function fullsiteroot()
{
	return sitehost() + "~";
}

function thispage()
{
	return location.href.replace(fullsiteroot(), "/");
}

var apprelurl = null;
var defaultaction = null;
var genome_projectid = null;
var createGenomeTickets = false

// attach the main context menu to the main document (run this once at onload)
function documentcontextint()
{
	var context = new XWebMenu.Context(document);
	addcontexteditableint(context);
	addcontexttabledbint(context);
	addcontextpageint(context);
	addcontextglobalint(context);
	setTimeout(elementcontextint, 500);
}

var elementcontextint_count = 0;
// attach different menus to elements (run this periodically to update the list)
function elementcontextint()
{
	var elems = getElementsByClassNameFaster('smartsite-element');
	for (var i = 0; i < elems.length; i++) {
		var thiselem = elems[i];
		
		if (thiselem.id == null || thiselem.id == "")
			thiselem.id = "smartsite-element-" + (elementcontextint_count++);	
			
		if (thiselem.className.indexOf(' smartsite-element-attached') == -1) {
			thiselem.className += ' smartsite-element-attached';
			var econtext = new XWebMenu.Context(thiselem);
			addcontexteditableint(econtext);
			addcontexttabledbint(econtext);
			addcontextpageint(econtext);
			addcontextelementint(econtext, thiselem);
			addcontextelementtabledbint(econtext, thiselem);
			addcontextglobalint(econtext);
			if(createGenomeTickets){
				addCreateTicketMenuItems(econtext);
			}
		}
		
		
		/*
		// attach a menu to each editable element 
		var editables = getElementsByClassNameFaster('smartsite-editable', thiselem);
		for (var j = 0; j < editables.length; j++) {
			var thiseditable = editables[j];
			
			if (thiseditable.id == null || thiseditable.id == "")
				thiseditable.id = thiselem.id + "-editable-" + j;	
			
			if (thiseditable.className.indexOf(' smartsite-editable-attached') == -1) {
				thiseditable.className += ' smartsite-editable-attached';
				var dcontext = new XWebMenu.Context(thiseditable);
				addcontexteditableint(dcontext, thiseditable);
				addcontextpageint(dcontext);
				addcontextelementint(dcontext, thiselem);
				addcontextglobalint(dcontext);
			}		
		}
		*/		
		
	}
	// retry building contexts, in case some ajax is going on
	setTimeout(elementcontextint, 1000);
}

// insert context items relative to the page
function addcontextpageint(econtext) {
	econtext.Add("Site Map", "location.href='~/administration/page/index/" + apprelurl + "';", 0, 0);
	if (defaultaction)
		econtext.Add("Edit this Page", "location.href='~/administration/page/" + defaultaction + "/" + apprelurl + "';", 0, 0);
	else
		econtext.Add("Edit this Page", "location.href='~/administration/page/edit/" + apprelurl + "';", 0, 0);
}

// insert context items relative to editables
addcontexteditableint = function(econtext, element, editable) { 
	// defined in util-admin-inline.js 
}
addcontexttabledbint = function(econtext, element, editable) {
	// defined in util-admin-inline.js 
}
addcontextelementtabledbint = function(econtext, element, editable) {
	// defined in util-admin-inline.js 
}

// insert context items relative to elements
function addcontextelementint(econtext, thiselem) {
	// recurse backwards to find any elements we need to provide a context menu for
	var editNames = new Array();
	var editClasses = new Array();
	var editItems = new Array();
	var editItemsPage = new Array();
	var iterateelem = thiselem;
	while (iterateelem != null) {
		if (iterateelem.className && iterateelem.className.match(/smartsite-element/)) {
			var erelurl = iterateelem.className.split(/ /)[0].substring(7).replace(/-/g,'/').replace(/index$/,'');
			// if element is the main page, don't show an Edit submenu for it
			if (erelurl == apprelurl) {
				iterateelem = iterateelem.parentNode;
				break;
			}
			//if (erelurl.id == null)
			//	erelurl.id = "smartsite-element-" + i;
			var ename = erelurl.replace(/.*\/([^/]+)\/?$/, "$1").replace("_", " ");
			editNames.push(ename);
			editClasses.push(iterateelem.className);
			editItems.push("location.href='~/administration/page/edit/" + erelurl + "?goback=" + apprelurl + "';");
			editItemsPage.push("location.href='~/administration/page/editinclusion/" + apprelurl + "?jumpto=" + erelurl + "';");
		}
		iterateelem = iterateelem.parentNode;
	}

	// actually add the context menu items for editing elements
	if (editNames.length > 0) {
		for (var j = editNames.length - 1; j >= 0; j--) {
			var elName = editNames[j];
			if (j != editNames.length - 1) {
				elName = editNames[j+1] + "/" + elName;
			}

			var elClass = editClasses[j];
			if (elClass.match(/smartsite-element-editmode-direct/)) {
				econtext.Add("Edit '" + editNames[j] + "'", editItems[j], 0, 0);
			}
			else if (elClass.match(/smartsite-element-editmode-included/)) {
				econtext.Add("Edit '" + editNames[j] + "' for this Page", editItemsPage[j], 0, 0);
			}
			else if (elClass.match(/smartsite-element-editmode-neither/)) {
			}
			else { 
				// smartsite-element-editmode-both
				econtext.Add("Element '" + elName + "'", 0, 0, "elementSubMenu");
				econtext.elementSubMenu.Add("Edit '" + editNames[j] + "'", editItems[j], 0, 0);
				econtext.elementSubMenu.Add("Edit '" + editNames[j] + "' for this Page", editItemsPage[j], 0, 0);
			}
		}
	}
}
// insert generic context items
function addcontextglobalint(econtext) {
	econtext.Add("Add Subpage", "location.href='~/administration/page/index/" + apprelurl + "?add=1';", 0, 0);
	econtext.Add("Publish", "location.href='~/administration/page/publish/" + apprelurl + "';", 0, 0);
	econtext.Add("Security", "location.href='~/administration/page/security/" + apprelurl + "';", 0, 0);
	econtext.Add("Time Machine", "location.href='~/administration/global/timemachine';", 0, 0);
	econtext.Add("Global", "location.href='~/administration/global/';", 0, 0);
	//econtext.Add("Toggle Inclusion Borders", "showhideinclusions();", 0, 0);
}

//Add Genome Ticket creation options
function addCreateTicketMenuItems(econtext){
	
	econtext.Add("Create a Ticket","showFloatingExtranetLightbox();",0,0);
	econtext.Add("Hide Tickets","document.getElementById('displayoverlays').style.display='none';createGenomeTickets = false;",0,0);
}

showFloatingExtranetLightbox = function(){
	var floatingdiv = document.getElementById('extranet_add_ticket_floating_div');
	if(floatingdiv){
		document.getElementById('extranet_add_ticket').src="http://extranet.klick.com/ticket/create?pageurl="+apprelurl+"&genomeprojectid="+genome_projectid+"&xcoord="+document.getElementById('TicketXCoord').value+"&ycoord="+document.getElementById('TicketYCoord').value;
			
		floatingdiv.style.display='';
		floatingdiv.style.left = ((document.body.clientWidth - floatingdiv.offsetWidth) / 2) + "px";
		floatingdiv.style.top = ((document.body.clientHeight - floatingdiv.offsetHeight) / 2) + "px";
		var mask;
		if(!$('extranet_floating_mask')){
			mask = document.createElement("div");
			mask.id="extranet_floating_mask";
			mask.style.background="#798e97";
			mask.style.filter="alpha(opacity=50)";
			mask.style.opacity="0.5";
			mask.style.position="absolute";
			mask.style.top = document.body.scrollTop + "px";
			mask.style.left = document.body.scrollLeft + "px";
			mask.style.width = (document.body.clientWidth) + "px";
			mask.style.height = (document.body.clientHeight) + "px";		
			document.body.appendChild(mask);	
		}
		else{
			mask = $('extranet_floating_mask');
			mask.style.display='';
		}
		

		
	}
		
}

function setCreateGenomeTickets(){
	createGenomeTickets = true;
}
function setGenomeProjectID(_genomeprojectid){
	genome_projectid = _genomeprojectid
}

function documentcontext(_apprelurl, _defaultaction)
{
	apprelurl = _apprelurl;
	defaultaction = _defaultaction;
	if (!apprelurl)
		apprelurl = thispage();
	XWebMenuEvent.SetEvent(window,"load",documentcontextint);
}

function Validate_Highlight(id)
{
	if ($(id) != null) {
		if ($(id).className != "")
			$(id).className = $(id).className + " validate-highlight";
		else
			$(id).className = "validate-highlight";
	}
}

/**********************************************************************
*
*  http://joehewitt.com/software/firebug/docs.php
*  This is a function to print to the console of the "firebug" firefox plugin.
*  Specify a type (debug, info, warn, error), and you will get colour-coded output
*
***********************************************************************/
printfire = function (msg, type /* optional */)
{
	type = type || " ";

	//firebug
	if (typeof console != "undefined" && console.debug != "undefined")
	{
		switch(type.charAt(0).toLowerCase())
		{
			case "d": //debug
				if(console.debug) console.debug(msg);
				break;
			case "i": //info
				if(console.info) console.info(msg);
				break;
			case "w": //warn
				if(console.warn) console.warn(msg);
				break;
			case "e": //error
				if(console.error) console.error(msg);
				break;
			default: //default to log
				if(console.log) console.log(msg);
				break;
		}
	}
	//safari
	else if (window.console && window.console.log)
	{
		window.console.log((type ? type + ": " : "") + msg);
	}
}



// ====================================================================
//       URLEncode and URLDecode functions
//
// Copyright Albion Research Ltd. 2002
// http://www.albionresearch.com/
//
// You may copy these functions providing that
// (a) you leave this copyright notice intact, and
// (b) if you use these functions on a publicly accessible
//     web site you include a credit somewhere on the web site
//     with a link back to http://www.albionresarch.com/
//
// If you find or fix any bugs, please let us know at albionresearch.com
//
// SpecialThanks to Neelesh Thakur for being the first to
// report a bug in URLDecode() - now fixed 2003-02-19.
// ====================================================================
function URLEncode(plaintext)
{
	// The Javascript escape and unescape functions do not correspond
	// with what browsers actually do...
	var SAFECHARS = "0123456789" +					// Numeric
					"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +	// Alphabetic
					"abcdefghijklmnopqrstuvwxyz" +
					"-_.!~*'()";					// RFC2396 Mark characters
	var HEX = "0123456789ABCDEF";

	var encoded = "";
	for (var i = 0; i < plaintext.length; i++ ) {
		var ch = plaintext.charAt(i);
	    if (ch == " ") {
		    encoded += "+";				// x-www-urlencoded, rather than %20
		} else if (SAFECHARS.indexOf(ch) != -1) {
		    encoded += ch;
		} else {
		    var charCode = ch.charCodeAt(0);
			if (charCode > 255) {
			    alert( "Unicode Character '"
                        + ch
                        + "' cannot be encoded using standard URL encoding.\n" +
				          "(URL encoding only supports 8-bit characters.)\n" +
						  "A space (+) will be substituted." );
				encoded += "+";
			} else {
				encoded += "%";
				encoded += HEX.charAt((charCode >> 4) & 0xF);
				encoded += HEX.charAt(charCode & 0xF);
			}
		}
	} // for

	return encoded;
};

function URLDecode(encoded)
{
   // Replace + with ' '
   // Replace %xx with equivalent character
   // Put [ERROR] in output if %xx is invalid.
   var HEXCHARS = "0123456789ABCDEFabcdef";
   var plaintext = "";
   var i = 0;
   while (i < encoded.length) {
       var ch = encoded.charAt(i);
	   if (ch == "+") {
	       plaintext += " ";
		   i++;
	   } else if (ch == "%") {
			if (i < (encoded.length-2)
					&& HEXCHARS.indexOf(encoded.charAt(i+1)) != -1
					&& HEXCHARS.indexOf(encoded.charAt(i+2)) != -1 ) {
				plaintext += unescape( encoded.substr(i,3) );
				i += 3;
			} else {
				alert( 'Bad escape combination near ...' + encoded.substr(i) );
				plaintext += "%[ERROR]";
				i++;
			}
		} else {
		   plaintext += ch;
		   i++;
		}
	} // while
	return plaintext;
};

/**********************************************************************
*
*  http://www.vivabit.com/code/domready/domready.js
*  http://www.vivabit.com/bollocks/
*  Usage: Event.onDOMReady(function() { // Stuff here! });
*
***********************************************************************/
Object.extend(Event, {
  _domReady : function() {
    if (arguments.callee.done) return;
    arguments.callee.done = true;

    if (this._timer)  clearInterval(this._timer);

    this._readyCallbacks.each(function(f) { f() });
    this._readyCallbacks = null;
},
  onDOMReady : function(f) {
    if (!this._readyCallbacks) {
      var domReady = this._domReady.bind(this);

      if (document.addEventListener)
        document.addEventListener("DOMContentLoaded", domReady, false);

        /*@cc_on @*/
        /*@if (@_win32)
            document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
            document.getElementById("__ie_onload").onreadystatechange = function() {
                if (this.readyState == "complete") domReady();
            };
        /*@end @*/

        if (/WebKit/i.test(navigator.userAgent)) {
          this._timer = setInterval(function() {
            if (/loaded|complete/.test(document.readyState)) domReady();
          }, 10);
        }

        Event.observe(window, 'load', domReady);
        Event._readyCallbacks =  [];
    }
    Event._readyCallbacks.push(f);
  }
});



