// When object is available, do function fn.
function when(obj, fn) {
  if (Object.isString(obj)) obj = /^[\w-]+$/.test(obj) ? $(obj) : $(document.body).down(obj);
  if (Object.isArray(obj) && !obj.length) return;
  if (obj) fn(obj);
}

document.observe('dom:loaded', function() {
  when('ul.images', function(list){
    // this check should be in the class, but i am worried about occupying more memory,
    // when the class is already created.
    if(list.select('li').length > 1){
      new SlideShow(list);
    }
  });

	when('ul.case-study-menu', function(list){
		new CaseStudyMenu(list);
	});
});

var CaseStudyMenu = Class.create({
	initialize: function( element ) {
    var options = Object.extend({
      duration: 1000
    }, arguments[1] || { });

		// start of state of this page is:
		// - first image displayed
    // - problem displayed
    // - all other images hidden
    // - solution and result hidden
		$(element).
        observe('click', this.onMenuClick.bindAsEventListener(this)).
        observe('mouseover', this.onMenuMouseOver.bindAsEventListener(this)).
        observe('mouseout', this.onMenuMouseOut.bindAsEventListener(this));;
	},

	onMenuClick: function( event ) {
		// this needs to be bound as the event listener on the menu

		//find the element clicked
		menu_item = event.findElement('li');
		if( menu_item ) {
			// we have a menu item, so therefore we will find out what page to display:none
			if (menu_item.id == 'full-story' ){
				//display all parts of this story
				this.displayFullStory();
			} else {
				name_array = menu_item.id.split(/-/);
				part_name = name_array.last();
				this.hideAllParts(part_name);
				this.displayPart(part_name);
				this.displayImage(part_name);
			};
		};
		event.stop();
	},

	onMenuMouseOut: function( event ) {
		menu_item = event.findElement('li');
		if( menu_item ){
			if( menu_item.id == 'full-story') {
				this.tabIn();
			};
		};
	},

	onMenuMouseOver: function ( event ) {
		menu_item = event.findElement('li');
		if( menu_item ){
			if( menu_item.id == 'full-story') {
				this.tabOut();
			};
		};
	},

	tabOut: function(){
		$('full-story').setStyle({
			left: '485px'
		});
	},

	tabIn: function(){
		$('full-story').setStyle({
			left: '475px'
		});
	},

	displayFullStory: function() {
		['problem', 'solution', 'result'].each(function(div_part){
			if ( !$(div_part).visible() ) {
				$(div_part).appear();
			};
		});
	},

	hideAllParts: function( except ) {
		['problem', 'solution', 'result'].without(except).each(function(div_part){
			if($(div_part).visible()) {
				$(div_part).fade();
			};
		});
	},

	displayPart: function( part_name ) {
		div_to_show = $(part_name);
		if( div_to_show ) {
			if( !div_to_show.visible() ){
				div_to_show.appear();
			};
		};
	},

	displayImage: function( part_name ){
		image_to_display = ['problem', 'solution', 'result'].indexOf(part_name);
		$$('ul.case-study-images li').each(function(image, index){
			if( image.visible() && index != image_to_display ){
				image.fade();
			};
			if( !image.visible() && index == image_to_display){
				image.appear();
			};
		});
	}
});


var SlideShow = Class.create({
  initialize: function( element ) {
    // element - should be a ul that contains the img tags wrapped with li tags.
    // to make the display nice and smooth to begin with, all but the first li tag should already have 'style="display:none;"' on them.
    // we do fix that here, but if the content loads first then hides them, you will have a FOUC. 'Flash of unstyled Content'
    this.list = $(element).select('li');
    var options = Object.extend({
      delay: 4000,
      duration: 2000
    }, arguments[1] || { });

    // hide all but the last
    for( ii = 0; ii < this.list.length; ii++ ){
      if( ii != (this.list.length - 1) ){
        this.list[ii].setStyle({
          display: 'none'
        });
      }
    }
    this.options = options;
    this.current = this.list.length - 1;
    this.timeout = null;
    this.timeout = this.start.bind(this).delay(this.eventDelay());
  },

  showNext: function() {
    if(this.current == (this.list.length - 1)) {
      this.current = 0;
    } else {
      this.current++;
    }
    Effect.Appear(this.list[this.current], {duration: this.eventDuration()});
  },

  showPrevious: function() {
    if(this.current == 0){
      this.current = (this.list.length - 1);
    } else {
      this.current--;
    }
    Effect.Appear(this.list[this.current], {duration: this.eventDuration()});
  },

  hideCurrent: function() {
    Effect.Fade(this.list[this.current], {duration: this.eventDuration()});
  },

  animateForward: function() {
    this.hideCurrent();
    this.showNext();
    this.animateForward.bind(this).delay(this.eventDelay());
  },

  stop: function() {
    // this needs to cancel all the delays setup.  There should only be one.
    if(this.timeout) {
      window.clearTimeout(this.timeout);
      this.timeout = null;
    }
  },

  start: function() {
    this.animateForward();
  },

  eventDelay: function() {
    return ((this.options.delay + this.options.duration) / 1000);
  },

  eventDuration: function() {
    return (this.options.duration / 1000);
  }

});

