// Classes and Functions for S4Gear's website
// Matthew Smallwood

// copy the 'multiple' function of the Effect object into one that allows for an afterFinish only after the last effect
Effect.multipleAfter = function(element, effect, finalAfter) {
	var elements;
	if (((typeof element == 'object') ||
		Object.isFunction(element)) &&
	   (element.length))
	  elements = element;
	else
	  elements = $(element).childNodes;
	
	var options = Object.extend({
	  speed: 0.1,
	  delay: 0.0
	}, arguments[3] || { });
	var masterDelay = options.delay;
	
	$A(elements).each( function(element, index) {
			if(index == elements.length - 1){
				new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay, afterFinish: finalAfter }));
			} else {
				new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
			}
	});
};

// the Page class handles (classy) animations for page transitions
var Page = Class.create({
  initialize: function() {
  	  // initialize cookie object
  	  this.cisfor = new Cookies();
  	  
  	  // get key elements of the page
  	  this.content = $('content');
  	  this.contentBG = $('content_bg');
  	  this.loading = $('loading');
  	  this.subnavs = $$('.subnav');
  	  
  	  // get elements that will be transitioned
  	  this.faders = this.content.select('div.fader', 'p', 'a', 'li', 'h2', 'img', 'fieldset', 'label', 'input', 'textarea');
  	  
  	  this.faders.push($('footer_inner'));
  	  
  	  // hide all the grabbed page elements
  	  this.faders.each(function(e, i){
  	  		  e.setStyle({ opacity: 0 });
  	  });
  	  
  	  // hide and move any subnavs
  	  $('nav_beta').setStyle({ display: "none" });
  	  if(this.subnavs[0]){
  	  	  this.subnavs.each(function(e, i) {
  	  	  		  e.hide();
  	  	  		  new Effect.Move(e, { x: -20, mode: 'relative', duration: 0 });
  	  	  });
	  }
	  
  	  this.thumblessKids = new Array();
  	  this.faders.each((function(e, i) {
  	  		  var classes = e.classNames();
  	  		  
  	  		  if(classes.grep(/thumb_img/) != 'thumb_img' && classes.grep(/thumb_glow/) != 'thumb_glow'){
  	  		  	  this.thumblessKids.push(e);
  	  		  }
  	  }).bind(this));
  	  this.pageIn();
  	  
  	  // get links and add an event listener to each  
  	  this.outLinks = $$('body')[0];
  	  Event.observe(this.outLinks, 'click', (function(e) {
  	  		  var clicked = e.findElement('a');
  	  		  if(clicked && clicked.target != '_blank'){
  	  		  	  e.stop();
  	  		  	  var dest = clicked.href;
  	  		  	  this.pageOut(dest);
  	  		  }
  	  }).bind(this));	  
  },
  pageIn: function() {
  	  // get height cookie
  	  var lastHeight = this.cisfor.get('height') ? this.cisfor.get('height') : 500;
  	  this.contentBG.setStyle({ height: lastHeight + "px" });
  	  function timed() {
  	  	  var nextHeight = this.content.getHeight();
  	  	  if(nextHeight < 200){
  	  	  	  nextHeight = 200 + "px";
  	  	  }
		  new Effect.Morph(this.contentBG, {
				  style: "height: " + nextHeight + "px;",
				  queue: 'front',
				  afterFinish: (function() {
				  	  clearTimeout(timey);
				  	  this.contentBG.setStyle({ height: "auto" });
				  }).bind(this)
		  });
		  Effect.multipleAfter(this.thumblessKids, Effect.Morph, (function() { Effect.SlideUp(this.loading, { duration: 0.3 }); }).bind(this), { 
				style: "opacity: 1;",
				speed: 0.1,
				duration: 0.2,
				delay: 0.5
		  });
		  
		  // If there's at least one subnav
		  if(this.subnavs[0]){
		  	  new Effect.SlideDown('nav_beta');
			  this.subnavs.each(function(e, i) {
					  new Effect.Parallel([
							  new Effect.Move(e, { x: 20, mode: 'relative', sync: true }),
							  new Effect.Appear(e, { sync: true })
					  ], {
						  duration: 1.0,
						  delay: 0.5
					  });
			  });
		  }
		  
	  }
  	  var timey = setTimeout(timed.bind(this), 800);
  },
  pageOut: function(dest) {
  	  // set height cookie for new page
  	  this.cisfor.set('height', this.content.getHeight());
  	  Effect.SlideDown(this.loading, { duration: 0.3 });
  	  if(this.subnavs[0]){
		  this.subnavs.each(function(e, i) {
				  new Effect.Parallel([
						  new Effect.Move(e, { x: 20, mode: 'relative', sync: true }),
						  new Effect.Fade(e, { sync: true })
				  ], {
					  duration: 0.25,
					  afterFinish: function() {
					  	  Effect.SlideUp('nav_beta');
					  }
				  });
		  });
	  }
  	  Effect.multipleAfter(this.faders, Effect.Morph, this.gotoPage.bind(this, dest), {
  	  		  style: "opacity: 0;",
  	  		  speed: 0.1,
  	  		  duration: 0.2,
  	  		  delay: 0.5
  	  });
  },
  gotoPage: function(dest) {
  	  location.href = dest;
  }
});

var thumbButton = Class.create({
		initialize: function(element, outScale, outOpacity) {
			
			this.timer = null;
			
			this.element = element;
			this.outOpacity = outOpacity;
			this.outScale = outScale;
			
			this.thumb = this.element.select('.thumb_img')[0];
			this.thumbglow = this.element.select('.thumb_glow')[0];
			this.thumbover = this.element.select('.thumb_over')[0];
			
			this.sibs = this.element.ancestors()[1].select('a');
						
			this.div = this.element.ancestors()[0];
			
			this.thumbSrc = this.thumb.src;
			this.thumbGlowSrc = this.thumbSrc.substring(0, this.thumbSrc.length - 4) + "_glow.gif";
			
			this.thumb.setStyle({ opacity: 0.0 });
			this.thumbglow.setStyle({ opacity: 0.0 });
			
			// outScale is the scale that it will appear at normally (ie. the scale used on the mouseout event)
			// ... so, let's calculate the scale (percentage) that will be used for the mouseover
			this.overScale = 100 / (this.outScale / 100);
			
			// the dimensions for mouseover are the original image dimensions
			// this.overH = this.thumb.getHeight();			
			// this.overW = this.thumb.getWidth();
			// that seems like the right way, but a lot of the time the images aren't loaded yet, so the dimensions come back wrong
			// since I'm on a deadline, for now I'm going to supply the numbers directly (since I know them)
			this.overH = 400;
			this.overW = 300;
							
			// the dimensions for mouseout...
			this.outW = this.overW * (this.outScale / 100);
			this.outH = this.overH * (this.outScale / 100);
			
			// calculate the 'final' top / left position so that the image appears to enlarge from the center			
			this.outL = parseInt(this.thumb.getStyle('left'));
			this.outT = parseInt(this.thumb.getStyle('top'));
			this.overL = this.outL - ((this.overW - this.outW) / 2);
			this.overT = this.outT - ((this.overH - this.outH) / 2);
						
			// resize the images to their scaled down size (mouseout / inactive state)
			this.thumb.setStyle({ height: this.outH + "px", width: this.outW + "px" });    
			this.thumbglow.setStyle({ height: this.outH + "px", width: this.outW + "px", top: this.outT + "px", left: this.outL + "px" });
			this.thumbover.setStyle({ height: this.outH + "px", width: this.outW + "px", top: this.outT + "px", left: this.outL + "px" });
			
			new Effect.Appear(this.thumb, { to: this.outOpacity, duration: 0.2, delay: 1 });
						
			this.thumbover.observe('mouseover', this.over.bind(this)).observe('mouseout', this.out.bind(this));
		},
		over: function() {
			if(!this.thumbglow.visible()){
				this.thumbglow.setStyle({ display: 'block' });
			}
			this.sibs.each((function(e,i){
					var thumb = e.select('.thumb_img')[0];
					if(thumb.id != this.thumb.id){
						var glow = e.select('.thumb_glow')[0];
						var over = e.select('.thumb_over')[0];
						thumb.setStyle({ zIndex: 2000, opacity: this.outOpacity, width: this.outW+"px", height: this.outH+"px", top: this.outT+"px", left: this.outL+"px" });
						glow.setStyle({ zIndex: 2001, opacity: 0, width: this.outW+"px", height: this.outH+"px", top: this.outT+"px", left: this.outL+"px" });
						over.setStyle({ zIndex: 2002, width: this.outW+"px", height: this.outH+"px", top: this.outT+"px", left: this.outL+"px" });
					}
			}).bind(this));
			new Effect.Parallel([
					new Effect.Morph(this.thumb, {
							style: "opacity: 1; width: " + this.overW + "px; height: " + this.overH + "px; top: " + this.overT + "px; left: " + this.overL + "px;",
							sync: true
					}),
					new Effect.Morph(this.thumbglow, {
							style: "opacity: 1; width: " + this.overW + "px; height: " + this.overH + "px; top: " + this.overT + "px; left: " + this.overL + "px;",
							sync: true
					})
			], {
				beforeStart: (function() {
						this.thumb.setStyle({ zIndex: 3000 });
						this.thumbglow.setStyle({ zIndex: 3001 });
						this.thumbover.setStyle({ zIndex: 3002, width: this.overW+"px", height: this.overH+"px", top: this.overT+"px", left: this.overL+"px" });
				}).bind(this),
				afterFinish: (function() {
						this.thumb.setStyle({ opacity: 1, width: this.overW+"px", height: this.overH+"px", top: this.overT+"px", left: this.overL+"px" });
						this.thumbglow.setStyle({ opacity: 1, width: this.overW+"px", height: this.overH+"px", top: this.overT+"px", left: this.overL+"px" });
				}).bind(this),
				duration: 0.2
			});
		},
		out: function() {
			new Effect.Parallel([
					new Effect.Morph(this.thumb, {
							style: "opacity: " + this.outOpacity + "; width: " + this.outW + "px; height: " + this.outH + "px; top: " + this.outT + "px; left: " + this.outL + "px;",
							sync: true
					}),
					new Effect.Morph(this.thumbglow, {
							style: "opacity: 0; width: " + this.outW + "px; height: " + this.outH + "px; top: " + this.outT + "px; left: " + this.outL + "px;",
							sync: true
					})
			], {
				afterFinish: (function() {
						this.thumb.setStyle({ zIndex: 2000, opacity: this.outOpacity, width: this.outW+"px", height: this.outH+"px", top: this.outT+"px", left: this.outL+"px" });
						this.thumbglow.setStyle({ zIndex: 2001, opacity: 0, display: 'none', width: this.outW+"px", height: this.outH+"px", top: this.outT+"px", left: this.outL+"px" });
						this.thumbover.setStyle({ zIndex: 2002, width: this.outW+"px", height: this.outH+"px", top: this.outT+"px", left: this.outL+"px" });
				}).bind(this),
				duration: 0.2
			});
		}
});

var bannerButton = Class.create({
		initialize: function(element, outScale, outOpacity) {
			this.timer = null;
			
			this.element = element;
			this.outOpacity = outOpacity;
			this.outScale = outScale;
			
			this.thumb = this.element.select('.banner_img')[0];
			
			this.div = this.element.ancestors()[0];
			
			this.thumbSrc = this.thumb.src;
			
			this.thumb.setStyle({ opacity: 0.0 });
			
			// outScale is the scale that it will appear at normally (ie. the scale used on the mouseout event)
			// ... so, let's calculate the scale (percentage) that will be used for the mouseover
			this.overScale = 100 / (this.outScale / 100);
			
			// the dimensions for mouseover are the original image dimensions
			// this.overH = this.thumb.getHeight();			
			// this.overW = this.thumb.getWidth();
			// that seems like the right way, but a lot of the time the images aren't loaded yet, so the dimensions come back wrong
			// since I'm on a deadline, for now I'm going to supply the numbers directly (since I know them)
			this.overH = 307;
			this.overW = 450;
							
			// the dimensions for mouseout...
			this.outW = this.overW * (this.outScale / 100);
			this.outH = this.overH * (this.outScale / 100);
			
			// calculate the 'final' top / left position so that the image appears to enlarge from the center			
			this.outL = parseInt(this.thumb.getStyle('left'));
			this.outT = parseInt(this.thumb.getStyle('top'));
			this.overL = this.overW;
			this.overT = this.overH;
						
			// resize the images to their scaled down size (mouseout / inactive state)
			this.thumb.setStyle({ height: this.outH + "px", width: this.outW + "px", zIndex: 4000 });    
			
			new Effect.Appear(this.thumb, { to: this.outOpacity, duration: 0.2, delay: 1 });
						
			this.thumb.observe('mouseover', this.over.bind(this)).observe('mouseout', this.out.bind(this));
		},
		over: function() {
			new Effect.Morph(this.thumb, {
				style: "opacity: 1; width: " + this.overW + "px; height: " + this.overH + "px;",
				afterFinish: (function() {
						this.thumb.setStyle({ zIndex: 5000, opacity: 1, width: this.overW+"px", height: this.overH+"px" });
				}).bind(this),
				duration: 0.2
			})
		},
		out: function() {
            new Effect.Morph(this.thumb, {
                style: "opacity: " + this.outOpacity + "; width: " + this.outW + "px; height: " + this.outH + "px;",
				afterFinish: (function() {
						this.thumb.setStyle({ zIndex: 4000, opacity: this.outOpacity, width: this.outW+"px", height: this.outH+"px"});
				}).bind(this),
				duration: 0.2
			});
		}
});

document.observe('dom:loaded', function() {
		new Page();
});
