Replace SuperTabNavigator (not compatible with Flex 4) with standard TabNavigator...
[potlatch2.git] / net / systemeD / halcyon / ImageBank.as
1 package net.systemeD.halcyon {
2     import flash.events.*;
3         import flash.display.*;
4         import flash.net.*;
5         import flash.utils.ByteArray;
6         import nochump.util.zip.*;
7
8         /*
9                 ImageBank stores and retrieves bitmap images.
10                 All images are internally stored as Loader.
11
12                 See blog.yoz.sk/2009/10/bitmap-bitmapdata-bytearray/ for a really useful conversion guide!
13         */
14
15     public class ImageBank extends EventDispatcher{
16                 private var images:Object={};
17                 private var imagesRequested:uint=0;
18                 private var imagesReceived:uint=0;
19                 
20                 public static const IMAGES_LOADED:String="imagesLoaded";
21                 
22                 private static const GLOBAL_INSTANCE:ImageBank = new ImageBank();
23                 public static function getInstance():ImageBank { return GLOBAL_INSTANCE; }
24
25                 public function hasImage(name:String):Boolean {
26                         if (images[name]) return true;
27                         return false;
28                 }
29
30                 /* ==========================================================================================
31                    Populate with images 
32                    ========================================================================================== */
33
34                 public function loadImage(filename:String):void {
35                         if (images[filename]) return;
36                         imagesRequested++;
37
38                         var loader:Loader=new Loader();
39                         images[filename]=loader;
40                         var request:URLRequest=new URLRequest(filename);
41                         loader.contentLoaderInfo.addEventListener(Event.COMPLETE,                                               loadedImage);
42                         loader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS,                  httpStatusHandler);
43                         loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR,    securityErrorHandler);
44                         loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,                                ioErrorHandler);
45                         loader.load(request);
46                 }
47
48                 private function loadedImage(event:Event):void {
49                         imageReceived();
50                 }
51                 private function httpStatusHandler(event:HTTPStatusEvent):void { }
52                 private function securityErrorHandler(event:SecurityErrorEvent):void { 
53                         trace("securityErrorEvent: "+event.target.url);
54                         imageReceived();
55                 }
56                 private function ioErrorHandler(event:IOErrorEvent):void { 
57                         trace("ioErrorEvent: "+event.target.url); 
58                         imageReceived();
59                 }
60                 private function imageReceived():void {
61                         imagesReceived++;
62                         if (imagesReceived==imagesRequested) { dispatchEvent(new Event(IMAGES_LOADED)); }
63                 }
64
65                 /* ==========================================================================================
66                    Load from .zip file
67                    ========================================================================================== */
68                 
69                 public function loadFromZip(filename:String, prefix:String=""):void {
70                         var urlstream:URLStream = new URLStream();
71                         urlstream.addEventListener(Event.COMPLETE, function(e:Event):void { zipReady(e,prefix); } );
72                         urlstream.load(new URLRequest(filename));
73                 }
74                 private function zipReady(event:Event, prefix:String):void {
75                         var zip:ZipFile = new ZipFile(URLStream(event.target));
76                         for (var i:uint=0; i<zip.entries.length; i++) {
77                                 var fileref:ZipEntry = zip.entries[i];
78                                 var data:ByteArray = zip.getInput(fileref);
79                                 var loader:Loader=new Loader();
80                                 images[prefix+fileref.name]=loader;
81                                 loader.loadBytes(data);
82                         }
83                 }
84
85
86                 /* ==========================================================================================
87                    Get images 
88                    getAsDisplayObject(filename)
89                    getAsBitmapData(filename)
90                    getAsByteArray(filename)
91                    ========================================================================================== */
92
93                 public function getAsDisplayObject(name:String):DisplayObject {
94                         /* If the image hasn't loaded yet, then add an EventListener for when it does. */
95                         if (getWidth(name)==0) {
96                                 var loader:Loader = new Loader();
97                                 images[name].contentLoaderInfo.addEventListener(Event.COMPLETE,
98                                         function(e:Event):void { loaderReady(e, loader) });
99                                 return loader;
100                         }
101                         /* Otherwise, create a new Bitmap, because just returning the raw Loader
102                            (i.e. images[name]) would only allow it to be added to one parent. (The other 
103                            way to do this would be by copying the bytes as loaderReady does.). */
104                         return new Bitmap(getAsBitmapData(name));
105                 }
106                 
107                 public function getOriginalDisplayObject(name:String):DisplayObject {
108                         /* But if we're going to clone it later, this'll work fine. */
109                         return images[name];
110                 }
111
112                 private function loaderReady(event:Event, loader:Loader):void {
113                         /* The file has loaded, so we can copy the data from there into our new Loader */
114                         var info:LoaderInfo = event.target as LoaderInfo;
115                         loader.loadBytes(info.bytes);
116                 }
117
118                 public function getAsBitmapData(name:String):BitmapData {
119                         var bitmapData:BitmapData=new BitmapData(getWidth(name), getHeight(name), true, 0xFFFFFF);
120                         bitmapData.draw(images[name]);
121                         return bitmapData;
122                 }
123                 
124                 public function getAsByteArray(name:String):ByteArray {
125                         return images[name].contentLoaderInfo.bytes;
126                 }
127
128                 /* ==========================================================================================
129                    Get file information
130                    ========================================================================================== */
131
132                 public function getWidth(name:String):int { 
133                         try { return images[name].contentLoaderInfo.width; }
134                         catch (error:Error) { } return 0;
135                 }
136
137                 public function getHeight(name:String):int { 
138                         try { return images[name].contentLoaderInfo.height; }
139                         catch (error:Error) { } return 0;
140                 }
141
142         }
143 }