/**
 * @classdescription: 
 * @author: Sebastian Martens; sebastian@sebastian-martens.de: blog.sebastian-martens.de
 * @copyright: Creative Commons. Free to use "as is"
 * @svn: $Id: swfJSPreLoader.js 3 2010-05-17 21:01:19Z dinnerout $
 * @uses: jQuery, swfObject
 */ 
var swfJSPreLoader = {
 	
 	_nodeId: 'swfJSPreLoaderNode',
 	_jsLoaderSWF: null,
 	
	_flashVersion:"9.0.0", // minimum version of test flash
	
	_swfPath:'./',
	_flashVars:{}, // flash vars
	_params:{ menu:false, wmode:'transparent', scale:'noScale' }, // flash parameters
	_attributes:{ id: this._nodeId, name: this._nodeId, style:'position:absolute;right:0px;bottom:0px' }, // flash atributes
	
	_isInitialized: false,
	_swfInstance: null,
	
	assets:[],
	
	loadComplete: null,
	loadError: null,
	callback: null,
	assetLoaded: null,
	
	_assetsMap: [],
	
	/**
	 * @public
	 * 
	 * init method, called on init
	 * @param {Object} obj - parameter object 
	 */ 
	init:function( obj ){
		// mixes given parameter into this
		this.mixIn( obj );
		
		this._isInitialized = false;
		this.createNode();
		
		return true;
	},
	
	/**
	 * @private 
	 * 
	 * mix a given object into this object
	 * @param {Object} obj - given object with parameters
	 */	
	mixIn: function( obj, scope ){
		var item;
		if(!scope) scope = this;
		for(item in obj){
			scope[ item ] = obj[item];
		}
	},
	
	/**
	 * @private 
	 * 
	 * load handler, called after document is fully loaded
	 * adds flash node via swfObjects into DOM
	 * @param {Object} obj - event parameter
	 */
	createNode:function( obj ){
		var node = document.createElement('DIV');
		node.setAttribute('id',this._nodeId);
		
		$('body')[0].appendChild( node );
		this._jsLoaderSWF = node;	
		
		swfobject.embedSWF(this._swfPath+"swfJSPreLoader.swf", this._nodeId, 1, 1, this._flashVersion,"expressInstall.swf", this._flashvars, this._params, this._attributes);
	},
	
	/**
	 * @private 
	 * 
	 * init function called from flash, flash is ready
	 * adds all initial assets to loading queue
	 */
	swfJSPreLoaderInit:function( ){
		// get swf instance
		if (navigator.appName.indexOf("Microsoft") != -1) {
        	this._swfInstance =  window[this._nodeId];
        } else {
        	this._swfInstance = document[this._nodeId];
        }
		// add assets to queue
		for(var i=0;i<this.assets.length;i++){
			if( this.assets[i]!='' ){
				this.addAsset( this.assets[i] );
			}
		}
		// 
		if( this.callback ) this.callback();
	},
	
	/**
	 * @private 
	 * 
	 * load complete handler for complete queue
	 */
	assetsLoadCompleteHandler: function(){
		// executes the load complete handler
		if( this.loadComplete ) this.loadComplete();
	},
	
	/**
	 * @private 
	 * 
	 * load complete handler for single file
	 * @param Object obj - parameter object
	 */
	loadCompleteHandler: function( obj ){
		var item;
		if( obj.status == 404 && this.loadError ) this.loadError();
		// search for file in local asset map
		for( item in this._assetsMap ){
			if( this._assetsMap[ item ] && 
				this._assetsMap[ item ].file == obj.file ){
				
				if( this.assetLoaded ) this.assetLoaded( obj.file, obj.size, obj.status );
				if( this._assetsMap[ item ].callback ) this._assetsMap[ item ].callback( obj.status );
				this._assetsMap.splice(item,1);
			}
		}
		// callback handler
		if( !this._assetsMap.length ) this.assetsLoadCompleteHandler();
	},
	
	/**
	 * @public 
	 * 
	 * returns the total number of loaded bytes
	 * @return int - number of loaded bytes
	 */
	loadedBytes: function(){
		return this._swfInstance.getTotalLoaded();	
	},
	
	/**
	 * @public 
	 * 
	 * adds asset to loading queue
	 * @param {String} assetPath - path to assets to load
	 * @param {Function} callback - optional callback handler
	 */
	addAsset:function( assetPath, callback ){
		this._assetsMap.push({
			'file':assetPath,
			'callback':callback
		});
		this._swfInstance.addAsset( {'path':assetPath} );
	}

};

// start on document load
$(document).ready( function(){
	 swfJSPreLoader.init.apply( swfJSPreLoader,[swfJSPreLoaderConfig] );
});
