/**
 * Raleigh specific classes. Requires Prototype and Scriptaculous libraries.
 * Author: Kris Hedstrom / POP. Unless otherwise noted.
 */
Slider = Class.create();
Slider.prototype = {
	    
	    initialize: function (pageid, options){
	        
	        var panelInit = true;
	        this.pageid = $(pageid);
			this.removeNonJs = $('slider_content_container').removeClassName('nojs');
	        this.scrollwindow = this.pageid.down('div#slider_window', 0); /* go "down" into the dom */
            
            /* -- debugging 
				console.log ("this.scrollwindow: " + this.scrollwindow); */
            /* -- end debugging */
            	        
            /* 
             * Setup some sensible defaults for the options 
             */     
	        this.options = Object.extend({ duration: 1.0 }, options || {});

	        this.events = {
	          click: this.click.bindAsEventListener(this)
	        };

	        this.__btn_Click();
	        
	        /*
	         * Hide the preloader
	         */
	        if (panelInit && $('slider_nav')){
	            this.slideTo('panel_1', this.scrollwindow, { duration: 0.8 });
	            $('slider_nav').down(0).addClassName('current');
	            //Effect.Fade('preload'); 
	        } 
        },
	
        __btn_Click: function() {
            
            /*
             * Find all internal anchors that start with #panel_
             */
            var subAnchors = $$('a[href^=#panel_])');
            subAnchors.invoke('observe', 'click', this.events.click);
            //subAnchors.invoke('observe', 'mouseover', this.events.click);
           
        },	

        click: function(event) {
		    //this.stop();
            var element = Event.findElement(event, 'a');
            /*
             * get the name of the element, and highlight the tab associated
             * with that subdivision 
             */
            var elementName = element.href.split("#")[1];
            var loopCounter = elementName.split("_")[1];
            var current = parseInt(loopCounter) - 1;
			var previous = parseInt(loopCounter) - 1;
            var next = parseInt(loopCounter) + 1;
            var sectionNamePrevious = "panel_" + previous;
            var sectionNameNext = "panel_" + next;
            var navNodes = $('slider_nav').childElements();		
			
			/*
			 * Loop through the navigation tabs and remove "current" classes
			 */
			 navNodes.each(function(navNode){
			 	navNode.removeClassName('current');
			 });
			
			navNodes[current].addClassName('current');
					
            if (this.slider){
                this.slider.cancel();
            }
            this.slideTo(elementName, this.scrollwindow, { duration:this.options.duration });     
            Event.stop(event);
            var sectionList = $('more_bikes').childElements();
            if(sectionList.include($(sectionNamePrevious))){
				$('button_arrow_previous').href = "#panel_" + previous;
				$('button_arrow_previous').className = 'enable';
            }
            else {
				$('button_arrow_previous').className = 'disable';
				$('button_arrow_previous').href = "#panel_" + loopCounter;
			}
            if(sectionList.include($(sectionNameNext))){
				$('button_arrow_next').href = "#panel_" + next;
				$('button_arrow_next').className = 'enable';
			}
			else {
				$('button_arrow_next').className = 'disable';
				$('button_arrow_next').href = "#panel_" + loopCounter;
			}	            
        },

	    slideTo: function(currentElement, slideWindow, options){
	        var windowOffset = Position.cumulativeOffset(slideWindow), elementOffset = Position.cumulativeOffset($(currentElement));
            /*
		     * subtract 30px to make up for left padding
             */ 
		    var elementAdjustX = elementOffset[0]-30;
		    /* 
             * Call scroll effect - script.aculo.us extended effect
             */
		    this.slider = new Effect.Hscroller(slideWindow, {duration:options.duration, x:(elementAdjustX-windowOffset[0])});
		}
};

/**
 * Modified by Kris Hedstrom / POP from Tooltip.js by Jonathan Weiss 
 * Copyright (c) 2006 Jonathan Weiss <jw@innerewut.de>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
var Tooltip = Class.create();
Tooltip.prototype = {
  
		initialize: function(element, tool_tip) {
		  	
		    var options = Object.extend({
		      	default_css: false,
			    min_distance_x: -65,
		      	min_distance_y: 10,
		      	delta_x: 0,
		      	delta_y: -10,
		      	zindex: 1000
		    }, arguments[2] || {});
		
		    this.element = $(element);
		    this.options = options;
		
			/* attempt to make it scalable */
			this.tool_tip = $(document.createElement("div")); 
		    document.body.appendChild(this.tool_tip);
		    this.tool_tip.addClassName("tooltip");
			
			var tool_tip_middle = this.tool_tip.appendChild($(document.createElement("div"))).addClassName("tooltip_mid");
			var tool_tip_middle_span = tool_tip_middle.appendChild(document.createElement("span"));
			tool_tip_middle_span.appendChild(document.createTextNode(tool_tip));
			var tool_tip_bottom = this.tool_tip.appendChild($(document.createElement("div"))).addClassName("tooltip_bottom");
		
		    // hide the tool-tip by default
		    this.tool_tip.hide();
			
		    this.eventMouseOver = this.showTooltip.bindAsEventListener(this);
		    this.eventMouseOut   = this.hideTooltip.bindAsEventListener(this);
		    this.eventMouseMove  = this.moveTooltip.bindAsEventListener(this);
		
		    this.registerEvents();
		  },
		
		  destroy: function() {
		    Event.stopObserving(this.element, "mouseover", this.eventMouseOver);
		    Event.stopObserving(this.element, "mouseout", this.eventMouseOut);
		    Event.stopObserving(this.element, "mousemove", this.eventMouseMove);
		  },
		
		  registerEvents: function() {
		    Event.observe(this.element, "mouseover", this.eventMouseOver);
		    Event.observe(this.element, "mouseout", this.eventMouseOut);
		    Event.observe(this.element, "mousemove", this.eventMouseMove);
		  },
		
		  moveTooltip: function(event){
			  //this.tip_height = height;
			  Event.stop(event);
			  // get Mouse position
		      var mouse_x = Event.pointerX(event);
			  var mouse_y = Event.pointerY(event);
			  
			  mouse_x = mouse_x + this.options.min_distance_x;
			  mouse_y = (mouse_y - this.options.min_distance_y);
			  //console.log(mouse_y);
			  
			  // set the styles
			  this.setStyles(mouse_x, mouse_y);
		  },
			
		  showTooltip: function(event) {
		    Event.stop(event);
			//console.log(this.tool_tip.getHeight());
			var height = this.tool_tip.getHeight();
			this.options.delta_y = height;
			//alert(this.options.delta_y);				

		    this.moveTooltip(event);
			Element.show(this.tool_tip);
		  },
		  
		  setStyles: function(x, y){
		    // set the right styles to position the tool tip
			 Element.setStyle(this.tool_tip, { 
			 	position:'absolute',
			 	top:y - this.options.delta_y + "px",
			 	left:x + this.options.delta_x + "px",
				zindex:this.options.zindex
			 });
		  },
		
		  hideTooltip: function(event){
			  Element.hide(this.tool_tip);
		  }
}

/**
 * Modified by Kris Hedstrom / POP from Stipey.Js by Aaron Gustafson
------------------------------------------------------------------------------
Function: Stripey()
Author: Aaron Gustafson (aaron at easy-designs dot net)
Creation Date: 28 August 2006
Version: 0.1
Homepage: http://code.google.com/p/easy-designs/Stripey
License: MIT License (see homepage)
------------------------------------------------------------------------------*/
var Striping = Class.create();
Striping.prototype = {
		el:         false,
  		type:       false,
  		// Default odd and even classes
  		odd:        'odd',
  		even:       'even',
  		curr_class: false,
  		initialize: function(id, odd, even) {

	    	// Get the element
	    	this.el = $( id );
	
	    	/* Check the type. We are looking for UL, OL, DL or TABLE */
	    	this.type = this.el.nodeName.toLowerCase();
	
	    	// Set the odd and even classes, if provided
	    	if( typeof( odd ) != 'undefined' ) this.odd = odd;
	    	if( typeof( even ) != 'undefined' ) this.even = even;
	
	    	// Stripe it
	    	this.stripeit();

  		},
  
  		stripeit: function(){
    		var collection, len, even = this.even, odd = this.odd, i;
    		if( this.type == 'ol' || this.type == 'ul' ){
      			collection = this.el.getElementsByTagName( 'li' );
      			len = collection.length;
      			for( i=0; i<len; i++ ){
        			this.curr_class = ( ( i & 1 ) == 0 ) ? odd : even;
        			Element.addClassName( collection[i], this.curr_class );
      			}
    		}
			else if( this.type == 'dl' ){
      			Element.cleanWhitespace( this.el );
      			this.curr_class = odd;
      			collection = $A( this.el.childNodes );
      			collection.each( function( item ){
        			Element.addClassName( item, this.curr_class );
        			if( item.nextSibling && ( item.nodeName.toLowerCase() == 'dd' && item.nextSibling.nodeName.toLowerCase() == 'dt' ) ){
          				this.curr_class = ( this.curr_class == odd ) ? even : odd;
        			}
      			}.bind( this ) );
    		}
			else if( this.type == 'table' ){
      			collection = this.el.getElementsByTagName( 'tr' );
      			len = collection.length;
      			for( i=0; i<len; i++ ){
	        		if( collection[i].parentNode.nodeName.toLowerCase() == 'thead' || collection[i].parentNode.nodeName.toLowerCase() == 'tfoot' ){
	          			continue;
	        		}
	        		this.curr_class = ( ( i & 1 ) == 0 ) ? odd : even;
	        		Element.addClassName( collection[i], this.curr_class );
      			}
    		}
			else{ }
  		}
};

var CompareBikes = Class.create({
  	// Default tableid
	sTableId: '1',
	//initialize: function (sUrl, iBid, sUpdateElementId, sTableId) {
	initialize: function (sUrl, sTableId) {
		var CompareBikes = this;
		CompareBikes.url = sUrl;
		//this.bid = sBid;
		/*this.updateElement = $(sUpdateElementId);
		this.updateElementId = sUpdateElementId;*/
		this.sTableId = sTableId;
		
		CompareBikes.bid = 'bid' + sTableId;
		
		var change_bike_id = "change_bike_" + sTableId;	
		var header_id = "bike_header_" + sTableId;
		var extras_id = "bike_extras_" + sTableId;
		var content_id = "content_" + sTableId;		
		var form_id = "compare_form_" + sTableId;			
		
		this.change_bike_id = change_bike_id;
		this.header_id = header_id;
		this.extras_id = extras_id;
		this.content_id = content_id;
		this.form_id = form_id;
		
		// This should probably happen after the update takes place
		//this.updateElement.removeClassName('hide');
	
		Event.observe($(CompareBikes.bid), "change", function(e){
			this.bid = $F(CompareBikes.bid);
			var opt = {
				method:'post',
				postBody:'bid=' + this.bid,
				// onLoading is not guaranteed to always work...
				onLoading: function(transport) { 
					CompareBikes.loadHandle(sTableId);
				},				
				onSuccess: function(transport) {
					var json = transport.responseText.evalJSON(true);
					CompareBikes.jsonHandle(json, sTableId);
				},
				onFailure: function() { 
					alert('Oops! Something went wrong...') 
				}
			};		
			var myAjax = new Ajax.Request(CompareBikes.url, opt);
		});
		
		if ($(this.change_bike_id)){
			Event.observe(this.change_bike_id, "click", this.changeBike.bindAsEventListener(this));				
		}	
	},
	
	jsonHandle: function (json, sTableId) {
	
		var table_prefix = "cell_" + sTableId + "_";	
		var table_cell_id = "";

		if(json.failure) {
			$(this.content_id).update(json.failure).show();
			$(this.form_id).show();	
		}
		else {
			// Update the header... set a little script.aculo.us effect on it... um, maybe.
			var header_html = json.bike_title + " <span>" + json.model_year + "</span>";	
			$(this.header_id).update(header_html);
			
			//$(header_id).toggleClassName('compare_bike_default');
			$(this.header_id).removeClassName('compare_bike_default');
			new Effect.Highlight($(this.header_id));	
	
			// update 'extras' div
			var extras_html = '<p><a href="' + json.bike_url + '">Go to bike overview</a> | <a href="#" id="' + this.change_bike_id +'">Change bike</a></p>';			
			$(this.extras_id).update(extras_html);
			$(this.extras_id).style.display = "block";
			
			Event.observe(this.change_bike_id, "click", this.changeBike.bindAsEventListener(this));
			
			// Update the content div with the bike image. First, make sure the form is really hidden.
			$(this.form_id).style.display = 'none';		
			//$(content_id).update(loading_message);
			var content_html = '<img src="' + json.photo_url + '" alt="' + json.bike_title + '" />';
			$(this.content_id).update(content_html);
			$(this.content_id).style.display = "block";
			
			// Create a hash and get each key/value pair.  
			$H(json).each(function(num) {
				table_cell_id = table_prefix + num.key;
				// Map key to a specific id in the table.
				// Check if the cell id exist first, before trying to assing it a value	
				if ($(table_cell_id)) {
					$(table_cell_id).update(num.value);	
				}
		
			});
		}
	},
	
	loadHandle: function(sTableId) {
		var content_id = "content_" + sTableId;
		var form_id = "compare_form_" + sTableId;	
		var path = window.rootVirtual;
		if (typeof path != 'undefined') {
			var loading_message = '<p><img src="' + path +'/_img/ajax_loader.gif" alt="loading" /> Loading...</p>'; 
		}	
		else {
			var loading_message = '<p>Loading...</p>'; 
		}				
		// Hide the forms. Update content id with loading message
		$(form_id).style.display = 'none';		
		$(content_id).update(loading_message);
	},
	
	changeBike: function(event) {
		Event.stop(event);
		// set style display: "none". Otherwise IE will shift the form down (still has display: "block" on the
		// (now) empty divs
		$(this.content_id).style.display = "none";
		$(this.content_id).update();
		$(this.extras_id).style.display = "none";
		$(this.extras_id).update();
		$(this.header_id).toggleClassName('compare_bike_default');
		$(this.header_id).update("Compare Another Bike");
		$(this.form_id).style.display = "block";
		$$('td[id^=cell_'+this.sTableId+'])').invoke('update');
	}		
	
});

Effect.Vscroller = Class.create();
Object.extend (Object.extend (Effect.Vscroller.prototype, Effect.Base.prototype), {
        
        initialize: function(element) {
            
            this.element = $(element);
            var options = Object.extend({
                from: 0,
                to: 0
            } , arguments[1] || {}  );
            
            this.start(options);
            
          },
          setup: function() {
          },
          update: function(position) {   
            this.element.style.top = position + "px";
          }
});

Effect.Hscroller = Class.create();
Object.extend (Object.extend (Effect.Hscroller.prototype, Effect.Base.prototype), {
        
        initialize: function(element) {
            
            this.element = $(element);
            var options = Object.extend({
                x:    0
            } , arguments[1] || {}  );
            
            this.start(options);
          },
          setup: function() {
            this.originalLeft = this.element.scrollLeft;
            this.options.x -= this.originalLeft;
          },
          update: function(position) {   
            this.element.scrollLeft = this.options.x * position + this.originalLeft;
          }
});

/**
 * Author: Dan Dean / POP
 */
var InPlaceInputLabel = Class.create();
InPlaceInputLabel.prototype = {
	initialize: function(sInputID) {
		this.input = $(sInputID);
		this.lbl = $$('label[for='+ sInputID +']')[0];
		if (this.input && this.lbl) {
			this.lbl.addClassName('overlay');
			this.input.setAttribute('label',this.lbl.innerHTML.strip());
			if (this.input.getAttribute('type') == 'password') {
				this.ispassword = true;
				this.input.setAttribute('ispassword','true');
				this.input.setAttribute('type','text');
			}
			this.form = this.input.up('form');
			
			Event.observe(this.input,'focus',this.__Focus.bindAsEventListener(this));
			Event.observe(this.input,'blur',this.__Blur.bindAsEventListener(this));
			Event.observe(this.form,'submit',this.__Submit.bindAsEventListener(this));

	    	this.updateLabel();

		}
	},
	/**
	 * Hides the 'label' text for the field, if the text has not changed
	 */
	hideLabel: function() {
		if (this.input.value.strip() == this.input.getAttribute('label')) {
			this.input.value = ''; // removes label text
			this.input.removeClassName('label');
			if (this.ispassword) {
				this.input.setAttribute('type','password');
			}
		}
	},
	/**
	 * Sets the value of the label to the LABEL text, if no other value is in place.
	 */
	updateLabel: function() {
	    if (this.input.value.strip().length == 0) {
			this.input.value = this.input.getAttribute('label');
			this.input.addClassName('label');
			if (this.ispassword) {
				this.input.setAttribute('type','text');
			}
	    }
	},
	__Focus: function(e) {
		this.hideLabel();
	},
	__Blur: function(e) {
		this.updateLabel();
	},
	__Submit: function(e) {
		this.hideLabel();
	}
}

var InPlaceLabelOptional = Class.create();
InPlaceLabelOptional.prototype = {
	initialize: function() {
		var optionals = $$('.optional');
		
			
		for(var i=0; i < optionals.length; i++) {
			if (optionals[i].nodeName.toLowerCase() == 'input' || optionals[i].nodeName.toLowerCase() == 'textarea') {
				var el = optionals[i];
				this.form = el.up('form');
				
				Event.observe(el,'focus',this.__Focus.bindAsEventListener(this, el));
				Event.observe(el,'blur',this.__Blur.bindAsEventListener(this, el));
				Event.observe(this.form,'submit',this.__Submit.bindAsEventListener(this, el));
				
		    	this.updateLabel(el);
			}	
		}
	},
	/**
	 * Hides the 'label' text for the field, if the text has not changed
	 */
	hideLabel: function(el) {
		if (el.value.strip() == 'Optional') {
			el.value = ''; // removes 'Optional' text
		}
	},
	/**
	 * Sets the value to be "Optional", if no other value is in place.
	 */
	updateLabel: function(el) {
	    
		if (el.value.strip().length == 0) {
			el.value = 'Optional';
	    }
	},
	__Focus: function(e, el) {
		this.hideLabel(el);
	},
	__Blur: function(e, el) {
		this.updateLabel(el);
	},
	__Submit: function(e, el) {
		this.hideLabel(el);
	}
}

var DisplayWindow = Class.create({
	sCaller: '.popup',
	sCloser: '.close',
	sRefreshParent: '.refresh_parent',
	/**
	 * 
	 * @param {String} sCaller CSS of calling element(s)
	 * @param {String} sCloser CSS of element(s) that should close the window
	 * @param {String} sRefreshParent CSS of Parent Element (opens link in parent window and closes DisplayWindow) 
	 */
	initialize: function (sCaller, sCloser, sRefreshParent) {
		//var open = $$(sCaller);
		//var close = $$(sCloser);

		this.open = (typeof sCaller == 'undefined') ? $$(this.sCaller) : $$(sCaller);
		this.close = (typeof sCloser == 'undefined') ? $$(this.sCloser) : $$(sCloser); 
		this.parent = (typeof sRefreshParent == 'undefined') ? $$(this.sRefreshParent) : $$(sRefreshParent); 
		
		this.open.invoke('observe', 'click', this.activate.bindAsEventListener(this));
		this.close.invoke('observe', 'click', this.deactivate.bindAsEventListener(this));
		this.parent.invoke('observe', 'click', this.refreshParent.bindAsEventListener(this));
		//target_blank.invoke('observe','click', this.__Click.bindAsEventListener(this));
	},
	
	activate: function (e) {
		
		var el = Event.element(e);
 		var url = el.readAttribute('href');
		
		// Does the element have a title? If so use that as the window name
		if (el.readAttribute('title')){
			var windowName = escape(el.readAttribute('title'));
		}
		else {
			var windowName = "DisplayWindow";
		}
		
		// Check for options set in the rel
		if (el.readAttribute('rel')) {
			var options = el.readAttribute('rel');
		}
		// if not use some default values 
		else {
			var options = "width=500,height=400,location=yes,menubar=yes,status=yes,toolbar=yes,scrollbars=yes";
		}
		
		// Open window and give it focus
		var win = window.open(url, windowName, options);
		if (window.focus) {
			win.focus()
		}
		
		// Stop default browser event
		Event.stop(e);
	},
	
	deactivate: function(e){
		window.close();
		//Event.stop(e);
	},
	
	refreshParent: function(e) {
		var el = Event.element(e);
 		var url = el.readAttribute('href');
		//console.log(url);
		//console.log(window.parent.parent.location.href);
		//console.log(window.parent.parent);
		if(window.opener){
			window.opener.location.href = url;
			this.deactivate();
			Event.stop(e);			
		}
		else {
			// Do nada. The user opened this up in a new tab / window themselves, let the browser
			// decide how to deal with the link (IE will ask if the user wants to close current tab / window and open
			// link in parent window. All other browsers will open the link in the same window)
		}	

	}
});

var Sub_photo = Class.create({
	
	initialize: function () {
		var sub_photo = $$('a.sub_photo');
		var target_image = $('current_photo');
		var target_image_link = $('current_image_link');
		var target_text_link = $('current_text_link');
		
		this.sub_photo = sub_photo;
		this.target_image = target_image;
		this.target_image_link = target_image_link;
		this.target_text_link = target_text_link;
		
		this.sub_photo.invoke('observe','click', this.__Click.bindAsEventListener(this));
	},
	
	__Click: function (e) {
		
		var el = Event.element(e);
 		var url = el.readAttribute('href');
		
		// Remove / set classname 'on'
		this.sub_photo.invoke('removeClassName','on');
		el.addClassName('on');		
		
		// Does the element have a rel attribute? If so use that as the href for lightwindow,
		if (el.readAttribute('rel')){
			this.target_text_link.show();
			
			var rel = el.readAttribute('rel');
			this.target_image_link.writeAttribute('href', rel);
			this.target_text_link.writeAttribute('href', rel);

		}
		// if not, hide text link and set lightwindow href to current photo
		else {
			this.target_text_link.hide();
			this.target_image_link.writeAttribute('href', url);
		}
		
		this.target_image.writeAttribute('src', url);
		
		// Stop default browser event
		Event.stop(e);
	}
});

var AdjustFooter = Class.create({
	
	initialize: function(){
		// 1000px is the assumed height of background photo
		if(document.viewport.getHeight() > 1000){
			var footerOffset = document.viewport.getHeight()-1010; // leave 10px padding
			$('footer').setStyle({bottom: footerOffset + 'px'});
		}
		Event.observe(window, 'resize', function() { 
			if ($('home').getHeight() < 1000) {
				$('footer').setStyle({bottom: '0'});
			}
			else {
				var footerOffset = $('home').getHeight()-1010; // leave 10px padding
				$('footer').setStyle({bottom: footerOffset + 'px'});
			}
		});
	}	
});	

var Flyout = Class.create({
	/* Default values */
	sCaller: 'dealer',
	sContainer: 'flyout',
	sEventType: 'click',
	bTimeOut: false,
	sTimer: 10000,
	/**
	 * @param {String} sCaller ID of calling element (most often the id of the link that opens flyout div)
	 * @param {String} sContainer Container for flyout element
	 * @param {String} sEventType Type of event, i.e. 'click', 'mouseover'
	 * @param {Boolean} sTimeOut Should the flyout auto-close if left open too long? True / false
	 * @param {Int} sTimer Time, in microseconds, before the flyout should close (only used if sTimeOut == true
	 * @param {String} sCloser ID of the element that closes the element. If not called, flyout will close on mouseout
	 */
	initialize: function(sCaller, sContainer, sEventType, bTimeOut, sTimer, sCloser) {
		/*var flyoutContainer = $(sContainer);*/
		this.sCaller = (typeof sCaller != 'undefined') ? sCaller : this.sCaller;
		this.sContainer = (typeof sContainer != 'undefined') ? sContainer : this.sContainer;
		this.sEventType = (typeof sEventType != 'undefined') ? sEventType : this.sEventType;
		this.bTimeOut = (typeof bTimeOut != 'undefined') ? bTimeOut : this.bTimeOut;
		this.sTimer = (typeof sTimer != 'undefined') ? sTimer : this.sTimer;
		//this.sCloser = (typeof sCloser != 'undefined') ? sCloser : this.sCloser;
		
		var caller = $(this.sCaller);
		var flyoutContainer = $(this.sContainer);
		this.flyoutContainer = flyoutContainer;
		
		/*this.events = {
      		mouseOver: this.mouseOver.bindAsEventListener(this),
      		mouseOut:  this.mouseOut.bindAsEventListener(this),
      		mouseMove: this.mouseMove.bindAsEventListener(this),
			click: this.click.bindAsEventListener(this)
    	}*/
		
		this.deactivate = this.deactivate.bindAsEventListener(this);
		
		caller.observe(this.sEventType, this.activate.bindAsEventListener(this));
		if (typeof sCloser != 'undefined') {
			var closer = $(sCloser);
			//closer.observe('click', this.deactivate.bindAsEventListener(this));
			Event.observe(closer, 'click', this.deactivate);
		}
		else {
			// mouseout applies to all element, creates problems with nested elements
			// might need alternative solution
			//Event.observe(this.flyoutContainer, 'mouseout', this.deactivate);

		}	
	},
	
	activate: function(e) {
		this.flyoutContainer.toggle();
		Event.stop(e); // Stop the default browser event propagation, if any
		if(this.bTimeOut == true) {
			this.timer();
		}
	},
	
	deactivate: function() {
		this.flyoutContainer.hide();
		clearTimeout(this.timeout);
	},
	/* not implemented, IE hides form buttons
	deactivateAnimation: function(e) {
		new Effect.Fade(this.flyoutContainer, 
							{ 	duration: 0.5,
      							transition: Effect.Transitions.linear, 
      							from: 1.0, to: 0
							 });
		clearTimeout(this.timeout);					 
		//new Effect.Squish(this.flyoutContainer);					
								
	},*/
	
	timer: function() {
		var thisFlyout = this;
		this.timeout = setTimeout(function(){thisFlyout.deactivate();}, this.sTimer);
	}
	
});

var CascadingSelect = Class.create({
	/**
	 * Create cascading selects, one select dropdown controls its slave. Sassy.
	 */
	initialize: function(sMasterMsg, sSlaveMsg){
		var selects = $$('select.cascading');
		var Scope = this;

		for (var i = 0; i < selects.length; i++) {
			
			var master = Scope.createMaster(selects[i]);
			if (!selects[i].hasAttribute('title')) {
				Scope.updateSlave(Scope, master);
			}	
			Event.observe(master, 'change', Scope.updateSlave.bindAsEventListener(Scope, master));
		}
	},
	
	createMaster: function(select) {
		var master = new Element('select');
		master.id = select.id + '_master';
		var title = select.readAttribute('title');
		master.setAttribute('name', master.id);
		if (title) {
			master.insert({
				top: '<option>' + title + '</option>'
			});
		}
		master._slave = select;
		master._slave.hide();
		var children = select.childElements();
		for (var i = 0; i < children.length; i++) {
			var optgroup = children[i];
			var optgroupLabel = children[i].readAttribute('label');
			var masterOption = new Element('option').update(optgroupLabel);

			master.insert(masterOption);
			var slaveOptions = [];
			var optgroupChildren = optgroup.childElements();
			for (var j = 0; j < optgroupChildren.length; j++) {
				var option = optgroupChildren[j];
				slaveOptions[slaveOptions.length] = option;
				//console.log(slaveOptions);
				optgroup.removeChild(option);	
			}
			if (children[i].hasAttribute('title')) {
				var optgroupTitle = children[i].readAttribute('title');
				var optionDefault = new Element('option').update(optgroupTitle);
				slaveOptions.unshift(optionDefault);
			}
			masterOption._slaveOptions = slaveOptions;
			select.removeChild(optgroup);
		}
		select.parentNode.insertBefore(master, select);
		
		return master;
		
	},
	
	updateSlave: function(event, master){
		//console.log(master._slave);
		var selectedOption = master.options[master.selectedIndex];
		
		// Empty the slave select
		while (master._slave.hasChildNodes()) {
			master._slave.removeChild(master._slave.firstChild);
		}
		if (selectedOption._slaveOptions) {
			// Insert (append) the array of options into the slave select
			for (var i = 0; i < selectedOption._slaveOptions.length; i++) {
				master._slave.appendChild(selectedOption._slaveOptions[i]);
			}
			master._slave.selectedIndex = 0;
			master._slave.show();
		}
		else {
			master._slave.hide();
		}
	}
});

var Adjuster = Class.create({
	
	initialize: function(){
		var bread_crumbs = $$('ul#nav_bread li');
		var last_item = bread_crumbs.length-1;
		bread_crumbs[last_item].addClassName('last');
	}	
});

document.observe('dom:loaded', function(){
  var labelPlaceCity = new InPlaceInputLabel('find_dealer_city');
  var labelPlaceZip = new InPlaceInputLabel('find_dealer_zip');
  var popups = new DisplayWindow('.display_win', '.close');
  var switch_photo = new Sub_photo();
  var cascading_selects = new CascadingSelect();
  if($('nav_bread')){
  	var adjust_crumbs = new Adjuster();
  }
  
  if($('dealer')) {
  	var flyout = new Flyout('dealer', 'dealer_flyout', 'click', true, 60000, 'close_button');
  }	
    
  if ($('jumpmenu')) {
  	$('submit_bike').addClassName('hide');
	$("jumpmenu").getElements().invoke("observe", "change", function(event) {
	  var select = $('jumpmenu')['select_bike'];
	  if ($F(select) != "") {
	  	window.location.href = $F(select);	
	  }
	});
  } 
  
  if ($('bike_page') && $('slider_window')) {
  	var slider = new Slider('bike_page', {duration: 0.5});
  }
 
  if ($('more_bikes')) {
	  $$('#more_bikes img[title]').findAll(function(node){
	  		return node.getAttribute('title');
	   		}).each(function(node){
	  			var tooltip = new Tooltip(node,node.title, {default_css: false});
	        	node.removeAttribute("title");
				// remove alt attribute too, otherwise IE will show default tooltip => annoying
				node.removeAttribute("alt"); 
	  });
   }
   
   if($('home') && $('footer')){
		var adjust = new AdjustFooter();
	}  

	/*if($('loading_msg') && $('register_description')) {
		$('loading_msg').update('Contacting National Bike Registry, please wait');
	}*/
     
}); 
