/**
 * @author POP webdev [tw]
 * @version 0.4
 * @classDescription Controls a scroller.
 * @return {Object}	Returns a new object.
 * @projectDescription
 * This class depends on Prototype v1.6, Scriptactulous Effects, and the Scroller class.
 * It extends Scroller and manages pagination for it (prev/next group links, group number links, and next/previous selection links).
 */

 var ScrollerPagingControl = Class.create(Scroller, {
	initialize: function($super, slideFrame, scrollerOptions, controlListContainer, controlOptions) {
		// set control options
		this.controlOptions = Object.extend({
			itemsPerGroup: 4,
			initialGroupIndex: 0,
			previousSlideTriggerID: 'select_previous_slide',
			nextSlideTriggerID: 'select_next_slide',
			previousGroupTriggerID: 'nav_previous_group',
			nextGroupTriggerID: 'nav_next_group',			
			autoGenerate: true
		}, controlOptions || {});
		
		// construction tasks
		$super(slideFrame, scrollerOptions); // initialize parent class
		
		var controlListContainer = $(controlListContainer);
		if(!controlListContainer){return;}
		
		if(this.controlOptions.autoGenerate === true){
			//create new list and append to container
			this.controlList = this._createControlList()
			controlListContainer.insert(this.controlList);
		}
		else{
			// get existing list
			this.controlList = controlListContainer.down('ul, ol');
		}

		// attach paging control events
		var controlLinks = this.controlList.select('li a');
		controlLinks.each(function(lnk) {
			// use parent li classname to identify individual event links
			var elLi = lnk.up('li');

			if (elLi.hasClassName('btn-previous')) {
				lnk.observe('click', this.__movePreviousClick.bindAsEventListener(this));
			} else if (elLi.hasClassName('btn-next')) {
				lnk.observe('click', this.__moveNextClick.bindAsEventListener(this));
			} else {
				lnk.observe('click', this.__moveToClick.bindAsEventListener(this));
				elLi.addClassName('group')
			}
		}.bind(this));
		
		
		// attach events to optional select next/previous slide links
		if($(this.controlOptions.previousSlideTriggerID)){
			$(this.controlOptions.previousSlideTriggerID).observe('click', this.__selectPreviousSlideClick.bindAsEventListener(this));
		}
		if($(this.controlOptions.nextSlideTriggerID)){
			$(this.controlOptions.nextSlideTriggerID).observe('click', this.__selectNextSlideClick.bindAsEventListener(this));
		}
		// attach events to optional select next/previous group links.
		this.previousGroupTrigger = $(this.controlOptions.previousGroupTriggerID) || false; 
		if(Object.isElement(this.previousGroupTrigger)){
			this.previousGroupTrigger.observe('click', this.__movePreviousClick.bindAsEventListener(this));
		}
		this.nextGroupTrigger = $(this.controlOptions.nextGroupTriggerID) || false; 
		if(Object.isElement(this.nextGroupTrigger)){
			this.nextGroupTrigger.observe('click', this.__moveNextClick.bindAsEventListener(this));
		}		
		
		this._adjustControlClasses();
		this.jumpToGroup(this.controlOptions.initialGroupIndex);
	},
	// event handlers
	__movePreviousClick: function(e) {
		e.stop();
		this.moveToPreviousGroup();
	},
	__moveNextClick: function(e) {
		e.stop();
		this.moveToNextGroup();
	},
	__moveToClick: function(e) {
		e.stop();
		var elLi = e.element().up('li');
		// get the groupIndex
		var elGroupItems = this.controlList.select('li.group');
		var groupNum = elGroupItems.indexOf(elLi);
		this.moveToGroup(groupNum);
	},
	__selectNextSlideClick: function(e){
		e.stop();
		this.selectNextSlide();
	},
	__selectPreviousSlideClick: function(e){
		e.stop();
		this.selectPreviousSlide();
	},
	// methods
	moveToNextGroup: function() {
		if (this.currentGroupIndex < (this.getGroupCount() - 1)) {
			this.moveToGroup(this.currentGroupIndex + 1);
		}
	},
	moveToPreviousGroup: function() {
		if (this.currentGroupIndex > 0) {
			this.moveToGroup(this.currentGroupIndex - 1);
		}		
	},
	moveToFirstGroup: function() {
		this.moveToGroup(0);
	},
	moveToLastGroup: function() {
		this.moveToGroup(this.getGroupCount() - 1);
	},
	moveToGroup: function(groupIndex) {
		if ((groupIndex < this.getGroupCount()) && (groupIndex > -1) && groupIndex != this.currentGroupIndex) {
			this.currentGroupIndex = groupIndex;
			//console.log('currentGroupIndex being set to : ' + this.currentGroupIndex);
			this.moveTo(groupIndex * this.controlOptions.itemsPerGroup);
			
			this._adjustControlClasses();

			this.lazyLoadImages();
		}
	},
	jumpToGroup: function(groupIndex) {
		this.currentGroupIndex = groupIndex;
		this.jumpTo(groupIndex * this.controlOptions.itemsPerGroup);

		this._adjustControlClasses();
	},
	selectNextSlide: function() {
		//if at the end of current group, move to next group
		var nextIndex = this.selectedSlideIndex +1;
		var lastIndexInGroup = this.currentSlideIndex + this.controlOptions.itemsPerGroup;
		if(nextIndex >= lastIndexInGroup){
			this.moveToNextGroup();
		}
		else if(nextIndex < this.getSlideCount()){
			this.setSelectedSlide(nextIndex);
		}
	},
	selectPreviousSlide: function() {
		// if at beginning of group, move to previous group
		var previousIndex = this.selectedSlideIndex - 1;
		if(previousIndex < this.currentSlideIndex && (this.currentGroupIndex > 0)){
			this.moveToPreviousGroup();
			this.setSelectedSlide(previousIndex);
		}
		else if(previousIndex >= 0){
			this.setSelectedSlide(previousIndex);
		}
	},
	// Pass in a slide LI, or the index in the slidelist
	selectSlide: function(slide){
		return this.setSelectedSlide(slide);
	},
	getGroupCount: function() {
		return Math.ceil(this.getSlideCount() / this.controlOptions.itemsPerGroup);
	},
	lazyLoadImages: function(){
		var numItems = this.selectedSlideIndex + this.controlOptions.itemsPerGroup;

		if(this.slides.length < numItems){
			numItems = this.slides.length;
		}

		for(var i = this.selectedSlideIndex; i<numItems; i++){
			var elImage = this.slides[i].select('img');

			if(elImage){
				for(var e=0; e<elImage.length; e++){
					if(elImage[e].readAttribute('src') == ''){
						var imageSrc = elImage[e].readAttribute('data-src');

						elImage[e].hide().removeClassName('invisible');

						elImage[e].observe('load', function(e){
							this.effects = new Effect.Appear(this,{
								duration: 0.3
							});
						});

						elImage[e].setAttribute('src', imageSrc);
					}
				}
			}
		}
	},
	_adjustControlClasses: function(){
		// adjust disabled class on next/previous 
		var groupCount = this.getGroupCount();
		var elPrevNavItem = this.controlList.down('li.btn-previous');
		(this.currentGroupIndex  > 0) ? elPrevNavItem.removeClassName('disabled').addClassName('enabled') : elPrevNavItem.removeClassName('enabled').addClassName('disabled');
		// adjust the optional extra previous
		if(Object.isElement(this.previousGroupTrigger)){
			(this.currentGroupIndex  > 0) ? this.previousGroupTrigger.removeClassName('disabled') : this.previousGroupTrigger.addClassName('disabled');
		}

		var elNextNavItem = this.controlList.down('li.btn-next');		
		(this.currentGroupIndex < (groupCount-1)) ? elNextNavItem.removeClassName('disabled').addClassName('enabled') : elNextNavItem.removeClassName('enabled').addClassName('disabled');
		// adjust the optional extra next
		if(Object.isElement(this.nextGroupTrigger)){
			(this.currentGroupIndex < (groupCount-1)) ? this.nextGroupTrigger.removeClassName('disabled') : this.nextGroupTrigger.addClassName('disabled');
		}
			
		// adjust selected classes
		var elNavItems = this.controlList.select('li.group');
	
		for(var i = 0, len = elNavItems.size(); i < len;i++){
			(i == this.currentGroupIndex) ? elNavItems[i].addClassName('on') : elNavItems[i].removeClassName('on');
		}
	},
	_createControlList: function(){
		var elUl = new Element('ul');
		
		var elPrev = new Element('li', {'class': 'btn-previous'});
		elPrev.insert(new Element('a', {'class': 'btn', 'href': '#previous'}).update('<span>previous</span>'));
		elUl.insert(elPrev);

		for(var i=0, len = this.getGroupCount(); i < len; i++){
			var elLi = new Element('li', {'class': 'btn-group'});
			elLi.insert(new Element('a', {'class': 'btn', 'href': '#' + i}).update('<span>' + (i+1) + '</span>'));
			elUl.insert(elLi);
		}
		
		var elNext = new Element('li', {'class': 'btn-next'});
		elNext.insert(new Element('a', {'class': 'btn', 'href': '#next'}).update('<span>next</span>'));
		elUl.insert(elNext);

		this.lazyLoadImages();

		return elUl;
	}
});
