/* SupreLoader
* Author: Ramon Tayag
* Sept, 2005
*
* Class description:
* Makes full use of time the user is not downloading anything.
*
* Loads everything that it is told to.
* SupreLoader uses an XML to load different objects.
*
* The format of the xml is as follows:
*
* <xml>
* <loc path="res/videos/">
* <file url="[file url]"></file>
* <file url="[file url]"></file>
* </loc>
* </xml>
*
* SUPPORTED FILE TYPES:
* - jpg
* - swf
* - xml
* - mp3
*
* Other notes:
* Can be interrupted at any time and it will continue where it left off (verify this)
* Use functions halt and resume to control the downloading.
*
* Please note that once this class starts to download one thing,
* you cannot stop it. You will have to wait for that item to download and it will
* not continue downloading the next item in queue until resume() is called.
*/
import net.quirkworks.utils.Delegate;
import mx.events.EventDispatcher;
import LuminicBox.Log.*;
class net.quirkworks.utils.SupreLoader extends MovieClip
{
private var _xmlFile:String;
private var _xmlList:XML;
private var _nTotalItems:Number;
private var _nLastLoadedItem:Number;
private var _nodeRoot:XMLNode;
private var _mcl:MovieClipLoader;
private var _mclListener:Object = new Object();
private var _aObjectsToLoad:Array;
//the movieclip will contain whatever needs to be loaded. we need to load it into a holder!
private var _mc:MovieClip;
private var _bHalt:Boolean;
private var _nIntervalLoadNext:Number;
public var addEventListener:Function;
public var removeEventListener:Function;
private var dispatchEvent:Function;
private var log:Logger;
//time it takes for loadNext to actually loadNext. in ms.
private static var _N_RESUME_TIME:Number = 1000;
function SupreLoader(mcHolder:MovieClip)
{
EventDispatcher.initialize(this);
log = new Logger("SupreLoader");
log.addPublisher(new ConsolePublisher() );
//attachMovie("mc.holder.file", "_mc", getNextHighestDepth() );
mcHolder.createEmptyMovieClip("_mcSupreLoader", mcHolder.getNextHighestDepth() );
_mc = mcHolder._mcSupreLoader;
_mc._visible = false;
//instantiate the moviecliplistener and add a listener
_mcl = new MovieClipLoader();
_mcl.addListener(_mclListener);
_mclListener.onLoadStart = Delegate.create(this, mclListenerOnLoadStart);
_mclListener.onLoadComplete = Delegate.create(this, mclListenerOnLoadComplete);
_mclListener.onLoadProgress = Delegate.create(this, mclListenerOnLoadProgress);
//set the last loaded item to the one before 0. we start counting at 0.
_nLastLoadedItem = -1;
}
private function loadXML(s:String):Void
{
//instantiate the xml and connect to it
_xmlList = new XML();
_xmlList.ignoreWhite = true;
_xmlList.load(_xmlFile);
_xmlList.onLoad = Delegate.create(this, xmlListOnLoad);
}
function createArray(x:XML):Array
{
//log.log("creating xml");
var a:Array = new Array();
var rootNode:XMLNode = x.firstChild;
//trace(rootNode);
//log.log(rootNode);
var aLocNodes:Array = rootNode.childNodes;
//trace(aLocNodes);
//trace("there are " + aLocNodes.length + " loc nodes.");
for (var i = 0; i < aLocNodes.length; i++)
{
var nodeLoc:XMLNode = aLocNodes[i];
var sLoc:String = nodeLoc.attributes.path;
var aFiles:Array = nodeLoc.childNodes;
for (var j = 0; j < aFiles.length; j++)
{
var nodeFile:XMLNode = aFiles[j];
var sFile:String = nodeFile.attributes.url;
a.push(sLoc + sFile);
//trace("pushing " + (sLoc + sFile) );
//log.log("pushing " + (sLoc + sFile) );
}
}
_nTotalItems = a.length;
//log.log(_nTotalItems);
return a;
}
//xml events stuff
private function xmlListOnLoad(b:Boolean):Void
{
if (b)
{
//then start the load
_aObjectsToLoad = createArray(_xmlList);
log.log(_aObjectsToLoad);
//log.log(_xmlList);
loadNext();
}
}
//Below are the functions of the mclListener
private function mclListenerOnLoadStart(mc:MovieClip)
{
//this._parent.tfMisc.text = "started to load " + _aObjectsToLoad[_nLastLoadedItem + 1];
}
private function mclListenerOnLoadComplete(mc:MovieClip):Void
{ //load next
loadNext();
_mc._visible = false;
}
private function mclListenerOnLoadProgress(mc:MovieClip):Void
{
log.log(mc.getBytesLoaded() );
}
private function soundOLC(s:Sound):Void
{
s.stop();
loadNext();
}
//////////////public functions/////////////////
public function halt():Void
{
_bHalt = true;
}
public function resume(Void):Void
{
_bHalt = false;
loadNext();
}
public function loadNext(Void):Void
{
//log.log("loading next");
if (isDone() )
{
dispatchEvent({target: this, type: 'onLoadComplete'});
} else if (!_bHalt)// && !isDone() )
{
_nIntervalLoadNext = setInterval(Delegate.create(this, intervalLoadNext), _N_RESUME_TIME);
}
}
private function intervalLoadNext(Void):Void
{
var sObjectToLoad:String = _aObjectsToLoad[_nLastLoadedItem + 1];
var sType:String = sObjectToLoad.substr(-3,3).toLowerCase();
//trace(_root.lbLog);
//_root.lbLog("Testing 2");
if (sType == "swf" || sType == "jpg")
{
log.log("loading swf/jpg");
_nLastLoadedItem++;
_mcl.loadClip(sObjectToLoad, _mc);
} else if (sType == "xml")
{
log.log("loading xml");
var xmlTemp:XML = new XML();
xmlTemp.load(sObjectToLoad);
_nLastLoadedItem++;
xmlTemp.onLoad = Delegate.create(this, loadNext);
} else if (sType == "mp3")
{
log.log("loading mp3");
var s:Sound = new Sound(_mc);
s.loadSound(sObjectToLoad);
s.onLoad = Delegate.create(this, soundOLC, s);
_nLastLoadedItem++;
}
_bHalt = false;
clearInterval(_nIntervalLoadNext);
}
public function isDone():Boolean
{
log.log("we have loaded " + _nLastLoadedItem + " items out of " + _nTotalItems);
return (_nLastLoadedItem + 1 >= _nTotalItems)
}
public function getLoadedItems():Number
{
return _nLastLoadedItem + 1;
}
public function getTotalItems():Number
{
return _nTotalItems;
}
//////////////INSPECTABLES////////////////////
//[Inspectable(defaultValue="", type=String)]
public function start(s:String):Void
{
_xmlFile = s;
//trace("setting xml to " + _xmlFile);
loadXML(_xmlFile);
}
public function getXMLFile():String
{
return _xmlFile;
}
}