/**
* @author: Alex Tse
* @version: 0.2
* @note: window need to be relative/absolute position and overflow to hidden
*       panes need to be absolute position and have its top / left set
*/
function ScrollingPane(el, w) {
	var pane = $(el);
	var win = $(w);
	var posPin = [];
	var currentIndex = 0;
	var toggleOptions = {};
	var SCROLLING_PANE = this;
	
	/**
	*	Scroll to specific position pointer
	*	@param obj Position pointer object (element with rel='scrollingPosition') or pointer index (integer)
	*	@param direction Final Position, "<vertical> <horizontal>", <vertical> = top / bottom / middle, <horizontal> = left / right / center
	*	@param option Options of the animation, including mandatory 'duration' and/or 'ease' and/or 'onComplete' properties
	*/
	this.scrollTo = function(obj, direction, option) {
		if (!posPin[obj] && posPin.indexOf(obj) < 0) return;

		// parsing direction
		var aDirection = direction.match(/^(top|bottom|middle|-?\d+px|auto)?\s*(left|right|center|-?\d+px|auto)?$/i);
		if (!aDirection) return;
		
		// setting target element and index of the element
		var targetElement;
		if (typeof obj == 'number') {
			targetElement = posPin[obj];
			currentIndex = obj;
		} else {
			targetElement = obj;
			currentIndex = posPin.indexOf(obj);
		}
		
		var transformObjSet = {};
		
		// setting vertical position
		switch (aDirection[1]) {
			case "top":
				transformObjSet['top'] = -$(targetElement).offsetTop + 'px';
			break;
			case "bottom":
				transformObjSet['top'] = win.getHeight() - ($(targetElement).offsetTop + targetElement.getHeight()) + 'px';
			break;
			case "middle":
				transformObjSet['top'] = win.getHeight()/2 - ($(targetElement).offsetTop + targetElement.getHeight()/2) + 'px';			
			break;
			default:
				if (aDirection[1] && !isNaN(parseInt(aDirection[1])) ) transformObjSet['top'] = -$(targetElement).offsetTop + parseInt(aDirection[1], 10) + 'px';
			break;
		}
		
		// setting horizontal position
		switch (aDirection[2]) {
			case "left":
				transformObjSet['left'] = -$(targetElement).offsetLeft + 'px';
			break;
			case "right":
				transformObjSet['left'] = win.getWidth() - ($(targetElement).offsetLeft + targetElement.getWidth()) + 'px';
			break;
			case "center":
				transformObjSet['left'] = win.getWidth()/2 - ($(targetElement).offsetLeft + targetElement.getWidth()/2) + 'px';			
			break;
			default:
				if (aDirection[2] && !isNaN(parseInt(aDirection[2])) ) transformObjSet['left'] = -$(targetElement).offsetLeft + parseInt(aDirection[2], 10) + 'px';
			break;
		}
		pane.transformStyleSet(transformObjSet, option);
	}
	
	
	
	this.setToggleOptions = function(options) {
		toggleOptions = options;
	}
	
	this.getCurrentIndex = function() { return currentIndex; }
	
	this.getLength = function() { return posPin.length; }

	/**
	*	Scroll to next indexed position pointer or reset to the first pointer automatically
	*	p.s: final position will be 'top left' corner of the panel window
	*	@param options Options of the animation, including mandatory 'duration' and/or 'ease' and/or 'onComplete' properties
	*/
	this.toggle = function() {
		this.next(toggleOptions, true);
	}
	
	this.next = function(allowCycle) {
		++currentIndex;
		if (allowCycle) {
			currentIndex %= posPin.length;
		} else if (currentIndex > posPin.length - 1) {
			--currentIndex;
			return false;
		}
		this.scrollTo(currentIndex, toggleOptions.stopPoint, toggleOptions);
		return SCROLLING_PANE.getCurrentIndex();
	}
	
	this.previous = function(allowCycle) {
		--currentIndex;
		if (allowCycle) {
			currentIndex = (currentIndex + posPin.length) % posPin.length;
		} else 	if (currentIndex < 0) {
			++currentIndex;
			return false;
		}
		this.scrollTo(currentIndex, toggleOptions.stopPoint, toggleOptions);
		return SCROLLING_PANE.getCurrentIndex();
	}
	
	posPin = posPin.merge(pane.getElementsBySelector('.scrollingPosition'));
	return this;
}