
function detect(target, string)
{
		place = target.indexOf(string) + 1;
		return place;
}

function getDivsByName(root, type, name)
{
	var result = new Array();
 	var nodes = root.getElementsByTagName(type);
    if (nodes != null)
    {
	    var cur = 0;
	    for(var i = 0; i < nodes.length; i++)
	    {
	        var attr = nodes[i].getAttribute("name");
	        if(attr == name)
	        {
	            result[cur++] = nodes[i];
	        }
	    }
	}
    return result;
}

/*
	approximate method currying in javascript, code from http://www.svendtofte.com/code/curried_javascript/
	example usage:
	
	function add (a,b,c){ 
	      if (arguments.length < this.add.length) {
	        return curry(this.add,arguments,this);
	      }  
	      return a+b+c;
	}
	  
	alert(add()(1,2,4));      // 7
	alert(add(1)(2)(5));      // 8
	alert(add(1)()(2)()(6));  // 9
	alert(add(1,2,7,8));      // 10
*/
function curry(func,args,space)
{
    var n  = func.length - args.length; //arguments still to come
    var sa = Array.prototype.slice.apply(args); // saved accumulator array
    function accumulator(moreArgs,sa,n)
    {
        var saPrev = sa.slice(0); // to reset
        var nPrev  = n; // to reset
        for(var i=0;i<moreArgs.length;i++,n--)
        {
            sa[sa.length] = moreArgs[i];
        }
        if ((n-moreArgs.length)<=0)
        {
            var res = func.apply(space,sa);
            // reset vars, so curried function can be applied to new params.
            sa = saPrev;
            n  = nPrev;
            return res;
        }
        else
        {
            return function ()
            {
                // arguments are params, so closure bussiness is avoided.
                return accumulator(arguments,sa.slice(0),n);
            }
        }
    }
    return accumulator([],sa,n);
}

// Positions a layer at the mouse cursor. If the layer would go outside the
// viewport, it is moved just inside w/ padding.
function displayPopupAtCursor2(targetObjectId, eventObj, leftAlign, minY)
{
  if (!eventObj) return false;
  var e = new Event(eventObj).stop();
  hideCurrentPopup();
  var elmt = $(targetObjectId);
  // make sure element is a direct child of the body for positioning
  if (elmt.parent != document.body) $(document.body).adopt(elmt);

  elmt.setStyle('left', '-999em');
  var eC = elmt.getCoordinates();

  var newPositionX = e.client.x;
  if (newPositionX + eC.width > window.getWidth()) newPositionX = window.getWidth() - eC.width - 10;// 10px away from right edge
  var newPositionY = e.client.y;
  if (newPositionY + eC.height > window.getHeight()) newPositionY = window.getHeight() - eC.height - 10;// 10px away from bottom edge

  if (leftAlign) newPositionX = newPositionX - eC.left;
  if (minY) newPositionY = Math.max(window.getScrollTop() + minY, newPositionY);

  elmt.setStyles({left: newPositionX, top: newPositionY});

  if(changeObjectVisibility(targetObjectId, 'visible'))
  {
    // if we successfully showed the popup
    // store its Id on a globally-accessible object
    window.currentlyVisiblePopup = targetObjectId;
    return true;
  }
  return false;
}

function dialog(url, name, width, height, scrollbars)
{
   var features = 'width=' + width + ',height=' + height + ',menubar=no,status=no,toolbar=no,';
   features += scrollbars ? 'scrollbars=yes,resizable=yes' : 'scrollbars=no,resizable=yes';
   var newName = name.replace(".", "_");
   var dlg = window.open(url, newName, features);
   dlg.focus();
   return false;
}

function setStatus(text)
{
   window.status = text;
   return true;
}

function trim(str)
{
   str = str.replace(/^\s+/g, "");
   str = str.replace(/\s+$/g, "");
   return str;
}
// External URL is of the form
// /Travel-g12345-s1234.html?nxa=edit

function buildExternalUrl(pageSpace, pageName, pageAction, queryString)
{
   var urlBase = "";
   var isCrawlableUrl = pageAction == "view" && (queryString == null || queryString == "");
   
   if(isCrawlableUrl)
   {
      urlBase = "/Travel";
   }
   else 
   {
      urlBase = "/mgo";
   }
   var url = urlBase + "-" + escape(pageSpace) + "-" + escape(pageName);
   if(pageAction != null && pageAction != "view")
   {
      queryString = "nxa=" + pageAction +(queryString ? "&" + queryString : "");
   }
   if(isCrawlableUrl)
   {
      url += ".html";
   }
   if(queryString)
   {
      url += "?" + queryString;
   }
   return url;
}
//
// These functions are for doing inline div popups
//

function toggleLayer(whichLayer)
{
   // this is the way the standards work
   var style2 = document.getElementById(whichLayer).style;
   style2.display = style2.display == "none" ? "block" : "none";
}

function displayPopupAtCursor(targetObjectId, eventObj, leftAlign)
{
   if(eventObj)
   {
      // move popup div to current cursor position 
      // (add scrollTop to account for scrolling for IE)
      var newXCoordinate =(eventObj.pageX) ? eventObj.pageX + xOffset : eventObj.x + xOffset +((document.body.scrollLeft) ? document.body.scrollLeft : 0);
      var newYCoordinate =(eventObj.pageY) ? eventObj.pageY + yOffset : eventObj.y + yOffset +((document.body.scrollTop) ? document.body.scrollTop : 0);
      if(leftAlign)
      {
         var styleObj = getStyleObject(targetObjectId);
         var match = styleObj.width.match(/(\d+)px/);
         if(match)
         {
            newXCoordinate = newXCoordinate - match[1];
         }
      }
      return displayPopup(targetObjectId, eventObj, newXCoordinate, newYCoordinate);
   }
   else 
   {
      // there was no event object, so we won't be able to position anything, so give up
      return false;
   }
}

function displayPopup(targetObjectId, eventObj, newXCoordinate, newYCoordinate)
{
  // hide any currently-visible popups
  hideCurrentPopup();
  // stop event from bubbling up any farther
  eventObj.cancelBubble = true;
  // move popup div to current cursor position 
  moveObject(targetObjectId, newXCoordinate, newYCoordinate);
  // and make it visible
  if(changeObjectVisibility(targetObjectId, 'visible'))
  {
    // if we successfully showed the popup
    // store its Id on a globally-accessible object
    window.currentlyVisiblePopup = targetObjectId;
    return true;
  }
  // we couldn't show the popup, boo hoo!
  return false;
}

function getStyleObject(objectId)
{
   // cross-browser function to get an object's style object given its id
   if(document.getElementById && document.getElementById(objectId))
   {
      // W3C DOM
      return document.getElementById(objectId).style;
   }
   else if(document.all && document.all(objectId))
   {
      // MSIE 4 DOM
      return document.all(objectId).style;
   }
   else if(document.layers && document.layers[objectId])
   {
      // NN 4 DOM.. note: this won't find nested layers
      return document.layers[objectId];
   }
   else 
   {
      return false;
   }
}
// getStyleObject

function changeObjectVisibility(objectId, newVisibility)
{
   // get a reference to the cross-browser style object and make sure the object exists
   var styleObject = getStyleObject(objectId);
   if(styleObject)
   {
      styleObject.visibility = newVisibility;
      return true;
   }
   else 
   {
      // we couldn't find the object, so we can't change its visibility
      return false;
   }
}
// changeObjectVisibility

function moveObject(objectId, newXCoordinate, newYCoordinate)
{
   // get a reference to the cross-browser style object and make sure the object exists
   var styleObject = getStyleObject(objectId);
   if(styleObject)
   {
      styleObject.left = newXCoordinate + 'px';
      styleObject.top = newYCoordinate + 'px';
      return true;
   }
   else 
   {
      // we couldn't find the object, so we can't very well move it
      return false;
   }
}
// store variables to control where the popup will appear relative to the cursor position
// positive numbers are below and to the right of the cursor, negative numbers are above and to the left
var xOffset = 30;
var yOffset = - 5;

function hideCurrentPopup()
{
   // we've stored the currently-visible popup on the global object window.currentlyVisiblePopup
   if(window.currentlyVisiblePopup)
   {
      changeObjectVisibility(window.currentlyVisiblePopup, 'hidden');
      window.currentlyVisiblePopup = false;
   }
}
// hideCurrentPopup
// initialize hacks whenever the page loads
origWindowOnload = window.onload;
window.onload = initializeHacks;
// setup an event handler to hide popups for generic clicks on the document
document.onclick = hideCurrentPopup;

function initializeHacks()
{
   // this ugly little hack resizes a blank div to make sure you can click
   // anywhere in the window for Mac MSIE 5
   if((navigator.appVersion.indexOf('MSIE 5') != - 1) &&(navigator.platform.indexOf('Mac') != - 1) && getStyleObject('blankDiv'))
   {
      window.onresize = explorerMacResizeFix;
   }
   resizeBlankDiv();
   // this next function creates a placeholder object for older browsers
   createFakeEventObj();
   if (origWindowOnload != null) {
     origWindowOnload();
   }
}

function createFakeEventObj()
{
   // create a fake event object for older browsers to avoid errors in function call
   // when we need to pass the event object to functions
   if(!window.event)
   {
      window.event = false;
   }
}
// createFakeEventObj

function resizeBlankDiv()
{
   // resize blank placeholder div so IE 5 on mac will get all clicks in window
   if((navigator.appVersion.indexOf('MSIE 5') != - 1) &&(navigator.platform.indexOf('Mac') != - 1) && getStyleObject('blankDiv'))
   {
      getStyleObject('blankDiv').width = document.body.clientWidth - 20;
      getStyleObject('blankDiv').height = document.body.clientHeight - 20;
   }
}

function explorerMacResizeFix()
{
   location.reload(false);
}

function isValidPageName(name)
{
   // Nexus pages are for now going to contain only alphanumerics, no punctuation. : and . are specifically problems, but
   // it is easier to rule out all specials -- note only allows ASCII at present, not any Unicode char
   // but we do need to allow spaces
   var pattern = /[^a-zA-Z0-9 ]/;
   if(pattern.test(name))
   {
      return false;
   }
   return true;
}

function jsonDecode(jsonText)
{
	var myObject = eval('(' + jsonText + ')');
	return myObject;
}

function defaultErrFunc(req, msg)
{
	var errorMsg = msg;
	if (req)
	{
		errorMsg += ":\n" + req.responseText;
	}
	alert(errorMsg);
}

function defaultSuccessFunc(req, callback)
{ 	 
    try
    {
        data = jsonDecode(req.responseText);
		if (data && data.debug && data.editErrorTag)
		{
			alert("Error during ajax call, \nTag: " + data.editErrorTag + "\nMsg: " + data.editErrorMessage + "\nContent:" + data.editErrorContent);
		}
		if (data.readonly)
		{
			document.location = data.maintenanceUrl;
		}
		else
		{
	        callback(data);
	    }
    }
    catch(e) {alert(e);}
}

function createCustomDoc(sTitle, sCategory, sSpace, callback)
{ 
    if (!sTitle)
    {
      alert("The title must be populated");
      return;
    }

    var errFunc = function(req) {
        defaultErrFunc(req, "Unable to create a new page");
    }
    var resFunc = function(req) { 	 
        defaultSuccessFunc(req, callback);
    }
 	 
    var req = new HttpRpc('/mgo', errFunc, defaultSuccessFunc); 	 
    var params = new UrlParams();
    params.add('nxa', 'createcustom'); 	 
    params.add('title', sTitle); 	 
    params.add('category', sCategory); 	 
    params.add('space', sSpace); 	 
    params.add('noredir', 'true'); 	 
    req.sendRequest(params.toString()); 	 
}

// used to put comments into a given div ajax style
function fillComments(nId,reqtype,div)
{
    var errFunc = function(req) {
        //defaultErrFunc(req, "Unable to execute action: " + sAction);
    }

    var resFunc = function(req) { 	 
       if (req.responseText)
       {
           div.innerHTML= "" + req.responseText;
       }
    }

    var req = new HttpRpc('/mgo', errFunc, resFunc); 	 
    var params = new UrlParams();
    params.add('nxa', 'allcomments'); 	 
    params.add('nxi', nId);
    params.add('reqtype', reqtype); 	 	 
    req.sendRequest(params.toString());
}

function modSubscription(nId,sSpace,sAction,sReturnTo,callback)
{

    var errFunc = function(req) {
        defaultErrFunc(req, "Unable to execute subscription action: " + sAction);
    }
    var resFunc = function(req) { 	 
        defaultSuccessFunc(req, callback);
    }

    var req = new HttpRpc('/mgo', errFunc, resFunc); 	 
    var params = new UrlParams();
    params.add('nxa', 'modifysub'); 	 
    params.add('nxi', nId);
    params.add('nxs', sSpace); 	 	 
    params.add('nxsa', sAction);
    if (sReturnTo) params.add('returnTo', encodeURIComponent(sReturnTo));
    req.sendRequest(params.toString());
}

function modViewSubscription(nId,sSpace,sAction,sReturnTo,sDivOn)
{
    var callback = function(data) { 	 
        if(data.result)
        {
        		document.getElementById(sAction).style.display = 'none';
        		document.getElementById(sDivOn).style.display = 'block';
        }
        else if(data.loginUrl)
        {
        	document.location = data.loginUrl;
        }
    }
    
    modSubscription(nId, sSpace, sAction, sReturnTo, callback);

    return false;
}

// For doing Revision comparisons
//
function getSelectedVersions(selected)
{
    // check the url for a revision selected from a previous page
    var prev = 0;
    var qs = window.location.href.split("&");
    for (var i = 0; i < qs.length; i++ )
    {
        if (qs[i].indexOf("rev0=") > -1 )
        {
            var pair = qs[i].split("=");
            prev = pair[1];
            break;
        }
    }

    var boxes = new Array();
    var elements = document.getElementById('revisionsForm').elements;
    boxes.selected_index = -1;

    for(var i = 0; i < elements.length; i++)
    {
      if(elements[i].name == "diffVersion") 
      {
        if (elements[i].checked)
        {
          if(elements[i] == selected)
          {
            boxes.selected_index = boxes.length;
          }

          boxes.push(elements[i].value);
        }
        else
        {
            // if the prev version is on this page and it is unchecked
            // then stop passing it through the chain of pages
            if (elements[i].value == prev)
            {
              prev = 0;
            }
        }
      }
    }

    // if 2 checkboxes are selected on the current page then don't add 
    // the version that was passed through
    if (boxes.length < 2 && prev > 0)
    {
        boxes.push(prev);
    }
    else
    {
        // if two boxes were selected, don't continue to pass prev
        prev = 0;
    }
    return boxes;
}

function compareSelectedVersions(compareUrl)
{
    var boxes = getSelectedVersions();
    if(boxes.length == 2)
    {
       var revparams = (/\?/.test(compareUrl) ? "&" : "?") + "rev1=" + boxes[1] + "&rev2=" + boxes[0];
       dialog(compareUrl + revparams, 'compare', 800, 700);
    }
    else
    {
        alert("You must select two versions to compare.");
    }
    return false;
}

// helper function for passing the previous version through the verison paging
function pageVersionHistory(url)
{
    var boxes = getSelectedVersions();
    if(boxes.length > 0)
    {
       var revparam = (/\?/.test(url) ? "&" : "?") + "rev0=" + boxes[0];
       url += revparam;
    }
    window.location.href = url;
}

function checkboxSelected(checkbox)
{
    if(! checkbox.checked)
    {
      document.getElementById('compareRevisionsButton').disabled = true;
      return;
    }

    var selections = this.getSelectedVersions();
    if(selections.length > 2)
    {
        var elements = document.getElementById('revisionsForm').elements;
        for(var i = 0; i < elements.length; i++)
        {
            if(elements[i].name == "diffVersion") 
            {
                if(elements[i] != checkbox)
                {
                    elements[i].checked = false;
                }
            }
        }
    }

    this.examineCompareButton();
}

function examineCompareButton()
{
    var boxes = this.getSelectedVersions();
    document.getElementById('compareRevisionsButton').disabled = (boxes.length != 2);
}

function doRollback(rollbackUrl)
{
  if (confirm("You are about to revert the text for this page to a previous version.  Are you sure you want to continue?"))
  {
      window.location = rollbackUrl;
  }
}

function setDetails(id,  title, category, space)
{
  $('title_' + id).value = title;
  $('category_' + id).value = category;
  $('space_' + id).value = space;
}

function editNewPage(id)
{
  var docTitle = $('title_' + id).value;
  var docCategory = $('category_' + id).value;
  if (!docTitle)
  {
    alert("The title must be populated");
  }
  else
  {
    $('newPage_' + id).submit(); 
  }
}

//
// End revision comparison code
