/* -------------------------------------------------------------------------- */
/** 
 *    @fileoverview
 *       Slide canvas.
 *
 *    @version rev001.2007-10-04
 *    @requires smoothScroll.js
 *    @requires slideCanvas.css
 */
/* -------------------------------------------------------------------------- */


var BASLIDECANVAS_INSTANCES = [];



/* -------------------- Settings for BASlideCanvas -------------------- */

var BASLIDECANVAS_DURATION    = 500;
var BASLIDECANVAS_INTERVAL    = 1;
var BASLIDECANVAS_EASING_FUNC = function(t, b, c, d) {
	// cubic easing in/out
	if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
	return c / 2 *((t -= 2) * t * t + 2) + b;
}



/* -------------------- Settings for BASlideCanvasAutoSetup -------------------- */

var BASLIDECANVAS_AS_ENABLED         = true;
var BASLIDECANVAS_AS_ROTATE_INTERVAL = 8000;
var BASLIDECANVAS_AS_TARGET_CNAMES   = ['slide-canvas'];



/* -------------------- Constructor : BASlideCanvas -------------------- */

function BASlideCanvas(node, interval) {
	if (!node || node.instanceOf != 'BAElement') {
		throw 'BASlideCanvas: first argument must be a BAElement node.';
	}

	this.node           = node;
	this.rotateInterval = (interval > 0) ? interval : 0;
	this.rotateTimer    = null;
	this.scrollField    = null;
	this.slideNodes     = [];
	this.selectButton   = [];
	this.stepButton     = { prev : null , next : null };
	this.currentNum     = 0;
	
	if (BA.env.isDOMReady) {
		this.init();
		this.startRotate();
	}
}

BASlideCanvas.prototype.init = function() {
	var viewportNode   = this.node.getElementsByClassNameBA('slide-viewport'  , 'div')[0];
	var controllerNode = this.node.getElementsByClassNameBA('slide-controller', 'ul' )[0];
	if (!viewportNode || !controllerNode) {
		throw 'BASlideCanvas.init: essential nodes are not found.';
	} else {
		// init scroll field.
		this.scrollField = new BASmoothScrollField(
			/* node     */ viewportNode,
			/* offsetX  */ (BA.ua.isSafari) ? -4 : 0,
			/* offsetY  */ 0,
			/* duration */ BASLIDECANVAS_DURATION,
			/* interval */ BASLIDECANVAS_INTERVAL,
			/* func     */ BASLIDECANVAS_EASING_FUNC
		);

		// prepare slide nodes.
		this.slideNodes = viewportNode.getElementsByClassNameBA('slide-unit', 'div');

		if (this.slideNodes.length > 1) {
			// find control button node.
			var anchors = controllerNode.getElementsByTagNameBA('a');

			// create step buttons
			this.stepButton.prev = new BASlideCanvas_StepBtn(anchors.shift(), -1);
			this.stepButton.next = new BASlideCanvas_StepBtn(anchors.pop()  , +1);
			for (var kind in this.stepButton) {
				this.stepButton[kind].addCallBack('onclick', this.selectBy, this);
			}

			// create select buttons
			anchors.forEach(function(node, i) {
				var btn = new BASlideCanvas_SelectButton(node, i);
				btn.addCallBack('onclick', this.select, this);
				this.selectButton.push(btn);
			}, this);

			// select first slide.
			this.select(0);

			// indicate enabled className
			this.node.appendClassNameBA('slide-canvas-enabled');
		}
	}
}

BASlideCanvas.prototype.select = function(num) {
	if (typeof num != 'number') {
		return;
	} else {
		this.startRotate();  // reset timer and continue rotation.

		var node = this.slideNodes[num];
		if (node) {
			// scroll slides.
			this.scrollField.stop();
			this.scrollField.scrollToNode(node);

			// select/unselect select buttons
			this.selectButton.forEach(function(btn, i) {
				if (num == i) {
					btn.select();
				} else {
					btn.unselect();
				}
			});

			// enable/disable step buttons
			this.stepButton.prev.enable();
			this.stepButton.next.enable();
			if (num == 0) {
				this.stepButton.prev.disable();
			} else if (num == this.slideNodes.length - 1) {
				this.stepButton.next.disable();
			}
			this.currentNum = num;
		}
	}
}

BASlideCanvas.prototype.selectBy = function(step) {
	if (typeof step != 'number' || step == 0) {
		return;
	} else {
		var len = this.currentNum.length;
		var num = this.currentNum + step;
		if (!this.slideNodes[num]) {
			num = (step > 0) ? 0 : this.slideNodes.length + step;
		}
		this.select(num);
	}
}

BASlideCanvas.prototype.startRotate = function() {
	this.stopRotate();
	if (this.rotateInterval > 0) {
		this.rotateTimer = new BASetInterval(function() { this.selectBy(1) }, this.rotateInterval, this);
	}
}

BASlideCanvas.prototype.stopRotate = function() {
	if (this.rotateTimer) {
		this.rotateTimer.clearTimer();
		this.rotateTimer = null;
	}
}


/* -------------------- Constructor : BASlideCanvas_StepBtn inherits BAObservable -------------------- */

function BASlideCanvas_StepBtn(node, step) {
	this.node     = node;
	this.step     = step;
	this.disabled = false;

	if (BA.env.isDOMReady) {
		this.init();
		
	}
}

BASlideCanvas_StepBtn.prototype = new BAObservable;

BASlideCanvas_StepBtn.prototype.init = function() {
	this.node.addEventListenerBA('click', this.onclick, this);
}

BASlideCanvas_StepBtn.prototype.onclick = function(e) {
	e.preventDefault();
	if (!this.disabled) {
		this.doCallBack('onclick', this.step);
	}
}

BASlideCanvas_StepBtn.prototype.enable = function() {
	this.disabled = false;
	this.node.removeClassNameBA('pseudo-disabled');
}

BASlideCanvas_StepBtn.prototype.disable = function() {
	this.disabled = true;
	this.node.appendClassNameBA('pseudo-disabled');
}





/* -------------------- Constructor : BASlideCanvas_SelectButton inherits BAObservable -------------------- */

function BASlideCanvas_SelectButton(node, index) {
	this.node     = node;
	this.index    = index;
	this.selected = false;

	if (BA.env.isDOMReady) {
		this.init();
		
	}
}

BASlideCanvas_SelectButton.prototype = new BAObservable;

BASlideCanvas_SelectButton.prototype.init = function() {
	this.node.addEventListenerBA('click', this.onclick, this);
}

BASlideCanvas_SelectButton.prototype.onclick = function(e) {
	e.preventDefault();
	this.doCallBack('onclick', this.index);
}

BASlideCanvas_SelectButton.prototype.select = function() {
	this.selected = true;
	this.node.appendClassNameBA('pseudo-selected');
}

BASlideCanvas_SelectButton.prototype.unselect = function() {
	this.selected = false;
	this.node.removeClassNameBA('pseudo-selected');
}






/* -------------------- Function : BASlideCanvasAutoSetup -------------------- */

function BASlideCanvasAutoSetup() {
	BASLIDECANVAS_AS_TARGET_CNAMES.forEach(function(className) {
		document.getElementsByClassNameBA(className, 'div').forEach(function(node) {
			BASLIDECANVAS_INSTANCES.push(
				new BASlideCanvas(node, BASLIDECANVAS_AS_ROTATE_INTERVAL)
			);
		});
	});
}






/* -------------------- Main : register start-up -------------------- */

if (typeof BA == 'object' && BA.ua.isDOMReady && BASLIDECANVAS_AS_ENABLED) {
	BAAddOnload(BASlideCanvasAutoSetup);
}



