// coverflow.js v0.0.1
//
// Copyright (c) 2007 stickmanlabs | http://www.stickmanlabs.com
//  - Kevin P Miller
// 
// CoverFlow is freely distributable under the terms of the MIT-style license.
//

/*-----------------------------------------------------------------------------------------------*/

if (typeof Effect == 'undefined') { 
	throw("coverflow.js requires including script.aculo.us' effects.js library!");
}

var CoverFlow = Class.create({

  duration: null,
  container: null,
	preview: [],
	navigation: null,
	slides: null,
	thumbs: null,
	viewport: null,
	thumbIndex: [],
	thumbContainers: [],
	tours: null,
	currentTour: null,
	
	initialize: function(options) {
		this.options = Object.extend({
			resizeSpeed: 8,
			selectors: {
				overlay: 'cover-flow-overlay',
				preview: 'cover-flow-preview',
				slides: 'cover-flow-slides',
				slide: 'cover-flow-slide',
				navigation: 'cover-flow-navigation',
				navigationInner: 'cover-flow-navigation-inner',
				navigationBack: 'cover-flow-navigation-link-left',
				navigationNext: 'cover-flow-navigation-link-right',
				thumbs: 'cover-flow-thumbs',
				thumb: 'cover-flow-thumb',
				thumbAnchorPrefix: 'thumb_',
				tab: 'cover-flow-tab',
				tabContent: 'cover-flow-content',
				close: 'cover-flow-close',
				tour: 'cover-flow-tour',
				iframe: 'cover-flow-tour-iframe'
			},
			thumbsScrollIncrement: 4,
			fixes: {
			  opacity: false
			}
		}, options || {});

    if (this.options.fixes.opacity) {
      this.container.setStyle({
        opacity: 0.99999
      });
    }
		
    this.duration = ((11 - this.options.resizeSpeed) * 0.15);

		this.slides = $$('.' + this.options.selectors.slide);
		
		this.thumbs = $$('.' + this.options.selectors.thumb);

		this.updateViewport();
		
    Event.observe(window, 'resize', this.updateViewport.bind(this), false);
		
		$(this.options.selectors.close).onclick = function() { return false; }
  	Event.observe(this.options.selectors.close, 'click', this.deactivate.bind(this), false);
  	
		this.createSlides();	
		
		this.thumbContainers = $$('.' + this.options.selectors.thumbs);
		for (var y = 0; y < this.thumbContainers.length; y++) {

			this.thumbContainers[y].scrollLeft = 0;

			Event.observe(this.thumbContainers[y].up('.' + this.options.selectors.navigationInner).down('.' + this.options.selectors.navigationBack), 'click', this.scrollThumbs.bindAsEventListener(this, -1, y), true);
			Event.observe(this.thumbContainers[y].up('.' + this.options.selectors.navigationInner).down('.' + this.options.selectors.navigationNext), 'click', this.scrollThumbs.bindAsEventListener(this, 1, y), true);

		}
		
		this.tours = $$('.' + this.options.selectors.tour);
		for (var y = 0; y < this.tours.length; y++) {

			Event.observe(this.tours[y], 'click', this.showTour.bindAsEventListener(this), true);
		}
					
		this.accordion = new TabAccordion(this.options.selectors.overlay, {
			resizeSpeed: 5,
			selectors: {
				toggle: '.' + this.options.selectors.tab,
				content: '.' + this.options.selectors.tabContent
			}
		});

    var _t = $$('.' + this.options.selectors.tab);
    var _c = $$('.' + this.options.selectors.tabContent);
    this.accordion.onOpen(null, 0, {toggle: _t[0], content: _c[0]}, null);
		
		$(this.options.selectors.overlay).setStyle({
			display: 'none',
			visibility: 'visible'
		});

	},

	activate: function() {

		new Effect.Appear(this.options.selectors.overlay, {
			duration: 0.40,
			queue: {
        position: 'end',
        scope: 'slides_animation'
      }
		});
	},

  deactivate: function() {
		new Effect.Fade(this.options.selectors.overlay, {
			duration: 0.40,
			queue: {
        position: 'end',
        scope: 'slides_animation'
      }
		});
  },
  
  showTour: function(event) {
    var element = Event.element(event);
    this.currentTour = element;
    this.currentTour.hide();
    new Insertion.After(element, '<iframe id="cover-flow-tour-iframe" name="cover-flow-tour-iframe" src="' +  element.getAttribute('rel') + '" frameborder="no" height="400" width="600" scrolling="no"></iframe>');
  },
  
  hideTour: function(event) {
    if (this.currentTour) {
      $(this.options.selectors.iframe).remove();
      this.currentTour.show();
      this.currentTour = null;
    }
  },
  
	_getViewport: function() {
		this.viewport = document.viewport.getDimensions();
	},
	
	updateViewport: function() {
		this._getViewport();
		this.updateDimensions();
	},
	
	updateDimensions: function() {
		$(this.options.selectors.overlay).setStyle({
			height: this.viewport.height * 2 + 'px',
			width: this.viewport.width + 'px'
		});
		
		$$('.cover-flow-content').each(function(content) {
			content.setStyle({
				height: this.viewport.height * 2 + 'px',
				width: this.viewport.width + 'px'
			});				
		}.bind(this));
		
    $$('.' + this.options.selectors.preview).each(function(preview) {
     preview.setStyle({
       height: this.viewport.height + 'px',
       width: this.viewport.width + 'px'
     });
    }.bind(this));
    
    $$('.' + this.options.selectors.navigation).each(function(navigation) {
     navigation.setStyle({
       width: this.viewport.width + 'px'
     });     
    }.bind(this));     
    
    $$('.' + this.options.selectors.slides).each(function(slide) {
     slide.setStyle({
       width: this.viewport.width + 'px'
     });
    }.bind(this));
    
    this.slides.each(function(slide) {
     slide.setStyle({
       width: this.viewport.width + 'px'
     });
    }.bind(this)); 
    
	},
	
	createSlides: function() {
	
		var slides = $$('.' + this.options.selectors.slides);
		
		for (var y = 0; y < slides.length; y++) {

			this.preview.push(
				new CoverSlides(slides[y].getAttribute('id'), {
			    delay: 600,
			    size: {
    			  height: 800,
    			  width: 'auto'
    			},
			    defaultOffset: this.viewport.width,
			    defaultIndex: 1,
					selectors: {
						slide: this.options.selectors.slide
					}
			  })
			);
			
			var thumbs = $$('#' + slides[y].getAttribute('id') + '-thumbs .' + this.options.selectors.thumb);
			
			for (var x = 0; x < thumbs.length; x++) {
				Event.observe(thumbs[x], 'click', this.navigate.bind(this, y, x + 1), true);
			}
			
		}

	},
	
	navigate: function(slider, index) {
	  
	  this.hideTour();

    this.preview[slider].slide(index);
	},
	
	scrollThumbs: function(event, direction, thumb_index) {
		
		if (!this.thumbIndex[thumb_index]) { 
		  this.thumbIndex[thumb_index] = 0;
		}
		
		var index = (this.thumbIndex[thumb_index] + (direction * this.options.thumbsScrollIncrement));

    var thumbs = $$('#' + this.thumbContainers[thumb_index].id + ' .' + this.options.selectors.thumb);

		if (index < 1) {
			index = 1;
		} else if (index >= (thumbs.length - 3)) {
			index = (thumbs.length - 3);
		}
    
		this.thumbIndex[thumb_index] = index;
		
		var thumb = this.thumbContainers[thumb_index].down('#' + this.options.selectors.thumbAnchorPrefix + index);

		var delta = thumb.positionedOffset()[0] - this.thumbContainers[thumb_index].scrollLeft - 15;

		new Effect.Scroll(this.thumbContainers[thumb_index], { 
			x: delta, 
			duration: 0.20 
		});
		
		Event.stop(event);
	}
		
});
	
Element.addMethods({
  scrollTo: function(element, left, top){
    var element = $(element);
    if (arguments.length == 1) {
      var pos = element.cumulativeOffset();
      window.scrollTo(pos[0], pos[1]);
    } else {
      element.scrollLeft = left;
      element.scrollTop  = top;
    }
    return element;
  }
});

Effect.Scroll = Class.create();
Object.extend(Object.extend(Effect.Scroll.prototype, Effect.Base.prototype), {
  initialize: function(element) {
    this.element = $(element);
    if(!this.element) throw(Effect._elementDoesNotExistError);
    this.start(Object.extend({x: 0, y: 0}, arguments[1] || {}));
  },

  setup: function() {
    var scrollOffsets = (this.element == window) ? document.viewport.getScrollOffsets() : Element._returnOffset(this.element.scrollLeft, this.element.scrollTop) ;
    this.originalScrollLeft = scrollOffsets.left;
    this.originalScrollTop  = scrollOffsets.top;
  },
 
 update: function(pos) {
    this.element.scrollTo(Math.round(this.options.x * pos + this.originalScrollLeft), Math.round(this.options.y * pos + this.originalScrollTop));
  }
});