
Function.prototype.closure = function(obj)
{
  // Init object storage.
  if (!window.__objs)
  {
    window.__objs = [];
    window.__funs = [];
  }

  // For symmetry and clarity.
  var fun = this;

  // Make sure the object has an id and is stored in the object store.
  var objId = obj.__objId;
  if (!objId)
    __objs[objId = obj.__objId = __objs.length] = obj;

  // Make sure the function has an id and is stored in the function store.
  var funId = fun.__funId;
  if (!funId)
    __funs[funId = fun.__funId = __funs.length] = fun;

  // Init closure storage.
  if (!obj.__closures)
    obj.__closures = [];

  // See if we previously created a closure for this object/function pair.
  var closure = obj.__closures[funId];
  if (closure)
    return closure;

  // Clear references to keep them out of the closure scope.
  obj = null;
  fun = null;

  // Create the closure, store in cache and return result.
  return __objs[objId].__closures[funId] = function ()
  {
    var aDebugDummyLine = "can stop just after this";
    return __funs[funId].apply(__objs[objId], arguments);
  };
};

//******************************************************************************************************************************
// Utility functions
//

function FormatPostCode (postCode) {
	if (postcodeRe.test(postCode)) {
		if (postCode.substr((postCode.length - 4), 1) != " ") postCode = postCode.substr(0, (postCode.length - 3)) + " " + postCode.substr(postCode.length - 3);
	}
	return postCode;
}

function FormatYear(yearValue) {
	if (yearValue == -1) {
		return "All years";
	} else if (yearValue == today.getFullYear()) {
		return "This year";
	} else {
		return yearValue;
	}
}

Object.extend(String.prototype, {
    truncateParagraph : function (maxLength, endString) {

        var theText = this;
        
        if (theText.length > 0) {
            var len = (maxLength || 250);
            var elipsis = (endString || "...");
            
            if (theText.length > len) {

                /* Truncate the content of the P, then go back to the end of the
                previous word to ensure that we don't truncate in the middle of
                a word */
                theText = theText.substring(0, len);
                theText = theText.replace(/\w+$/, '');

                /* Add an ellipses to the end and make it a link that expands
                the paragraph back to its original size */
                theText += elipsis;
            }
            
        }

        return theText;

    }
});

Object.extend(Array.prototype, {
    removeMember : function (memberIndex) {
        
        var theNewArray = this;
        
        if (memberIndex) {
        
            var actualIndex = null;
            
            if (isNaN(memberIndex)) {
                var currentIndex = 0;
                for (memberName in this) {
                    if (memberIndex == memberName) {
                        memberIndex = currentIndex;
                        break;
                    }
                    currentIndex++;
                }
            }
            
            if (!isNaN(memberIndex)) {
                theNewArray.splice(memberIndex, 1);
            }
            
        }
        
        return theNewArray;
    }
});

Object.extend(Number.prototype, {
    toPrimitiveNumber : function() {
        return this.valueOf();
        numberValue = this;
        if (!isNaN(numberValue)) {
            var topValue = (limit || 1000);
            for (var i = 0; i <= topValue; i++) {
                if (i == numberValue) return i;
            }
        } else {
            throw new Error(numberValue + " is not a number.");
        }
    }
});

Object.extend(Number.prototype, {
  isEven : function() {
    var numberValue = this;
    return (Math.round(numberValue/2) == (numberValue/2));
  }
});


// Form Auto-clear & and submit stuff
function clearMe(s, defaultValue) {
	if(defaultValue == null || defaultValue == undefined) defaultValue = "Type location";
	if (s.value) {
	  if (s.value == defaultValue) {
		  s.value = "";
		  return false;
	  }
	} else if (s.innerHTML) {
	  if (s.innerHTML == defaultValue) {
		  s.innerHTML = "";
		  return false;
	  }
	}
	return true;
}

function ReturnSubmitHandler (e) { 
    if (clearMe(this)) { 
        return submitenter(this, (e || event), DoSearch); 
    }
    
    return true;
}

function selectSubmitChangeHandler (e) {
    return DoSearch();
}

function submitenter(myfield,e,action)
{

    if(e) {
	    var keycode = e.keyCode;
    /*
	    if (window.event) 
		    keycode = window.event.keyCode;
	    else if (e) keycode = e.which;
	    else return true;
    */
	    if (keycode == Event.KEY_RETURN && action != null){
		    action();
		    return false;
	    } 
    }

    return true;
}

function GetAdvertUrl(adUrlPart) 
{
    return adUrlSuffix + adUrlPart;
}

function GetTrackerLink(categoryName, destinationURL)
{

	var trackerUrl = "";

	if (linkTrackerURL.length > 0) {
		trackerUrl += linkTrackerURL;
		trackerUrl += "?s=";
		trackerUrl += linkTrackerSiteName;
		trackerUrl += "&t=";
		trackerUrl += categoryName;
		trackerUrl += "&l=";
	}

	trackerUrl += destinationURL;

	return trackerUrl;
}

function CreateBookmarkLink() {
  var title = document.title;
  var url = location.href;
  
  if (url.indexOf("map.aspx") >= 0)
  {
    url = $("pageLink").href;
  }
  
	if (window.sidebar) { // Mozilla Firefox Bookmark
		window.sidebar.addPanel(title, url, "");
	} else if( window.external ) { // IE Favorite
		window.external.AddFavorite( url, title); 
	}	else if(window.opera && window.print) { // Opera Hotlist
		return true; 
  }
}

//******************************************************************************************************************************
// Background fades
//

// This is the amount of time (in milliseconds) that will lapse between each step in the fade
var FadeInterval = 600;

// This is list of steps that will be used for the color to fade out
var fadeDefinitions = 
{
						redToDarkBlue : new Array("ff0000", "dd0033", "bb1155", "993377", "775599", "5566aa", "2772c1"),
						yellowToDarkBlue : new Array("ffff99", "ddeeaa", "bbddbb", "99ccc1", "77bbc1", "5599c1", "2772c1"),
						yellowToLightBlue : new Array("ffff99", "eeffaa", "e3ffbb", "ddffcc", "d3ffdd", "ccffee", "c3e6ff")
};

// This is the recursive function call that actually performs the fade
function DoFade(targetId, fadeDefinition, fadeOutTimerId, colorId) {
	if (colorId == null) colorId = 0
    if (colorId < fadeDefinitions[fadeDefinition].length) {
        $(targetId).style.backgroundColor = "#" + fadeDefinitions[fadeDefinition][colorId];
        colorId++;
        // Wait a little bit and fade another shade
        timeouts[fadeOutTimerId] = setTimeout("DoFade('" + targetId + "', '" + fadeDefinition + "', '" + fadeOutTimerId + "', " + colorId +")", FadeInterval);
    }
}

function GetSiteRootUrl() {
    return "http://" + window.location.host + window.location.pathname;
}

//*******************************************************************************************************************************
// Ajax Request Stuff
//
function MakeAjaxRequest(ajaxUrl, parameterString, callBackHandler, timeOutDelay, currentContext) {

    jslog.debug("MakeAjaxRequest(\"" + ajaxUrl + "\", \"" + parameterString + "\", CallBack, " + timeOutDelay + ", " + currentContext + ")");

    var ajaxRequest; 
    
    currentAJAXRequestTS = (new Date()).valueOf();
    
    //alert(parameterString);
    
    var opt = {
        requestHeaders: ['x-nep.ajax-timestamp', currentAJAXRequestTS.toString()],
        parameters : parameterString,
        method: 'get',
        // Handle successful response
        onComplete: function(t) {
            try
            {
              //jslog.debug("onComplete Called (MakeAjaxRequest)");
              var responseObject = eval("(" + t.responseText + ")");
              if(ajaxRequest.header("x-nep.ajax-timestamp") ) {
                responseObject.requestTimestamp = ajaxRequest.header("x-nep.ajax-timestamp");
              }
              callBackHandler(responseObject, currentContext);
            }
            catch(e)
            {
              jslog.error(e.message + " (MakeAjaxRequest - onComplete)");
            }
        },
        // Handle other errors
        onFailure: function(t) {
          jslog.error(t.statusText + " (MakeAjaxRequest - onFailure)");
        }
    }
            
	return setTimeout(function() { 

                            ajaxRequest = new Ajax.Request(ajaxUrl, opt); 
       						  }, 
									  timeOutDelay
					  );  
}


