﻿// Common functions that can be used throughout any Ship site.


// Add methods to the "String" object to trim leading and/or trailing space characters.
String.prototype.ltrim = function() { return this.replace(/^\s+/, ''); };
String.prototype.rtrim = function() { return this.replace(/\s+$/, ''); };
String.prototype.trim = function() { return this.ltrim().rtrim(); };
String.prototype.normalize = function() { return this.trim().replace(/\s{2,}/g, ' '); };


/**
* Developer:    Craig Hutchison
* Date Created: 2008-Jan-20
* 
* Purpose:  For IE browsers, instead of having to click the search
*           button, this allows clients to press the "Enter" or key
*           while the cursor is inside the TextBox used for the site
*           search.
*
* Notes:  Must be used with the "onKeyDown" event of the TextBox.
*         Because this code shifts focus from the TextBox to the
*         ImageButton before the event completes, the enter/return
*         event is attributed to the button instead.
**/
function enterClick(e, btn) {
  var key = e.charCode
                  ? e.charCode
                  : e.keyCode
                    ? e.keyCode
                    : e.which
                      ? e.which
                      : 0;
  if (key == 13)
    btn.focus();
  return true;
}


// *************************************
// * Image Rollover setup code - BEGIN *
// *************************************
var imgErrors = new Array();  // indicates which URLs produced an error and should not be loaded
var dummyImages = new Array();  // needed to make sure images objects aren't destroyed when scope is lost and before they've had a chance to error

// Preload the rollover images so we check for errors before the client rolls over them.
function imgRollover_Preload(images) {
  for (var i = 0; i < images.length; i++) {
    if (images[i].src.match(/\/uploadedImages\/.+/i)  // only apply rollovers for images in the CMS Library
                && (!images[i].src.match(/\/headerbar_.+/i))) { // don't do rollovers for the header images
      var srcOver = images[i].src.replace(/(\.[^\.]+)$/, '_over$1');
      imgErrors[srcOver] = false;
      var img = new Image();
      img.src = srcOver;
      img.onerror = imgRollover_Error;
      dummyImages.push(img);
    }
  }
}

function imgRollover_Over() {
  var srcOver = this.src.replace(/(\.[^\.]+)$/, '_over$1');
  if (!imgErrors[srcOver])
    this.src = srcOver;
  return true;
}

function imgRollover_Out() {
  var srcOut = this.src.replace(/_over(\.[^\.]+)$/, '$1');
  if (this.src != srcOut)
    this.src = srcOut;
  return true;
}

function imgRollover_Error() {
  imgErrors[this.src] = true;
  return imgRollover_Out;
}

function imgRollover_ElementsToArray(images) {
  var arr = new Array();
  for (var i = 0; i < images.length; i++)
    arr.push(images[i]);
  return arr;
}

function imgRollover_Load() {
  var imagesLeft = document.getElementById("leftColumn").getElementsByTagName("img");  // get all images on the left
  var imagesRight = document.getElementById("rightColumn").getElementsByTagName("img");  // get all images on the right
  var images = imgRollover_ElementsToArray(imagesLeft).concat(imgRollover_ElementsToArray(imagesRight));
  imgRollover_Preload(images); // preload for all images
  
  // loop through all images and attach events
  for (var i = 0; i < images.length; i++) {
    if (images[i].src.match(/\/uploadedImages\/.+/i)  // only apply rollovers for images in the CMS Library
                && (! images[i].src.match(/\/headerbar_.+/i))) { // don't do rollovers for the header images
      images[i].onmouseover = imgRollover_Over;
      images[i].onmouseout = imgRollover_Out;
      images[i].onerror = imgRollover_Error;
    }
  }
}
// ***********************************
// * Image Rollover setup code - END *
// ***********************************



// AWStats - change external links so that we can log page exits.
function logExternalLinks() {
  var anchors = document.getElementsByTagName("a");
  for (var i = 0; i < anchors.length; i++)
    if (anchors[i].href.length > 0 && anchors[i].protocol.match(/^http(s)?:$/i) && anchors[i].hostname != location.hostname && location.hostname.match(/[^\.]+\.[^\.]+/))
      anchors[i].href = '/stats/cgi-bin/awredir.pl?url=' + anchors[i].href; //encodeURIComponent(anchors[i].href);
}


// DropDownList with URL values
function ddlGo(ddl) {
  var val = ddl.options[ddl.selectedIndex].value;
  if (val != '0')
    top.location.href = val;
  return true;
}



// Finally... Add functions to be run after the page has finished loading.
function addLoadEvent(new_f) {
  var old_f = window.onload;
  if (typeof window.onload != 'function')
    window.onload = new_f;
  else {
    window.onload = function() {
      if (old_f)
        old_f();
      new_f();
    };
  }
}
addLoadEvent(imgRollover_Load);
addLoadEvent(logExternalLinks);
addLoadEvent(outlineInit);


// Script to be used in combination with CSS to allow list items that open on click
var outlineItems = new Array();

function outlineInit()
{
	var elements = outlineGetTopLevelLists();
	for (var i = 0; (i < elements.length); i++) {
		outlineInitOutline(elements[i]);
	}		
}

function outlineInitOutline(outline)
{
	var kids = outline.childNodes;
	for (var i = 0; (i < kids.length); i++) {
		var kid = kids[i];
		if (kid.nodeName == "LI") {
			outlineInitItem(kid);
		}
	}
}

function outlineInitItem(item)
{
	var kids = item.childNodes;
	var hasKids = false;
	var outlines = new Array();
	for (var i = 0; (i < kids.length); i++) {
		var kid = kids[i];	
		if (kid.nodeName == "UL") {
			kid.style.display = "none";
			outlineInitOutline(kid);
			hasKids = true;
			outlines[outlines.length] = kid;
		}
	}
	if (hasKids) {
		item.style.cursor = "pointer";
		var len = outlineItems.length;
		outlineItems[len] = item;
		// We can't just modify item.innerHTML, because that would
		// invalidate JavaScript objects that already refer to
		// other elements in the outlineItems array. So we use
		// the clunky DOM way of creating a span element. Then we
		// tuck the "a" element inside it so we can use
		// innerHTML for that and avoid various IE bugs.
		var div = document.createElement("div");
		div.innerHTML = "<a href='#' " +
			"onClick='outlineItemClickByOffset(" + len + 
			"); return false' " +
			"class='olink'>";
		item.insertBefore(div, kids[0]);
		item.onclick = outlineItemClick;
	}
}

function outlineGetTarget(evt)
{
	var target;
        if (!evt) {
                // Old IE
                evt = window.event;
        }
	// Prevent double event firing (sigh)
	evt.cancelBubble = true;
	if (evt.stopPropagation) {
		evt.stopPropagation();
	}
        var target = evt.target;
        if (!target) {
                // Old IE
                target = evt.srcElement;
        }
	return target;
}

function outlineItemClickByOffset(id)
{
	outlineItemClickBody(outlineItems[id]);
}

function outlineItemClick(evt)
{
	target = outlineGetTarget(evt);
	outlineItemClickBody(target);
}

function outlineItemClickBody(target)
{
	var closed = true;
	var kids = target.childNodes;
	var hasKids = false;
	for (var i = 0; (i < kids.length); i++) {
		var kid = kids[i];	
		if (kid.nodeName == "UL") {
			if (kid.style.display == "none") {
				kid.style.display = "block";
			} else {	
				kid.style.display = "none";
				closed = false;
			}
			hasKids = true;
		}
	}
	if (!hasKids) {
		// We're here because of a click on a
		// childless node. Ignore that.
		return;
	}	
}
	
function outlineGetDescendantWithClassName(parent, cn)
{
	// Regular expression: beginning with class name, or
	// class name preceded by a space; and ending with class name, or
	// class name followed by a space. Covers the ways a single class
	// name can appear with or without others in the className attribute.
	var elements = parent.childNodes;
	var length = elements.length;
	var i;
	var regexp = new RegExp("(^| )" + cn + "( |$)");
	for (i = 0; (i < length); i++) {
		if (regexp.test(elements[i].className)) {
			return elements[i];
		}
		var result = outlineGetDescendantWithClassName(
			elements[i], cn);	
		if (result) {
			return result;
		}
	}
	return null;
}

function outlineGetTopLevelLists()
{
	// Regular expression: beginning with class name, or
	// class name preceded by a space; and ending with class name, or
	// class name followed by a space. Covers the ways a single class
	// name can appear with or without others in the className attribute.
	var cn = "outline";
	var elements = document.getElementsByTagName("ul");
	var length = elements.length;
	var i;
	var regexp = new RegExp("(^| )" + cn + "( |$)");
	var results = new Array();
	for (i = 0; (i < length); i++) {
		if (regexp.test(elements[i].className)) {
			results.push(elements[i]);
		}
	}
	return results;
}