1 /**
  2  * @namespace
  3  */
  4 var TiledImageStore; if( !TiledImageStore ) TiledImageStore = {};
  5 
  6 /**
  7  * Implements a store for image tiles that are only available at a
  8  * fixed set of sizes and zoom levels.  Most often used with
  9  * pre-generated image tiles served statically.
 10  * @class
 11  * @extends Store
 12  */
 13 
 14 TiledImageStore.Fixed = function(args) {
 15     Store.call( this, args );
 16     if( !args )
 17         return;
 18 
 19     this.tileToImage = {};
 20     this.zoomCache = {};
 21 
 22     this.refSeq = args.refSeq;
 23 
 24     this.url = Util.resolveUrl(
 25                    args.baseUrl,
 26                    Util.fillTemplate( args.urlTemplate,
 27                                       {'refseq': this.refSeq.name } )
 28                );
 29 };
 30 
 31 TiledImageStore.Fixed.prototype = new Store('');
 32 
 33 TiledImageStore.Fixed.prototype.loadSuccess = function(o) {
 34     this.stats = o.stats;
 35 
 36     //tileWidth: width, in pixels, of the tiles
 37     this.tileWidth = o.tileWidth;
 38     this.align = o.align;
 39     //zoomLevels: array of {basesPerTile, urlPrefix} hashes
 40     this.zoomLevels = o.zoomLevels;
 41     this.setLoaded();
 42 };
 43 
 44 /**
 45  * @private
 46  */
 47 TiledImageStore.Fixed.prototype._getZoom = function(scale) {
 48     var result = this.zoomCache[scale];
 49     if (result) return result;
 50 
 51     result = this.zoomLevels[0];
 52     var desiredBases = this.tileWidth / scale;
 53     for (var i = 1; i < this.zoomLevels.length; i++) {
 54         if (Math.abs(this.zoomLevels[i].basesPerTile - desiredBases)
 55             < Math.abs(result.basesPerTile - desiredBases))
 56             result = this.zoomLevels[i];
 57     }
 58 
 59     this.zoomCache[scale] = result;
 60     return result;
 61 };
 62 
 63 /**
 64  * Fetch an array of <code><img></code> elements for the image
 65  * tiles that should be displayed for a certain magnification scale
 66  * and section of the reference.
 67  * @param {Number} scale     the current ratio of pixels per base in the view
 68  * @param {Number} startBase the start of the region (in interbase coordinates)
 69  * @param {Number} endBase   the end of the region   (in interbase coordinates)
 70  */
 71 TiledImageStore.Fixed.prototype.getImages = function( scale, startBase, endBase ) {
 72 
 73     var zoom = this._getZoom( scale );
 74 
 75     var startTile = Math.max( startBase / zoom.basesPerTile, 0 ) | 0;
 76     var endTile   =           endBase   / zoom.basesPerTile      | 0;
 77 
 78     var result = [];
 79     var im;
 80     for (var i = startTile; i <= endTile; i++) {
 81 	im = this.tileToImage[i];
 82 	if (!im) {
 83 	    im = document.createElement("img");
 84             dojo.connect(im, "onerror", this.handleImageError );
 85             im.src = this._imageSource( zoom, i );
 86             //TODO: need image coord systems that don't start at 0?
 87 	    im.startBase = (i * zoom.basesPerTile); // + this.refSeq.start;
 88 	    im.baseWidth = zoom.basesPerTile;
 89 	    im.tileNum = i;
 90 	    this.tileToImage[i] = im;
 91 	}
 92 	result.push(im);
 93     }
 94     return result;
 95 };
 96 
 97 /**
 98  * Gives the image source for a given zoom (as returned by _getZoom())
 99  * and tileIndex.
100  * @private
101  */
102 TiledImageStore.Fixed.prototype._imageSource = function( zoom, tileIndex ) {
103     return Util.resolveUrl(this.url, zoom.urlPrefix + tileIndex + ".png");
104 };
105 
106 /**
107  * Clear the store's cache of image elements.
108  */
109 TiledImageStore.Fixed.prototype.clearCache = function() {
110     this.tileToImage = {};
111 };
112 
113 /**
114  * Remove the given image element from the cache.
115  */
116 TiledImageStore.Fixed.prototype.unCacheImage = function( /**HTMLImageElement*/ im) {
117     delete this.tileToImage[ im.tileNum ];
118 };
119