//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

jQuery.fx.interval = 25

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
if (!Array.prototype.forEach)
{
  Array.prototype.forEach = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
        fun.call(thisp, this[i], i, this);
    }
  };
}

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
if (!Array.prototype.map)
{
  Array.prototype.map = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array(len);
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
        res[i] = fun.call(thisp, this[i], i, this);
    }

    return res;
  };
}

$(document).ready(
	function(){
		
		// ***** ANIMATE SHADOW FADEIN ***** //
		
		$('#shadow').animate(
			{opacity: 1.0},
			6000
		)
		// ***** REPLACE BROKEN DOWNLOAD IMAGES IN CATALOG ***** //
		
		$("#bike_dls img").error(function () {
 			$(this).unbind("error").attr("src", "/images/icons/pdf.png");
		});

		// ########## SEARCH BOX ########## //
		
		prepSearchBox = function(){
			jqSE = new Object()
			jqSE.box = $('#search_entry')
			jqSE.text = 'Search...'
			
			jqSE.box.focus(
				function(){
					if ($(this).val() == jqSE.text) {
						$(this).val('')
						$(this).css({fontStyle:'normal'})
					}
					$(this).addClass('focus')
				}
			).blur(
				function(){
					if ($(this).val() == '') {
						$(this).val(jqSE.text)
						$(this).css({fontStyle:''})
					}
					$(this).removeClass('focus')
				}
			)
		}
		prepSearchBox() //this function is used on all pages


		// ########## MASTER NAVIGATION FUNCTIONS ########## //


		
		prepMasterNav = function(callback){
			jqMN = new Object()
			jqMN.container		= $('#mn_container')
			jqMN.sectLinks		=	$('#bx4 a')
			jqMN.bikeUL			=	$('<ul class="bx6 bikes"></ul>')
			jqMN.closeLink		=	$('#mn_close')
			jqMN.contFadeDur	=	250
			jqMN.descFadeDur	=	250
			jqMN.linkFadeDur	=	250
			jqMN.live			=	null
			jqMN.indicator		=	$('<div id="mn_indicator"></div>')
			jqMN.indStrtPos		=	null
			jqMN.indBX4Offset	=	$('#bx4').position().top
			jqMN.indBX3Offset	=	$('#bx3').position().top
		
			// prepares navigation section links with related content, modifies DOM for menu presentation
			jqMN.sectLinks.each(
				function(i){
					var title = $(this).attr('href').substring(1,30)
					$(this).data('title', title)
					$(this).data('desc', jqMN.container.find('#'+title+' .bx5').detach() )
					$(this).data('bikes', jqMN.container.find('#'+title+' .bikes li').detach() )
					$(this).click(
						function(){
							activateMenu($(this))
							return false;
						}
					)
				}
			)
			
			// after processing menu, remove residual containers
			jqMN.container.find('div').remove()
			// now add the link container we'll be using
			jqMN.container.append(jqMN.bikeUL)
			// attach click handlers to the menu opening links
			jqMN.closeLink.click(
				function(){
					hideBikes('closeMenu()')
					return false;
				}
			)
		
			callback ? eval(callback) : false
		
		}
		
		// opens the menu to the section indicated with the m element
		openMenu = function(m){
			jqMN.live = m
			updateIndicator(m);
			pauseSlideShow();
			//console.log('open menu')
			jqMN.container.css({opacity:0,display:'block'}).animate(
				{opacity:1},
				jqMN.contFadeDur,
				function(){
					//console.log('more open menu')
					var desc = m.data('desc')
					showBikes(m)
					jqMN.closeLink.add(desc).css({opacity:0,display:'block'})
					jqMN.container.append(desc)
					jqMN.closeLink.add(desc).animate(
						{opacity:1},
						jqMN.linkFadeDur
					)
				}
			)
		}
			
		// changes the menu to the section indicated with the m element
		changeMenu = function(m){
			var newDesc = m.data('desc')
			var oldDesc = jqMN.live.data('desc')
			jqMN.live = m
			newDesc.css({opacity:0})
			jqMN.container.append(newDesc)
			oldDesc.animate(
				{opacity:0},
				jqMN.descFadeDur,
				function(){
					oldDesc.remove()
				}
			)
			newDesc.animate(
				{opacity:1},
				jqMN.descFadeDur
			)
			updateIndicator(m);
			hideBikes('showBikes(jqMN.live)')
		}
			
		// closes the menu and returns it to the pre-menu state
		closeMenu = function(){
			updateIndicator();
			jqMN.container.animate(
				{opacity:0},
				jqMN.contFadeDur,
				function(){
					jqMN.container.css({display:'none'})
					jqMN.closeLink.css({opacity:0,display:'none'})
					jqMN.live.data('desc').remove();
					jqMN.live = null;
					resumeSlideShow();
				}
			)
		}
			
		// displays the bike links sequentially based on the m element passed
		showBikes = function(m){
			m.data('bikes').css({opacity:0})
			jqMN.bikeUL.append(m.data('bikes'))
			m.data('bikes').each(
				function(i){
					$(this).animate(
						{opacity:0}, 
						jqMN.linkFadeDur*i 
					).animate(
						{opacity:1}, 
						jqMN.linkFadeDur * 2
					)
				}
			)
		}
			
		// hides the bike currently being displayed, callback when done hiding
		hideBikes = function(callback){
			bikeUL = jqMN.bikeUL
			bikeUL.animate(
				{opacity:0},
				jqMN.lindFadeDur,
				function(){
					$(this).empty().css({opacity:1})
					eval(callback)
				}
			)
		}
			
		// updates the position of the indicator based on selected section, current visibility, and start status (vis or not)
		updateIndicator = function(m){
			var visible = jqMN.indicator.is(':visible')
			if (m && visible) {
				// if m and visible then move
				top_offset = m.position().top + jqMN.indBX4Offset 
				jqMN.indicator.animate(
					{top:top_offset+'px'},
					jqMN.descFadeDur
				)
			} else if (m) {
				// if m and not visibile then fade in
				top_offset = m.position().top + jqMN.indBX4Offset 
				jqMN.indicator.css(
					{opacity:0,top:top_offset+'px'}
				).appendTo(
					'#box'
				).animate(
					{opacity:1},
					jqMN.descFadeDur
				)
			} else if (jqMN.indStrtPos) {
				// if no m and start pos then move to start pos
				jqMN.indicator.animate(
					{top:jqMN.indStrtPos+'px'},
					jqMN.descFadeDur
				)
			} else {
				// if no m and no start pos then fade out
				jqMN.indicator.animate(
					{opacity:0},
					jqMN.descFadeDur,
					function(){
						$(this).remove();
					}
				)
			}
		}
			
		// activates menu based on conditions of page
		activateMenu = function(m){
			//console.log(m)
			if (jqMN.live == null) {
				openMenu(m);
			} else if (jqMN.live.data('title') == m.data('title')) {
				hideBikes('closeMenu();')
			} else {
				changeMenu(m)
			}
		}
		
		prepNavIndicator = function(){
			bx3_set = $('#bx3 .mn_live')
			bx4_set = $('#bx4 .mn_live')
			if (bx3_set.length > 0){
				var top_offset = bx3_set.position().top + jqMN.indBX3Offset
			}
			if (bx4_set.length > 0){
				var top_offset = bx4_set.position().top + jqMN.indBX4Offset
			}
			jqMN.indStrtPos = top_offset
			if (top_offset) {
				jqMN.indicator.css({top:top_offset + 'px'})
				$('#box').append(jqMN.indicator)
			}
		}
		
		
		
		
		// ########## PRELOAD IMAGES FUNCTION ########## //
		
		
		
		
		

		
		preloadImages = function(imgs,callback,loadBox){
			// imgs - either single url string, or array of multiple strings
			// callback - function called, passed element with loaded images
			// loadbox - element that will display indicators
			// loadedClass - class applied to indicator elements when image done loading
			
			var defIndicatorID		=	'<div></div>'
			var defLoadedClass		=	'loaded'
			var defErrorClass		=	'error'
			
			loadBox = loadBox ? $(loadBox) : $(defIndicatorID)
			// called on each image load or error
			var checkIfDone = function(){
				// if we're at the end of the list, then finish loadbox and fire callback
				if (numberReady == imgs.length && callback) {
					$('span', loadBox).animate(
						{opacity:0},
						2000,
						function(){
							loadBox.css({display:'none'})
							$(this).remove()
						}
					)
					eval(callback+'(tempContainer)')
				}
			}
			// create array for images
			tempContainer = $()
			// keep track of how many images have been loaded
			numberReady = 0
			// create appropriate number of waiting class elements
			loadBox.append(Array(imgs.length + 1).join('<span></span>')).css({display:'block'})
			// if passed a string, then create an array
			imgs = imgs instanceof Array ? imgs : new Array(imgs) 
			// loop through img url array
			for (i=0;i<imgs.length;i++) {
				// create the image. use 'order' as dirty hack since they don't load in order
				var theImg = $(new Image())
				theImg.data('sequence',i)
				// put the new image in the temp container
				tempContainer = tempContainer.add(theImg)
				// attach load event to the image to update status indicators
				theImg.load(
					function(){
						// update the indicator
						$('span:eq('+$(this).data('sequence')+')',loadBox).addClass(defLoadedClass)
						// incriment the indicator counter
						numberReady++
						// if we're done loading everything, pass image container to the callback
						checkIfDone()
					}
				).error(
					function(){
						// update the indicator
						$('span:eq('+$(this).data('sequence')+')',loadBox).addClass(defErrorClass)
						// incriment the indicator counter
						numberReady++
						// remove the fauly image from the temp container
						tempContainer = tempContainer.not($(this))
						// 
						checkIfDone()
					}
				).attr('src',imgs[i]) // apply src AFTER load to make IE happy
			}
		}

		
		
		
		// ########## SLIDESHOW FUNCTIONS ########## //
		
		
		
		
		
		// prepare images, but in container, and start slideshow
		prepSlideShow = function(imgsContainer){
			jqSS = new Object
			jqSS.container	=	imgsContainer
			jqSS.pauseDur	=	7000
			jqSS.fadeDur	=	1500
			jqSS.slideImgs	=	null
			jqSS.curSlide	=	0
			jqSS.timer		=	null
			
			imgs = jqSS.container.attr('slides').split(',')
			preloadImages(imgs,'finalPrepSlideShow','#load_indicator')
		}
		
		finalPrepSlideShow = function(imgs){
			jqSS.slideImgs	=	imgs
			jqSS.slideImgs.css({opacity:0,position:'absolute',top:0,right:0})
			jqSS.container.append(jqSS.slideImgs)
			showSlide() // get that first slide going immidiatly
			resumeSlideShow()
		}
		
		
		// called by interval to perform slide animation
		showSlide = function(){
			var cur = jqSS.curSlide
			var prev = jqSS.curSlide == 0 ? jqSS.slideImgs.length-1 : jqSS.curSlide - 1
			var next = jqSS.curSlide == jqSS.slideImgs.length-1 ? 0 : jqSS.curSlide + 1
			jqSS.curSlide = next
			$(jqSS.slideImgs[prev]).css({zIndex:0})
			$(jqSS.slideImgs[cur]).css({zIndex:10}).animate(
				{opacity:1},
				jqSS.fadeDur,
				function(){
					$(jqSS.slideImgs[prev]).css({opacity:0})
				}
			)
		}
		// pauses running slideshow
		pauseSlideShow = function(){
			if (typeof jqSS != "undefined") {
				clearInterval(jqSS.timer)
			}
		}
		// resumes running slideshow
		resumeSlideShow = function(){
			if (typeof jqSS != "undefined" && jqSS.slideImgs.length > 0){
				clearInterval(jqSS.timer)
				jqSS.timer = setInterval('showSlide()',jqSS.pauseDur)
			}
		}
		
		// ***** BIKE SECTIONS FUNCTIONS ***** //
		
		jqBS = {
			container 	: $('#bike_sections'),
			links				:	$('#bike_nav a'),
			scrollSpd		: 1000,
			easing			:	'easeInOutQuad',
			activeLink	:	null,
			defOffset		:	452,
			fullOffset	:	593 // pixels from top for starting position
		}
		
		prepBikeSections = function(){
			$('#bike_nav_specs').data('nav_offset', -141 ) // hard coded values for simplicity
			$('#bike_nav_geo').data('nav_offset', -734 )
			$('#bike_nav_dls').data('nav_offset', -1327 )
			$('#bike_nav_revs').data('nav_offset', -1920 )
			
			jqBS.links.click(
				function(){
					if ( jqBS.activeLink && jqBS.activeLink.get(0) == $(this).get(0) ) {
						closeBikeSection()
					} else {
						showBigBikeImg()
						goToBikeSection($(this))
					} 
					return false;
				}
			)
		}
		
		goToBikeSection = function(link,callback){
			jqBS.activeLink = link ? link : null
			onlyOneLive(link)
			var offset = link ? link.data('nav_offset') : jqBS.defOffset
			jqBS.container.stop().animate(
				{top:offset,opacity:1},
				jqBS.scrollSpd,
				jqBS.easing,
				function(){
					callback ? eval(callback) : null
				}
			)
		}
		
		closeBikeSection = function(callback){
			jqBS.activeLink = null
			onlyOneLive()
			jqBS.container.stop().animate(
				{top:jqBS.defOffset},
				jqBS.scrollSpd,
				jqBS.easing,
				function(){
					callback ? eval(callback) : null
				}
			)
		}
		
		hideBikeSection = function(callback){
			jqBS.container.stop().animate(
				{top:jqBS.fullOffset,opacity:0},
				jqBS.scrollSpd,
				jqBS.easing,
				function(){
					callback ? eval(callback) : null
				}
			)
		}
		
		
		// *************** BIKE IMAGE FUNCTIONS *************** //
		

		
		prepBikeImages = function(){
			jqBI				= new Object
			jqBI.box			= $('#box')
			jqBI.links			= $('ul.bike_imgs_single a, ul.bike_imgs_group a')
			jqBI.bigImgCont		= $('<div class="bx6 border" style="z-index:10"></div>')
			jqBI.ImgFadeIn		= 250
			jqBI.ImgFadeOut		= 250
			jqBI.contSmall		= 593
			jqBI.contFull		= 960
			jqBI.currentZoom	= null
			jqBI.currentLink	= null
		
			jqBI.links.click(
				function(){
					showBigBikeImg($(this))
					return false
				}
			)
		}
		
		showBigBikeImg = function(imgLink) {
			if (imgLink && imgLink.get(0) != jqBI.currentLink) {
				jqBI.currentLink = imgLink.get(0)
				onlyOneLive(imgLink)
				hideBikeSection()
				var scale = jqBI.contSmall / jqBI.contFull
				var img = $('<img>')
				img.load(
					function(){
						var box = $('<div class="bike_big_img"></div>').css({opacity:0}).append(img)
						jqBI.bigImgCont.find('img').animate(
							{opacity:0},
							500,
							function(){
								$(this).parent().remove()
							}
						)
						var zoomIn = $('<a class="zoom_in">ZOOM IN</a>')
						var zoomOut = $('<a class="zoom_out">ZOOM OUT</a>')
						
						jqBI.box.append(jqBI.bigImgCont.append(box))
						var imgW = img.width()
						var imgH = img.height()
						img.data('fullW', imgW)
						img.data('fullH', imgH)
						img.css({width:imgW*scale,height:imgH*scale})
						box.css({width:jqBI.contSmall,height:jqBI.contSmall,lineHeight:jqBI.contSmall+'px'})
						box.animate(
							{opacity:1},
							500
						)
					}
				).attr('src',imgLink.attr('href')) // apply src AFTER load to make IE happy
			} else if (jqBI.currentLink) {
				onlyOneLive()
				goToBikeSection()
				jqBI.currentLink = null
				jqBI.bigImgCont.stop().animate(
					{opacity:0},
					500,
					function(){
						jqBI.bigImgCont.css({opacity:1}).empty().remove()
					}
				)
				
			}
		}
		
		onlyOneLive = function(clicked){
			jqBI.links.add(jqBS.links).removeClass('live')
			clicked ? clicked.addClass('live') : false
		}
		
		// ADMIN SPECIFIC STUFF
		
		doFCK = function(){
			$('.fck_full:visible').fck({
				path:		'/fckeditor/',
				toolbar:	'RLFull',
				height:		300
			});
			$('.fck_full_tall:visible').fck({
				path:		'/fckeditor/',
				toolbar:	'RLFull',
				height:		500
			});
			$('.fck_basic:visible').fck({
				path:		'/fckeditor/',
				toolbar:	'RLBasic',
				height:		200
			});
		}
		
		$('#cancel_record, #delete_record').click(
			function(){
				window.location=$(this).attr('href');
			}
		)

		$(".raw tr:odd").addClass("kt");
	}
)

