/*
================================================================================
 .............     ......                                                       
    ....   .....     ....                                                       
    ....    ....     ....                                                       
    ....     ....    ....                                                       
    ....     ....    ....                                                       
    ....     ....    ....                                                       
    ....    ....     ....      ......        ......... .....  .....     ...  .  
    ....   ....      ....    ..   ....     .... ....    ....   ....    ..  ...  
    ..........       ....   ...    ....   ....   ....   ....   ....   ...   ..  
    ....   .....     ....   ....   ....   ....   ....   ....   ....   ....   .  
    ....     ....    ....    ..    ....   ....   ....   ....   ....   ......    
    ....     .....   ....        ......   ....   ....   ....   ....    ......   
    ....     .....   ....      ..  ....   ....   ...    ....   ....      .....  
    ....     .....   ....    ...   ....    .... ...     ....   ....       ..... 
    ....     .....   ....   ....   ....     ......      ....   ....   .    .... 
    ....    .....    ....   ....  .....    .            ....  .....   ..    ... 
    ....   .....     ....   ...... .....  ..            ...........   ...   ..  
 .............     ........  ....   ...   ..........     ..... .....  .  ....   
                                          ............                          
                                            ...........                         
                                           ..        ..                         
                                           ..        ..                         
                                           ...      ..                          
                                             .......                            
================================================================================
H   o   r   i   z   o   n   t   a   l              S   c   r   o   l   l   e   r
version 1.10                             by Alexander Blagus <blagus@pop.com.br>
This    software   is   available    under   the    General    Public    License
GPL - The GNU General Public License         http://www.gnu.org/licenses/gpl.txt
================================================================================
*/
// Aplication settings
// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ

// trace highlight color
var sc = "#309"; // lc stands for scroller color

// Global variables
// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
// enable trace for this lib
var trc = function(a, b){
	trace(a, b);
	// console.log(a);
}

// =============================================================================
var Scroller = function(
	/*
	Purpose: horizontal scroller class.
	Return:  object, current Scroller.
	*/
	argObjContainer,  /* DOM element object, usually a div. inside this div 
	                     must be the elements to be scrolled, [very important]    
	                                all of then with CSS width declared inline. */
	argRefreshRate,   /* integer,  representing the intervel in 
	                                      miliseconds of the scroller animation */
	argPhaseDisplace  /* integer, how many pixels will be 
	                                            the phase movement, default = 1 */
){
	trc("Scroller(" + getInfo(arguments) + ")", sc);
	
	/* -------------------------------------------------------------------------- */
	/* define properties */
	this.objContainer  = argObjContainer;
	this.refreshRate   = isNaN(argRefreshRate)   ? 50 : parseInt(argRefreshRate);
	this.phaseDisplace = isNaN(argPhaseDisplace) ?  1 : parseInt(argPhaseDisplace);
	this.running = false;
	this.paused  = false;
	
	/* define sub-objects */
	this.scrollables = [];
	
	/* -------------------------------------------------------------------------- */
	/* create micro-db objects */
	this.retrieveScrollables = function(){
		trc("Scroller.retrieveScrollables(" + getInfo(arguments) + ")", sc);
		
		trc("this.objContainer.childNodes.length: " + this.objContainer.childNodes.length);
		this.scrollables = [];
		for (loopObjs=0; loopObjs<this.objContainer.childNodes.length; loopObjs++){
			if ( this.objContainer.childNodes[loopObjs].nodeType == 1 ){ // must be a HTML object
				if (this.objContainer.childNodes[loopObjs].style.width.indexOf("px") > 1){ // must have width in pixels declared inline
					trc("Element this.objContainer.childNodes[" + loopObjs + "] is a HTML object and have width declared");
					// add object
					this.scrollables[this.scrollables.length] = this.objContainer.childNodes[loopObjs];
				} else {
					trc("Element this.objContainer.childNodes[" + loopObjs + "] is an HTML object but desn't have width declared");
				}
			} else {
				trc("Element this.objContainer.childNodes[" + loopObjs + "] is not a HTML object");
			}
		}
	};
	this.retrieveScrollables();

	/* -------------------------------------------------------------------------- */
	/* Add mouse behaviors */
	this.addBehaviors = function(){
		trc("Scroller.addBehaviors(" + getInfo(arguments) + ")", sc);
		if ( this.scrollables.length > 2 ){
			// add icons behaviors
			for(loopBehavior=0; loopBehavior<this.scrollables.length; loopBehavior++){
				trc("this.scrollables[" + loopBehavior + "]: " + getInfo(this.scrollables[loopBehavior]));
				var t=this;
				addEvent(this.scrollables[loopBehavior], "mouseover", function(){t.stop();}    );
				addEvent(this.scrollables[loopBehavior], "mouseout",  function(){t.animate();} );
			}
		}
	};
	this.addBehaviors();

	/* -------------------------------------------------------------------------- */
	/* move objects to the left */
	this.move = function(){
		trc("Scroller.animate(" + getInfo(arguments) + ")", sc);
		
		if ( !this.paused ){

			// create margin
			if( !this.scrollables[0].style.marginLeft ){ this.scrollables[0].style.marginLeft = "0px"; }
			if( !this.scrollables[1].style.marginLeft ){ this.scrollables[1].style.marginLeft = "0px"; }

			var mL = parseInt(this.scrollables[0].style.marginLeft.replace(/\s*px/i, "")); // mL stands for marginLeft
			var wi = parseInt(this.scrollables[0].style.width.replace(/\s*px/i, "")); // wi stands for width
			var pD = this.phaseDisplace // pD stands fo phaseDisplace
			trc("mL: " + mL);
			trc("wi: " + wi);
			trc("pD: " + pD);
			
			if ( Math.abs(mL) < wi ) {
				trc("Move to left");
				this.scrollables[0].style.marginLeft = (mL-pD) + "px";
			} else {
				trc("Move to the end");
				var objMoving = this.objContainer.removeChild(this.scrollables[0]);
				objMoving.style.marginLeft = "0px";
				var objLast = this.scrollables[this.scrollables.length-1];
				objLast.parentNode.insertBefore(
					objMoving, 
					objLast.nextSibling
				);

				// reset micro-db
				this.retrieveScrollables();
				
				// continue animation for next object, if there's a rest of last animation
				var rest = 0;
				if (Math.abs(mL) > wi) {
					rest = Math.abs(mL)-wi; 
					trc("rest: " + rest);
				}
				
				this.scrollables[0].style.marginLeft = "-" + (pD+rest) + "px";
			}
		}
	};

	/* -------------------------------------------------------------------------- */
	/* repeat movement */
	this.animate = function (){
		trc("Scroller.animate(" + getInfo(arguments) + ")", sc);
		if ( this.scrollables.length > 2 && !this.running ){
			this.interval = setInterval(this.move.bind(this), this.refreshRate);
			this.running = true;
		}
	};
	// auto-start
	this.animate();

	/* -------------------------------------------------------------------------- */
	/* stop ! */
	this.stop = function(){
		trc("Scroller.stop(" + getInfo(arguments) + ")", sc);
		if (this.running) {
			window.clearInterval(this.interval);
			this.running = false;
		}
	};
	trc("<a href=\"javascript:void(worksScroller.stop());\">worksScroller.stop();</a>");
	
	/* -------------------------------------------------------------------------- */
	/* pause ! */
	this.pause = function(b){
		this.paused = b;
	}

	// exit function
	return undefined;
}

// =============================================================================
Function.prototype.bind = function() {
	/* bind method for function extension. 
	   Thanks to Wilker (wilkerlucio88@hotmail.com) */
	var __method = this;
	var __scope = arguments[0];
	var __arguments = [];

	for(var i = 1; i < arguments.length; i++)
		__arguments.push(arguments[i]);

	return function() {
		var args = [];
		for(var i = 0; i < arguments.length; i++)
			args.push(arguments[i]);

		return __method.apply(__scope, __arguments.concat(args));
	};
};

// =============================================================================
function addEvent(obj, evType, fn){ 
 if (obj.addEventListener){ 
   obj.addEventListener(evType, fn, false); 
   return true; 
 } else if (obj.attachEvent){ 
   var r = obj.attachEvent("on"+evType, fn); 
   return r; 
 } else { 
   return false; 
 } 
}

// =============================================================================
var myFunction = function(){
	/*
	Purpose: what the procedure does (not how).
	Inputs:  argument name: data type, explanation;
	Return:  data type, explanation of the value returned.
	*/
	trc("myFunction(" + getInfo(arguments) + ")", sc);
	
	// ...
	
	// exit function
	return undefined;
}
// =============================================================================
