/*
 * Image pre-loader
 * DEO 2010.05.22
 */
 
var preloader = (function() {
	var _index = 0, _curClass = 'preloader_cur';
						  
	// 全局Hash 变量
	var cacheList = {};
	
	// 预加载的配置文件
	var config = {
		LOADING	: 'Loading...',
		ERROR	: 'Error'
	};
	
	// 图片加载状态
	var status = {
		LOADING	: 'loading',
		LOADED	: 'loaded',
		ERROR	: 'error'
	};
	
	var effectTimerHandler = null;
	
	function Extend( destination, source ){
		for( var property in source )
			destination[ property ] = source[ property ];
	}
	
	// 将不同的调用放入全局的Hash 中
	// 避免多个调用时配置发生冲突
	function GetCache( boxID, conID, options ) {
		// 当该Key 值存在于Hash 中
		if( cacheList[boxID] )
			return cacheList[boxID];
		
		var // 将新的调用信息添加到Hash 中
			data = {}, 
			
			// 创建一个用于实例化预加载的Temp
			tempImg = null, 
			
			imgs = document.getElementById( boxID ).getElementsByTagName('img');
		
		for( var i = 0; i < imgs.length; i ++ ) {
			tempImg = new Image();
			tempImg.src = imgs[i].src;//+ '?'+(new Date()).getTime();
			tempImg._i = i;
			
			// 添加一个新的图片信息到Temp
			if( !data[i] ) {
				data[i] = {};
				
				data[i].loaded 	= false;
				data[i].error 	= false;
				data[i].src 	= tempImg.src;
			}
			
			// 图片的加载事件
			tempImg.onload = function() {
				data[this._i].loaded = true;
			};
			
			// 图片的加载错误事件
			tempImg.onerror = function() {
				data[this._i].error = true;
			};
		}
		
		// 创建一个新的Hash 数据
		cacheList[boxID] = {};
		cacheList[boxID].image 		= data;
		cacheList[boxID].size 		= 0;
		cacheList[boxID].controlID	= conID;
		
		cacheList[boxID].autoTimerHandler = null;
		cacheList[boxID].listenerTimerHandler 	= null;
		
		
		// 设置该Key 的可选配置
		cacheList[boxID].options = {
			curClass	: _curClass,
			index		: _index,
			auto		: false,
			autoTimer	: 5000
		};
		
		Extend( cacheList[boxID].options, options || {} );
		
		cacheList[boxID].autoIndex 	= cacheList[boxID].options.index;
	}
	
	// 控制按钮点击函数
	function Main( boxID ) {
		
		var data = cacheList[boxID],
			
			con = document.getElementById( data.controlID ), 
		
			links = con.getElementsByTagName('a');
			
		data.size = links.length;
			
		for( var i = 0, len = links.length; i < len; i ++ ) {
			
			// 控制按钮单击事件
			links[i].onclick = function() {
				
				var index = parseInt( this.getAttribute( 'rel' ) ) - 1;
				
				// 清楚图片加载缓存的Timer
				clearTimeout( cacheList[boxID].timer );
				cacheList[boxID].timer = null;
				
				Listener( boxID, data.autoIndex = index );
				
				var curStatus = status.LOADING;
				
				// 图片未加载失败时
				if( !data.image[index].error ) {
					// 图片加载完成
					if( data.image[index].loaded ) {
						curStatus = status.LOADED;
					}
					
				} else {
					curStatus = status.ERROR;
				}
				
				GetInfoBox( boxID, curStatus );
				
				SetLinkClass( boxID, index );
				
				data.autoIndex = data.autoIndex ++ >= data.size ? 0: index + 1;
				
				return false;
			}
			
			AutoControl( links[i], data, boxID );
			
		}
		
	}
	
	// 自动播放函数
	function Auto( boxID ) {
		var data = cacheList[boxID];
		
		clearTimeout( data.autoTimerHandler );
		
		if( data.autoIndex >= data.size ) {
			data.autoIndex = 0;
		}
		
		SetLinkClass( boxID, data.autoIndex );
		
		Listener( boxID, data.autoIndex ++ );
		
		data.autoTimerHandler = setTimeout( function(){ Auto( boxID ); }, data.options.autoTimer );
	}
	
	// 自动播放的停止或者重新播放函数
	function AutoControl( elem, data, boxID ) {
		
		elem.onmouseover = function() {
			clearTimeout( data.autoTimerHandler );
		};
		
		elem.onmouseout = function() {
			data.autoTimerHandler = setTimeout( function(){ Auto( boxID ); }, data.options.autoTimer );
		};
	}
	
	// 函数 - 设置超链接样式
	function SetLinkClass( boxID, index ) {
		var data = cacheList[boxID],
		
			con = document.getElementById( data.controlID ), 
		
			links = con.getElementsByTagName('a');
			
		for( var i = 0; i < links.length; i ++ ) {
			
			if( index == i ) {
				
				ClassEvent( links[i] ).add( data.options.curClass );
			} else {
				
				ClassEvent( links[i] ).remove( data.options.curClass );
			}
			
		}
		
	}
	
	// 函数 - 加载的监听
	function Listener( boxID, i ) {
		// 从Hash 中获取该Key 值的数据
		var data = cacheList[boxID];
		
		clearTimeout( data.timer );
	
		var // 获取图片信息
			image = data.image[i];
		
		if( !image.loaded ) {
			
			// 只调用一次
			if( data.listenerTimerHandler == null ) 
				ToDisplay( boxID, status.LOADING, i );
			
		} else {
			
			// 缓存图片已加载
			ToDisplay( boxID, status.LOADED, i );
		}
		
		if( image.error ) {
			
			// 图片加载错误
			ToDisplay( boxID, status.ERROR, i );
			
			clearTimeout( data.listenerTimerHandler );
			
			return;
		}
			
		if( !image.loaded )
			data.listenerTimerHandler = setTimeout( function() { Listener( boxID, i ); }, 100 );
	}
	
	// 函数 - 显示图片
	function ToDisplay( boxID, curStatus, index ) {
		
		var data = cacheList[boxID],
			
			// 展示容器中的超链接列表
			list = document.getElementById( boxID ).getElementsByTagName( 'a' );
		
		for( var i = 0, len = list.length; i < len; i ++ ) {
			
			// 展示当前图片
			if( index == i ) {
				
				list[i].style.display = 'block';
				
				var img = list[i].getElementsByTagName( 'img' )[0];
				
				opacity( list[i], n = 0 );
				// Fade in effect
				fadeIn( list[i] );
				
				// Loading
				if( curStatus == status.LOADING ) {
					
					GetInfoBox( boxID, curStatus );
					
				}
				
				// Error
				if( curStatus == status.ERROR ) {
					
					GetInfoBox( boxID, curStatus );
					
				}
				
				// LOADED
				if( curStatus == status.LOADED ) {
					
					GetInfoBox( boxID, curStatus );
					
					img.src = data.image[index].src;
					
				}
			} 
			
			// 隐藏未点击的列表
			else {
				
				list[i].style.display = 'none';
				
			}
			
			AutoControl( list[i], data, boxID );
		}
		
	}
	
	var n = 0;
	function fadeIn( elem ) {
		clearTimeout( effectTimerHandler );
		
		if( n <= 10 ) {		
			opacity( elem, ( n ++ ) / 10 );
			
			effectTimerHandler = setTimeout( function(){ fadeIn( elem ); }, 100 );
		}
	}
	
	function opacity( elem, num ) {
		elem.style.opacity = num;
		
		if( document.all )
			elem.style.filter = 'alpha(opacity='+num*100+')';
	}
	
	// 函数 - 显示信息
	function GetInfoBox( boxID, curStatus ) {
		var infoBox = document.getElementById( 'preloader-info_' +boxID );
		
		ClassEvent( infoBox ).remove( 'preloader-info-hidden' );
		
		if( curStatus == status.LOADING ) {
			
			infoBox.innerHTML = IsImage( config.LOADING ) ? '<img src="'+ config.LOADING +'" alt="" />&nbsp;': config.LOADING;
		}
		
		else if( curStatus == status.ERROR ) {
			
			infoBox.innerHTML = IsImage( config.ERROR ) ? '<img src="'+ config.ERROR +'" alt="" />&nbsp;': config.ERROR;
		}
		
		else if( curStatus == status.LOADED ) {
			
			ClassEvent( infoBox ).add( 'preloader-info-hidden' );
			
		}
	}
	
	// 函数 - 为每个实例创建一个信息框
	function CreateInfoBox( boxID ) {
		var info = document.createElement( 'div' );
			info.id = 'preloader-info_' + boxID;
			info.className = 'preloader-info';
		
		var elem = document.getElementById( boxID );
		
		info.style.width = elem.offsetWidth + 'px';
		info.style.height = elem.offsetHeight + 'px';
		info.style.lineHeight = elem.offsetHeight + 'px';
		
		elem.appendChild( info );
	}
	
	// 函数 - 默认显示
	function DefaultDisplay( boxID, i ) {
		// 设置默认样式
		SetLinkClass( boxID, i );
		
		Listener( boxID, i );
	}
	
	// 函数 - 判断是否为图片
	function IsImage( src ) {
		return /.\.(jpg|gif|png|bmp)/.test( src );
	}
	
	// 函数 - 元素的class 操作
	function ClassEvent( elem ) {
		var arr = [], map = {}, isClass = false;
		
		function eachClass( elem, className ) {
			var hasClass = elem.className.split(/\s+/);
			for (var i = 0; i < hasClass.length; i ++) {
				if (hasClass[i] != className) { map[ hasClass[i] ] = hasClass[i]; }
				else { isClass = true; }
				arr.push( hasClass[i] );
			}
		}
		
		return {
			add: function( className ) {
				eachClass( elem, className );
				
				if ( !isClass ) { arr.push( className ); }
				elem.className = arr.join(" ").replace(/^\s*|\s*$/g,'');
			},
			remove: function( className ) {
				eachClass( elem, className );
				
				arr = []; for (var key in map) { arr.push( key ); }
				elem.className = arr.join(" ").replace(/^\s*|\s*$/g,'');
			}
		}
	}
	
	return {
		init: function( boxID, conID, options ) {
			
			// 添加样式
			// 自动创建一个信息元素
			ClassEvent( document.getElementById( boxID ) ).add( 'preloader' );
			CreateInfoBox( boxID );
			
			GetCache( boxID, conID, options );	
			
			Main( boxID );
			
			// 进行默认显示
			var defIndex = cacheList[boxID].options.index;
			DefaultDisplay( boxID, defIndex );
			
			// 调用自动播放函数
			if( cacheList[boxID].options.auto ) {
				Auto( boxID );
			}
		},
		
		setConfig: function( options ) {
			Extend( config, options );
		}
	};
	
})();




 
