﻿/**
 * @fileOverview Slideshow
 * @author 彭日聪
 * @version 1.0.0
 * @change
    修改者      修改时间         版本       修改描述
*/
/*
RL.provide("fx.Slideshow");
*/
RL.loadCss("decorator.slideshow");

/**
 * @class 
 * @constructor
 * @description Construct a new instance by specified config.
 * @param {Object} [config]
 */
RL.createClass("RL.fx.Slideshow", {
	superClass : RL.util.EventProvider,
	
	members : {
		/** @lends RL.fx.Slideshow# */
		
		autoDecorate : true,
		
		target : "",
		
		iniActive : 0,
		
		enableAutoPlay : true,
		
		autoPlayIntervel : 5,
		
		activateEventName : "mousedown",
		
		initialize : function(config){
			RL.lend(this, config);
			RL.fx.Slideshow.superClass.prototype.initialize.call(this, config);
			
			if(this.autoDecorate){
				RL.on("ready", this.decorateTarget, this);
			}
		},
		
		decorateTarget : function(){
			this.initEvents();
			this.createAnimation();
			if(this.enableAutoPlay){
				this.startAutoPlay();
			}else{
				this.iniFirstActive();
			}
		},
		
		startAutoPlay : function(){
			if(this._autoPlaying) return ;
			var intervel = this.autoPlayIntervel * 1000;
			this._autoPlayTimer = RL.interval(this.autoPlay, intervel, this);
			this.autoPlay();
			this._autoPlaying = true;
		},
		
		stopAutoPlay : function(){
			window.clearInterval(this._autoPlayTimer);
			this._autoPlaying = false;
		},
		
		autoPlay : function(){
			var index = this.getActiveIndex();
			if(isNaN(index)
			   || index >= this.length - 1) index = -1;
			index ++;
			this.setActive(index);
		},
		
		initEvents : function(){
			var ele, hndlBarEle, bodyStackEle,
				hasClass = RL.dom.hasClass;
			if(RL.isNonNullStr(this.target)){
				this.target = document.getElementById(this.target);
			}
			if(!RL.isElement(this.target)) throw {
				description : "Invalid target to bulid a Slideshow!"
			}
			
			RL.toList(this.target.childNodes)
			  .each(function(node){
				if(RL.isElement(node) && hasClass(node, "pos_wrap")){
					RL.toList(node.childNodes)
					  .each(function(node){
						if(RL.isElement(node)){
							RL.dom.cleanWhitespace(node);
							if(hasClass(node, "body_stack")){
								this.bodyStackEle = node;
								this.length = node.childNodes.length;
							}else if(hasClass(node, "hndl_bar")){
								this.hndlBarEle = node;
							}else if(hasClass(node, "title_stack")){
								this.titleStackEle = node;
							}
						}
					}, this);
					//RL.dom.cleanWhitespace(node);
					throw RL.BREAK_EACH;
				}
			}, this);
			
			this.hndActivate = RL.bind(this.hndActivate, this);
			this.hndMouseover = RL.bind(this.hndMouseover, this);
			this.hndMouseout = RL.bind(this.hndMouseout, this);			
			
			this.target.onmouseover = this.hndMouseover;
			this.target.onmouseout = this.hndMouseout;
			this.hndlBarEle["on" + this.activateEventName] = this.hndActivate;
		},
        
		iniFirstActive : function(){
			if(this.iniActive > -1) this.setActive(this.iniActive);
		},
        
		createAnimation : function(){
			this.titleLeaverAni = new RL.fx.Animation({
				duration : 0.5,
				onStop : RL.bind(this.updateIncomeTitle, this)
			});
			this.titleIncomerAni = new RL.fx.Animation({
				easingDetais : "easeOut",
				onStart : RL.bind(this.hndIncomeTitleStart, this)
			});
			this.imgAni = new RL.fx.Animation({
				easingDetais : "easeOut",
				attributes : {
					opacity : {from: 0, to : 1}
				}
			});
		},
		 
		setActive : function(index){
			if(!(this.hndlBarEle && this.hndlBarEle)
			   || this._activeIndex == index
			   || this.animated) return this;
			
			this.animated = true;
			if(this._activeIndex > -1) this.updateLeaverStyle(this._activeIndex);
			if(index > -1) this.updateIncomerStyle(index);
			
			this._activeIndex = index;
			this.fireEvent("activechange", index, this._activeIndex);
			
			return this;
		},
			
		updateLeaverStyle : function(index){
			var hndlEle, bodyEle, titleEle ;
			
			if(index > -1){
				hndlEle = this.hndlBarEle.childNodes[index];
				bodyEle = this.bodyStackEle.childNodes[index];
				titleEle = this.titleStackEle.childNodes[index];
				
				RL.dom.removeClass(hndlEle, "active_hndl");
				RL.dom.removeClass(bodyEle, "active_slide");
				
				bodyEle.style.zIndex = 0;
				
				if(this.titleIncomerAni.target == titleEle){
					this.titleIncomerAni.stop(true);
				}
				if(this.titleLeaverAni.animated) this.titleLeaverAni.stop(true);
				this.titleLeaverAni.target = titleEle;
				this.titleLeaverAni.attributes = {
					top : {from: 0, to: titleEle.offsetHeight}
				};
				
				this.titleLeaverAni.start();
			}
		},
			
		updateIncomerStyle : function(index){
			var hndlEle, bodyEle, titleEle ;
			if(index > -1){
				hndlEle = this.hndlBarEle.childNodes[index];
				bodyEle = this.bodyStackEle.childNodes[index];
				if(hndlEle && bodyEle){
					RL.dom.addClass(hndlEle, "active_hndl");
					RL.dom.addClass(bodyEle, "active_slide");
					
					if(this.imgAni.animated)this.imgAni.stop(true);
					bodyEle.style.zIndex = 1;
					
					this.imgAni.target = bodyEle;
					this.imgAni.start();
					if(!(this._activeIndex > -1)){
						this.updateIncomeTitle(index);
					}
				}
			}
		},
			
		getActiveIndex : function(){
			return this._activeIndex;
		},
        
		hndMouseover : function(evt){
			this._mouseovering = true;
		},
		
		hndMouseout : function(evt){
			this._mouseovering = false;
		},
		
		hndActivate : function(evt){
			evt = evt || window.event;
			var target = evt.target || evt.srcElement,
				index = this._getChildNodeIndex(target);
			
			this.setActive(index);
		},
		
		updateIncomeTitle : function(index){
			if(isNaN(index)) index = this.getActiveIndex();
			var titleEle = this.titleStackEle.childNodes[index];
			RL.debug('index = ' + index);
			if(this.titleIncomerAni.animated){
				this.titleIncomerAni.stop(true);
			}
			this.titleIncomerAni.target = titleEle;
			this.titleIncomerAni.attributes = {
				top : {from: titleEle.offsetHeight , to : 0}
			};
			this.titleIncomerAni.start();
		},
		
		hndIncomeTitleStart : function(){
			this.animated = false;
		},
		
		_getChildNodeIndex : function(target){
			var index = -1;
			if(RL.isElement(target) && target.parentNode){
				index = RL.toList(target.parentNode.childNodes)
						  .indexOf(function(chd){ return (chd == target);});
			}
			return index;
		},
        
		toString : function(){return "[object RL.fx.Slideshow]";}
	}
});

RL.fireEvent("load:fx.slideshow");
