import org.swxformat.*; class ExternalAsset extends EventfulObject { public static var LOAD:String = "LOAD"; public static var PROGRESS:String = "PROGRESS"; public static var TIMEOUT:String = "TIMEOUT"; public static var POST:String = "POST"; public static var GET:String = "GET"; private var _holder:MovieClip = null; private var _innerHolder:MovieClip = null; private var url:String; private var data:Object = null; private var encoding:String = ExternalAsset.POST; private var resultObj:Object; private var resultFn:Function; private var progressObj:Object; private var progressFn:Function; private var checkLoadProgressInterval; private var _loaded:Boolean = false; private var _cancelled:Boolean = false; private var loadAttempts:Number = 0; function ExternalAsset (holder:MovieClip, url:String, data:Object, encoding:String) { this.holder = holder; this.url = url; this.data = data; setEncoding(encoding); } public function setResultHandler (resultObj:Object, resultFn:Function) { this.resultObj = resultObj; this.resultFn = resultFn; } public function setProgressHandler (progressObj:Object, progressFn:Function) { this.progressObj = progressObj; this.progressFn = progressFn; } public function setEncoding (encoding:String) { if (encoding != ExternalAsset.POST && encoding != ExternalAsset.GET) { trace ("Warning: Encoding must be either POST or GET. Keeping current setting ("+this.encoding+")"); } else { this.encoding = encoding; } } public function get hasHolder():Boolean { trace("_holder = " + _holder); return (_holder != null); } public function set holder(holder:MovieClip):Void { _holder = holder; _holder.createEmptyMovieClip("innerHolder", 1); _innerHolder = _holder["innerHolder"]; } public function get loaded():Boolean { return _loaded; } public function get cancelled():Boolean { return _cancelled; } public function get holder():MovieClip { return _holder; } public function get clip():MovieClip { return _holder.innerHolder; } public function load():Void { // Copy any data to be sent to the server into the holder movie clip for (var i in data) { _innerHolder[i] = data[i]; } // Load the movie if (data == null) { _innerHolder.loadMovie(url); } else { _innerHolder.loadMovie(url, encoding); } // Check for load every 250 ms loadAttempts = 0; checkLoadProgressInterval = setInterval(this, "checkLoadProgress", 250); } public function cancel():Boolean { if (_loaded) { trace("Warning: Cannot cancel loading clip since it has already loaded: " + url); return false; } else { // Cancel loading the clip _innerHolder.loadMovie("http://aralbalkan.com/DoesNotExist.swf"); return true; } } private function checkLoadProgress() { var bytesLoaded:Number = _innerHolder.getBytesLoaded(); var bytesTotal:Number = _innerHolder.getBytesTotal(); trace("Load attempt: " + loadAttempts + ": " + bytesLoaded + " of " + bytesTotal + " for " +url); if (bytesTotal == -1) loadAttempts++; if (loadAttempts > 20) { trace("Timeout! Possibly trying to load a PNG into a Flash 7 SWF."); clearInterval(checkLoadProgressInterval); // TODO: Fail -- call status handler. dispatchEvent({type:ExternalAsset.TIMEOUT}); } if (bytesLoaded > 4 && (bytesLoaded == bytesTotal)) { trace("loaded!"); clearInterval(checkLoadProgressInterval); _loaded = true; // Dispatch the load event on the next frame so that // developers don't have to wait a frame themselves for things // to initialize and become available. _holder.objectRef = this; _holder.functionRef = dispatchEventLater; _holder.onEnterFrame = function () { this.functionRef.apply(this.objectRef); this.onEnterFrame = null; }; } else { dispatchEvent({type:ExternalAsset.PROGRESS, bytesLoaded:bytesLoaded, bytesTotal:bytesTotal}) } } private function dispatchEventLater() { dispatchEvent({type:ExternalAsset.LOAD}); } }