/* FilmStrip creates a scrolling filmstrip for thumbnails
   
   Dependencies:
   - Class.Binds
   - Fx.Move
*/

var FilmStrip = new Class({
	Implements: [Options, Events],
	Binds: ['animateScroll'],
	options: {
		forwardSelector: '.next',
		backSelector: '.prev',
		frameSelector: '.frame',
		thumbSelector: '.frame li',
		thumbParentSelector: null, // Optional; if the parent isn't the direct parent
		disabledClass: 'disabled',
		orientation: 'horizontal', // or 'vertical'
		increment: null, // If null, will be auto-calculated based on size of thumbnails
		// Animation settings
		duration: 'long',
		trasition: 'sine:out',
		position: 'upperLeft'
	},
	wrapper: null,
	
	// wrapper can be an element or an ID
	initialize: function(wrapper, options) {
		this.setOptions(options);
		
		// Set up universal variables
		this.wrapper = $(wrapper); // Just in case
		this.frame = this.wrapper.getElement(this.options.frameSelector);
		this.thumbs = this.wrapper.getElements(this.options.thumbSelector);
		this.thumbparent = ($type(this.options.thumbParentSelector) == 'string' ? this.thumbs[0].getParent(this.options.thumbParentSelector) : this.thumbs[0].getParent());
		this.forward = this.wrapper.getElement(this.options.forwardSelector);
		this.back = this.wrapper.getElement(this.options.backSelector);
		
		if (this.options.orientation == 'horizontal') {
			this.thumbmargin = this.thumbs[0].getStyle('margin-left').toInt() + this.thumbs[0].getStyle('margin-right').toInt();
		} else {
			this.thumbmargin = this.thumbs[0].getStyle('margin-top').toInt() + this.thumbs[0].getStyle('margin-bottom').toInt();
		}
		if (this.options.orientation == 'horizontal') this.thumbspace = this.thumbs[0].getSize().x + this.thumbmargin;
		else this.thumbspace = this.thumbs[0].getSize().y + this.thumbmargin;
		
		if ($chk(this.options.increment)) {
			this.increment = this.options.increment;
		} else {
		 	var frameheight;
			if (this.options.orientation == 'horizontal') {
				frameheight = this.frame.getSize().x;
			} else {
				frameheight = this.frame.getSize().y;
			}
			this.increment = Math.floor(frameheight / this.thumbspace);
		}
		
		// Do the actual setup
		if (this.thumbs.length <= this.increment) {
			// Not enough to scroll
			this.back.addClass(this.options.disabledClass);
			this.forward.addClass(this.options.disabledClass);
			this.back.addEvent('click', this.deadEvent);
			this.forward.addEvent('click', this.deadEvent);
		} else {
			if (this.options.orientation == 'horizontal') this.thumbparent.setStyle('width', this.thumbs.length * this.thumbspace);
			else this.thumbparent.setStyle('height', this.thumbs.length * this.thumbspace);
			
			this.back.addClass(this.options.disabledClass); // always start at the beginning
			this.movementside = (this.options.orientation == 'horizontal' ? 'left' : 'top');
			
			// Actual movement logic
			this.back.addEvent('click', function(e) {
				e.stop();
				// Moving "back" means either towards the top or left, so towards zero (positive direction)
				if (this.thumbparent.getStyle(this.movementside).toInt() < 0) {
					this.animateScroll(this.increment);
				}
			}.bind(this));
			this.forward.addEvent('click', function(e) {
				e.stop();
				// Moving "forward" means towards the bottom or right, so away from zero (negative direction)
				if (this.thumbparent.getStyle(this.movementside).toInt() - (this.increment * this.thumbspace) > -(this.thumbs.length * this.thumbspace)) {
					this.animateScroll(-this.increment);
				}
			}.bind(this));
			
			this.thumbparent.set('move', {
				duration: this.options.duration,
				transition: this.options.transition,
				position: this.options.position,
				relativeTo: this.frame
			});
		}
	},
	
	animateScroll: function(num) {
		var targetPos = (num * this.thumbspace) + this.thumbparent.getStyle(this.movementside).toInt();
		if (this.options.orientation == 'horizontal') {
			this.thumbparent.move({offset: {x: targetPos, y: this.thumbparent.getStyle('top').toInt()}});
		} else {
			this.thumbparent.move({offset: {x: this.thumbparent.getStyle('left').toInt(), y: targetPos}});
		}
		// Movement done, now set disabled state for buttons
		if (targetPos == 0 && !this.back.hasClass(this.options.disabledClass)) {
			this.back.addClass(this.options.disabledClass);
		} else if (this.back.hasClass(this.options.disabledClass)) {
			this.back.removeClass(this.options.disabledClass);
		}
		if (targetPos - (Math.abs(num) * this.thumbspace) <= -(this.thumbs.length * this.thumbspace) && !this.forward.hasClass(this.options.disabledClass)) {
			this.forward.addClass(this.options.disabledClass);
		} else if (this.forward.hasClass(this.options.disabledClass)) {
			this.forward.removeClass(this.options.disabledClass);
		}
	},
	
	deadEvent: function(e) {
		e.stop();
	}
	
});