package org.libspark.thread.threads.net
{
	import flash.errors.*;
	import flash.events.*;
	import flash.net.*;
	import org.libspark.thread.threads.net.*;
	import org.libspark.thread.utils.*;

	/* URLLoaderThreadの不具合修正版です(リリース版に適用されるまでの暫定処置) */
	
	public class URLLoaderThreadPatch extends URLLoaderThread
	{
		public function URLLoaderThreadPatch(request:URLRequest, loader:URLLoader = null):void
		{
			super(request, loader);
		}

		override protected function run():void
		{
			events();
			interrupted(interruptedHandler);
			next(function ():void{ loader.load(request); }); // 直後にCOMPLETEイベントが起きると捕捉できないので遅延させる
		}

		private function events():void
		{
			var _loader:URLLoader = loader;
			event(_loader, Event.COMPLETE, completeHandler);
			event(_loader, ProgressEvent.PROGRESS, progressHandler);
			event(_loader, IOErrorEvent.IO_ERROR, ioErrorHandler);
			event(_loader, SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
		}
		
		private function notifyStartIfNeeded(total:Number):void
		{
			var _progress:Progress = progress as Progress;
			if (!_progress.isStarted) {
				_progress.start(total);
			}
		}
		
		private function progressHandler(e:ProgressEvent):void
		{
			notifyStartIfNeeded(e.bytesTotal);
			(progress as Progress).progress(e.bytesLoaded);
			interrupted(interruptedHandler);
			events();
		}

		private function completeHandler(e:Event):void
		{
			notifyStartIfNeeded(0);
			(progress as Progress).complete();
		}
		
		private function ioErrorHandler(e:IOErrorEvent):void
		{
			notifyStartIfNeeded(0);
			(progress as Progress).fail();
			throw new IOError(e.text);
		}
		
		private function securityErrorHandler(e:SecurityErrorEvent):void
		{
			notifyStartIfNeeded(0);
			(progress as Progress).fail();
			throw new SecurityError(e.text);
		}
		
		private function interruptedHandler():void
		{
			notifyStartIfNeeded(0);
			loader.close();
			(progress as Progress).cancel();
		}
	}
}
