
// Object with commonly used properties.
NCLUtils = function() {};

NCLUtils.prototype = {
  onLoadEventCache: new Array(),
  eventInterval: null,
  isSafari: /WebKit/i.test(navigator.userAgent),
  
  /*
   * Prefixes URL with context of the application creating
   * absolute based URI. If URL does not start with / then 
   * folders after context will also be appended.
   *
   * url - URI appended to context
   */
  createURL: function(url) {
    if (document.getElementsByTagName('base').length > 0) {
      var baseURI = document.getElementsByTagName('base')[0].href;
      return '/' + baseURI.split('/')[3] + url;
    } else if (url.indexOf('/') != 0) {
      return document.location.pathname.substring(0, document.location.pathname.lastIndexOf('/')) + '/' + url;
    } else {
      return '/' + document.location.pathname.split('/')[1] + url;
    }
  },
  
  /*
   * Executes function after DOM was loaded and parsed.
   *
   * handler - reference to function to be executed after load
   * param - value passed to executed function
   * deferUntilAll - used in case handler specifies creation of flash objects.
   *                 Only used for Safari browser because it wan't display flash
   *                 until all resources are loaded 
   */
  onDocumentAvailable: function(handler, param, deferUntilAll) {
    this.onLoadEventCache.push( { eventHandler: handler, parameter: param } );
    var objRef = this;
    var readyStateString = (this.isSafari && deferUntilAll) ? /complete/ : /loaded|complete/;
    
    // Firefox
    if (document.addEventListener && !this.isSafari) {
      document.addEventListener('DOMContentLoaded', function() {objRef._handleLoadEvents(); }, false);
    } 
    // IE & Safari
    else if (this.eventInterval == null) {
      this.eventInterval = setInterval(
        function() {
          if (readyStateString.test(document.readyState)) {
            objRef._handleLoadEvents(); 
            clearInterval(objRef.eventInterval);
            objRef.eventInterval = null;
          }
        }, 10);
    }
  },

  /*
   * Executes specified functions when DOM was loaded and parsed.
   */
  _handleLoadEvents: function() {
    while (this.onLoadEventCache.length > 0) {
      this.onLoadEventCache[0].eventHandler(this.onLoadEventCache[0].parameter);
      this.onLoadEventCache.splice(0, 1);
    }
  },

  /*
   * Returns value of a CSS attribute for an element. In case of Safari
   * browser if element's display css atribute is set to none then '' will 
   * be returned for every attribute.
   *
   * elmnt - object whose styles to return
   * cssAttr - css attribute whose value to return
   */
  computedStyle: function(elmnt, cssAttr) {
    var computedStyle = null;
    elmnt = getElement(elmnt);

    if (document.defaultView && document.defaultView.getComputedStyle(elmnt, '') != null) {
      computedStyle = document.defaultView.getComputedStyle(elmnt, '').getPropertyValue(cssAttr);
    } else if (elmnt.currentStyle) {
      computedStyle = elmnt.currentStyle[cssAttr];
    } else {
      computedStyle = elmnt.style[cssAttr];
    }

    return computedStyle;
  },
  
  /*
   * Creates media object that displays flash movie.
   *
   *  id - identifier of element that will hold flash movie
   *  flashURL - location of flash movie
   *  width - width of flash movie
   *  height - height of flash movie
   *  flashVariables - additional parameters to movie
   *  bgColor - background color of flash container. Defaulted to 'transparent'
   */
  createFlashElement: function(id, flashURL, width, height, flashVariables, bgColor) {
    var flashString = '<object type="application/x-shockwave-flash" data="' + flashURL + '" width="' + width + '" height="' + height + '">'
      + '<param name="movie" value="' + flashURL + '" />'
      + '<param name="bgcolor" value="' + ((bgColor == null) ? 'transparent': bgColor) + '" />'
      + '<param name="flashvars" value="' + ((flashVariables == null) ?  '': flashVariables)+ '" />'
      + '<param name="quality" value="high" /><param name="allowScriptAccess" value="sameDomain" /><param name="wmode" value="transparent" /></object>';

    if (this.checkFlashVerAtLeast8()) {
      YAHOO.util.Dom.get(id).innerHTML = flashString;
    } else if (getElement('flashUpgradeMessage') == null) {
      var upgradeMessage = document.createElement('div');
      upgradeMessage.id = 'flashUpgradeMessage';
      upgradeMessage.innerHTML = 'If you are reading this, you are missing out on our flash content. To view it, you\'ll need to upgrade to the latest version of <a href="http://www.macromedia.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash" target="_blank">Adobe Flash</a>.';

      var container = (YAHOO.util.Dom.get('contentcenter') != null) ? YAHOO.util.Dom.get('contentcenter'): YAHOO.util.Dom.get('contentcenterFull');
      container.insertBefore(upgradeMessage, container.firstChild);
    }
  },
  
  /*
   * Tests flash plug-in version is at least 8.
   */
  checkFlashVerAtLeast8: function() {
    var pluginFound = false;
  
    if (navigator.plugins && navigator.plugins["Shockwave Flash"]
        && parseInt(navigator.plugins["Shockwave Flash"].description.match(/\d+/)) >= 8) {
      pluginFound = true;
    } else {
      try {
        new ActiveXObject("ShockwaveFlash.ShockwaveFlash.8");
        pluginFound = true;
      } catch (exception) {}
    }
  
    return pluginFound;
  },

  /*
   * Shows or hides an element. There two possible usages; if second parameter
   * has value either 'show', 'hide' or null then displays or hides element
   * identified by first parameter. If second parameter is an integer then
   * iterates through all elements on the page that are identified by first
   * parameter as prefix and counter added to prefix. Counter starts from 1,
   * if counter equals to second parameter then shows that element. Other
   * elements will be hidden.
   *
   * contentIdPrefix - id of elements that belong to same group should start
   *                   with this string. Or id of element to be shown or hidden
   * index - after prefix comes number that identifies element in group
   *         This parameter has dual usage its value could be an integer or 
   *         string with value 'show' or 'hide' 
   */
  displayContent: function(contentIdPrefix, index) {
    var currentElmnt = getElement(contentIdPrefix);

    if (!/undefined|show|hide/.test(index)) {
      var counter = 1;
      while ((currentElmnt = getElement(contentIdPrefix + counter)) != null) {
        currentElmnt.style.display = (counter != index) ? 'none': 'block';
        counter++;
      }
    } else if (index == 'show' || NCLUtils.computedStyle(currentElmnt, 'display') == ''
               || NCLUtils.computedStyle(currentElmnt, 'display') == 'none' && /undefined|show/.test(index)) {
      currentElmnt.style.display = 'block';
    } else {
      currentElmnt.style.display = 'none';
    }
  },
  
  /*
   * Converts form values to a string of URL parameters.
   * 
   * formId - The id of the form
   */
  collectFormValues: function (formId) {
		var textFields = Dom.get(formId).getElementsByTagName('input');
		var dropDowns = Dom.get(formId).getElementsByTagName('select');
		var values = '';

		for ( var i = 0; i < textFields.length; i++) {
			if (!textFields[i].disabled
					&& (textFields[i].type != 'radio' || (textFields[i].type == 'radio' && textFields[i].checked))) {
				values += textFields[i].name + '='
						+ encodeURIComponent(textFields[i].value);
				if (i < (textFields.length - 1) || dropDowns.length > 0) {
					values += '&';
				}
			}
		}

		for ( var i = 0; i < dropDowns.length; i++) {

			if (dropDowns[i].className.match('no_display') == null) {
				values += dropDowns[i].name + '=' + dropDowns[i].value;
			}

			if (i < (dropDowns.length - 1)) {
				values += '&';
			}
		}

		return values;
	},
  
  
  /*
   * Cross-browser support for adding a new <tbody> element to an existing table. 
   * IE does not allow editing of a table's innerHTML so we'll edit it using a 
   * <div> wrapper surrounding the table. 
   * 
   * htmlStr - The html string that we want inside the <tbody>
   * tlbId - The id of the <table>
   * tbodyId - The id of the <tbody> that we want to replace. (optional)
   * 
   */
  addTbodyInnerHtml: function(htmlStr, tblId, tbodyId) {
	
	var tblElem = YAHOO.util.Dom.get(tblId);
	
	/* Check to see if there is already an existing tbody for the errors */
	var existingTbody = (tbodyId) ? YAHOO.util.Dom.get(tbodyId) : null;

	/* IE */
	if (YAHOO.env.ua.ie) {
		/* Remove the existing <tbody> */
		if (existingTbody) {
			tblElem.removeChild(existingTbody);
		}
		/* Create a new <tbody> element and add it to the table */
		var newTbodyElem = this.buildElement('tbody', {'id': tbodyId}, null, tblElem);
		tblElem.appendChild(newTbodyElem);
		
		/* Get all of the html inside of our <div> wrapper */
		var wrapperHtml = tblElem.parentNode.innerHTML;
		
		/* Insert our htmlStr inside the innerHTML of the div. This makes me cry. */
		var endIndex = wrapperHtml.indexOf("</TBODY></TABLE><SPAN>");
		var newHtml = wrapperHtml.substring(0, endIndex) + htmlStr + wrapperHtml.substring(endIndex, wrapperHtml.length);
		tblElem.parentNode.innerHTML = newHtml;
	}

	/* Firefox, Safari, etc.. */
	else {
		if(existingTbody) {
			existingTbody.innerHTML = htmlStr;
		}
		else {
			var tbody = this.buildElement('tbody', {'id': 'error_reservations'}, htmlStr, tblElem);
		}	
	}
  },
  
  
  /*
   * Utility function for creating a DOM element.
   * 
   * tag - The type of tag. ex. <a>, <div>, <span>, etc...
   * opts - The attributes in JSON notation - ex. {'id':'someId', 'class':'someClass'}
   * htmlStr (optional) - The innerHtml text string of the element 
   * parent (optional) - The parent element to which we want to append.
   * 
   */
  buildElement: function(tag, opts, htmlStr, parent) {
		var el = document.createElement(tag);
		if (parent) {
			parent.appendChild(el);
		}
		if (opts) {
			for ( var i in opts) {
				el.setAttribute(i, opts[i]);
			}
		}
		if (htmlStr) {
			el.innerHTML = htmlStr;
		}
		return el;
  }
};

var NCLUtils = new NCLUtils();

(function(){
	var yu = YAHOO.util;
	var Evt = yu.Event;
	var Dom = yu.Dom;
	YAHOO.namespace("ncl");
	YAHOO.ncl.Interstitial = function(element){
		var el = Dom.get(element);
		var shim = document.createElement("iframe");
		
		var appendObj = function(el, zIndex){
			Dom.get(document.body).appendChild(el);
			Dom.addClass(el, "mask");
			Dom.setStyle(el, "z-index", zIndex);
			Dom.setStyle(el, "display", "none");
			Dom.setStyle(el, "position", "absolute");
			Dom.setStyle(el, "opacity", 0);
		}
		
		appendObj(el, 10000);
		appendObj(shim, 9000);
		
		var setSize = function (el){
			Dom.setStyle(el, "height", Dom.getViewportHeight() + "px");
			Dom.setStyle(el, "width", Dom.getViewportWidth() + "px");
		};
		
		var reset = function(el){
			setSize(el);
	  		Dom.setStyle(el, "top", Dom.getDocumentScrollTop() + "px");			
		};

		return {
			show: function(){
					reset(el);
					reset(shim);
					var myAnim = new YAHOO.util.Anim(el, { 
					    opacity: { from: 0.5, to: 1 }  
					    }, 0.5); 
					Dom.setStyle(el, "display", "block");
					Dom.setStyle(shim, "display", "block");
					myAnim.animate();
					Evt.on(window, "scroll", function(e){
						reset(el);
					});
				  },
			hide: function(){
					var myAnim = new YAHOO.util.Anim(el, { 
					    opacity: { from: 0.5, to: 0 }  
					    }, 0.5); 
					myAnim.animate();
					Dom.setStyle(el, "display", "none");
					Dom.setStyle(shim, "display", "none");
					Evt.removeListener(window, "scroll");
				}	
		};
	};
	
	YAHOO.ncl.InterstitialManager = function(/* string|HTMLelement */  target, 
												 /* string */ event,
												 /* function */ callback){
		var Dom = YAHOO.util.Dom;
		var Evt = YAHOO.util.Event;
		var el = Dom.get("interstitial");
		function delay(e){
			var target = Evt.getTarget(e);
			Evt.stopEvent(e);
			var interstitial = new YAHOO.ncl.Interstitial(el);
			var pause = parseInt(Dom.getStyle(el, "pause-before")) || 3000;
			interstitial.show();
			setTimeout(callback, pause);
		}
		Evt.on(target, event, (el == null) ? callback : delay);
	};
	
})();

