1  /**
     2   * com.sekati.display.BitmapImageClip
     3   * @version 1.0.2
     4   * @author jason m horwitz | sekati.com | tendercreative.com
     5   * Copyright (C) 2007  jason m horwitz, Sekat LLC. All Rights Reserved.
     6   * Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
     7   */
     8  
     9   import com.sekati.display.IBitmapImageClip;
    10   import com.sekati.display.BaseClip;
    11   import com.sekati.utils.Delegate;
    12   import com.sekati.utils.MovieClipUtils;
    13   import com.sekati.except.FatalException;
    14   import flash.display.BitmapData;
    15  
    16  /**
    17   * BitmapImageClip - load an image, convert it to a smoothed BitmapData object available for manipulation.
    18   * NOTE: The clip image is automatically hidden (_alpha:0) until manually tweened in by developer.
    19   * 
    20   * {@code Usage:
    21   * 	import com.sekati.utils.*
    22   * 	import caurina.transitions.Tweener;
    23   * 	
    24   * 	function _onProgress(l:Number, t:Number):Void { trace("img_onProgress: "+l+" / "+t); }
    25   * 	function _onInit():Void { Tweener.addTween(image, {_alpha:100, time:0.3, transition:"easeInOutQuint"}); }
    26   * 	function _onError(code:String):Void { trace("oh noes! The image couldnt be loaded: "+ecode); }
    27   * 	
    28   * 	// create an empty BitmapImageClip
    29   * 	var image:MovieClip =  ClassUtils.createEmptyMovieClip (com.sekati.display.BitmapImageClip, this, "image", {_x:0, _y:0});
    30   * 	
    31   * 	// load an image and define onProgress onInit Delegates.
    32   * 	image.load("test.jpg", Delegate.create(this, _onInit), Delegate.create(this, _onProgress), Delegate.create(this, _onError));
    33   * }
    34   */
    35  class com.sekati.display.BitmapImageClip extends BaseClip implements IBitmapImageClip {
    36  	
    37  	public var img:MovieClip;
    38  	public var bmp:BitmapData;
    39  	private var _uri:String;
    40  	private var _smooth:Boolean;
    41  	private var _progressCb:Function;
    42  	private var _initCb:Function;
    43  	private var _errorCb:Function;
    44  	private var _loader:MovieClipLoader;
    45  	private var _tmp:MovieClip;
    46  	
    47  	/**
    48  	 * Constructor
    49  	 */
    50  	public function BitmapImageClip() {
    51  		super();
    52  		_loader = new MovieClipLoader();
    53  		_this.onLoadInit = Delegate.create(_this, _onInit);
    54  		_this.onLoadError = Delegate.create(_this, _onError);
    55  		_this.onLoadProgress = Delegate.create(_this, _onProgress);
    56  		_loader.addListener(_this);
    57  	}
    58  	
    59  	/**
    60  	 * Load image and convert to bitmap
    61  	 * @param uri (String)
    62  	 * @param isSmoothed (Boolean) - enable smoothing on the bitmap.
    63  	 * @param onInit (Function) - cb when image is loaded, converted, ready for use.
    64  	 * @param onProgress (Function) - cb is passed args: bytesLoaded, bytesTotal.
    65  	 * @param onError (Function) - cb is passed arg errorCode, httpStatus.
    66  	 * @return Void
    67  	 */
    68  	public function load(uri:String, isSmoothed:Boolean, onInit:Function, onProgress:Function, onError:Function):Void {
    69  		_uri = uri;
    70  		_smooth = isSmoothed;
    71  		_progressCb = onProgress;
    72  		_initCb = onInit;
    73  		_errorCb = onError;
    74  		createContainers();
    75  		_loader.loadClip(_uri, _tmp);	
    76  	}
    77  	
    78  	/**
    79  	 * Remove the bitmap and clips.
    80  	 * @return Void
    81  	 */
    82  	public function unload():Void {
    83  		_loader.unloadClip(img);
    84  		bmp.dispose();
    85  		MovieClipUtils.rmClip(_tmp); 
    86  		MovieClipUtils.rmClip(img);
    87  	}
    88  
    89  	/**
    90  	 * Create the temporary image Container
    91  	 * @return Void
    92  	 */
    93  	private function createContainers():Void {
    94  		if (_tmp) MovieClipUtils.rmClip(_tmp); 
    95  		if (img) MovieClipUtils.rmClip(img);
    96  		if (bmp) bmp.dispose();
    97  		img = _this.createEmptyMovieClip("img", _this.getNextHighestDepth());
    98  		_tmp = _this.createEmptyMovieClip("_tmp", _this.getNextHighestDepth());
    99  		//img.cacheAsBitmap = true;
   100  		_tmp._visible = false;
   101  		_this._alpha = 0;
   102  	}
   103  	
   104  	/**
   105  	 * Clear existing callbacks in preparation for another load
   106  	 * @return Void
   107  	 */
   108  	private function clearCallbacks():Void {
   109  		_initCb = undefined;
   110  		_progressCb = undefined;
   111  		_errorCb = undefined;		
   112  	}
   113  	
   114  	/**
   115  	 * Once external image is loaded, convert to smoothed bitmapData object
   116  	 * and run the {@link _initCb} if it was defined during {@link load}.
   117  	 * @return Void
   118  	 */
   119  	private function _onInit():Void {
   120  		bmp = new BitmapData(_tmp._width, _tmp._height, true, 0x00FFFFFF);
   121  		bmp.draw(_tmp);
   122  		img.attachBitmap(bmp, img.getNextHighestDepth(), "auto", _smooth);
   123  		MovieClipUtils.rmClip(_tmp);
   124  		_initCb();
   125  		clearCallbacks();
   126  	}
   127  
   128  	/**
   129  	 * Call the onProgress cb
   130  	 * @param target (MovieClip)
   131  	 * @param bytesLoaded (Number)
   132  	 * @param bytesTotal (Number)
   133  	 * @return Void
   134  	 */
   135  	private function _onProgress(target:MovieClip, bytesLoaded:Number, bytesTotal:Number):Void {
   136  		//trace("loading: "+target + " " + bytesLoaded + "/" + bytesTotal);
   137  		_progressCb(bytesLoaded, bytesTotal);
   138  	}
   139  
   140  	/**
   141  	 * Call the onError cb
   142  	 * @param errorCode (String)
   143  	 * @param httpStatus (String)
   144  	 */
   145  	private function _onError(target_mc:MovieClip, errorCode:String, httpStatus:Number):Void {
   146  		_errorCb(errorCode, httpStatus);
   147  		clearCallbacks();
   148  		throw new FatalException(_this, "Could not load image from url:"+_uri, arguments);
   149  	}
   150  }
   151