	YAHOO.namespace("YAHOO.util.App");
	
	var Dom = YAHOO.util.Dom;
	var Evt = YAHOO.util.Event;
	var Fn  = YAHOO.util.Functional;
	var App = YAHOO.util.App;
	
	YAHOO.lang.augmentObject(App, {
	  show: function (el, fn) { 
	    Dom.setStyle(el, 'display', 'block');
	    if (typeof fn === "function") { fn(Dom.get(el)); }
	  },
	
	  hide: function (el, fn) {
	    Dom.setStyle(el, 'display', 'none');
	    if (typeof fn === "function") { fn(Dom.get(el)); }
	  },
	
	  is_hidden: function (el) {
	    return ('none' === Dom.getStyle(el, 'display') || 'hidden' === Dom.getStyle(el, 'visibility'));
	  },
	
	  // Toggle any block-level element by setting its display style
	  toggleDisplay: function (el, onshow, onhide) {
	    if (this.is_hidden(el)) {
	      this.show(el, onshow);   
	    }
	    else {
	      this.hide(el, onhide); 
	    }
	  },
		
		remove_element: function(el) {
			Dom.get(el).parentNode.removeChild(Dom.get(el));
		}		
	});
	
	// Credit: Dustin Diaz - http://www.dustindiaz.com/ajax-contact-updated/
	YAHOO.util.App.effects = function() {
	  return {
	    /*
	      @param {String/HTMLElement} | oEl : Accepts a string to use as an ID for getting a DOM reference, or an actual DOM reference
	      @param {Int} | iOffset : The unit (in 'px') that the element will be shaken 'by'
	      @param {Int} | iNum : The number of times the motion will iterate
	      @param {Int} | iSpeed : The speed at which the motion will animate
	    */
	  
	    shake : function(oEl, iOffset, iNum, iSpeed) {
	      var xy = YAHOO.util.Dom.getXY(oEl);
	      var left = xy[0]-iOffset;
	      var right = xy[0]+iOffset;
	      (function(type, args, count) {
	        if ( count >= iNum ) {
	          var a = {
	            points : {
	              to : xy
	            }
	          };
	          var anim = new YAHOO.util.Motion(oEl, a, iSpeed);
	          anim.animate();
	          return;
	        }
	        else if ( count % 2 ) {
	          var c = count+1;
	          var a = {
	            points : {
	              to : [right, xy[1]]
	            }
	          };
	          var anim = new YAHOO.util.Motion(oEl, a, iSpeed);
	          anim.onComplete.subscribe(arguments.callee, c);
	          anim.animate();
	        }
	        else {
	          var c = count+1;
	          var a = {
	            points : {
	              to : [left, xy[1]]
	            }
	          };
	          var anim = new YAHOO.util.Motion(oEl, a, iSpeed);
	          anim.onComplete.subscribe(arguments.callee, c);
	          anim.animate();
	        }
	      })(null, null, 1);
	    }
	  };
	}();
	
	YAHOO.lang.augmentObject(YAHOO.namespace("YAHOO.util.App.VideoPlayer"), {
	  players: {},
	  
	  find_player: function (el) {
	    if (typeof this.players[el] !== "object") {
	      var container = Dom.get(el);       
	      this.players[el] = new SWFObject('/nclweb/flash/jwplayer/4.4/player-licensed.swf', 'mpl', container.clientWidth, container.clientHeight, '9');
	      this.players[el].addParam('allowscriptaccess','always');
	      this.players[el].addParam('allowfullscreen','true');
				this.players[el].addParam('wmode','opaque');            
	    }   
	    return this.players[el];
	  },
	  
	  create: function (el, params) {
	    var container = Dom.get(el);  
	    if (typeof container !== "object") { return; }    
			
	    var flashvars = '&duration=' + params.duration + '&file=' + params.file + '&image=' + params.image;
	    
			if (typeof params.controls === "string") {
	      flashvars += '&controlbar=' + params.controls;
	    }
			
			if (typeof params.streamer === "string") {
				flashvars += "&streamer=" + params.streamer;
			}
	            
	    var so = this.find_player(el);        
	    so.addParam('flashvars', flashvars);
	    so.write(el); 
	  }
	});
	
	YAHOO.lang.augmentObject(YAHOO.namespace("YAHOO.util.App.SitewidePromos"), {  
	  buttons: {
	    plus: '/nclweb/images/promo/plus.gif',
	    minus: '/nclweb/images/promo/minus.gif' 
	  },
	  
	  attach_events: function () {
	    if (Dom.get('sitewide_toggle_btn')) {
	      Evt.on('sitewide_toggle_btn', 'click', function () {        
	        (App.is_hidden('sitewide_promo') ? App.SitewidePromos.open : App.SitewidePromos.close)();
	      });
	    } 
	  },
	  
	  randomize: function () {  
	    if (!this.promotions || 0 == this.promotions.length) { return null; }
	    return this.promotions[parseInt((Math.random() * 100)) % this.promotions.length];
	  },
	  
	  // Don't display the promotion if the current url matches any excluded pattern
	  should_display: function (promotion) {    
	    if (Fn.detect(promotion.exclude, function (exclusion) {
	      return document.location.href.match(exclusion);  
	    })) { return false; }   
	    return true;
	  },
	  
	  set_message: function (el, promotion) {
	    if (!el || !promotion || !promotion.button_text) { return; }
	    el.innerHTML = promotion.button_text;
	  },
	  
	  set_link: function (el, promotion) {
	    if (!el || !promotion || !promotion.link) { return; }
	    if (promotion.link.target) { el.target = promotion.link.target; }
	    if (promotion.link.href)   { el.href   = promotion.link.href; }
	    if (promotion.link.title)  { el.title  = promotion.link.title; }
	  },
	  
	  set_banner: function (el, promotion) {
	    if (!el || !promotion) { return; }
	    if (promotion.banner)    { el.src = promotion.banner; }
	    if (promotion.link.title)  { el.alt = promotion.link.title; }
	  },
	  
	  display: function () {
	    var selected_promotion = this.randomize();
	    
	    if (!selected_promotion || !this.should_display(selected_promotion)) { return false; }
	    if (YAHOO.env.ua.gecko && (1.9 > YAHOO.env.ua.gecko)) { return false; }
	    
	    this.set_message(Dom.get('sitewide_message'), selected_promotion);
	    this.set_link(Dom.get('sitewide_message_link'), selected_promotion);    
	    this.set_banner(Dom.get('sitewide_promo_banner'), selected_promotion);
	    this.set_link(Dom.get('sitewide_promo_link'), selected_promotion);
	    
	    if (this.should_be_closed()) {
	      this.close();
	    }
	    else {
	      this.open();
	    }
	    
	    App.show('sitewide_toggle');    
	    this.attach_events();  
	  },
	  
	  open: function () {
	    App.show('sitewide_promo', function () {
	      Dom.get('sitewide_toggle_btn').src = App.SitewidePromos.buttons.minus;
	      App.SitewidePromos.closed("false"); 
	    });  
	  },
		
		show: function () {
			this.open();
		},
	  
	  close: function () {
	    App.hide('sitewide_promo', function () {
	      Dom.get('sitewide_toggle_btn').src = App.SitewidePromos.buttons.plus;
	      App.SitewidePromos.closed("true");    
	    }); 
	  },
		
		hide: function () {
      this.close();
    },
		
		toggle: function () {
			App.is_hidden('sitewide_promo') ? App.SitewidePromos.show() : App.SitewidePromos.hide();
		},
	  
	  midnight: function () {
	    var dt = new Date();
	    dt.setHours(24);
	    dt.setMinutes(0);
	    dt.setSeconds(0);
	    return dt;
	  },
	  
	  closed: function (value) {    
	    YAHOO.util.Cookie.set('sitewide_promo_closed', value, {
	      path: "/",
	      expires: this.midnight()
	    });
	  },
	  
	  should_be_closed: function () { 
	    var cookie_value = YAHOO.util.Cookie.get('sitewide_promo_closed');  
	    if (null == cookie_value) { return false; } 
	    return ("true" == cookie_value);  
	  }
	});
	
	YAHOO.lang.augmentObject(YAHOO.namespace("YAHOO.util.App.CruiseSearch"), {
		show: function () { 			
			showCruiseSearchForm();			 			
		},
		hide: function () { 		 
      Dom.setStyle('cruiseSearchPopoutForm', 'visibility', 'hidden');       
      removeEventHandler(document, 'click', closeCruiseSearchForm, true);				
		},
		toggle: function () { App.is_hidden('cruiseSearchPopoutForm') ? App.CruiseSearch.show() : App.CruiseSearch.hide(); }
	});
	
	YAHOO.lang.augmentObject(YAHOO.namespace("YAHOO.util.App.TabView"), {
		/*
		 * Source: http://blog.davglass.com/files/yui/tab7/
		 * 
		 * example:
		 * 
		 * http://www.ncl.com/nclweb/destination/details.html?destinationCode=ALASKA#stories
		 * 
		 * would set the stories tab as active if the stories tab's 'a href' were defined as follows:
		 * 
		 * <li id="tabStories"><a href="#stories">Stories</a></li>
		 * 
		 * It does nothing if no '#' value is specified.
		 */
		selectFromUrl: function(tab_view) {
		    var url = location.href.split('#');
		    if (url[1]) {
		        var tabHash = url[1];
		        var tabs = tab_view.get('tabs');
		        for (var i = 0; i < tabs.length; i++) {
		            if (tabs[i].get('href') == '#' + tabHash) {
		                tab_view.set('activeIndex', i);
		                break;
		            }
		        }
		    }
		}
	});
	
	Evt.onContentReady("menu", function () {
		  var Sel = YAHOO.util.Selector;
			
			var menu = new YAHOO.widget.MenuBar("menu", { 
	      autosubmenudisplay: true, lazyload: false,
				showdelay: 0, hidedelay: 0
	    });
	    menu.render();
			
			Dom.getElementsByClassName('yuimenu', 'DIV', 'menu', function (el) {
				Dom.setStyle(el, 'display', 'block');
			});
			
			Evt.on(Sel.query('#menu #find_cruise'), 'click', function (e) {
        Evt.stopEvent(e);
        App.CruiseSearch.toggle();
      });
	});
	
	Evt.on(document.body, 'load', bodyOnLoad);
	
	YAHOO.register("application", App, {version: "1.0", build: "0"}); 