[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/modules/image_fupload/swfupload/tmp/Flash/ -> SWFUpload.as (source)

   1  package {
   2      import flash.display.BlendMode;
   3      import flash.display.DisplayObjectContainer;
   4      import flash.display.Loader;
   5      import flash.display.Stage;
   6      import flash.display.Sprite;
   7      import flash.display.StageAlign;
   8      import flash.display.StageScaleMode;
   9      import flash.net.FileReferenceList;
  10      import flash.net.FileReference;
  11      import flash.net.FileFilter;
  12      import flash.net.URLRequest;
  13      import flash.net.URLRequestMethod;
  14      import flash.net.URLVariables;
  15      import flash.events.*;
  16      import flash.external.ExternalInterface;
  17      import flash.system.Security;
  18      import flash.text.AntiAliasType;
  19      import flash.text.GridFitType;
  20      import flash.text.StaticText;
  21      import flash.text.StyleSheet;
  22      import flash.text.TextDisplayMode;
  23      import flash.text.TextField;
  24      import flash.text.TextFieldType;
  25      import flash.text.TextFieldAutoSize;
  26      import flash.text.TextFormat;
  27      import flash.ui.Mouse;
  28      import flash.utils.Timer;
  29  
  30      import FileItem;
  31      import ExternalCall;
  32  
  33      public class SWFUpload extends Sprite {
  34          // Cause SWFUpload to start as soon as the movie starts

  35  		public static function main():void
  36          {
  37              var SWFUpload:SWFUpload = new SWFUpload();
  38          }
  39          
  40          private const build_number:String = "SWFUPLOAD 2.2.0";
  41          
  42          // State tracking variables

  43          private var fileBrowserMany:FileReferenceList = new FileReferenceList();
  44          private var fileBrowserOne:FileReference = null;    // This isn't set because it can't be reused like the FileReferenceList. It gets setup in the SelectFile method

  45  
  46          private var file_queue:Array = new Array();        // holds a list of all items that are to be uploaded.

  47          private var current_file_item:FileItem = null;    // the item that is currently being uploaded.

  48  
  49          private var file_index:Array = new Array();
  50          
  51          private var successful_uploads:Number = 0;        // Tracks the uploads that have been completed

  52          private var queue_errors:Number = 0;            // Tracks files rejected during queueing

  53          private var upload_errors:Number = 0;            // Tracks files that fail upload

  54          private var upload_cancelled:Number = 0;        // Tracks number of cancelled files

  55          private var queued_uploads:Number = 0;            // Tracks the FileItems that are waiting to be uploaded.

  56          
  57          private var valid_file_extensions:Array = new Array();// Holds the parsed valid extensions.

  58          
  59          private var serverDataTimer:Timer = null;
  60          private var assumeSuccessTimer:Timer = null;
  61          
  62          private var restoreExtIntTimer:Timer;
  63          private var hasCalledFlashReady:Boolean = false;
  64          
  65          // Callbacks

  66          private var flashReady_Callback:String;
  67          private var fileDialogStart_Callback:String;
  68          private var fileQueued_Callback:String;
  69          private var fileQueueError_Callback:String;
  70          private var fileDialogComplete_Callback:String;
  71          
  72          private var uploadStart_Callback:String;
  73          private var uploadProgress_Callback:String;
  74          private var uploadError_Callback:String;
  75          private var uploadSuccess_Callback:String;
  76  
  77          private var uploadComplete_Callback:String;
  78          
  79          private var debug_Callback:String;
  80          private var testExternalInterface_Callback:String;
  81          private var cleanUp_Callback:String;
  82          
  83          // Values passed in from the HTML

  84          private var movieName:String;
  85          private var uploadURL:String;
  86          private var filePostName:String;
  87          private var uploadPostObject:Object;
  88          private var fileTypes:String;
  89          private var fileTypesDescription:String;
  90          private var fileSizeLimit:Number;
  91          private var fileUploadLimit:Number = 0;
  92          private var fileQueueLimit:Number = 0;
  93          private var useQueryString:Boolean = false;
  94          private var requeueOnError:Boolean = false;
  95          private var httpSuccess:Array = [];
  96          private var assumeSuccessTimeout:Number = 0;
  97          private var debugEnabled:Boolean;
  98  
  99          private var buttonLoader:Loader;
 100          private var buttonTextField:TextField;
 101          private var buttonCursorSprite:Sprite;
 102          private var buttonImageURL:String;
 103          private var buttonWidth:Number;
 104          private var buttonHeight:Number;
 105          private var buttonText:String;
 106          private var buttonTextStyle:String;
 107          private var buttonTextTopPadding:Number;
 108          private var buttonTextLeftPadding:Number;
 109          private var buttonAction:Number;
 110          private var buttonCursor:Number;
 111          private var buttonStateOver:Boolean;
 112          private var buttonStateMouseDown:Boolean;
 113          private var buttonStateDisabled:Boolean;
 114          
 115          // Error code "constants"

 116          // Size check constants

 117          private var SIZE_TOO_BIG:Number        = 1;
 118          private var SIZE_ZERO_BYTE:Number    = -1;
 119          private var SIZE_OK:Number            = 0;
 120  
 121          // Queue errors

 122          private var ERROR_CODE_QUEUE_LIMIT_EXCEEDED:Number             = -100;
 123          private var ERROR_CODE_FILE_EXCEEDS_SIZE_LIMIT:Number         = -110;
 124          private var ERROR_CODE_ZERO_BYTE_FILE:Number                 = -120;
 125          private var ERROR_CODE_INVALID_FILETYPE:Number              = -130;
 126  
 127          // Upload Errors

 128          private var ERROR_CODE_HTTP_ERROR:Number                     = -200;
 129          private var ERROR_CODE_MISSING_UPLOAD_URL:Number            = -210;
 130          private var ERROR_CODE_IO_ERROR:Number                         = -220;
 131          private var ERROR_CODE_SECURITY_ERROR:Number                 = -230;
 132          private var ERROR_CODE_UPLOAD_LIMIT_EXCEEDED:Number            = -240;
 133          private var ERROR_CODE_UPLOAD_FAILED:Number                 = -250;
 134          private var ERROR_CODE_SPECIFIED_FILE_ID_NOT_FOUND:Number     = -260;
 135          private var ERROR_CODE_FILE_VALIDATION_FAILED:Number        = -270;
 136          private var ERROR_CODE_FILE_CANCELLED:Number                = -280;
 137          private var ERROR_CODE_UPLOAD_STOPPED:Number                = -290;
 138  
 139          
 140          // Button Actions

 141          private var BUTTON_ACTION_SELECT_FILE:Number                = -100;
 142          private var BUTTON_ACTION_SELECT_FILES:Number               = -110;
 143          private var BUTTON_ACTION_START_UPLOAD:Number               = -120;
 144          
 145          private var BUTTON_CURSOR_ARROW:Number                        = -1;
 146          private var BUTTON_CURSOR_HAND:Number                        = -2;
 147          
 148  		public function SWFUpload() {
 149              // Do the feature detection.  Make sure this version of Flash supports the features we need. If not

 150              // abort initialization.

 151              if (!flash.net.FileReferenceList || !flash.net.FileReference || !flash.net.URLRequest || !flash.external.ExternalInterface || !flash.external.ExternalInterface.available || !DataEvent.UPLOAD_COMPLETE_DATA) {
 152                  return;
 153              }
 154  
 155              Security.allowDomain("*");    // Allow uploading to any domain

 156              
 157              // Keep Flash Player busy so it doesn't show the "flash script is running slowly" error

 158              var counter:Number = 0;
 159              root.addEventListener(Event.ENTER_FRAME, function ():void { if (++counter > 100) counter = 0; });
 160  
 161              // Setup file FileReferenceList events

 162              this.fileBrowserMany.addEventListener(Event.SELECT, this.Select_Many_Handler);
 163              this.fileBrowserMany.addEventListener(Event.CANCEL,  this.DialogCancelled_Handler);
 164  
 165  
 166              this.stage.align = StageAlign.TOP_LEFT;
 167              this.stage.scaleMode = StageScaleMode.NO_SCALE;            
 168  
 169              // Setup the button and text label

 170              this.buttonLoader = new Loader();
 171              var doNothing:Function = function ():void { };
 172              this.buttonLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, doNothing );
 173              this.buttonLoader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, doNothing );
 174              this.stage.addChild(this.buttonLoader);
 175  
 176              var self:SWFUpload = this;
 177              
 178              this.stage.addEventListener(MouseEvent.CLICK, function (event:MouseEvent):void {
 179                  self.UpdateButtonState();
 180                  self.ButtonClickHandler(event);
 181              });
 182              this.stage.addEventListener(MouseEvent.MOUSE_DOWN, function (event:MouseEvent):void {
 183                  self.buttonStateMouseDown = true;
 184                  self.UpdateButtonState();
 185              });
 186              this.stage.addEventListener(MouseEvent.MOUSE_UP, function (event:MouseEvent):void {
 187                  self.buttonStateMouseDown = false;
 188                  self.UpdateButtonState();
 189              });
 190              this.stage.addEventListener(MouseEvent.MOUSE_OVER, function (event:MouseEvent):void {
 191                  self.buttonStateMouseDown = event.buttonDown;
 192                  self.buttonStateOver = true;
 193                  self.UpdateButtonState();
 194              });
 195              this.stage.addEventListener(MouseEvent.MOUSE_OUT, function (event:MouseEvent):void {
 196                  self.buttonStateMouseDown = false;
 197                  self.buttonStateOver = false;
 198                  self.UpdateButtonState();
 199              });
 200              // Handle the mouse leaving the flash movie altogether

 201              this.stage.addEventListener(Event.MOUSE_LEAVE, function (event:Event):void {
 202                  self.buttonStateMouseDown = false;
 203                  self.buttonStateOver = false;
 204                  self.UpdateButtonState();
 205              });
 206              
 207              this.buttonTextField = new TextField();
 208              this.buttonTextField.type = TextFieldType.DYNAMIC;
 209              this.buttonTextField.antiAliasType = AntiAliasType.ADVANCED;
 210              this.buttonTextField.autoSize = TextFieldAutoSize.NONE;
 211              this.buttonTextField.cacheAsBitmap = true;
 212              this.buttonTextField.multiline = true;
 213              this.buttonTextField.wordWrap = false;
 214              this.buttonTextField.tabEnabled = false;
 215              this.buttonTextField.background = false;
 216              this.buttonTextField.border = false;
 217              this.buttonTextField.selectable = false;
 218              this.buttonTextField.condenseWhite = true;
 219              
 220              this.stage.addChild(this.buttonTextField);
 221              
 222              
 223              this.buttonCursorSprite = new Sprite();
 224              this.buttonCursorSprite.graphics.beginFill(0xFFFFFF, 0);
 225              this.buttonCursorSprite.graphics.drawRect(0, 0, 1, 1);
 226              this.buttonCursorSprite.graphics.endFill();
 227              this.buttonCursorSprite.buttonMode = true;
 228              this.buttonCursorSprite.x = 0;
 229              this.buttonCursorSprite.y = 0;
 230              this.buttonCursorSprite.addEventListener(MouseEvent.CLICK, doNothing);
 231              this.stage.addChild(this.buttonCursorSprite);
 232              
 233              // Get the movie name

 234              this.movieName = root.loaderInfo.parameters.movieName;
 235  
 236              // **Configure the callbacks**

 237              // The JavaScript tracks all the instances of SWFUpload on a page.  We can access the instance

 238              // associated with this SWF file using the movieName.  Each callback is accessible by making

 239              // a call directly to it on our instance.  There is no error handling for undefined callback functions.

 240              // A developer would have to deliberately remove the default functions,set the variable to null, or remove

 241              // it from the init function.

 242              this.flashReady_Callback         = "SWFUpload.instances[\"" + this.movieName + "\"].flashReady";
 243              this.fileDialogStart_Callback    = "SWFUpload.instances[\"" + this.movieName + "\"].fileDialogStart";
 244              this.fileQueued_Callback         = "SWFUpload.instances[\"" + this.movieName + "\"].fileQueued";
 245              this.fileQueueError_Callback     = "SWFUpload.instances[\"" + this.movieName + "\"].fileQueueError";
 246              this.fileDialogComplete_Callback = "SWFUpload.instances[\"" + this.movieName + "\"].fileDialogComplete";
 247  
 248              this.uploadStart_Callback        = "SWFUpload.instances[\"" + this.movieName + "\"].uploadStart";
 249              this.uploadProgress_Callback     = "SWFUpload.instances[\"" + this.movieName + "\"].uploadProgress";
 250              this.uploadError_Callback        = "SWFUpload.instances[\"" + this.movieName + "\"].uploadError";
 251              this.uploadSuccess_Callback      = "SWFUpload.instances[\"" + this.movieName + "\"].uploadSuccess";
 252  
 253              this.uploadComplete_Callback       = "SWFUpload.instances[\"" + this.movieName + "\"].uploadComplete";
 254  
 255              this.debug_Callback              = "SWFUpload.instances[\"" + this.movieName + "\"].debug";
 256  
 257              this.testExternalInterface_Callback = "SWFUpload.instances[\"" + this.movieName + "\"].testExternalInterface";
 258              this.cleanUp_Callback              = "SWFUpload.instances[\"" + this.movieName + "\"].cleanUp";
 259              
 260              // Get the Flash Vars

 261              this.uploadURL = root.loaderInfo.parameters.uploadURL;
 262              this.filePostName = root.loaderInfo.parameters.filePostName;
 263              this.fileTypes = root.loaderInfo.parameters.fileTypes;
 264              this.fileTypesDescription = root.loaderInfo.parameters.fileTypesDescription + " (" + this.fileTypes + ")";
 265              this.loadPostParams(root.loaderInfo.parameters.params);
 266  
 267              
 268              if (!this.filePostName) {
 269                  this.filePostName = "Filedata";
 270              }
 271              if (!this.fileTypes) {
 272                  this.fileTypes = "*.*";
 273              }
 274              if (!this.fileTypesDescription) {
 275                  this.fileTypesDescription = "All Files";
 276              }
 277              
 278              this.LoadFileExensions(this.fileTypes);
 279              
 280              try {
 281                  this.debugEnabled = root.loaderInfo.parameters.debugEnabled == "true" ? true : false;
 282              } catch (ex:Object) {
 283                  this.debugEnabled = false;
 284              }
 285  
 286              try {
 287                  this.SetFileSizeLimit(String(root.loaderInfo.parameters.fileSizeLimit));
 288              } catch (ex:Object) {
 289                  this.fileSizeLimit = 0;
 290              }
 291              
 292  
 293              try {
 294                  this.fileUploadLimit = Number(root.loaderInfo.parameters.fileUploadLimit);
 295                  if (this.fileUploadLimit < 0) this.fileUploadLimit = 0;
 296              } catch (ex:Object) {
 297                  this.fileUploadLimit = 0;
 298              }
 299  
 300              try {
 301                  this.fileQueueLimit = Number(root.loaderInfo.parameters.fileQueueLimit);
 302                  if (this.fileQueueLimit < 0) this.fileQueueLimit = 0;
 303              } catch (ex:Object) {
 304                  this.fileQueueLimit = 0;
 305              }
 306  
 307              // Set the queue limit to match the upload limit when the queue limit is bigger than the upload limit

 308              if (this.fileQueueLimit > this.fileUploadLimit && this.fileUploadLimit != 0) this.fileQueueLimit = this.fileUploadLimit;
 309              // The the queue limit is unlimited and the upload limit is not then set the queue limit to the upload limit

 310              if (this.fileQueueLimit == 0 && this.fileUploadLimit != 0) this.fileQueueLimit = this.fileUploadLimit;
 311  
 312              try {
 313                  this.useQueryString = root.loaderInfo.parameters.useQueryString == "true" ? true : false;
 314              } catch (ex:Object) {
 315                  this.useQueryString = false;
 316              }
 317              
 318              try {
 319                  this.requeueOnError = root.loaderInfo.parameters.requeueOnError == "true" ? true : false;
 320              } catch (ex:Object) {
 321                  this.requeueOnError = false;
 322              }
 323  
 324              try {
 325                  this.SetHTTPSuccess(String(root.loaderInfo.parameters.httpSuccess));
 326              } catch (ex:Object) {
 327                  this.SetHTTPSuccess([]);
 328              }
 329  
 330              try {
 331                  this.SetAssumeSuccessTimeout(Number(root.loaderInfo.parameters.assumeSuccessTimeout));
 332              } catch (ex:Object) {
 333                  this.SetAssumeSuccessTimeout(0);
 334              }
 335  
 336              
 337              try {
 338                  this.SetButtonDimensions(Number(root.loaderInfo.parameters.buttonWidth), Number(root.loaderInfo.parameters.buttonHeight));
 339              } catch (ex:Object) {
 340                  this.SetButtonDimensions(0, 0);
 341              }
 342  
 343              try {
 344                  this.SetButtonImageURL(String(root.loaderInfo.parameters.buttonImageURL));
 345              } catch (ex:Object) {
 346                  this.SetButtonImageURL("");
 347              }
 348              
 349              try {
 350                  this.SetButtonText(String(root.loaderInfo.parameters.buttonText));
 351              } catch (ex:Object) {
 352                  this.SetButtonText("");
 353              }
 354              
 355              try {
 356                  this.SetButtonTextPadding(Number(root.loaderInfo.parameters.buttonTextLeftPadding), Number(root.loaderInfo.parameters.buttonTextTopPadding));
 357              } catch (ex:Object) {
 358                  this.SetButtonTextPadding(0, 0);
 359              }
 360  
 361              try {
 362                  this.SetButtonTextStyle(String(root.loaderInfo.parameters.buttonTextStyle));
 363              } catch (ex:Object) {
 364                  this.SetButtonTextStyle("");
 365              }
 366  
 367              try {
 368                  this.SetButtonAction(Number(root.loaderInfo.parameters.buttonAction));
 369              } catch (ex:Object) {
 370                  this.SetButtonAction(this.BUTTON_ACTION_SELECT_FILES);
 371              }
 372              
 373              try {
 374                  this.SetButtonDisabled(root.loaderInfo.parameters.buttonDisabled == "true" ? true : false);
 375              } catch (ex:Object) {
 376                  this.SetButtonDisabled(Boolean(false));
 377              }
 378              
 379              try {
 380                  this.SetButtonCursor(Number(root.loaderInfo.parameters.buttonCursor));
 381              } catch (ex:Object) {
 382                  this.SetButtonCursor(this.BUTTON_CURSOR_ARROW);
 383              }
 384              
 385              this.SetupExternalInterface();
 386              
 387              this.Debug("SWFUpload Init Complete");
 388              this.PrintDebugInfo();
 389  
 390              if (ExternalCall.Bool(this.testExternalInterface_Callback)) {
 391                  ExternalCall.Simple(this.flashReady_Callback);
 392                  this.hasCalledFlashReady = true;
 393              }
 394              
 395              // Start periodically checking the external interface

 396              var oSelf:SWFUpload = this;
 397              this.restoreExtIntTimer = new Timer(1000, 0);
 398              this.restoreExtIntTimer.addEventListener(TimerEvent.TIMER, function ():void { oSelf.CheckExternalInterface();} );
 399              this.restoreExtIntTimer.start();
 400          }
 401  
 402          // Used to periodically check that the External Interface functions are still working

 403  		private function CheckExternalInterface():void {
 404              if (!ExternalCall.Bool(this.testExternalInterface_Callback)) {
 405                  this.SetupExternalInterface();
 406                  this.Debug("ExternalInterface reinitialized");
 407                  if (!this.hasCalledFlashReady) {
 408                      ExternalCall.Simple(this.flashReady_Callback);
 409                      this.hasCalledFlashReady = true;
 410                  }
 411              }
 412          }
 413          
 414          // Called by JS to see if it can access the external interface

 415  		private function TestExternalInterface():Boolean {
 416              return true;
 417          }
 418          
 419  		private function SetupExternalInterface():void {
 420              try {
 421                  ExternalInterface.addCallback("SelectFile", this.SelectFile);
 422                  ExternalInterface.addCallback("SelectFiles", this.SelectFiles);
 423                  ExternalInterface.addCallback("StartUpload", this.StartUpload);
 424                  ExternalInterface.addCallback("ReturnUploadStart", this.ReturnUploadStart);
 425                  ExternalInterface.addCallback("StopUpload", this.StopUpload);
 426                  ExternalInterface.addCallback("CancelUpload", this.CancelUpload);
 427                  ExternalInterface.addCallback("RequeueUpload", this.RequeueUpload);
 428                  
 429                  ExternalInterface.addCallback("GetStats", this.GetStats);
 430                  ExternalInterface.addCallback("SetStats", this.SetStats);
 431                  ExternalInterface.addCallback("GetFile", this.GetFile);
 432                  ExternalInterface.addCallback("GetFileByIndex", this.GetFileByIndex);
 433                  
 434                  ExternalInterface.addCallback("AddFileParam", this.AddFileParam);
 435                  ExternalInterface.addCallback("RemoveFileParam", this.RemoveFileParam);
 436  
 437                  ExternalInterface.addCallback("SetUploadURL", this.SetUploadURL);
 438                  ExternalInterface.addCallback("SetPostParams", this.SetPostParams);
 439                  ExternalInterface.addCallback("SetFileTypes", this.SetFileTypes);
 440                  ExternalInterface.addCallback("SetFileSizeLimit", this.SetFileSizeLimit);
 441                  ExternalInterface.addCallback("SetFileUploadLimit", this.SetFileUploadLimit);
 442                  ExternalInterface.addCallback("SetFileQueueLimit", this.SetFileQueueLimit);
 443                  ExternalInterface.addCallback("SetFilePostName", this.SetFilePostName);
 444                  ExternalInterface.addCallback("SetUseQueryString", this.SetUseQueryString);
 445                  ExternalInterface.addCallback("SetRequeueOnError", this.SetRequeueOnError);
 446                  ExternalInterface.addCallback("SetHTTPSuccess", this.SetHTTPSuccess);
 447                  ExternalInterface.addCallback("SetAssumeSuccessTimeout", this.SetAssumeSuccessTimeout);
 448                  ExternalInterface.addCallback("SetDebugEnabled", this.SetDebugEnabled);
 449  
 450                  ExternalInterface.addCallback("SetButtonImageURL", this.SetButtonImageURL);
 451                  ExternalInterface.addCallback("SetButtonDimensions", this.SetButtonDimensions);
 452                  ExternalInterface.addCallback("SetButtonText", this.SetButtonText);
 453                  ExternalInterface.addCallback("SetButtonTextPadding", this.SetButtonTextPadding);
 454                  ExternalInterface.addCallback("SetButtonTextStyle", this.SetButtonTextStyle);
 455                  ExternalInterface.addCallback("SetButtonAction", this.SetButtonAction);
 456                  ExternalInterface.addCallback("SetButtonDisabled", this.SetButtonDisabled);
 457                  ExternalInterface.addCallback("SetButtonCursor", this.SetButtonCursor);
 458  
 459                  ExternalInterface.addCallback("TestExternalInterface", this.TestExternalInterface);
 460                  
 461              } catch (ex:Error) {
 462                  this.Debug("Callbacks where not set: " + ex.message);
 463                  return;
 464              }
 465              
 466              ExternalCall.Simple(this.cleanUp_Callback);
 467          }
 468          
 469          /* *****************************************

 470          * FileReference Event Handlers

 471          * *************************************** */
 472  		private function DialogCancelled_Handler(event:Event):void {
 473              this.Debug("Event: fileDialogComplete: File Dialog window cancelled.");
 474              ExternalCall.FileDialogComplete(this.fileDialogComplete_Callback, 0, 0, this.queued_uploads);
 475          }
 476  
 477  		private function Open_Handler(event:Event):void {
 478              this.Debug("Event: uploadProgress (OPEN): File ID: " + this.current_file_item.id);
 479              ExternalCall.UploadProgress(this.uploadProgress_Callback, this.current_file_item.ToJavaScriptObject(), 0, this.current_file_item.file_reference.size);
 480          }
 481          
 482  		private function FileProgress_Handler(event:ProgressEvent):void {
 483              // On early than Mac OS X 10.3 bytesLoaded is always -1, convert this to zero. Do bytesTotal for good measure.

 484              //  http://livedocs.adobe.com/flex/3/langref/flash/net/FileReference.html#event:progress

 485              var bytesLoaded:Number = event.bytesLoaded < 0 ? 0 : event.bytesLoaded;
 486              var bytesTotal:Number = event.bytesTotal < 0 ? 0 : event.bytesTotal;
 487              
 488              // Because Flash never fires a complete event if the server doesn't respond after 30 seconds or on Macs if there

 489              // is no content in the response we'll set a timer and assume that the upload is successful after the defined amount of

 490              // time.  If the timeout is zero then we won't use the timer.

 491              if (bytesLoaded === bytesTotal && bytesTotal > 0 && this.assumeSuccessTimeout > 0) {
 492                  if (this.assumeSuccessTimer !== null) {
 493                      this.assumeSuccessTimer.stop();
 494                      this.assumeSuccessTimer = null;
 495                  }
 496                  
 497                  this.assumeSuccessTimer = new Timer(this.assumeSuccessTimeout * 1000, 1);
 498                  this.assumeSuccessTimer.addEventListener(TimerEvent.TIMER_COMPLETE, AssumeSuccessTimer_Handler);
 499                  this.assumeSuccessTimer.start();
 500              }
 501              
 502              this.Debug("Event: uploadProgress: File ID: " + this.current_file_item.id + ". Bytes: " + bytesLoaded + ". Total: " + bytesTotal);
 503              ExternalCall.UploadProgress(this.uploadProgress_Callback, this.current_file_item.ToJavaScriptObject(), bytesLoaded, bytesTotal);
 504          }
 505          
 506  		private function AssumeSuccessTimer_Handler(event:TimerEvent):void {
 507              this.Debug("Event: AssumeSuccess: " + this.assumeSuccessTimeout + " passed without server response");
 508              this.UploadSuccess(this.current_file_item, "", false);
 509          }
 510  
 511  		private function Complete_Handler(event:Event):void {
 512              /* Because we can't do COMPLETE or DATA events (we have to do both) we can't

 513               * just call uploadSuccess from the complete handler, we have to wait for

 514               * the Data event which may never come. However, testing shows it always comes

 515               * within a couple milliseconds if it is going to come so the solution is:

 516               * 

 517               * Set a timer in the COMPLETE event (which always fires) and if DATA is fired

 518               * it will stop the timer and call uploadComplete

 519               * 

 520               * If the timer expires then DATA won't be fired and we call uploadComplete

 521               * */
 522              
 523              // Set the timer

 524              if (serverDataTimer != null) {
 525                  this.serverDataTimer.stop();
 526                  this.serverDataTimer = null;
 527              }
 528              
 529              this.serverDataTimer = new Timer(100, 1);
 530              //var self:SWFUpload = this;

 531              this.serverDataTimer.addEventListener(TimerEvent.TIMER, this.ServerDataTimer_Handler);
 532              this.serverDataTimer.start();
 533          }
 534  		private function ServerDataTimer_Handler(event:TimerEvent):void {
 535              this.UploadSuccess(this.current_file_item, "");
 536          }
 537          
 538  		private function ServerData_Handler(event:DataEvent):void {
 539              this.UploadSuccess(this.current_file_item, event.data);
 540          }
 541          
 542  		private function UploadSuccess(file:FileItem, serverData:String, responseReceived:Boolean = true):void {
 543              if (this.serverDataTimer !== null) {
 544                  this.serverDataTimer.stop();
 545                  this.serverDataTimer = null;
 546              }
 547              if (this.assumeSuccessTimer !== null) {
 548                  this.assumeSuccessTimer.stop();
 549                  this.assumeSuccessTimer = null;
 550              }
 551  
 552              this.successful_uploads++;
 553              file.file_status = FileItem.FILE_STATUS_SUCCESS;
 554  
 555              this.Debug("Event: uploadSuccess: File ID: " + file.id + " Response Received: " + responseReceived.toString() + " Data: " + serverData);
 556              ExternalCall.UploadSuccess(this.uploadSuccess_Callback, file.ToJavaScriptObject(), serverData, responseReceived);
 557  
 558              this.UploadComplete(false);
 559              
 560          }
 561  
 562  		private function HTTPError_Handler(event:HTTPStatusEvent):void {
 563              var isSuccessStatus:Boolean = false;
 564              for (var i:Number = 0; i < this.httpSuccess.length; i++) {
 565                  if (this.httpSuccess[i] === event.status) {
 566                      isSuccessStatus = true;
 567                      break;
 568                  }
 569              }
 570              
 571              
 572              if (isSuccessStatus) {
 573                  this.Debug("Event: httpError: Translating status code " + event.status + " to uploadSuccess");
 574  
 575                  var serverDataEvent:DataEvent = new DataEvent(DataEvent.UPLOAD_COMPLETE_DATA, event.bubbles, event.cancelable, "");
 576                  this.ServerData_Handler(serverDataEvent);
 577              } else {
 578                  this.upload_errors++;
 579                  this.current_file_item.file_status = FileItem.FILE_STATUS_ERROR;
 580  
 581                  this.Debug("Event: uploadError: HTTP ERROR : File ID: " + this.current_file_item.id + ". HTTP Status: " + event.status + ".");
 582                  ExternalCall.UploadError(this.uploadError_Callback, this.ERROR_CODE_HTTP_ERROR, this.current_file_item.ToJavaScriptObject(), event.status.toString());
 583                  this.UploadComplete(true);     // An IO Error is also called so we don't want to complete the upload yet.

 584              }
 585          }
 586          
 587          // Note: Flash Player does not support Uploads that require authentication. Attempting this will trigger an

 588          // IO Error or it will prompt for a username and password and may crash the browser (FireFox/Opera)

 589  		private function IOError_Handler(event:IOErrorEvent):void {
 590              // Only trigger an IO Error event if we haven't already done an HTTP error

 591              if (this.current_file_item.file_status != FileItem.FILE_STATUS_ERROR) {
 592                  this.upload_errors++;
 593                  this.current_file_item.file_status = FileItem.FILE_STATUS_ERROR;
 594  
 595                  this.Debug("Event: uploadError : IO Error : File ID: " + this.current_file_item.id + ". IO Error: " + event.text);
 596                  ExternalCall.UploadError(this.uploadError_Callback, this.ERROR_CODE_IO_ERROR, this.current_file_item.ToJavaScriptObject(), event.text);
 597              }
 598  
 599              this.UploadComplete(true);
 600          }
 601  
 602  		private function SecurityError_Handler(event:SecurityErrorEvent):void {
 603              this.upload_errors++;
 604              this.current_file_item.file_status = FileItem.FILE_STATUS_ERROR;
 605  
 606              this.Debug("Event: uploadError : Security Error : File Number: " + this.current_file_item.id + ". Error text: " + event.text);
 607              ExternalCall.UploadError(this.uploadError_Callback, this.ERROR_CODE_SECURITY_ERROR, this.current_file_item.ToJavaScriptObject(), event.text);
 608  
 609              this.UploadComplete(true);
 610          }
 611  
 612  		private function Select_Many_Handler(event:Event):void {
 613              this.Select_Handler(this.fileBrowserMany.fileList);
 614          }
 615  		private function Select_One_Handler(event:Event):void {
 616              var fileArray:Array = new Array(1);
 617              fileArray[0] = this.fileBrowserOne;
 618              this.Select_Handler(fileArray);
 619          }
 620          
 621  		private function Select_Handler(file_reference_list:Array):void {
 622              this.Debug("Select Handler: Received the files selected from the dialog. Processing the file list...");
 623  
 624              var num_files_queued:Number = 0;
 625              
 626              // Determine how many queue slots are remaining (check the unlimited (0) settings, successful uploads and queued uploads)

 627              var queue_slots_remaining:Number = 0;
 628              if (this.fileUploadLimit == 0) {
 629                  queue_slots_remaining = this.fileQueueLimit == 0 ? file_reference_list.length : (this.fileQueueLimit - this.queued_uploads);    // If unlimited queue make the allowed size match however many files were selected.

 630              } else {
 631                  var remaining_uploads:Number = this.fileUploadLimit - this.successful_uploads - this.queued_uploads;
 632                  if (remaining_uploads < 0) remaining_uploads = 0;
 633                  if (this.fileQueueLimit == 0 || this.fileQueueLimit >= remaining_uploads) {
 634                      queue_slots_remaining = remaining_uploads;
 635                  } else if (this.fileQueueLimit < remaining_uploads) {
 636                      queue_slots_remaining = this.fileQueueLimit - this.queued_uploads;
 637                  }
 638              }
 639              
 640              if (queue_slots_remaining < 0) queue_slots_remaining = 0;
 641              
 642              // Check if the number of files selected is greater than the number allowed to queue up.

 643              if (queue_slots_remaining < file_reference_list.length) {
 644                  this.Debug("Event: fileQueueError : Selected Files (" + file_reference_list.length + ") exceeds remaining Queue size (" + queue_slots_remaining + ").");
 645                  ExternalCall.FileQueueError(this.fileQueueError_Callback, this.ERROR_CODE_QUEUE_LIMIT_EXCEEDED, null, queue_slots_remaining.toString());
 646              } else {
 647                  // Process each selected file

 648                  for (var i:Number = 0; i < file_reference_list.length; i++) {
 649                      var file_item:FileItem = new FileItem(file_reference_list[i], this.movieName, this.file_index.length);
 650                      this.file_index[file_item.index] = file_item;
 651  
 652                      // Verify that the file is accessible. Zero byte files and possibly other conditions can cause a file to be inaccessible.

 653                      var jsFileObj:Object = file_item.ToJavaScriptObject();
 654                      var is_valid_file_reference:Boolean = (jsFileObj.filestatus !== FileItem.FILE_STATUS_ERROR);
 655                      
 656                      if (is_valid_file_reference) {
 657                          // Check the size, if it's within the limit add it to the upload list.

 658                          var size_result:Number = this.CheckFileSize(file_item);
 659                          var is_valid_filetype:Boolean = this.CheckFileType(file_item);
 660                          if(size_result == this.SIZE_OK && is_valid_filetype) {
 661                              file_item.file_status = FileItem.FILE_STATUS_QUEUED;
 662                              this.file_queue.push(file_item);
 663                              this.queued_uploads++;
 664                              num_files_queued++;
 665                              this.Debug("Event: fileQueued : File ID: " + file_item.id);
 666                              ExternalCall.FileQueued(this.fileQueued_Callback, file_item.ToJavaScriptObject());
 667                          }
 668                          else if (!is_valid_filetype) {
 669                              file_item.file_reference = null;     // Cleanup the object

 670                              this.queue_errors++;
 671                              this.Debug("Event: fileQueueError : File not of a valid type.");
 672                              ExternalCall.FileQueueError(this.fileQueueError_Callback, this.ERROR_CODE_INVALID_FILETYPE, file_item.ToJavaScriptObject(), "File is not an allowed file type.");
 673                          }
 674                          else if (size_result == this.SIZE_TOO_BIG) {
 675                              file_item.file_reference = null;     // Cleanup the object

 676                              this.queue_errors++;
 677                              this.Debug("Event: fileQueueError : File exceeds size limit.");
 678                              ExternalCall.FileQueueError(this.fileQueueError_Callback, this.ERROR_CODE_FILE_EXCEEDS_SIZE_LIMIT, file_item.ToJavaScriptObject(), "File size exceeds allowed limit.");
 679                          }
 680                          else if (size_result == this.SIZE_ZERO_BYTE) {
 681                              file_item.file_reference = null;     // Cleanup the object

 682                              this.queue_errors++;
 683                              this.Debug("Event: fileQueueError : File is zero bytes.");
 684                              ExternalCall.FileQueueError(this.fileQueueError_Callback, this.ERROR_CODE_ZERO_BYTE_FILE, file_item.ToJavaScriptObject(), "File is zero bytes and cannot be uploaded.");
 685                          }
 686                      } else {
 687                          file_item.file_reference = null;     // Cleanup the object

 688                          this.queue_errors++;
 689                          this.Debug("Event: fileQueueError : File is zero bytes or FileReference is invalid.");
 690                          ExternalCall.FileQueueError(this.fileQueueError_Callback, this.ERROR_CODE_ZERO_BYTE_FILE, file_item.ToJavaScriptObject(), "File is zero bytes or cannot be accessed and cannot be uploaded.");
 691                      }
 692                  }
 693              }
 694              
 695              this.Debug("Event: fileDialogComplete : Finished processing selected files. Files selected: " + file_reference_list.length + ". Files Queued: " + num_files_queued);
 696              ExternalCall.FileDialogComplete(this.fileDialogComplete_Callback, file_reference_list.length, num_files_queued, this.queued_uploads);
 697          }
 698  
 699          
 700          /* ****************************************************************

 701              Externally exposed functions

 702          ****************************************************************** */
 703          // Opens a file browser dialog that allows one file to be selected.

 704  		private function SelectFile():void  {
 705              this.fileBrowserOne = new FileReference();
 706              this.fileBrowserOne.addEventListener(Event.SELECT, this.Select_One_Handler);
 707              this.fileBrowserOne.addEventListener(Event.CANCEL,  this.DialogCancelled_Handler);
 708  
 709              // Default file type settings

 710              var allowed_file_types:String = "*.*";
 711              var allowed_file_types_description:String = "All Files";
 712  
 713              // Get the instance settings

 714              if (this.fileTypes.length > 0) allowed_file_types = this.fileTypes;
 715              if (this.fileTypesDescription.length > 0)  allowed_file_types_description = this.fileTypesDescription;
 716  
 717              this.Debug("Event: fileDialogStart : Browsing files. Single Select. Allowed file types: " + allowed_file_types);
 718              ExternalCall.Simple(this.fileDialogStart_Callback);
 719  
 720              try {
 721                  this.fileBrowserOne.browse([new FileFilter(allowed_file_types_description, allowed_file_types)]);
 722              } catch (ex:Error) {
 723                  this.Debug("Exception: " + ex.toString());
 724              }
 725          }
 726          
 727          // Opens a file browser dialog that allows multiple files to be selected.

 728  		private function SelectFiles():void {
 729              var allowed_file_types:String = "*.*";
 730              var allowed_file_types_description:String = "All Files";
 731              
 732              if (this.fileTypes.length > 0) allowed_file_types = this.fileTypes;
 733              if (this.fileTypesDescription.length > 0)  allowed_file_types_description = this.fileTypesDescription;
 734  
 735              this.Debug("Event: fileDialogStart : Browsing files. Multi Select. Allowed file types: " + allowed_file_types);
 736              ExternalCall.Simple(this.fileDialogStart_Callback);
 737  
 738              try {
 739                  this.fileBrowserMany.browse([new FileFilter(allowed_file_types_description, allowed_file_types)]);
 740              } catch (ex:Error) {
 741                  this.Debug("Exception: " + ex.toString());
 742              }
 743          }
 744  
 745  
 746          // Cancel the current upload and stops.  Doesn't advance the upload pointer. The current file is requeued at the beginning.

 747  		private function StopUpload():void {
 748              if (this.current_file_item != null) {
 749                  // Cancel the upload and re-queue the FileItem

 750                  this.current_file_item.file_reference.cancel();
 751  
 752                  // Remove the event handlers

 753                  this.removeFileReferenceEventListeners(this.current_file_item);
 754  
 755                  this.current_file_item.file_status = FileItem.FILE_STATUS_QUEUED;
 756                  this.file_queue.unshift(this.current_file_item);
 757                  var js_object:Object = this.current_file_item.ToJavaScriptObject();
 758                  this.current_file_item = null;
 759                  
 760                  this.Debug("Event: uploadError: upload stopped. File ID: " + js_object.ID);
 761                  ExternalCall.UploadError(this.uploadError_Callback, this.ERROR_CODE_UPLOAD_STOPPED, js_object, "Upload Stopped");
 762                  this.Debug("Event: uploadComplete. File ID: " + js_object.ID);
 763                  ExternalCall.UploadComplete(this.uploadComplete_Callback, js_object);
 764                  
 765                  this.Debug("StopUpload(): upload stopped.");
 766              } else {
 767                  this.Debug("StopUpload(): No file is currently uploading. Nothing to do.");
 768              }
 769          }
 770  
 771          /* Cancels the upload specified by file_id

 772           * If the file is currently uploading it is cancelled and the uploadComplete

 773           * event gets called.

 774           * If the file is not currently uploading then only the uploadCancelled event is fired.

 775           * */
 776  		private function CancelUpload(file_id:String, triggerErrorEvent:Boolean = true):void {
 777              var file_item:FileItem = null;
 778              
 779              // Check the current file item

 780              if (this.current_file_item != null && (this.current_file_item.id == file_id || !file_id)) {
 781                      this.current_file_item.file_reference.cancel();
 782                      this.current_file_item.file_status = FileItem.FILE_STATUS_CANCELLED;
 783                      this.upload_cancelled++;
 784                      
 785                      if (triggerErrorEvent) {
 786                          this.Debug("Event: uploadError: File ID: " + this.current_file_item.id + ". Cancelled current upload");
 787                          ExternalCall.UploadError(this.uploadError_Callback, this.ERROR_CODE_FILE_CANCELLED, this.current_file_item.ToJavaScriptObject(), "File Upload Cancelled.");
 788                      } else {
 789                          this.Debug("Event: cancelUpload: File ID: " + this.current_file_item.id + ". Cancelled current upload. Suppressed uploadError event.");
 790                      }
 791                      this.UploadComplete(false);
 792              } else if (file_id) {
 793                      // Find the file in the queue

 794                      var file_index:Number = this.FindIndexInFileQueue(file_id);
 795                      if (file_index >= 0) {
 796                          // Remove the file from the queue

 797                          file_item = FileItem(this.file_queue[file_index]);
 798                          file_item.file_status = FileItem.FILE_STATUS_CANCELLED;
 799                          this.file_queue[file_index] = null;
 800                          this.queued_uploads--;
 801                          this.upload_cancelled++;
 802                          
 803                          // Cancel the file (just for good measure) and make the callback

 804                          file_item.file_reference.cancel();
 805                          this.removeFileReferenceEventListeners(file_item);
 806                          file_item.file_reference = null;
 807                          
 808                          if (triggerErrorEvent) {
 809                              this.Debug("Event: uploadError : " + file_item.id + ". Cancelled queued upload");
 810                              ExternalCall.UploadError(this.uploadError_Callback, this.ERROR_CODE_FILE_CANCELLED, file_item.ToJavaScriptObject(), "File Cancelled");
 811                          } else {
 812                              this.Debug("Event: cancelUpload: File ID: " + file_item.id + ". Cancelled current upload. Suppressed uploadError event.");
 813                          }
 814  
 815                          // Get rid of the file object

 816                          file_item = null;
 817                      }
 818              } else {
 819                  // Get the first file and cancel it

 820                  while (this.file_queue.length > 0 && file_item == null) {
 821                      // Check that File Reference is valid (if not make sure it's deleted and get the next one on the next loop)

 822                      file_item = FileItem(this.file_queue.shift());    // Cast back to a FileItem

 823                      if (typeof(file_item) == "undefined") {
 824                          file_item = null;
 825                          continue;
 826                      }
 827                  }
 828                  
 829                  if (file_item != null) {
 830                      file_item.file_status = FileItem.FILE_STATUS_CANCELLED;
 831                      this.queued_uploads--;
 832                      this.upload_cancelled++;
 833                      
 834  
 835                      // Cancel the file (just for good measure) and make the callback

 836                      file_item.file_reference.cancel();
 837                      this.removeFileReferenceEventListeners(file_item);
 838                      file_item.file_reference = null;
 839  
 840                      if (triggerErrorEvent) {
 841                          this.Debug("Event: uploadError : " + file_item.id + ". Cancelled queued upload");
 842                          ExternalCall.UploadError(this.uploadError_Callback, this.ERROR_CODE_FILE_CANCELLED, file_item.ToJavaScriptObject(), "File Cancelled");
 843                      } else {
 844                          this.Debug("Event: cancelUpload: File ID: " + file_item.id + ". Cancelled current upload. Suppressed uploadError event.");
 845                      }
 846  
 847                      // Get rid of the file object

 848                      file_item = null;
 849                  }
 850                  
 851              }
 852  
 853          }
 854  
 855          /* Requeues the indicated file. Returns true if successful or if the file is

 856           * already in the queue. Otherwise returns false.

 857           * */
 858  		private function RequeueUpload(fileIdentifier:*):Boolean {
 859              var file:FileItem = null;
 860              if (typeof(fileIdentifier) === "number") {
 861                  var fileIndex:Number = Number(fileIdentifier);
 862                  if (fileIndex >= 0 && fileIndex < this.file_index.length) {
 863                      file = this.file_index[fileIndex];                    
 864                  }
 865              } else if (typeof(fileIdentifier) === "string") {
 866                  file = FindFileInFileIndex(String(fileIdentifier));
 867              } else {
 868                  return false;
 869              }
 870              
 871              if (file !== null) {
 872                  if (file.file_status === FileItem.FILE_STATUS_IN_PROGRESS || file.file_status === FileItem.FILE_STATUS_NEW) {
 873                      return false;
 874                  } else if (file.file_status !== FileItem.FILE_STATUS_QUEUED) {
 875                      file.file_status = FileItem.FILE_STATUS_QUEUED;
 876                      this.file_queue.unshift(file);
 877                      this.queued_uploads++;
 878                  }
 879                  return true;
 880              } else {
 881                  return false;
 882              }
 883          }
 884          
 885          
 886  		private function GetStats():Object {
 887              return {
 888                  in_progress : this.current_file_item == null ? 0 : 1,
 889                  files_queued : this.queued_uploads,
 890                  successful_uploads : this.successful_uploads,
 891                  upload_errors : this.upload_errors,
 892                  upload_cancelled : this.upload_cancelled,
 893                  queue_errors : this.queue_errors
 894              };
 895          }
 896  		private function SetStats(stats:Object):void {
 897              this.successful_uploads = typeof(stats["successful_uploads"]) === "number" ? stats["successful_uploads"] : this.successful_uploads;
 898              this.upload_errors = typeof(stats["upload_errors"]) === "number" ? stats["upload_errors"] : this.upload_errors;
 899              this.upload_cancelled = typeof(stats["upload_cancelled"]) === "number" ? stats["upload_cancelled"] : this.upload_cancelled;
 900              this.queue_errors = typeof(stats["queue_errors"]) === "number" ? stats["queue_errors"] : this.queue_errors;
 901          }
 902  
 903  		private function GetFile(file_id:String):Object {
 904              var file_index:Number = this.FindIndexInFileQueue(file_id);
 905              if (file_index >= 0) {
 906                  var file:FileItem = this.file_queue[file_index];
 907              } else {
 908                  if (this.current_file_item != null) {
 909                      file = this.current_file_item;
 910                  } else {
 911                      for (var i:Number = 0; i < this.file_queue.length; i++) {
 912                          file = this.file_queue[i];
 913                          if (file != null) break;
 914                      }
 915                  }
 916              }
 917              
 918              if (file == null) {
 919                  return null;
 920              } else {
 921                  return file.ToJavaScriptObject();
 922              }
 923              
 924          }
 925          
 926  		private function GetFileByIndex(index:Number):Object {
 927              if (index < 0 || index > this.file_index.length - 1) {
 928                  return null;
 929              } else {
 930                  return this.file_index[index].ToJavaScriptObject();
 931              }
 932          }
 933  
 934  		private function AddFileParam(file_id:String, name:String, value:String):Boolean {
 935              var item:FileItem = this.FindFileInFileIndex(file_id);
 936              if (item != null) {
 937                  item.AddParam(name, value);
 938                  return true;
 939              }
 940              else {
 941                  return false;
 942              }
 943          }
 944  		private function RemoveFileParam(file_id:String, name:String):Boolean {
 945              var item:FileItem = this.FindFileInFileIndex(file_id);
 946              if (item != null) {
 947                  item.RemoveParam(name);
 948                  return true;
 949              }
 950              else {
 951                  return false;
 952              }
 953          }
 954          
 955  		private function SetUploadURL(url:String):void {
 956              if (typeof(url) !== "undefined" && url !== "") {
 957                  this.uploadURL = url;
 958              }
 959          }
 960          
 961  		private function SetPostParams(post_object:Object):void {
 962              if (typeof(post_object) !== "undefined" && post_object !== null) {
 963                  this.uploadPostObject = post_object;
 964              }
 965          }
 966          
 967  		private function SetFileTypes(types:String, description:String):void {
 968              this.fileTypes = types;
 969              this.fileTypesDescription = description;
 970              
 971              this.LoadFileExensions(this.fileTypes);
 972          }
 973  
 974          // Sets the file size limit.  Accepts size values with units: 100 b, 1KB, 23Mb, 4 Gb

 975          // Parsing is not robust. "100 200 MB KB B GB" parses as "100 MB"

 976  		private function SetFileSizeLimit(size:String):void {
 977              var value:Number = 0;
 978              var unit:String = "kb";
 979              
 980              // Trim the string

 981              var trimPattern:RegExp = /^\s*|\s*$/;
 982              
 983              size = size.toLowerCase();
 984              size = size.replace(trimPattern, "");
 985  
 986              
 987              // Get the value part

 988              var values:Array = size.match(/^\d+/);
 989              if (values !== null && values.length > 0) {
 990                  value = parseInt(values[0]);
 991              }
 992              if (isNaN(value) || value < 0) value = 0;
 993              
 994              // Get the units part

 995              var units:Array = size.match(/(b|kb|mb|gb)/);
 996              if (units != null && units.length > 0) {
 997                  unit = units[0];
 998              }
 999              
1000              // Set the multiplier for converting the unit to bytes

1001              var multiplier:Number = 1024;
1002              if (unit === "b")
1003                  multiplier = 1;
1004              else if (unit === "mb")
1005                  multiplier = 1048576;
1006              else if (unit === "gb")
1007                  multiplier = 1073741824;
1008              
1009              this.fileSizeLimit = value * multiplier;
1010          }
1011          
1012  		private function SetFileUploadLimit(file_upload_limit:Number):void {
1013              if (file_upload_limit < 0) file_upload_limit = 0;
1014              this.fileUploadLimit = file_upload_limit;
1015          }
1016          
1017  		private function SetFileQueueLimit(file_queue_limit:Number):void {
1018              if (file_queue_limit < 0) file_queue_limit = 0;
1019              this.fileQueueLimit = file_queue_limit;
1020          }
1021          
1022  		private function SetFilePostName(file_post_name:String):void {
1023              if (file_post_name != "") {
1024                  this.filePostName = file_post_name;
1025              }
1026          }
1027          
1028  		private function SetUseQueryString(use_query_string:Boolean):void {
1029              this.useQueryString = use_query_string;
1030          }
1031          
1032  		private function SetRequeueOnError(requeue_on_error:Boolean):void {
1033              this.requeueOnError = requeue_on_error;
1034          }
1035          
1036  		private function SetHTTPSuccess(http_status_codes:*):void {
1037              this.httpSuccess = [];
1038  
1039              if (typeof http_status_codes === "string") {
1040                  var status_code_strings:Array = http_status_codes.replace(" ", "").split(",");
1041                  for each (var http_status_string:String in status_code_strings) 
1042                  {
1043                      try {
1044                          this.httpSuccess.push(Number(http_status_string));
1045                      } catch (ex:Object) {
1046                          // Ignore errors

1047                          this.Debug("Could not add HTTP Success code: " + http_status_string);
1048                      }
1049                  }
1050              }
1051              else if (typeof http_status_codes === "object" && typeof http_status_codes.length === "number") {
1052                  for each (var http_status:* in http_status_codes) 
1053                  {
1054                      try {
1055                          this.Debug("adding: " + http_status);
1056                          this.httpSuccess.push(Number(http_status));
1057                      } catch (ex:Object) {
1058                          this.Debug("Could not add HTTP Success code: " + http_status);
1059                      }
1060                  }
1061              }
1062          }
1063  
1064  		private function SetAssumeSuccessTimeout(timeout_seconds:Number):void {
1065              this.assumeSuccessTimeout = timeout_seconds < 0 ? 0 : timeout_seconds;
1066          }        
1067          
1068  		private function SetDebugEnabled(debug_enabled:Boolean):void {
1069              this.debugEnabled = debug_enabled;
1070          }
1071          
1072          /* *************************************************************

1073              Button Handling Functions

1074          *************************************************************** */
1075  		private function SetButtonImageURL(button_image_url:String):void {
1076              this.buttonImageURL = button_image_url;
1077  
1078              try {
1079                  if (this.buttonImageURL !== null && this.buttonImageURL !== "") {
1080                      this.buttonLoader.load(new URLRequest(this.buttonImageURL));
1081                  }
1082              } catch (ex:Object) {
1083              }
1084          }
1085          
1086  		private function ButtonClickHandler(e:MouseEvent):void {
1087              if (!this.buttonStateDisabled) {
1088                  if (this.buttonAction === this.BUTTON_ACTION_SELECT_FILE) {
1089                      this.SelectFile();
1090                  }
1091                  else if (this.buttonAction === this.BUTTON_ACTION_START_UPLOAD) {
1092                      this.StartUpload();
1093                  }
1094                  else {
1095                      this.SelectFiles();
1096                  }
1097              }
1098          }
1099          
1100  		private function UpdateButtonState():void {
1101              var xOffset:Number = 0;
1102              var yOffset:Number = 0;
1103              
1104              this.buttonLoader.x = xOffset;
1105              this.buttonLoader.y = yOffset;
1106              
1107              if (this.buttonStateDisabled) {
1108                  this.buttonLoader.y = this.buttonHeight * -3 + yOffset;
1109              }
1110              else if (this.buttonStateMouseDown) {
1111                  this.buttonLoader.y = this.buttonHeight * -2 + yOffset;
1112              }
1113              else if (this.buttonStateOver) {
1114                  this.buttonLoader.y = this.buttonHeight * -1 + yOffset;
1115              }
1116              else {
1117                  this.buttonLoader.y = -yOffset;
1118              }
1119          };
1120  
1121  		private function SetButtonDimensions(width:Number = -1, height:Number = -1):void {
1122              if (width >= 0) {
1123                  this.buttonWidth = width;
1124              }
1125              if (height >= 0) {
1126                  this.buttonHeight = height;
1127              }
1128              
1129              this.buttonTextField.width = this.buttonWidth;
1130              this.buttonTextField.height = this.buttonHeight;
1131              this.buttonCursorSprite.width = this.buttonWidth;
1132              this.buttonCursorSprite.height = this.buttonHeight;
1133              
1134              this.UpdateButtonState();
1135          }
1136          
1137  		private function SetButtonText(button_text:String):void {
1138              this.buttonText = button_text;
1139              
1140              this.SetButtonTextStyle(this.buttonTextStyle);
1141          }
1142          
1143  		private function SetButtonTextStyle(button_text_style:String):void {
1144              this.buttonTextStyle = button_text_style;
1145              
1146              var style:StyleSheet = new StyleSheet();
1147              style.parseCSS(this.buttonTextStyle);
1148              this.buttonTextField.styleSheet = style;
1149              this.buttonTextField.htmlText = this.buttonText;
1150          }
1151  
1152  		private function SetButtonTextPadding(left:Number, top:Number):void {
1153                  this.buttonTextField.x = this.buttonTextLeftPadding = left;
1154                  this.buttonTextField.y = this.buttonTextTopPadding = top;
1155          }
1156          
1157  		private function SetButtonDisabled(disabled:Boolean):void {
1158              this.buttonStateDisabled = disabled;
1159              this.UpdateButtonState();
1160          }
1161          
1162  		private function SetButtonAction(button_action:Number):void {
1163              this.buttonAction = button_action;
1164          }
1165          
1166  		private function SetButtonCursor(button_cursor:Number):void {
1167              this.buttonCursor = button_cursor;
1168              
1169              this.buttonCursorSprite.useHandCursor = (button_cursor === this.BUTTON_CURSOR_HAND);
1170          }
1171          
1172          /* *************************************************************

1173              File processing and handling functions

1174          *************************************************************** */
1175  		private function StartUpload(file_id:String = ""):void {
1176              // Only upload a file uploads are being processed.

1177              if (this.current_file_item != null) {
1178                  this.Debug("StartUpload(): Upload already in progress. Not starting another upload.");
1179                  return;
1180              }
1181  
1182              this.Debug("StartUpload: " + (file_id ? "File ID: " + file_id : "First file in queue"));
1183  
1184              // Check the upload limit

1185              if (this.successful_uploads >= this.fileUploadLimit && this.fileUploadLimit != 0) {
1186                  this.Debug("Event: uploadError : Upload limit reached. No more files can be uploaded.");
1187                  ExternalCall.UploadError(this.uploadError_Callback, this.ERROR_CODE_UPLOAD_LIMIT_EXCEEDED, null, "The upload limit has been reached.");
1188                  this.current_file_item = null;
1189                  return;
1190              }
1191              
1192              // Get the next file to upload

1193              if (!file_id) {
1194                  while (this.file_queue.length > 0 && this.current_file_item == null) {
1195                      this.current_file_item = FileItem(this.file_queue.shift());
1196                      if (typeof(this.current_file_item) == "undefined") {
1197                          this.current_file_item = null;
1198                      }
1199                  }
1200              } else {
1201                  var file_index:Number = this.FindIndexInFileQueue(file_id);
1202                  if (file_index >= 0) {
1203                      // Set the file as the current upload and remove it from the queue

1204                      this.current_file_item = FileItem(this.file_queue[file_index]);
1205                      this.file_queue[file_index] = null;
1206                  } else {
1207                      this.Debug("Event: uploadError : File ID not found in queue: " + file_id);
1208                      ExternalCall.UploadError(this.uploadError_Callback, this.ERROR_CODE_SPECIFIED_FILE_ID_NOT_FOUND, null, "File ID not found in the queue.");
1209                  }
1210              }
1211  
1212  
1213              if (this.current_file_item != null) {
1214                  // Trigger the uploadStart event which will call ReturnUploadStart to begin the actual upload

1215                  this.Debug("Event: uploadStart : File ID: " + this.current_file_item.id);
1216                  
1217                  this.current_file_item.file_status = FileItem.FILE_STATUS_IN_PROGRESS;
1218                  ExternalCall.UploadStart(this.uploadStart_Callback, this.current_file_item.ToJavaScriptObject());
1219              }
1220              // Otherwise we've would have looped through all the FileItems. This means the queue is empty)

1221              else {
1222                  this.Debug("StartUpload(): No files found in the queue.");
1223              }
1224          }
1225  
1226          // This starts the upload when the user returns TRUE from the uploadStart event.  Rather than just have the value returned from

1227          // the function we do a return function call so we can use the setTimeout work-around for Flash/JS circular calls.

1228  		private function ReturnUploadStart(start_upload:Boolean):void {
1229              if (this.current_file_item == null) {
1230                  this.Debug("ReturnUploadStart called but no file was prepped for uploading. The file may have been cancelled or stopped.");
1231                  return;
1232              }
1233              
1234              var js_object:Object;
1235              
1236              if (start_upload) {
1237                  try {
1238                      // Set the event handlers

1239                      this.current_file_item.file_reference.addEventListener(Event.OPEN, this.Open_Handler);
1240                      this.current_file_item.file_reference.addEventListener(ProgressEvent.PROGRESS, this.FileProgress_Handler);
1241                      this.current_file_item.file_reference.addEventListener(IOErrorEvent.IO_ERROR, this.IOError_Handler);
1242                      this.current_file_item.file_reference.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.SecurityError_Handler);
1243                      this.current_file_item.file_reference.addEventListener(HTTPStatusEvent.HTTP_STATUS, this.HTTPError_Handler);
1244                      this.current_file_item.file_reference.addEventListener(Event.COMPLETE, this.Complete_Handler);
1245                      this.current_file_item.file_reference.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, this.ServerData_Handler);
1246                      
1247                      // Get the request (post values, etc)

1248                      var request:URLRequest = this.BuildRequest();
1249                      
1250                      if (this.uploadURL.length == 0) {
1251                          this.Debug("Event: uploadError : IO Error : File ID: " + this.current_file_item.id + ". Upload URL string is empty.");
1252  
1253                          // Remove the event handlers

1254                          this.removeFileReferenceEventListeners(this.current_file_item);
1255  
1256                          this.current_file_item.file_status = FileItem.FILE_STATUS_QUEUED;
1257                          this.file_queue.unshift(this.current_file_item);
1258                          js_object = this.current_file_item.ToJavaScriptObject();
1259                          this.current_file_item = null;
1260                          
1261                          ExternalCall.UploadError(this.uploadError_Callback, this.ERROR_CODE_MISSING_UPLOAD_URL, js_object, "Upload URL string is empty.");
1262                      } else {
1263                          this.Debug("ReturnUploadStart(): File accepted by startUpload event and readied for upload.  Starting upload to " + request.url + " for File ID: " + this.current_file_item.id);
1264                          this.current_file_item.file_status = FileItem.FILE_STATUS_IN_PROGRESS;
1265                          this.current_file_item.file_reference.upload(request, this.filePostName, false);
1266                      }
1267                  } catch (ex:Error) {
1268                      this.Debug("ReturnUploadStart: Exception occurred: " + message);
1269  
1270                      this.upload_errors++;
1271                      this.current_file_item.file_status = FileItem.FILE_STATUS_ERROR;
1272  
1273                      var message:String = ex.errorID + "\n" + ex.name + "\n" + ex.message + "\n" + ex.getStackTrace();
1274                      this.Debug("Event: uploadError(): Upload Failed. Exception occurred: " + message);
1275                      ExternalCall.UploadError(this.uploadError_Callback, this.ERROR_CODE_UPLOAD_FAILED, this.current_file_item.ToJavaScriptObject(), message);
1276                      
1277                      this.UploadComplete(true);
1278                  }
1279              } else {
1280                  // Remove the event handlers

1281                  this.removeFileReferenceEventListeners(this.current_file_item);
1282  
1283                  // Re-queue the FileItem

1284                  this.current_file_item.file_status = FileItem.FILE_STATUS_QUEUED;
1285                  js_object = this.current_file_item.ToJavaScriptObject();
1286                  this.file_queue.unshift(this.current_file_item);
1287                  this.current_file_item = null;
1288                  
1289                  this.Debug("Event: uploadError : Call to uploadStart returned false. Not uploading the file.");
1290                  ExternalCall.UploadError(this.uploadError_Callback, this.ERROR_CODE_FILE_VALIDATION_FAILED, js_object, "Call to uploadStart return false. Not uploading file.");
1291                  this.Debug("Event: uploadComplete : Call to uploadStart returned false. Not uploading the file.");
1292                  ExternalCall.UploadComplete(this.uploadComplete_Callback, js_object);
1293              }
1294          }
1295  
1296          // Completes the file upload by deleting it's reference, advancing the pointer.

1297          // Once this event fires a new upload can be started.

1298  		private function UploadComplete(eligible_for_requeue:Boolean):void {
1299              var jsFileObj:Object = this.current_file_item.ToJavaScriptObject();
1300              
1301              this.removeFileReferenceEventListeners(this.current_file_item);
1302  
1303              if (!eligible_for_requeue || this.requeueOnError == false) {
1304                  this.current_file_item.file_reference = null;
1305                  this.queued_uploads--;
1306              } else if (this.requeueOnError == true) {
1307                  this.current_file_item.file_status = FileItem.FILE_STATUS_QUEUED;
1308                  this.file_queue.unshift(this.current_file_item);
1309              }
1310  
1311              this.current_file_item = null;
1312              
1313              this.Debug("Event: uploadComplete : Upload cycle complete.");
1314              ExternalCall.UploadComplete(this.uploadComplete_Callback, jsFileObj);
1315          }
1316  
1317  
1318          /* *************************************************************

1319              Utility Functions

1320          *************************************************************** */
1321  
1322          
1323          // Check the size of the file against the allowed file size. If it is less the return TRUE. If it is too large return FALSE

1324  		private function CheckFileSize(file_item:FileItem):Number {
1325              if (file_item.file_reference.size == 0) {
1326                  return this.SIZE_ZERO_BYTE;
1327              } else if (this.fileSizeLimit != 0 && file_item.file_reference.size > this.fileSizeLimit) {
1328                  return this.SIZE_TOO_BIG;
1329              } else {
1330                  return this.SIZE_OK;
1331              }
1332          }
1333          
1334  		private function CheckFileType(file_item:FileItem):Boolean {
1335              // If no extensions are defined then a *.* was passed and the check is unnecessary

1336              if (this.valid_file_extensions.length == 0) {
1337                  return true;
1338              }
1339              
1340              var fileRef:FileReference = file_item.file_reference;
1341              var last_dot_index:Number = fileRef.name.lastIndexOf(".");
1342              var extension:String = "";
1343              if (last_dot_index >= 0) {
1344                  extension = fileRef.name.substr(last_dot_index + 1).toLowerCase();
1345              }
1346              
1347              var is_valid_filetype:Boolean = false;
1348              for (var i:Number=0; i < this.valid_file_extensions.length; i++) {
1349                  if (String(this.valid_file_extensions[i]) == extension) {
1350                      is_valid_filetype = true;
1351                      break;
1352                  }
1353              }
1354              
1355              return is_valid_filetype;
1356          }
1357  
1358  		private function BuildRequest():URLRequest {
1359              // Create the request object

1360              var request:URLRequest = new URLRequest();
1361              request.method = URLRequestMethod.POST;
1362              
1363              var file_post:Object = this.current_file_item.GetPostObject();
1364              
1365              if (this.useQueryString) {
1366                  var pairs:Array = new Array();
1367                  for (key in this.uploadPostObject) {
1368                      this.Debug("Global URL Item: " + key + "=" + this.uploadPostObject[key]);
1369                      if (this.uploadPostObject.hasOwnProperty(key)) {
1370                          pairs.push(escape(key) + "=" + escape(this.uploadPostObject[key]));
1371                      }
1372                  }
1373  
1374                  for (key in file_post) {
1375                      this.Debug("File Post Item: " + key + "=" + file_post[key]);
1376                      if (file_post.hasOwnProperty(key)) {
1377                          pairs.push(escape(key) + "=" + escape(file_post[key]));
1378                      }
1379                  }
1380                  
1381                  request.url = this.uploadURL  + (this.uploadURL.indexOf("?") > -1 ? "&" : "?") + pairs.join("&");
1382                      
1383              } else {
1384                  var key:String;
1385                  var post:URLVariables = new URLVariables();
1386                  for (key in this.uploadPostObject) {
1387                      this.Debug("Global Post Item: " + key + "=" + this.uploadPostObject[key]);
1388                      if (this.uploadPostObject.hasOwnProperty(key)) {
1389                          post[key] = this.uploadPostObject[key];
1390                      }
1391                  }
1392  
1393                  for (key in file_post) {
1394                      this.Debug("File Post Item: " + key + "=" + file_post[key]);
1395                      if (file_post.hasOwnProperty(key)) {
1396                          post[key] = file_post[key];
1397                      }
1398                  }
1399  
1400                  request.url = this.uploadURL;
1401                  request.data = post;
1402              }
1403              
1404              return request;
1405          }
1406          
1407  		private function Debug(msg:String):void {
1408              try {
1409                  if (this.debugEnabled) {
1410                      var lines:Array = msg.split("\n");
1411                      for (var i:Number=0; i < lines.length; i++) {
1412                          lines[i] = "SWF DEBUG: " + lines[i];
1413                      }
1414                          ExternalCall.Debug(this.debug_Callback, lines.join("\n"));
1415                  }
1416              } catch (ex:Error) {
1417                  // pretend nothing happened

1418                  trace(ex);
1419              }
1420          }
1421  
1422  		private function PrintDebugInfo():void {
1423              var debug_info:String = "\n----- SWF DEBUG OUTPUT ----\n";
1424              debug_info += "Build Number:           " + this.build_number + "\n";
1425              debug_info += "movieName:              " + this.movieName + "\n";
1426              debug_info += "Upload URL:             " + this.uploadURL + "\n";
1427              debug_info += "File Types String:      " + this.fileTypes + "\n";
1428              debug_info += "Parsed File Types:      " + this.valid_file_extensions.toString() + "\n";
1429              debug_info += "HTTP Success:           " + this.httpSuccess.join(", ") + "\n";
1430              debug_info += "File Types Description: " + this.fileTypesDescription + "\n";
1431              debug_info += "File Size Limit:        " + this.fileSizeLimit + " bytes\n";
1432              debug_info += "File Upload Limit:      " + this.fileUploadLimit + "\n";
1433              debug_info += "File Queue Limit:       " + this.fileQueueLimit + "\n";
1434              debug_info += "Post Params:\n";
1435              for (var key:String in this.uploadPostObject) {
1436                  if (this.uploadPostObject.hasOwnProperty(key)) {
1437                      debug_info += "                        " + key + "=" + this.uploadPostObject[key] + "\n";
1438                  }
1439              }
1440              debug_info += "----- END SWF DEBUG OUTPUT ----\n";
1441  
1442              this.Debug(debug_info);
1443          }
1444  
1445  		private function FindIndexInFileQueue(file_id:String):Number {
1446              for (var i:Number = 0; i < this.file_queue.length; i++) {
1447                  var item:FileItem = this.file_queue[i];
1448                  if (item != null && item.id == file_id) return i;
1449              }
1450  
1451              return -1;
1452          }
1453          
1454  		private function FindFileInFileIndex(file_id:String):FileItem {
1455              for (var i:Number = 0; i < this.file_index.length; i++) {
1456                  var item:FileItem = this.file_index[i];
1457                  if (item != null && item.id == file_id) return item;
1458              }
1459              
1460              return null;
1461          }
1462          
1463          
1464          // Parse the file extensions in to an array so we can validate them agains

1465          // the files selected later.

1466  		private function LoadFileExensions(filetypes:String):void {
1467              var extensions:Array = filetypes.split(";");
1468              this.valid_file_extensions = new Array();
1469  
1470              for (var i:Number=0; i < extensions.length; i++) {
1471                  var extension:String = String(extensions[i]);
1472                  var dot_index:Number = extension.lastIndexOf(".");
1473                  
1474                  if (dot_index >= 0) {
1475                      extension = extension.substr(dot_index + 1).toLowerCase();
1476                  } else {
1477                      extension = extension.toLowerCase();
1478                  }
1479                  
1480                  // If one of the extensions is * then we allow all files

1481                  if (extension == "*") {
1482                      this.valid_file_extensions = new Array();
1483                      break;
1484                  }
1485                  
1486                  this.valid_file_extensions.push(extension);
1487              }
1488          }
1489          
1490  		private function loadPostParams(param_string:String):void {
1491              var post_object:Object = {};
1492  
1493              if (param_string != null) {
1494                  var name_value_pairs:Array = param_string.split("&amp;");
1495                  
1496                  for (var i:Number = 0; i < name_value_pairs.length; i++) {
1497                      var name_value:String = String(name_value_pairs[i]);
1498                      var index_of_equals:Number = name_value.indexOf("=");
1499                      if (index_of_equals > 0) {
1500                          post_object[decodeURIComponent(name_value.substring(0, index_of_equals))] = decodeURIComponent(name_value.substr(index_of_equals + 1));
1501                      }
1502                  }
1503              }
1504              this.uploadPostObject = post_object;
1505          }
1506          
1507  		private function removeFileReferenceEventListeners(file_item:FileItem):void {
1508              if (file_item != null && file_item.file_reference != null) {
1509                  file_item.file_reference.removeEventListener(Event.OPEN, this.Open_Handler);
1510                  file_item.file_reference.removeEventListener(ProgressEvent.PROGRESS, this.FileProgress_Handler);
1511                  file_item.file_reference.removeEventListener(IOErrorEvent.IO_ERROR, this.IOError_Handler);
1512                  file_item.file_reference.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, this.SecurityError_Handler);
1513                  file_item.file_reference.removeEventListener(HTTPStatusEvent.HTTP_STATUS, this.HTTPError_Handler);
1514                  file_item.file_reference.removeEventListener(DataEvent.UPLOAD_COMPLETE_DATA, this.ServerData_Handler);
1515              }
1516          }
1517  
1518      }
1519  }


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7