/* 
   START of DynAPI Distribution compatible with Amazoom Internal Zoom Viewer
*/
/*
   DynAPI Distribution
   Browser Class

   The DynAPI Distribution is distributed under the terms of the GNU LGPL license.
*/
var topLayerId;
function Browser() {
    var b=navigator.appName;
    if (b.indexOf('Netscape')!=-1) this.b="ns";
    else if ((b=="Opera") || (navigator.userAgent.indexOf("Opera")>0)) this.b = "opera";
    else if (b=="Microsoft Internet Explorer") this.b="ie";
    if (!b) alert('Unidentified browser.\nThis browser is not supported,');
    this.version=navigator.appVersion;
    this.v=parseInt(this.version);
    this.ns=(this.b=="ns" && this.v>=4);
    this.ns4=(this.b=="ns" && this.v==4);
    this.ns6=(this.b=="ns" && this.v==5);
    this.ie=(this.b=="ie" && this.v>=4);
    this.ie4=(this.version.indexOf('MSIE 4')>0);
    this.ie5=(this.version.indexOf('MSIE 5')>0);
    this.ie55=(this.version.indexOf('MSIE 5.5')>0);
    this.ie6=(this.version.indexOf('MSIE 6.0')>0);
    this.opera=(this.b=="opera");
    this.dom=(document.createElement && document.appendChild && document.getElementsByTagName)?true:false;
    this.def=(this.ie||this.dom); // most used browsers, for faster if loops
    var ua=navigator.userAgent.toLowerCase();
    if (ua.indexOf("win")>-1) this.platform="win32";
    else if (ua.indexOf("mac")>-1) this.platform="mac";
    else this.platform="other";
}
is=new Browser();



/*
   DynAPI Distribution
   DynAPI base Object. Empty shell defining common properties and methods

   The DynAPI Distribution is distributed under the terms of the GNU LGPL license.
*/
DynObject = function() {
    this.setID("DynObject"+(DynObject.Count++));
    this.isChild = false;
    this.created = false;
    this.parent = null;
    this.children = [];
    this.eventListeners = [];
    this.hasEventListeners = false;
};
DynObject.prototype.getClass = function() { return this.constructor };
DynObject.prototype.setID = function(id) {
    if (this.id) delete DynObject.all[this.id];
    this.id = id;
    DynObject.all[this.id] = this;
};
DynObject.prototype.addChild = function(c) {
    if(c.isChild) c.parent.removeChild(c);
    c.isChild = true;
    c.parent = this;
    if(this.created) c.create()
    this.children[this.children.length] = c;
    return c;
};
DynObject.prototype.removeChild = function(c) {
    var l = this.children.length;
    for(var i=0;i<l && this.children[i]!=c;i++);
    if(i!=l) {
        c.invokeEvent("beforeremove");
        c.specificRemove();
        c.created=false;
        c.invokeEvent("remove");
        c.isChild = false;
        c.parent = null;
        this.children[i] = this.children[l-1];
        this.children[l-1] = null;
        this.children.length--;
    }
};
DynObject.prototype.deleteFromParent = function () {
    if(this.parent) this.parent.deleteChild(this);
};
DynObject.prototype.removeFromParent = function () {
    if(this.parent) this.parent.removeChild(this);
};
DynObject.prototype.create = function() {
    this.flagPrecreate();
    this.specificCreate();
    this.created = true;
    var l = this.children.length;
    for(var i=0;i<l;i++) this.children[i].create()
    this.invokeEvent("create");
};
DynObject.prototype.flagPrecreate = function() {
    if (this.precreated) return;
    var l=this.children.length;
    for (var i=0; i<l;  i++) this.children[i].flagPrecreate();
    this.invokeEvent('precreate');
    this.precreated=true;
};
DynObject.prototype.del = function() {
    this.deleteAllChildren();
    this.invokeEvent("beforeremove");
    this.specificRemove();
    this.precreated = this.created = false;
    this.invokeEvent("remove");
    this.invokeEvent("delete");
};
DynObject.prototype.deleteChild = function(c) {
    var l = this.children.length;
    for(var i=0;i<l && this.children[i]!=c;i++);
    if(i!=l) {
        this.children[i] = this.children[l-1];
        this.children[l-1] = null;
        this.children.length--;
        c.del()
        c = null;
    }
};
DynObject.prototype.deleteAllChildren = function() {
    var l = this.children.length;
    for(var i=0;i<l;i++) {
        this.children[i].del();
        delete this.children[i];
    }
    this.children = [];
};
DynObject.prototype.toString = function() {
    return "DynObject.all."+this.id
};
DynObject.prototype.getAll = function() {
    var ret = [];
    var temp;
    var l = this.children.length;
    for(var i=0;i<l;i++) {
        ret[this.children[i].id] = this.children[i];
        temp = this.children[i].getAll();
        for(var j in temp) ret[j] = temp[j];
    }
    return ret
};
DynObject.prototype.isParentOf = function(obj,equality) {
    if(!obj) return false
    return (equality && this==obj) || this.getAll()[obj.id]==obj
}
DynObject.prototype.isChildOf = function(obj,equality) {
    if(!obj) return false
    return (equality && this==obj) || obj.getAll()[this.id]==this
}
DynObject.prototype.specificCreate    = function() {};
DynObject.prototype.specificRemove    = function() {};
DynObject.prototype.invokeEvent        = function() {};
DynObject.Count = 0;
DynObject.all = [];
Methods = {
    removeFromArray : function(array, index, id) {
        var which=(typeof(index)=="object")?index:array[index];
        if (id) delete array[which.id];
            else for (var i=0; i<array.length; i++)
            if (array[i] == which) {
                if(array.splice) array.splice(i,1);
                else {    for(var x=i; x<array.length-1; x++) array[x]=array[x+1];
                         array.length -= 1; }
            break;
            }
        return array;
    },
    getContainerLayerOf : function(element) {
        if(!element) return null
        if(is.def&&!is.ie) while (!element.lyrobj && element.parentNode && element.parentNode!=element) element=element.parentNode;
        else if(is.ie) while (!element.lyrobj && element.parentElement && element.parentElement!=element) element=element.parentElement;
        return element.lyrobj
    }
};
DynAPIObject = function() {
    this.DynObject = DynObject;
    this.DynObject();

    this.loaded = false;
    this.librarypath = '';
    this.packages = [];
    this.errorHandling = false;
    this.returnErrors = false;
    this.onLoadCodes = [];
    this.onUnLoadCodes = [];
    this.onResizeCodes = [];
}
DynAPIObject.prototype = new DynObject();
DynAPIObject.prototype.setLibraryPath = function(path) {
    if (path.substring(path.length-1)!='/') path+='/';
    this.librarypath=path;
}
DynAPIObject.prototype.addPackage = function(pckg) {
    if (this.packages[pckg]) return;
    this.packages[pckg] = { libs: [] };
}
DynAPIObject.prototype.addLibrary = function(path,files) {
    var pckg = path.substring(0,path.indexOf('.'));
    if (!pckg) {
        alert("DynAPI Error: Incorrect DynAPI.addLibrary usage");
        return;
    }
    var name = path.substring(path.indexOf('.')+1);
    if (!this.packages[pckg]) this.addPackage(pckg);
    if (this.packages[pckg].libs[name]) {
        alert("DynAPI Error: Library "+name+" already exists");
        return;
    }
    this.packages[pckg].libs[name] = files;
}
DynAPIObject.prototype.include = function(src,pth) {
    src=src.split('.');
    if (src[src.length-1] == 'js') src.length -= 1;
    var path=pth||this.librarypath||'';
    if (path.substr(path.length-1) != "/") path += "/";
    var pckg=src[0];
    var grp=src[1];
    var file=src[2];
    if (file=='*') {
        if (this.packages[pckg]) group=this.packages[pckg].libs[grp];
        if (group) for (var i=0;i<group.length;i++) document.write('<script language="Javascript1.2" src="'+path+pckg+'/'+grp+'/'+group[i]+'.js"><\/script>');
        else alert('include()\n\nThe following package could not be loaded:\n'+src+'\n\nmake sure you specified the correct path.');
    } else document.write('<script language="Javascript1.2" src="'+path+src.join('/')+'.js"><\/script>');
}
DynAPIObject.prototype.errorHandler = function (msg, url, lno) {
    if (!this.loaded || !this.errorHandling) return false;
    if (is.ie) {
        lno-=1;
        alert("DynAPI reported an error\n\nError in project: '" + url + "'.\nLine number: " + lno + ".\n\nMessage: " + msg);
    } else if (is.ns) {
        alert("DynAPI reported an error\n\nError in file: '" + url + "'.\nLine number: " + lno + ".\n\nMessage: " + msg);
    } else return false;
    return this.returnErrors;
}
DynAPIObject.prototype.addLoadFunction = function(f) {
    this.onLoadCodes[this.onLoadCodes.length] = f;
}
DynAPIObject.prototype.addUnLoadFunction = function(f) {
    this.onUnLoadCodes[this.onUnLoadCodes.length] = f;
}
DynAPIObject.prototype.addResizeFunction = function(f) {
    this.onResizeCodes[this.onResizeCodes.length] = f;
}
DynAPIObject.prototype.loadHandler = function() {
    this.create();
    eval(this.onLoadCodes.join(";"));
    if (this.onLoad) this.onLoad();
    this.loaded=true;
}
DynAPIObject.prototype.unloadHandler = function() {
    if (!is.ns4) this.deleteAllChildren();
    eval(this.onUnLoadCodes.join(";"));
    if (this.onUnload) this.onUnload();
}
DynAPIObject.prototype.resizeHandler = function() {
    eval(this.onResizeCodes.join(";"));
    if (this.onResize) this.onResize();
}
DynAPIObject.prototype.addZoomViewer = function(zoomImageURL,width,height,imgWidth,imgHeight,version,viewerType,scaleLevels) {
        // Write Zoom Viewer to the page and initialize it
        document.writeln("<div id='zoomViewerDiv' stype='cursor:hand' align=left style='position:relative;width:"+width+"px;height:"+height+"px;'>");
    document.writeln("<div id='zoomViewerDiv' style='cursor:hand' align=left style='position:absolute;width:"+width+"px;height:"+height+"px;'>");

    DynAPI.view = new MediaServicesZoomView(zoomImageURL + ".",width,height,imgWidth,imgHeight,version,viewerType,scaleLevels);
    DynAPI.document.addChild(DynAPI.view);
    
    DynAPI.onLoad = function(){
        DynAPI.view.initialize();
    }
    
    document.writeln("</div>");
    document.writeln("</div>");
}

// Create base objects
DynAPI = new DynAPIObject();

// Native events
onload = function() { DynAPI.loadHandler(); }
onunload = function() { DynAPI.unloadHandler(); }
onerror = function(msg, url, lno) { DynAPI.errorHandler(msg, url, lno); }
onresize = function() { DynAPI.resizeHandler(); }


/*
   DynAPI Distribution
   DynDocument Class

   The DynAPI Distribution is distributed under the terms of the GNU LGPL license.
*/
DynDocument = function(frame) {
    this.DynObject = DynObject
    this.DynObject()
    this.elm = frame;
    this.doc = frame.document;
    this.frame = frame;
    this.fgColor = this.doc.fgColor||'';
    this.bgColor = this.doc.bgColor||'';
    this.elm.lyrobj=this;
    this.doc.lyrobj=this;
}
DynDocument.prototype = new DynObject();
DynDocument.prototype.isDynDocument = true;
DynDocument.prototype.getBgColor = function() {
    return this.bgColor;
};
DynDocument.prototype.specificCreate=function() {
    this.findDimensions();
    // Following Silly Patch allows sharing of assignChildren() between DynDocument and DynLayer (IE only)
    if(is.ie) this.elm.all = this.doc.all
    this.assignChildren();
    DynAPI.addResizeFunction(this+".resizeHandler()");
};
DynDocument.prototype._Old_addChild=DynDocument.prototype.addChild;
DynDocument.prototype.addChild=function(c) {
    if(!this.created) this.doc.write(c.getOuterHTML());
    return this._Old_addChild(c);
};
DynDocument.prototype.addInflowChild=function(c) {
    if(!this.created) this.doc.write(c.getOuterHTML(true));
    return this._Old_addChild(c);
};
DynDocument.prototype.specificRemove=function() {
    this.elm=null;
    this.doc=null;
    this.frame=null;
};
DynDocument.prototype.getX=function() { return 0; };
DynDocument.prototype.getY=function() { return 0; };
DynDocument.prototype.getPageX=function() { return 0; };
DynDocument.prototype.getPageY=function() { return 0; };
DynDocument.prototype.getWidth = function() {
    if (!this.w) this.findDimensions();
    return this.w;
};
DynDocument.prototype.getHeight = function() {
    if (!this.h) this.findDimensions();
    return this.h;
};
DynDocument.prototype.findDimensions = function() {
    this.w=(is.ns||is.opera)? this.elm.innerWidth : this.doc.body.clientWidth;
    this.h=(is.ns||is.opera)? this.elm.innerHeight : this.doc.body.clientHeight;
    if (is.ns && this.frame.parent.frames.length>1) {
        if (is.ns4) { this.w=this.w+4; this.h=this.h+4; }
        else this.h=this.h-2;
    };
};
DynDocument.prototype.setBgColor = function(color) {
    if (color == null) color='';
    if (is.ns4 && color == '') color = '#ffffff';
    this.bgColor = color;
    this.doc.bgColor = color;
};
DynDocument.prototype.setFgColor = function(color) {
    if (color == null) color='';
    if (is.ns4 && color == '') color='#ffffff';
    this.fgColor = color;
    this.doc.fgColor = color;
};
DynDocument.prototype.load = function(path) {
    this.doc.location = path;
};
DynDocument.prototype.resizeHandler=function() {
    var w=this.w;
    var h=this.h;
    this.findDimensions();
    if (is.ns4&&((this.w!=w)||(this.h!=h)))    {
        for (var i=0;i<this.children.length;i++) {
            this.children[i].elm=null;
            this.children[i].specificCreate();
        }
    }
};
//If DynLayer was included before DynDocument
if(DynLayer)DynDocument.prototype.assignChildren=DynLayer.prototype.assignChildren;

DynAPI.document = DynAPI.addChild(new DynDocument(self));
DynAPI.document.all = DynObject.all;



/*
   DynAPI Distribution
   DynLayer Class

   The DynAPI Distribution is distributed under the terms of the GNU LGPL license.
*/
function DynLayer() {
    this.DynObject = DynObject;
    this.DynObject();

    var a=arguments;
    if(a[0]) this.setID(a[0]);
    this.x=a[1]||0;
    this.y=a[2]||0;
    this.w=a[3]||null;
    this.h=a[4]||null;
    this.bgColor=a[5]||null;
    this.visible=(a[6]!=false && a[6]!='hidden');
    this.z=a[7]||0;
    this.bgImage=a[8]||null;
    this.html=a[9]||null;

    this.elm=null;
    this.doc=null;
    this.css=null;
};
DynLayer.prototype = new DynObject();
DynLayer.prototype.isDynLayer = true;
DynLayer.prototype.specificCreate=function() {
    // Check for this.wasBuiltInline allows inflow layers to skip recreation onResize (NS4)
    if (!this.parent||this.elm||this.wasBuiltInline) return;
    if (is.ns6) {
        var parentElement=(this.parent.isDynLayer)?this.parent.elm:this.parent.doc.body;
        var r = parentElement.ownerDocument.createRange();
        r.setStartBefore(parentElement);
        var ptxt = r.createContextualFragment(this.getOuterHTML());
        parentElement.appendChild(ptxt);
        this.elm=parentElement.lastChild;
        this.css=this.elm.style;
        this.doc=this.parent.doc;
        this.css.zIndex=this.z;
        this.css.cursor="pointer";
    } else if (is.ie) {
        var parentElement=(this.parent.isDynLayer)?this.parent.elm:this.parent.doc.body;
        parentElement.insertAdjacentHTML("beforeEnd",this.getOuterHTML());
        this.elm=parentElement.children[parentElement.children.length-1];
        this.css=this.elm.style;
        this.doc=this.parent.doc;
        this.css.cursor="hand";
    } else if (is.ns4) {
        var recycled=this.parent.doc.recycled;
        if (this.created) recycled=[];
        if (recycled && recycled.length>0) {
            this.elm=recycled[recycled.length-1];
            recycled.length--;
        } else {
            this.elm=new Layer(this.w,this.parent.elm);
            this.elm.captureEvents(Event.LOAD);
            this.elm.onload=function() {};
        }
        this.css=this.elm;
        this.doc=this.elm.document;
        this.doc.lyrobj=this;
        if (this.w) this.css.clip.width=(is.def && is.ns) ? this.w + 'px' : this.w;
        if (this.h) this.css.clip.height=(is.def && is.ns) ? this.h + 'px' : this.h;
        this.elm.moveTo(this.x,this.y);
        this.doc.write(this.getInnerHTML());
        this.doc.close();
        if (this.bgColor!=null) this.setBgColor(this.bgColor);
        if (this.bgImage!=null) this.setBgImage(this.bgImage);
        if (this.clip) this.setClip(this.clip);
        this.css.cursor="pointer";
        this.css.zIndex=this.z;
        this.css.visibility=this.visible? "inherit" : "hide";
        for (var i=0;i<this.doc.images.length;i++) this.doc.images[i].lyrobj=this;
        for (i=0;i<this.doc.links.length;i++) this.doc.links[i].lyrobj=this;
    }
    this.frame=this.parent.frame;
    this.elm.lyrobj=this;
    this.assignChildren();
    if (this.html!=null) {
        if (this.w==null && this.getContentWidth()>0) this.setWidth(this.getContentWidth(), false);
        if (this.h==null && this.getContentHeight()>0) this.setHeight(this.getContentHeight(), false);
    }
};
DynLayer.prototype.assignChildren=function() {
    var l=this.children.length;
    if(is.def) {
        for (var i=0; i<l; i++) {
            var child=this.children[i];
            if (is.ie) var elm=this.elm.all[child.id];
            else var elm=this.doc.getElementById(child.id);
            child.elm=elm;
            child.css=child.elm.style;
            child.doc=this.doc;
            child.elm.lyrobj=child;
            child.frame=this.frame;
            child.assignChildren();
            if (child.z) child.css.zIndex=child.z;
            if (child.w==null && child.getContentWidth()>0) child.setWidth(child.getContentWidth(), false);
            if (child.h==null && child.getContentHeight()>0) child.setHeight(child.getContentHeight(), false);
        }
    } else if(is.ns4) {
        for (var i=0; i<l; i++) {
            var child=this.children[i];
            // In order to allow inline dynlayers, which are wrapped by a ILAYER. See getOuterHTML()
            var elm=this.doc.layers[child.id]||this.doc.layers[child.id+"C"].document.layers[child.id];
            child.elm=elm;
            child.css=elm;
            child.doc=elm.document;
            child.doc.lyrobj=child;
            child.elm.lyrobj=child;
            for (var j=0;j<child.doc.images.length;j++) child.doc.images[j].lyrobj=child;
            for (j=0;j<child.doc.links.length;j++) child.doc.links[j].lyrobj=child;
            child.assignChildren();
            if (child.z) child.css.zIndex=child.z;
            if (child.w==null && child.getContentWidth()>0) child.setWidth(child.getContentWidth(), false);
            if (child.h==null && child.getContentHeight()>0) child.setHeight(child.getContentHeight(), false);
        }
    }
};
//If DynDocument was included before DynLayer
if(DynDocument)DynDocument.prototype.assignChildren=DynLayer.prototype.assignChildren;

DynLayer.prototype.specificRemove=function() {
    if (is.def && this.elm) {
        this.elm.style.visibility = "hidden";
        this.elm.innerHTML = "";
        this.elm.outerHTML = "";
    }
    else if (is.ns4 && this.elm) {
        if(!this.wasBuiltInline) {
            // These can't be reused
            if (!this.parent.doc.recycled) this.parent.doc.recycled=[];
            this.parent.doc.recycled[this.parent.doc.recycled.length]=this.elm;
        }
        this.wasBuiltInline = false
        this.elm.visibility="hide";
    }
    this.frame = null;
    this.elm = null;
    this.doc = null;
    this.css = null;
};
DynLayer.prototype.getInnerHTML=function() {
    var s="";
    if (this.html!=null) s+=this.html;
    var l=this.children.length;
    for (var i=0;i<l;i++) s+=this.children[i].getOuterHTML();
    return s;
};
if (is.def) {
    DynLayer.prototype.getOuterHTML=function(inflow) {
        var s='<div id="'+this.id+'" style="';
        if (this.visible==false) s+=' visibility:hidden;';
        if (!inflow && this.x!=null) s+=' left:'+this.x+'px;';
        if (!inflow && this.y!=null) s+=' top:'+this.y+'px;';
        if (this.w!=null) s+=' width:'+this.w+'px;';
        if (this.h!=null) s+=' height:'+this.h+'px;';
        if (this.clip) s+=' clip:rect('+this.clip[0]+'px '+this.clip[1]+'px '+this.clip[2]+'px '+this.clip[3]+'px);';
        else if (this.w!=null && this.h!=null) s+=' clip:rect(0px '+this.w+'px '+this.h+'px 0px);';
        if (this.z!=null) s+=' z-index='+this.z+';';
        if (this.bgImage!=null)    s+=' background-image:url('+this.bgImage+');';
        if (this.bgColor!=null)    s+=' background-color:'+this.bgColor+';';
        if (is.ie55 && this.bgImage==null && this.html==null) s+=' background-image:url('+DynAPI.librarypath+'dynapi/images/common/transparent.gif);';
        if(!inflow) s+=' position:absolute;'; else s+=' position:relative;';
        s+=' overflow:hidden">';
        if (this.html!=null) s+=this.html;
        for (var i=0; i<this.children.length; i++) s+=this.children[i].getOuterHTML();
        s+='</div>';
        return s;

    };
} else if (is.ns4) {
    DynLayer.prototype.getOuterHTML=function(inflow) {
        var s='\n'
        if(inflow) {
            // These should not be recreated on resize
            this.wasBuiltInline = true

            s+= '<ilayer id="'+this.id+'C"' 
            if (this.w!=null) s+=' width='+this.w+'px';
            if (this.h!=null) s+=' height='+this.h+'px';
            s+= '">'
        }
    
        s+='<layer id="'+this.id+'"';
        if (this.visible==false) s+=' visibility="hide"';
        if (!inflow && this.x!=null) s+=' left='+this.x;
        if (!inflow && this.y!=null) s+=' top='+this.y;
        if (this.w!=null) s+=' width='+this.w+'px';
        if (this.h!=null) s+=' height='+this.h+'px';
        if (this.clip) s+=' clip="'+this.clip[3]+','+this.clip[0]+','+this.clip[1]+','+this.clip[2]+'"';
        else if (this.w!=null && this.h!=null) s+=' clip="0,0,'+this.w+','+this.h+'"';
        if (this.z!=null) s+=' zIndex='+this.z;
        if (this.bgImage!=null)    s+=' background="'+this.bgImage+'"';
        if (this.bgColor!=null)    s+=' bgcolor="'+this.bgColor+'"';
        s+='>';
        if (this.html!=null) s+=this.html;
        for (var i=0; i<this.children.length; i++) s+=this.children[i].getOuterHTML();
        s+='</layer>';
        
        if(inflow) s+="</ilayer>\n"
        return s;
    };
};
DynLayer.prototype._dynlayer_create = DynLayer.prototype.create;
DynLayer.prototype.create = function() {
    this._dynlayer_create();
    this.invokeEvent("resize");
};
if (is.ns) {
    DynLayer.prototype._setX=function(){ this.css.left=this.x+'px'; };
    DynLayer.prototype._setY=function(){ this.css.top=this.y+'px'; };
} else {
    DynLayer.prototype._setX=function(){ this.css.pixelLeft=this.x; };
    DynLayer.prototype._setY=function(){ this.css.pixelTop=this.y; };
};
DynLayer.prototype.moveTo=function(x,y) {
    if (x!=null) this.x=x;
    if (y!=null) this.y=y;
    if (this.css==null) return;
    this._setX();
    this._setY();
    this.invokeEvent('move');
};
DynLayer.prototype.moveBy=function(x,y) {
    this.moveTo(this.x+x,this.y+y);
};
DynLayer.prototype.setX=function(x) { this.moveTo(x,null); };
DynLayer.prototype.setY=function(y) { this.moveTo(null,y); };
DynLayer.prototype.getX=function() { return this.x; };
DynLayer.prototype.getY=function() { return this.y; };
DynLayer.prototype.getPageX=function() {
    if (this.css==null) return null;
    if (is.ns4) return this.css.pageX;
    else return (this.isChild)? this.parent.getPageX()+this.x : this.x;
};
DynLayer.prototype.getPageY=function() {
    if (this.css==null) return null;
    if (is.ns4) return this.css.pageY;
    else return (this.isChild)? this.parent.getPageY()+this.y : this.y;
};
DynLayer.prototype.setPageX=function(x) {
    if (this.css==null) return;
    if (is.ns4) this.css.pageX=x;
    if (is.ie) {
        if (this.isChild) this.setX(x-this.parent.getPageX());
        else this.setX(x);
    }
    this.getX();
    this.invokeEvent('move');
};
DynLayer.prototype.setPageY=function(y) {
    if (this.css==null) return;
    if (is.ns4) this.css.pageY=y;
    if (is.ie) {
        if (this.isChild) this.setY(y-this.parent.getPageY());
        else this.setY(y);
    }
    this.getY();
    this.invokeEvent('move');
};
DynLayer.prototype.setVisible=function(b) {
    this.visible=b;
    if (this.css==null) return;
    this.css.visibility = b? "inherit" : (is.ns4?"hide":"hidden");
};
DynLayer.prototype.getVisible=function() {
    return this.visible;
};
DynLayer.prototype.setZIndex=function(z) {
    this.z=z;
    if (this.css==null) return;
    this.css.zIndex=z;
};
DynLayer.prototype.getZIndex=function() {
    return this.z;
};
DynLayer.prototype.setBgImage=function(path) {
    this.bgImage=path;
    if (this.css==null) return;
    if (is.ns4) {
        this.elm.background.src=path;
        if (!path) this.setBgColor(this.getBgColor());
    }
    else this.css.backgroundImage='url('+path+')';
};
DynLayer.prototype.getBgImage=function() {
    return this.bgImage;
};
DynLayer.prototype.setBgColor=function(color) {
    if (color==null) {
        if (is.ns4) color=null;
        else color='transparent';
    }
    this.bgColor=color;
    if (this.css==null) return;
    if (is.ns4) this.doc.bgColor=color;
    else this.css.backgroundColor=color;
};
DynLayer.prototype.getBgColor=function() {
    return this.bgColor;
};
if (is.ns4) {
    DynLayer.prototype._setHTML=function(html) {
        var sTmp=(this.w==null)?'<NOBR>'+this.html+'</NOBR>':this.html;
        this.doc.open();
        this.doc.write(sTmp);
        this.doc.close();
            for (var i=0;i<this.doc.images.length;i++) this.doc.images[i].lyrobj=this;
            for (i=0;i<this.doc.links.length;i++) this.doc.links[i].lyrobj=this;
    }
} else if (is.ie) {
    DynLayer.prototype._setHTML=function(html) {
        if (is.platform=="mac") html+='\n';
        this.elm.innerHTML=html;
        var images = this.elm.all.tags("img");
        for (var i=0;i<images.length;i++) images[i].lyrobj=this;
    }
} else {
    DynLayer.prototype._setHTML=function(html) {
        sTmp=(this.w==null)?'<NOBR>'+this.html+'</NOBR>':this.html;
        while (this.elm.hasChildNodes()) this.elm.removeChild(this.elm.firstChild);
        var r=this.elm.ownerDocument.createRange();
        r.selectNodeContents(this.elm);
        r.collapse(true);
        var df=r.createContextualFragment(sTmp);
        this.elm.appendChild(df);
    }
};
DynLayer.prototype.setHTML=function(html,noevt) {
    this.html=html?html:'';
    if (this.css==null) return;
    if (noevt!=false) this.invokeEvent("beforeload");
    this._setHTML(html);
    if (noevt!=false) this.invokeEvent("load");
}
DynLayer.prototype.getHTML=function() {
    return this.html;
};
DynLayer.prototype.setSize = function(w,h,noevt) {
    this.w=(w===null)?this.w:w<0?0:w;
    this.h=(h===null)?this.h:h<0?0:h;
    if (this.w===null&&this.h===null) return;
    if (this.css!=null) {
        if (is.ns4) {
            this.css.clip.width = this.w + 'px';
            this.css.clip.height = this.h + 'px';
            }
        else {
            this.css.width = is.ns ? this.w + 'px' : this.w;
            this.css.height = is.ns ? this.h + 'px' : this.h;
            this.css.clip = 'rect(0px '+(this.w||0)+'px '+(this.h||0)+'px 0px)';
        }
    }
    if (noevt!=false) this.invokeEvent('resize');
};
DynLayer.prototype.setNoFlickerSize = function(w,h,redraw) {
          if(redraw === undefined) {
        redraw = true;
      }
          if(!is.ie && DynAPI.document.doc.images[this.id+'Image']) {
        this.setSize(w,h,false);
        DynAPI.document.doc.images[this.id+'Image'].width = w;
        DynAPI.document.doc.images[this.id+'Image'].height = h;
      } else {
        this.setSize(w,h,redraw);
      }
};
DynLayer.prototype.setWidth=function(w,noevt) {
    this.w=(w===null)?this.w:w<0?0:w;
    if (this.w===null) return;
    if (this.css!=null) {
        if (is.ns4) this.css.clip.width = this.w + 'px';
        else {
            this.css.width = is.ns ? this.w + 'px' : this.w;
            this.css.clip = 'rect(0px '+(this.w||0)+'px '+(this.h||0)+'px 0px)';
        }
    }
    if (noevt!=false) this.invokeEvent('resize');
};
DynLayer.prototype.setHeight=function(h,noevt) {
    this.h=(h===null)?this.h:h<0?0:h;
    if (this.h===null) return;
    if (this.css!=null) {
        if (is.ns4) this.css.clip.height = this.h + 'px';
        else {
            this.css.height = is.ns ? this.h + 'px' : this.h;
            this.css.clip = 'rect(0px '+(this.w||0)+'px '+(this.h||0)+'px 0px)';
        }
    }
    if (noevt!=false) this.invokeEvent('resize');
};
DynLayer.prototype.getWidth=function() {
    return this.w;
};
DynLayer.prototype.getHeight=function() {
    return this.h;
};
DynLayer.prototype.getContentWidth=function() {
    if (this.elm===null) return 0;
    else {
        if (is.ns4) return this.doc.width;
        //if this.elm.offsetWidth/Height is not accessed, then ie5mac will return NaN.
        else if (is.ie) {
                   if (is.platform==="mac") this.elm.offsetWidth=this.elm.offsetWidth;
                return parseInt(this.elm.scrollWidth);
        }
        else {
            var tw = this.elm.style.width;
            this.elm.style.width = "auto";
                var w = this.elm.offsetWidth;
                this.elm.style.width = tw;
                return w;
        }
    };
};
DynLayer.prototype.getContentHeight=function() {
    if (this.elm===null) return 0;
    else {
        if (is.ns4) return this.doc.height;
        //if this.elm.offsetWidth/Height is not accessed, then ie5mac will return NaN.
        else if (is.ie) {
                   if (is.platform==="mac") this.elm.offsetHeight=this.elm.offsetHeight;
                return parseInt(this.elm.scrollHeight);
            }
        else {
            var th = this.elm.style.height;
            this.elm.style.height = "auto";
                var h = this.elm.offsetHeight;
                this.elm.style.height = th;
                return h;
        }
    }
};
DynLayer.prototype.setClip=function(clip) {
    var cc=this.getClip();
    for (var i=0;i<clip.length;i++) if (clip[i]==null) clip[i]=cc[i];
    this.clip=clip;
    if (this.css==null) return;
    var c=this.css.clip;
    if (is.ns4) c.top=clip[0], c.right=clip[1], c.bottom=clip[2], c.left=clip[3];
    else this.css.clip="rect("+clip[0]+"px "+clip[1]+"px "+clip[2]+"px "+clip[3]+"px)";
};
DynLayer.prototype.getClip=function() {
    if (this.css==null || !this.css.clip) return [0,0,0,0];
    var c = this.css.clip;
    if (c) {
        if (is.ns4) return [c.top,c.right,c.bottom,c.left];
        if (c.indexOf("rect(")>-1) {
            c=c.split("rect(")[1].split(")")[0].split("px");
            for (var i=0;i<c.length;i++) c[i]=parseInt(c[i]);
            return [c[0],c[1],c[2],c[3]];
        }
        else return [0,this.w,this.h,0];
    }
};

DynLayer.prototype.setMouseCursor=function(cursor) {
    if (this.css==null) return 0;

        if (is.ie && cursor=="pointer") {
            this.css.cursor="hand";
        } else {
            this.css.cursor=cursor;
        }
};


/*
   DynAPI Distribution
   Advanced Event object. Generic Event Listeners

   The DynAPI Distribution is distributed under the terms of the GNU LGPL license.
*/
DynEvent=function(type,src,target) {
    this.type=type;
    this.src=src;
    this.target=target;
    this.bubble=false;
};
DynEvent.prototype.setBubble=function(b) {this.bubble=b};
DynEvent.prototype.getType=function() {return this.type};
DynEvent.prototype.getSource=function() {return this.src};
DynEvent.prototype.getTarget=function() {return this.target};
DynEvent.prototype.preBubbleCode = function() {};

EventListener = function(target) { this.target=target };
EventListener.prototype.handleEvent=function(type,e,args) {
    if(this["on"+type]) this["on"+type](e,args);
};
// Extend DynObject to support EventListeners
DynObject.prototype.addEventListener=function(listener) {
    //removed to counter inheritance bug (#425789)
    //if(!this.eventListeners) { this.eventListeners = []; }
    this.hasEventListeners = true;
    for (var i=0;i<this.eventListeners.length;i++) if (this.eventListeners[i]==listener) return;
    this.eventListeners[this.eventListeners.length]=listener;
}
DynObject.prototype.removeEventListener=function(listener) {
    Methods.removeFromArray(this.eventListeners, listener, false);
    if(this.eventListeners.length==0) {
        this.hasEventListeners=false;
    }
}
DynObject.prototype.removeAllEventListeners=function() {
    if (!this.hasEventListeners) return;
    this.eventListeners=[];
    this.hasEventListeners=false;
}
DynObject.prototype.invokeEvent=function(type,e,args) {
    if (!e) e=new DynEvent(type,this);
    if (this.hasEventListeners) for(var i=0;i<this.eventListeners.length;i++) {
        e.target=this.eventListeners[i].target;
        this.eventListeners[i].handleEvent(type,e,args);
    }
    if(e.bubble && this.parent) {
        e.preBubbleCode();
        e.src = this.parent;
        this.parent.invokeEvent(type,e,args);
    }
}
//removed to counter inheritance bug (#425789)
//DynObject.prototype.eventListeners = null;
DynObject.prototype._listeners_del = DynObject.prototype.del
DynObject.prototype.del = function() {
    this.removeAllEventListeners();
    this._listeners_del();
};


/*
   DynAPI Distribution
   Event Classes

   The DynAPI Distribution is distributed under the terms of the GNU LGPL license.

   Requirements:
    dynapi.api [dynlayer, dyndocument, browser]
    dynapi.event [listeners]

*/
// The mouseEvent object
DynMouseEvent=function(old) {
    this.DynEvent=DynEvent;
    this.DynEvent();
    // Copy properties from given event, if any
    if (old) for(var i in old) this[i]=old[i]
};
DynMouseEvent.prototype=new DynEvent();
DynMouseEvent.prototype.preBubbleCode=function() {
    this.x+=this.src.x;
    this.y+=this.src.y;
};
DynMouseEvent.prototype.getX=function() {return this.x};
DynMouseEvent.prototype.getY=function() {return this.y};
DynMouseEvent.prototype.getPageX=function() {return this.pageX};
DynMouseEvent.prototype.getPageY=function() {return this.pageY};
DynMouseEvent.prototype.cancelBrowserEvent=function() {
    this.browserReturn=false
    var evt = DynMouseEvent._e
    if(!is.ns4 || evt.type != "mousedown") return
    // If we cancel a mousedown in NS4. We must remember it so a click event is manually
    // generated afterwards
    var realsrc = evt.src
    realsrc.ns4clktimer = true
    setTimeout(realsrc+'.ns4clktimer=false',300);
};
// This is THE event.
DynMouseEvent._e=new DynMouseEvent()
// If this is true, then mouseups always happen where the mousedown happened ( true is recommended )
DynMouseEvent.forceMouseUp = true

DynMouseEvent.EventMethod=function(e) {
    var dynobject=this.lyrobj;
    if(is.def) {
        if (is.ie) var e=dynobject.frame.event
            e.cancelBubble=true;

        if (DynAPI.wasDragging && e.type=="click") {
            DynAPI.wasDragging=false;
            return false;
        }
    }

    // Get the real source for the event
    if(is.def) var realsrc = Methods.getContainerLayerOf(is.ie?e.srcElement:e.target) || dynobject
    else if(is.ns4) var realsrc=e.target.lyrobj || dynobject

    // Now 'realsrc' should point to the DynLayer object where the event initially was triggered
    if (!realsrc) { alert('Error in MouseEvents'); return false; }

    if(is.def) {
        if(e.type=="mouseout" && realsrc.isParentOf(Methods.getContainerLayerOf(is.ie?e.toElement:e.relatedTarget),true)) return true;
        if(e.type=="mouseover" && realsrc.isParentOf(Methods.getContainerLayerOf(is.ie?e.fromElement:e.relatedTarget),true)) return true;
    }
    var evt=DynMouseEvent._e
    // Step one: properties common to all DynEvents
    var type = e.type
    evt.type = type;
    evt.src=realsrc;
    evt.browserReturn=true;
    evt.bubble=true;

    // Step two: mouse coordinate properties
    if (is.ns4 && type=='mouseover') {
        // debugging for NS4 mouseover event
        evt.pageX=evt.pageX;
        evt.pageY=evt.pageY;
        evt.x=evt.pageX-evt.src.getPageX()
        evt.y=evt.pageY-evt.src.getPageY()
    } else {
        // standard DynAPI coordinate calculation
        evt.pageX=is.ie?e.x+document.body.scrollLeft:e.pageX;
        evt.pageY=is.ie?e.y+document.body.scrollTop:e.pageY;
        evt.x=is.ie?evt.pageX-evt.src.getPageX():e.layerX
        evt.y=is.ie?evt.pageY-evt.src.getPageY():e.layerY
    }

    // Step three: mouse buttons
    var b=is.ie?e.button:e.which;
    if (is.ie){
        if (b==2) b=3;
        else if (b==4) b=2;
    };
    evt.button=b;
    if (evt.button==2 && (type=='mousedown' || type=='mouseup' || type=='mouseclick')) type=evt.type='md'+type;
    if (evt.button==3 && (type=='mousedown' || type=='mouseup' || type=='mouseclick')) type=evt.type='rt'+type;

    // Step four: modifiers
    if (is.def){
        evt.altKey=(e.altKey||e.altLeft);
        evt.ctrlKey=(e.ctrlKey||e.ctrlLeft);
        evt.shiftKey=(e.shiftKey||e.shiftLeft);
    }
    else if (is.ns4){
        var m=e.modifiers;
        evt.altKey=(m==1||m==3||m==5||m==7);
        evt.ctrlKey=(m==2||m==3||m==6||m==7);
        evt.shiftKey=(m==4||m==5||m==6||m==7);
    }

    // Step five: reference to the original event
    evt.orig=e

    if(is.def) {
        if (evt.type=='mouseover') {
            var fromL = Methods.getContainerLayerOf(is.ie?e.fromElement:e.relatedTarget)
            if(fromL && fromL.isChildOf(realsrc.parent,true)) evt.setBubble(false);
        }
        if (evt.type=='mouseout') {
            var toL = Methods.getContainerLayerOf(is.ie?e.toElement:e.relatedTarget)
            if(toL && toL.isChildOf(realsrc.parent,true)) evt.setBubble(false);
        }
    }
    else if(is.ns4 && (e.type=="mouseover" || e.type=="mouseout")) evt.setBubble(false);

    // This forces mouseUps to happen in the same place where mousedowns took place
    if (DynMouseEvent.forceMouseUp && is.def) {
        if (e.type=='mousedown') DynMouseEvent.focus=realsrc;
        else if (e.type=='mouseup' && DynMouseEvent.focus!=null)
        evt.src=realsrc=DynMouseEvent.focus;
    };

    // Invoke the event
    realsrc.invokeEvent(type,evt);

    // Other checks. NS4 mainly
    if (is.ns4) {
        // See cancelBrowserEvent()
        if (realsrc.ns4clktimer && type=="mouseup") {
            evt.type=type="click";
            evt.bubble = true;
            realsrc.invokeEvent(type,evt);
        }
        // Linux platforms' dblclicks
        if (is.platform=="other" && type=="mousedown") {
            if (realsrc.dbltimer!=null) {
                evt.type=type="dblclick";
                evt.bubble = true;
                realsrc.invokeEvent(type,evt);
            }
            else realsrc.dbltimer=setTimeout(realsrc+'.dbltimer=null',300);
        }

            // Click on links and form elements
            if(e && e.target.handleEvent && e.target!=this && (e.target.handleEvent(e) == false)) evt.browserReturn = false;
        }
        else {
                if(e.preventDefault && !evt.browserReturn) e.preventDefault();
        if (evt.type=='rtmouseup') document.oncontextmenu=evt.browserReturn ? null : DynAPI.FalseFunction;
        else if (evt.type=='mousedown') document.onselectstart=evt.browserReturn ? null : DynAPI.FalseFunction; 
        }
        // If Internet Explorer AND evt.browserReturn is false,
        // OR _any other browser_, THEN return evt.browserReturn.
        // [So in IE either return false or nothing at all. This allows user
        // code (<A onclick> for example) to set e.returnValue (in IE) or return
        // true/false. If evt.browserReturn is false it means we're to
        // disable the default action, no matter what.]
        if(!is.ie || evt.browserReturn==false) return evt.browserReturn;
}
DynAPI.FalseFunction = function() { return false }
// Extend DynDocument to capture its events
DynDocument.prototype.captureMouseEvents = function() {
    if(is.def&&!is.ie) {
        this.doc.addEventListener("mousemove",DynMouseEvent.EventMethod,false)
        this.doc.addEventListener("mousedown",DynMouseEvent.EventMethod,false)
        this.doc.addEventListener("mouseup",DynMouseEvent.EventMethod,false)
        this.doc.addEventListener("mouseover",DynMouseEvent.EventMethod,false)
        this.doc.addEventListener("mouseout",DynMouseEvent.EventMethod,false)
        this.doc.addEventListener("click",DynMouseEvent.EventMethod,false)
        this.doc.addEventListener("dblclick",DynMouseEvent.EventMethod,false)
    }
    else {
        if (is.ns4) this.doc.captureEvents(Event.MOUSEMOVE | Event.MOUSEOVER | Event.MOUSEOUT | Event.MOUSEDOWN | Event.MOUSEUP | Event.CLICK | Event.DBLCLICK);
        this.doc.onmouseover=this.doc.onmouseout=this.doc.onmousemove=this.doc.onmousedown=this.doc.onmouseup=this.doc.onclick=this.doc.ondblclick=DynMouseEvent.EventMethod;
    }
}
DynDocument.prototype.releaseMouseEvents=function() {
    if(is.def&&!is.ie) {
        this.doc.removeEventListener("mousemove",DynMouseEvent.EventMethod,false)
        this.doc.removeEventListener("mousedown",DynMouseEvent.EventMethod,false)
        this.doc.removeEventListener("mouseup",DynMouseEvent.EventMethod,false)
        this.doc.removeEventListener("mouseover",DynMouseEvent.EventMethod,false)
        this.doc.removeEventListener("mouseout",DynMouseEvent.EventMethod,false)
        this.doc.removeEventListener("click",DynMouseEvent.EventMethod,false)
        this.doc.removeEventListener("dblclick",DynMouseEvent.EventMethod,false)
    }
    else {
        if (is.ns4) this.doc.releaseEvents(Event.MOUSEMOVE | Event.MOUSEOVER | Event.MOUSEOUT | Event.MOUSEDOWN | Event.MOUSEUP | Event.CLICK | Event.DBLCLICK);
        this.doc.onmouseover=this.doc.onmouseout=this.doc.onmousemove=this.doc.onmousedown=this.doc.onmouseup=this.doc.onclick=this.doc.ondblclick=null
    }
}
// DynDocument Specific
DynDocument.prototype._OldM_specificCreate = DynDocument.prototype.specificCreate
DynDocument.prototype.specificCreate = function() {
    this._OldM_specificCreate()
    this.captureMouseEvents()
}
DynDocument.prototype._OldM_specificRemove = DynDocument.prototype.specificRemove
DynDocument.prototype.specificRemove = function() {
    this.releaseMouseEvents()
    this._OldM_specificRemove()
}


/*
   DynAPI Distribution
   DragEvent Class

   The DynAPI Distribution is distributed under the terms of the GNU LGPL license.
*/

// DragEvent object
function DragEvent(type,src) {
    this.DynEvent = DynEvent
    this.DynEvent()
    this.dragEnabled=true;
}
DragEvent.prototype = new DynEvent()
DragEvent.prototype.getX=function() {return this.x;};
DragEvent.prototype.getY=function() {return this.y;};
DragEvent.prototype.getPageX=function() {return this.pageX;};
DragEvent.prototype.getPageY=function() {return this.pageY;};
DragEvent.prototype.cancelDrag=function() {this.dragEnabled=false;};
DragEvent.dragPlay=0;
DragEvent.dragevent=new DragEvent();

DragEvent.lyrListener=new EventListener();
DragEvent.lyrListener.onmousedown=function(e) {
    //fix to allow forms in draggable layers to select text.
    if (is.def&&e.orig) {
        var tn = is.ie? e.orig.srcElement.tagName : e.orig.target.tagName;
        if (tn=="INPUT" || tn=="TEXTAREA") return;
    }

    e.cancelBrowserEvent();
    if (DragEvent.dragevent.src) return;

    var lyr=e.getSource();
    if (is.ie) lyr.doc.body.onselectstart = function() { return false; }
        if(window.dragStartCursor != undefined)
        {
            var curv = document.getElementById("DynObject"+ topLayerId );
            if(curv != undefined)
                curv.style.cursor = dragStartCursor;
        }
    // Initialize dragEvent object
    var de=DragEvent.dragevent;
    de.type="dragstart"
    de.src=lyr

    // Set properties
    de.isDragging=false;
    de.x=e.getPageX()-e.getSource().getPageX();
    de.y=e.getPageY()-e.getSource().getPageY();
    de.pageX=e.getPageX();
    de.pageY=e.getPageY();
    de.parentPageX=lyr.parent.getPageX();
    de.parentPageY=lyr.parent.getPageY();
};
DragEvent.docListener=new EventListener();
DragEvent.docListener.onmousemove=function(e) {
    // Get, if any, the currently drag in process and the layer. If none, return
    var de = DragEvent.dragevent;
    if (!de) return;
    var lyr = de.src;
    if (!lyr) return;
    // Also, if the dragged layer is not in this document, return
    if(lyr.frame&&lyr.frame.lyrobj!=e.getSource()) return

    if(!de.isDragging)
    // Detect if we should start the drag
    if(DragEvent.dragPlay==0 || (Math.abs(de.pageX-e.getPageX())-DragEvent.dragPlay>0) || (Math.abs(de.pageY-e.getPageY())-DragEvent.dragPlay>0)) {
        de.isDragging=true;
        de.src.invokeEvent("dragstart",de);
        e.setBubble(de.bubble);
    }
    if (!de.isDragging) return;
    else if (!de.dragEnabled) {
        // This allows 'cancelDrag' method to fire the mouseUp as if had been released by the user
        lyr.invokeEvent("mouseup");
        return;
    }

    // Properties
    de.type="dragmove";
    de.pageX=e.getPageX();
    de.pageY=e.getPageY();
    var x=de.pageX-de.parentPageX-de.x;
    var y=de.pageY-de.parentPageY-de.y;

    // Respect boundary, if any
    if (lyr.dragBoundary) {
        var dB=lyr.dragBoundary;
        if (dB=="parent") {
            var b=lyr.parent.getHeight();
            var r=lyr.parent.getWidth();
            var l=0;
            var t=0;
        } else {
            var b=dB[2];
            var r=dB[1];
            var l=dB[3];
            var t=dB[0];
        }
        var w=lyr.w;
        var h=lyr.h;
        if (x<l) x=l;
        else if (x+w>r) x=r-w;
        if (y<t) y=t;
        else if (y+h>b) y=b-h;
    }

    // Move dragged layer
    lyr.moveTo(x,y);
    lyr.invokeEvent("dragmove",de);
    e.cancelBrowserEvent();
    e.setBubble(de.bubble);
};
DragEvent.docListener.onmouseup=function(e) {
    // Get, if any, the currently drag in process and the layer. If none, return
    var de=DragEvent.dragevent;
    if (!de) return;
    var lyr=de.src;
    if (!lyr) return;
        if(window.dragEndCursor != undefined)
        {
            var curv = document.getElementById("DynObject"+ topLayerId );
            if(curv != undefined)
            {
                if(DynAPI.view.getZoomLevel() == -1)
                    curv.style.cursor = 'pointer';
                else
                    curv.style.cursor = dragEndCursor;
            }
        }
    if (!de.isDragging) {
            de.type="dragend";
            de.src=null;
            e.setBubble(true);
        return;
    }
    if (is.ie) lyr.doc.body.onselectstart = null;

    //refresh screen to display form objects in draggable layers
    if(lyr.doc.forms.length>0){
        if (is.ie && is.platform=="mac") document.body.className = document.body.className;
        else if (is.ns4 && is.platform=="win32") document.bgColor = document.bgColor;
    }

    // Avoid click for the dragged layer ( with MouseEvent addition )
    if (is.def) DynAPI.wasDragging=true;
    if (lyr.parent.DragDrop) lyr.parent.DragDrop(lyr,e);
    // Properties for the event
    de.type="dragend";
    de.isDragging=false;
    lyr.invokeEvent("dragend",de);

    // Clean drag stuff
    de.src=null;
    e.cancelBrowserEvent();
    e.setBubble(de.bubble);
};
DragEvent.setDragBoundary=function(dlyr,t,r,b,l) {
    var a=arguments;
    if (a.length==0) return;
    if (a.length==1) dlyr.dragBoundary="parent";
    else if (a.length==5) dlyr.dragBoundary=new Array(t,r,b,l);
};
DragEvent.enableDragEvents=function(dlyr,doc) {
    if (!dlyr.isDynLayer) return;
    dlyr.addEventListener(DragEvent.lyrListener);
    var dyndoc=doc||DynAPI.document;
    if (dlyr.frame) dyndoc=dlyr.frame.lyrobj;
    dyndoc.addEventListener(DragEvent.docListener);
    dyndoc.dragEnabled=true;
};
DragEvent.disableDragEvents=function() {
    for (var i=0;i<arguments.length;i++) {
        var lyr=arguments[i];
        lyr.removeEventListener(DragEvent.lyrListener);
    }
};



/*
   DynAPI Distribution
   Key Event Extensions by Henrik Våglin (hvaglin@yahoo.com)

   The DynAPI Distribution is distributed under the terms of the GNU LGPL license.

   Requirements:
    dynapi.api [dynlayer, dyndocument, browser]
    dynapi.event [listeners]
*/
DynKeyEvent=function() {
    this.DynEvent=DynEvent;
    this.DynEvent();
};
DynKeyEvent.prototype=new DynEvent();
DynKeyEvent.prototype.getKey=function() {
    return this.charKey;
};
DynKeyEvent.prototype.bubbleEvent=function() {
    if (!this.bubble||this.src.isDynDocument||this.src.parent==null) return;
    this.src=this.src.parent;
    this.src.invokeEvent(this.type,this);
    this.bubbleEvent();
    return;
};
DynKeyEvent.EventMethod = function(e) {
    var dynobject=this.lyrobj;
    if(is.def) {
        if (is.ie) var e=dynobject.frame.event;
        else if (e.eventPhase!=3) return false;
            e.cancelBubble=true;
    }
    if(is.def) var realsrc = Methods.getContainerLayerOf(is.ie?e.srcElement:e.target)||dynobject;
    else if(is.ns4) var realsrc=e.target.lyrobj||dynobject;

    if (!realsrc) { alert('Error in MouseEvents'); return true; }

    var evt=DynKeyEvent._e;
    evt.type=e.type;
    evt.src=realsrc;
    evt.browserReturn=true;
    evt.bubble=true;
    evt.which=(is.ns4)?e.which:e.keyCode;
    var curKey = String.fromCharCode(evt.which).toLowerCase();

    if (((curKey>='a')&&(curKey<='z'))||((curKey>='0')&&(curKey<='9'))) evt.charKey=curKey;
    else evt.charKey=null;

    evt.ctrlKey=(is.ns4)?(e.modifiers & Event.CONTROL_MASK):(e.ctrlKey||e.ctrlLeft||e.keyCode==17);
    evt.shiftKey=(is.ns4)?(e.modifiers & Event.SHIFT_MASK):(e.shiftKey||e.shiftLeft||e.keyCode==16);
    evt.orig=e;

    realsrc.invokeEvent(evt.type,evt);
    evt.bubbleEvent();
    return evt.browserReturn;
};
DynKeyEvent._e=new DynKeyEvent();
DynDocument.prototype.captureKeyEvents=function() {
    if(is.def&&!is.ie) {
        this.doc.addEventListener("keydown",DynKeyEvent.EventMethod,false)
        this.doc.addEventListener("keyup",DynKeyEvent.EventMethod,false)
        this.doc.addEventListener("keypress",DynKeyEvent.EventMethod,false)
    }
    else {
        if (is.ns4) this.doc.captureEvents(Event.KEYPRESS | Event.KEYDOWN | Event.KEYUP);
        this.doc.onkeypress=this.doc.onkeydown=this.doc.onkeyup=DynKeyEvent.EventMethod;
    };
};
DynDocument.prototype.releaseKeyEvents=function() {
    if(is.def&&!is.ie) {
        this.doc.removeEventListener("keydown",DynKeyEvent.EventMethod,false)
        this.doc.removeEventListener("keyup",DynKeyEvent.EventMethod,false)
        this.doc.removeEventListener("keypress",DynKeyEvent.EventMethod,false)
    }
    else {
        if (is.ns4) this.doc.releaseEvents(Event.KEYPRESS | Event.KEYDOWN | Event.KEYUP);
        this.doc.onkeypress=this.doc.onkeydown=this.doc.onkeyup=null;
    };
};
// DynDocument specific
DynDocument.prototype._OldK_specificCreate = DynDocument.prototype.specificCreate;
DynDocument.prototype.specificCreate = function() {
    this._OldK_specificCreate();
    this.captureKeyEvents();
};
DynDocument.prototype._OldK_specificRemove = DynDocument.prototype.specificRemove;
DynDocument.prototype.specificRemove = function() {
    this.releaseKeyEvents();
    this._OldK_specificCreate();
};



/*
   DynAPI Distribution
   Inline Layers Extensions

   The DynAPI Distribution is distributed under the terms of the GNU LGPL license.

   Requirements: 
    dynapi.api [dynlayer, dyndocument, browser]
*/
DynObject.prototype.findLayers=function() {
    var divs=[];
    if (is.def&&!is.ie) divs=this.doc.getElementsByTagName("DIV");
    else if (is.ie) divs=this.doc.all.tags("DIV");
    else if (is.ns4) divs=this.doc.layers;
    else return;
    for (var i=0; i<divs.length; i++) {
        if(Methods.isDirectChildOf(divs[i],this.elm)) {
            var id=is.ns4? divs[i].name : divs[i].id;
            var dlyr=new DynLayer(id);
            dlyr.parent=this;
            dlyr.created=true;
            dlyr.isChild=true;
            dlyr.elm=divs[i];
            if (is.def) {
                dlyr.css=dlyr.elm.style;
                dlyr.doc=this.doc
            }
            else if (is.ns4) { 
                dlyr.css=dlyr.elm;
                dlyr.doc=dlyr.elm.document;
            }
            dlyr.frame=this.frame;
            //Event stuff
            dlyr.elm.lyrobj=dlyr.doc.lyrobj=dlyr;
            if(is.ns4) {
                for (var j in dlyr.doc.images) dlyr.doc.images[j].lyrobj=dlyr; 
                for (j=0;j<dlyr.doc.links.length;j++) dlyr.doc.links[j].lyrobj=dlyr;
            }
            // DynObject.all[dlyr.id]=dlyr;
            // JM: Constructors take care of this
            this.children[this.children.length]=dlyr;
            dlyr.updateValues();
            dlyr.findLayers();
        }
    }
};
DynLayer.prototype.updateValues=function() {
    if (is.def) {
        this.x=this.elm.offsetLeft;
        this.y=this.elm.offsetTop;
        this.w=is.ie4? this.css.pixelWidth||this.getContentWidth() : this.elm.offsetWidth;
        this.h=is.ie4? this.css.pixelHeight||this.getContentHeight() : this.elm.offsetHeight;
        this.bgImage = this.css.backgroundImage;
        this.bgColor = this.css.backgroundColor;
        this.html = this.innerHTML = this.elm.innerHTML;
    }
    else if (is.ns4) {
        this.x=parseInt(this.css.left);
        this.y=parseInt(this.css.top);
        this.w=this.css.clip.width;
        this.h=this.css.clip.height;
        this.clip=[this.css.clip.top,this.css.clip.right,this.css.clip.bottom,this.css.clip.left];
        this.bgColor=this.doc.bgColor!="this.doc.bgColor"?this.doc.bgColor:null;
        this.bgImage=this.elm.background.src!=""?this.elm.background.src:null;
        this.html=this.innerHTML = this.elm.innerHTML = "";
    }
    this.z=this.css.zIndex;
    var b=this.css.visibility;
    this.visible=(b=="inherit"||b=="show"||b=="visible"||b=="");
};
Methods.isDirectChildOf = function(l, parent) {
    if(is.def&&!is.ie) {
        for(var p=l.parentNode;p;p=p.parentNode) if(p.nodeName.toLowerCase()=='div') return p==parent;
        return !parent.nodeName;
    }
    else if (is.ie) {
        for(var p=l.parentElement;p;p=p.parentElement) if(p.tagName.toLowerCase()=='div') return p==parent;
        return !parent.tagName;
    }
    else if(is.ns4) return (l.parentLayer == parent);
};
/* Place Initialization code */
DynDocument.prototype._OldI_specificCreate = DynDocument.prototype.specificCreate
DynDocument.prototype.specificCreate = function() {
    this._OldI_specificCreate()
    this.findLayers()
}


/*
   DynAPI Distribution
   Layer Extensions

   The DynAPI Distribution is distributed under the terms of the GNU LGPL license.

   Requirements:
    dynapi.api [dynlayer, dyndocument, browser]
*/ 
DynLayer.prototype.setMaxSize=function(p,noevt) {
    if (!this.created && !p) return;
    var w=h=0;
    if (this.created) {
        w=(is.ns?this.doc.width:parseInt(this.elm.scrollWidth));
        h=(is.ns?this.doc.height:parseInt(this.elm.scrollHeight));
    }
    if (typeof(p)=='object') {
        w=(w>p.w?w:p.w);
        h=(h>p.h?h:p.h);
    } else if (typeof(p)=='boolean') noevt=p;
    this.setSize(w,h,noevt);
};
DynLayer.prototype.setPadding=function(p) {
    this.pad=p;
    if (this.created) {
        if (is.ie || is.ns6) this.elm.style.padding=p;
        else if (is.ns4) this.elm.padding=p;
    }
};
DynLayer.prototype.getPadding=function() { 
    return this.pad;
};
DynLayer.prototype.getTopZIndex=function() {
    if(!this.origZIndex||typeof(this.origZIndex)!="number") this.origZIndex=this.getZIndex();
    var n=1,child,z;
    for (var i in this.parent.children) {
        child=this.parent.children[i];
        z=child.getZIndex();
        if (n<=z) n=z+5;
    }
    return n;
};



/*
   DynAPI Distribution
   Thread Class

   The DynAPI Distribution is distributed under the terms of the GNU LGPL license.

   Requirements:
    dynapi.api [dynlayer, dyndocument, browser, events]
*/
function Thread(dlyr) {
    // Inherit from object. Provides unique ID
    this.DynObject = DynObject
    this.DynObject()
    
    this.setDynLayer(dlyr);
}
Thread.prototype = new DynObject
Thread.prototype.active = false;
Thread.prototype.interval = 50;
Thread.prototype.cancelThread = false;
Thread.prototype.sleep = function (ms) {
    this.interval = Math.abs(parseInt(ms));
    if (this.active) {
        this.stop();
        setTimeout(this+'.start()',this.interval+1);
    }
};
Thread.prototype.setFPS = function (fps) {
    this.sleep(Math.floor(1000/fps));
};
Thread.prototype.cancel = function () {
    this.cancelThread = true;
    this.stop();
};
Thread.prototype.start = function () {
    if (!this.active) {
        this.active = true;
        if (!this.cancelThread) this.timer = setInterval(this+'.run()',this.interval);
    }
};
Thread.prototype.run = function () {}; // overwrite run
Thread.prototype.stop = function () {
    this.active = false;
    if (!this.cancelThread && this.timer) {
        clearInterval(this.timer);
        delete this.timer;
    }
};
Thread.prototype.setDynLayer = function (dlyr) {
    this.dlyr = dlyr;
};
Thread.prototype.getDynLayer = function () {
    return this.dlyr;
};


/*
   DynAPI Distribution
   DynImage Class

   The DynAPI Distribution is distributed under the terms of the GNU LGPL license.

   Requirements:
    dynapi.api [dynlayer, dyndocument, browser, events]
*/
function DynImage() {
    this.DynLayer = DynLayer;
    this.DynLayer();

    if (typeof(arguments[0])=="string") this.setImageSrc(arguments[0]);
    else if (typeof(arguments[0])=="object") this.setImage(arguments[0]);
    else this.img = null;
    if (this.img && this.img.dynimages) {
        this.img.dynimages[this.img.dynimages.length]=this;
          this.imgresize=true;
    }
    this.addEventListener(DynImage.listener);
};

DynImage.prototype = new DynLayer;

DynImage.listener = new EventListener();

DynImage.listener.onprecreate = function(e) {
    var o = e.getSource();
    if (o.w!=null && o.h!=null) {
        o.setImage(o.img,true);
    }
};

DynImage.listener.onresize = function (e) {
    var o = e.getSource();
    if (o.created) {
        if (o.img) {
            o.setImage(o.img,true);
        }
    }
};

// this is an optional method that only effects the behaviour on subsequent image changes.
// During the first creation of DynImage if no w/h is set it will automatically resize
// during creation regardless of whether this value is set or not (that is a function of the DynLayer).
// If you setAutoResize(true) when you change images after creation it will resize itself again.
DynImage.prototype.setAutoResize = function (b) {
    this.autoResize = b;
    if (this.created) this.setImage(this.img);
};

DynImage.prototype.setImage = function (imgObject,bRedraw) {
    if (!imgObject) {
        return;
    }
    this.img = imgObject;

    if (this.created && this.autoResize && !bRedraw) {
        if (this.img.width!=this.w && this.img.height!=this.h) {
            this.setNoFlickerSize(this.img.width, this.img.height, false);
            bRedraw = true;
        }
    }

    if (!this.created || bRedraw) {
        var wh = ((this.w!=null && this.h!=null)) ? ' width='+this.w+' height='+this.h : '';
        this.setHTML('<img name="'+this.id+'Image" src="'+imgObject.src+'"'+wh+' border=0>');
    }
    else if (this.created) {
        this.doc.images[this.id+'Image'].src = this.img.src;
    }
};
DynImage.prototype.getImage = function (imgObject) {
    return this.img;
};
DynImage.prototype.setImageSrc = function (imgsrc) {
    if (imgsrc) {
        this.setImage(DynImage.getImage(imgsrc));
    }
};
DynImage.prototype.getImageSrc = function () {
    return this.img? this.img.src : null;
};

// Functions

DynImage.loadimages=[];
DynImage.getImage=function(src,w,h) {
    for (var i=0;i<DynImage.loadimages.length;i++) {
        if (DynImage.loadimages[i].img.origsrc==src || DynImage.loadimages[i].img.src==src)
            return DynImage.loadimages[i].img;
    }
    DynImage.loadimages[i] = {};
    if (w&&h) DynImage.loadimages[i].img = new Image(w,h);
    else DynImage.loadimages[i].img = new Image();
    DynImage.loadimages[i].img.name = src;
    var stamp = new Date();
    DynImage.loadimages[i].img.src=DynImage.loadimages[i].img.origsrc=src;
    DynImage.loadimages[i].img.dynimages=[];
    if (DynAPI.loaded && !DynImage.timerId) DynImage.loaderStart();
    return DynImage.loadimages[i].img;
};
DynImage.loaderStart=function() {
    DynImage.timerId=setTimeout('DynImage.loadercheck()',50);
    if (DynImage.onLoaderStart) DynImage.onLoaderStart();
};
DynImage.loadercheck=function() {
    DynImage.ItemsDone=0;
    var max=DynImage.loadimages.length;
    for (var i=0; i<max; i++) if (DynImage.loadimages[i].img.complete){ 
        var stamp = new Date();
        DynImage.ItemsDone+=1;
    } 
    if (DynImage.ItemsDone<max) {
        if (DynImage.onLoading) DynImage.onLoading();
        DynImage.timerId=setTimeout('DynImage.loadercheck()',25);
    }
    else {
    for (var i=0; i<DynImage.loadimages.length; i++) {
            if (DynImage.loadimages[i].img.dynimages) {
            var dlen=DynImage.loadimages[i].img.dynimages.length;
                  for (var j=dlen-1;j>=0;j--){
                        if (DynImage.loadimages[i].img.dynimages[j].imgresize) {
                            DynImage.loadimages[i].img.dynimages[j].setNoFlickerSize(DynImage.loadimages[i].img.width,DynImage.loadimages[i].img.height,false);
                            DynImage.loadimages[i].img.dynimages[j].imgresize=false;
                            DynImage.loadimages[i].img.dynimages[j]=null;
                        }
                      }
                  DynImage.loadimages[i].img.dynimages=null;
            }
        }
        if (DynImage.onLoaderDone) DynImage.onLoaderDone();
        DynImage.timerId=null;
    }
};
DynAPI.addLoadFunction("DynImage.loaderStart()")




/*
   DynAPI Distribution
   Debug Extensions

   The DynAPI Distribution is distributed under the terms of the GNU LGPL license.

   Requirements:
    dynapi.api [dynlayer, dyndocument, browser]
*/ 
DynLayer.prototype.debug = function() {
    var str ="";
    str += "DynLayer: "+this.id+"\n";
    str += "-----------------------\n";
    str += "     Size: "+this.getWidth()+"x"+this.getHeight()+"\n";
    str += " Position: "+this.getX()+","+this.getY()+"\n";
    str += "  BgImage: "+this.getBgImage()+"\n";
    str += "  BgColor: "+this.getBgColor()+"\n";
    str += "  Content: "+this.getHTML()+"\n";
    str += "   zIndex: "+this.getZIndex()+"\n";
    str += "  Visible: "+this.getVisible()+"\n";
    str += "----- Number of Children: "+this.children.length+"\n";
    return str;
}
DynObject.prototype.tree = function(space) {
    var ret ='';
    space = space||".";
    ret += space +" "+this.getDef()+"\n"
    for(i in this.children)
        ret += this.children[i].tree(space+" . ."); // JM: With simple spaces NS6 does not indent (pfff !!!)
    return ret;
}
DynAPIObject.prototype.getDef=function(){return "DynAPI"}
DynDocument.prototype.getDef=function(){return "DynDocument ( "+this.id+" )"}
DynLayer.prototype.getDef=function(){return this.id}



/*
   DynAPI Distribution
   Console Debugging Utility

   The DynAPI Distribution is distributed under the terms of the GNU LGPL license.

   Requirements:
    none
*/

DynAPI.console={
    enabled : true,

    open : function() {
        if (!DynAPI.console.enabled) return;
        DynAPI.console.consolewin=window.open('','DynAPIConsoleWindow','resizable=1,scrollbars=1');
        DynAPI.console.consolewin.document.open('text/plain');
    },
    write : function(msg) {
        if (!DynAPI.console.enabled) return;
        if (!DynAPI.console.consolewin || DynAPI.console.consolewin.closed) DynAPI.console.open();
        if (is.ns6 || (is.platform=="mac" && is.ie)) {
            msg = msg.toString();
            msg = msg.replace(/</g,'&lt;');
            msg = msg.replace(/>/g,'&gt;');
            msg = msg.replace(/\n/g,'<br/>\n');
            msg += '<br/>\n';
        }
        DynAPI.console.consolewin.document.writeln(msg);
        if (is.ie) DynAPI.console.consolewin.scrollTo(0, document.body.scrollHeight);
    },
    close : function() {
        if (DynAPI.console.consolewin) DynAPI.console.consolewin.close();
    },
    enable : function() {
        DynAPI.console.enabled=true;
    },
    disable : function() {
        DynAPI.console.enabled=false;
    },
    clear : function() {
        DynAPI.console.consolewin.document.open('text/plain');
    },
    dumpProperties : function(obj,hidemethods) {
        DynAPI.console.write('\nObject Properties\n-----------------')
        var s=[];
        for (var i in obj) {
            var l=s.length;
            if (typeof obj[i]=='function') {
                if (!hidemethods) s[l]=i+' = [method]';
                else continue;
            }
            else if (typeof obj[i]=='object') s[l]=i+' = '+obj[i];
            else s[l]=i+' ('+(typeof obj[i])+')'+' = '+obj[i];
        };
        s.sort();
        DynAPI.console.write(s.join('\n'));
    }
};






/*
   START of Amazoom Internal Zoom Viewer code
*/

/* 
  Amazoom Internal Class: MediaServicesZoomScale
*/

function MediaServicesZoomScale(width, height, tilesize){
     this.width = width;
     this.height = height;
         this.tilesize = tilesize;
}

/*
  Amazoom Internal Class: MediaServicesZoomImage
*/

MediaServicesZoomImage.prototype = new DynLayer;

//CONSTANTS
MediaServicesZoomImage.prototype.BG_COLOR = "#fff";
MediaServicesZoomImage.prototype.ZINDEX = 0; //tiles = ZINDEX+1 ; background = ZINDEX, drag must be > ZINDEX
MediaServicesZoomImage.prototype.TILE_DIM =256;
MediaServicesZoomImage.prototype.BLANK_TILE = DynImage.getImage("http://images.amazon.com/images/G/01/richmedia/images/blank.png");
MediaServicesZoomImage.prototype.PARALLEL_DOWNLOAD_SLOTS = 1;

/**
 * @requires urlStem != undefined
 * @requires width > 0 && height > 0
 * @requries {width,height,majorWidth,majorHeight} in integers
 * @modifies this.scale,this.centerX,this.centerY,this.width,this.height,this.majorWidth,this.majorHeight
 * @effects this.centerX = this.majorWidth/2
 * @effects this.centerY = this.majorHeight/2
 * @effects this.scale = n for the greatest n: this.majorWidth/n <= width && this.majorHeight/2 <= height 
 */
function MediaServicesZoomImage(urlStem,width,height,majorWidth,majorHeight,version,viewerType,scaleLevels){
    this.DynLayer = DynLayer;
    this.DynLayer(null,0,0,width,height,this.BG_COLOR);
    
        this.version = version;

    this.urlStem = urlStem;
    this.viewerType = viewerType;

    // Convert urlStem to new format if amztile image for backwards compatibility
    if(this.viewerType == "amztile") {
      //Parse out VIP, ASIN, OU, CustomerID, Variant
        
        // UrlStem will look like:
        // http://z2-ec2.images-amazon.com/images/R/B000EY5ETE.01-AS22343KD.
          //or http://z2-ec2.images-amazon.com/images/R/B000EY5ETE.01.
          //or http://z2-ec2.images-amazon.com/images/R/B000EY5ETE.01-AS22343KD.PT01
      
      var text = this.urlStem.split("/");

      this.vip = text[2];

      imageName = text[text.length-1];

      var item = imageName.split(".");

      this.asin = item[0];

      var ouDashCustID = item[1];

      var ouItem = ouDashCustID.split("-");
 
      this.ou = ouItem[0]; 
      this.customerID = ouItem[1];

      this.variant = item[2];

      if(!this.variant) {
        this.variant = "MAIN";
      }

      this.size = "RMTILE";  // Hardcoded to RMTILE for amztile images
      this.ext = ".jpg";     // Hardcoded to .jpg for amztile images
    }    

    if(this.viewerType == "amztile" && scaleLevels != undefined) {
        this.maxScaleLevel = scaleLevels.length - 1;
        this.scaleLevel = 0;     //Always start at scale level 0
        MediaServicesZoomImage.prototype.TILE_DIM = scaleLevels[this.maxScaleLevel].tilesize;
        this.scaleLevels = scaleLevels;
    }
    
    this.tileWidth = this.TILE_DIM;
    this.tileHeight = this.TILE_DIM;
    
    this.width = width;
    this.height = height;
    
    this.majorWidth = majorWidth;
    this.majorHeight = majorHeight;
    
    var xscale = majorWidth/width;
    var yscale = majorHeight/height;
    
    var resize;
    
    if(xscale > yscale){
        this.scale = xscale;
        
    } else{
        this.scale = yscale;
    }    
    
    this.primeScale = this.scale;    

    this.centerX = this.majorWidth/2.0;
    this.centerY = this.majorHeight/2.0;
    
    //Create the low resolution background
    this.macroLayer = new DynLayer(null,0,0,width,height,this.BG_COLOR);
    
    this.layer = new DynLayer(null,0,0,width,height,this.BG_COLOR);

    if(this.viewerType == "amztile") {
// Removed because this was causing flickering errors in IE
//      this.background = new DynImage(DynImage.getImage(this._getAmzTileImageUrl(0,0,0,this.majorWidth/this.scale)));
//      this.background2 = new DynImage(DynImage.getImage(this._getAmzTileImageUrl(0,0,0,this.majorWidth/this.scale)));

      this.background = new DynImage(DynImage.getImage(this._getImageUrl(undefined,undefined,this.majorWidth/this.scale)));
      this.background2 = new DynImage(DynImage.getImage(this._getImageUrl(undefined,undefined,this.majorWidth/this.scale)));
    } else {
      this.background = new DynImage(DynImage.getImage(this._getImageUrl(undefined,undefined,this.majorWidth/this.scale)));
      this.background2 = new DynImage(DynImage.getImage(this._getImageUrl(undefined,undefined,this.majorWidth/this.scale)));
    }

    this.background.setZIndex(this.ZINDEX);
    this.background2.setZIndex(this.ZINDEX);
    this.layer.setZIndex(0);
    
    this.layer.addChild(this.background);
    this.layer.addChild(this.background2);
    this.macroLayer.addChild(this.layer);
    this.addChild(this.macroLayer);

    this.resetBackground = 1;
    this._rescale();    

    //Initializing tiles - Change this code to 
    var tileCount = Math.ceil((this.width/this.tileWidth+1))*Math.ceil(this.height/this.tileHeight+1); //total number of tiles
    this.tilePool = new Array();
    
    //initialize tiles
    for(i = 0; i < tileCount; i++){
        var tile = new DynLayer(null,0,0,this.tileWidth,this.tileHeight);
        var image = new DynImage(this.BLANK_TILE);
        
        //tile.setWidth(this.tileWidth);
        //tile.setHeight(this.tileHeight);
        tile.image = image;
        tile.image.setAutoResize(true);
        tile.addChild(image);
        tile.setZIndex(this.ZINDEX+2);
        tile.r = tile.c = tile.scale = -1;
        this.layer.addChild(tile);
        this.tilePool.push(tile);
        tile.setVisible(true);
    }
    
    this.imageCache = new Array();
    this.imageQueue = new Array();
    this.activeTiles = new Array();
    
    this.setZIndex(this.ZINDEX);
    
    //Update thread for asynchronously handling repaint requests
    this.wasPainting = false;
    this.thread = new Thread(this);
    this.thread.run = this._repaintCheck;
    this.thread.start();
    
}


/**
 * @requires {x,y} in real numbers
 * @modifies this.centerX, this.centerY
 * @effects this.centerX 
 * @effects this.centerY 
 */    
MediaServicesZoomImage.prototype.moveRelative=function(x,y){
    x += this.centerX;
    y += this.centerY;
    
    this.moveAbsolute(x,y);
}


/**
 * @requires {x,y} in real numbers
 * @modifies this.centerX, this.centerY
 * @effects this.centerX
 * @effects this.centerY
 */    
MediaServicesZoomImage.prototype.moveAbsolute=function(x,y){
    pt = new Pair(x,y);
        //this.stopRepaint();
    this._restrictToBoundary(pt);
    this.centerX = pt.x;
    this.centerY = pt.y;
    
    this.layer.moveTo(
        -1*(this.centerX - this.wRadius*this.scale)/this.scale,
        -1*(this.centerY - this.hRadius*this.scale)/this.scale);
    
}


function Pair(x,y){
    this.x = x;
    this.y = y;
}


/**
 * @modifies this.scale,this.centerX,this.centerY
 * @effects this.scale = n for n in integers closest to scale: scale > 0 && scale < this.primeScale
 * @effects this.centerX = x for x closest to \old{this.centerX}: x > this.xBorder && x < (this.majorWidth - this.xBorder)
 * @effects this.centerY = y for y closest to \old{this.centerY}: y > this.yBorder && y < (this.majorHeight - this.yBorder)
 */
MediaServicesZoomImage.prototype.setScale = function(scale,anim){
    if(scale < 1) scale = 1;
    if(scale > this.primeScale) scale = this.primeScale
    
    if(anim == undefined || anim == 0) {

      if(scale == this.scale) {
          setZoomButtons();
        return;
      }

      this.scale = scale;
      this.next_scale = scale;
      this._hideTiles();
      this._rescale();
      this.moveAbsolute(this.centerX,this.centerY);
      setZoomButtons();
        } else {

      if(scale == this.scale) return;
      this.scale = scale;
      this.next_scale = scale;
      this._hideTiles();
      this._rescale();
    }
}

MediaServicesZoomImage.prototype.setScaleAndMove = function(scale,next_scale,anim,x,y){
    if(scale < 1) scale = 1;
    if(scale > this.primeScale) scale = this.primeScale;
    
    if(next_scale < 1) next_scale = 1;
    if(next_scale > this.primeScale) next_scale = this.primeScale;

    if(anim == undefined || anim == 0) {

      if(scale == this.scale) {
          setZoomButtons();
        return;
      }

      this.scale = scale;
      this.next_scale = scale;
//////!      this._hideTiles();
      this._rescale();
      this.moveAbsolute(this.centerX,this.centerY);
      setZoomButtons();
        } else {

///      if(scale == this.scale) return;  //larpente: removing to enable click navigation

      this.scale = scale;
      this.next_scale = next_scale;
//////!      this._hideTiles();
      this._rescaleAndMove(x,y);
    }
}

MediaServicesZoomImage.prototype.repaint = function(){
    
    if(this.wasPainting)
        this.stopRepaint();
    else
        this.wasPainting = true;

    if(this.scale == this.primeScale){
        this.wasPainting = false;
        return;
    }
    
    
    var R_0 = Math.floor((this.centerY - this.hRadius*this.scale)/(this.tileHeight*this.scale));
    var R_M = Math.floor((this.centerY + this.hRadius*this.scale)/(this.tileHeight*this.scale));
    var C_0 = Math.floor((this.centerX - this.wRadius*this.scale)/(this.tileWidth*this.scale));
    var C_N = Math.floor((this.centerX + this.wRadius*this.scale)/(this.tileWidth*this.scale));
    
    //for each column
    k=0;
    for(i = C_0; i <= C_N; i++){
        
        //for each row
        for(j = R_0; j<= R_M; j++){ 
            var tile = this.tilePool[k++];
            this._populateTile(tile,j,i,this.viewerType, this.scaleLevel);
            this.imageQueue.push(tile);
            
        }
    }
}

MediaServicesZoomImage.prototype._populateTile = function(tile,r,c,viewerType,scaleLevel){
            tile.r = r;
            tile.c = c;
            tile.scale = this.scale;
            
            tile.image.setImage(this.BLANK_TILE,true);

            tile.moveTo(i*this.tileWidth,j*this.tileHeight);
            
            crop_tl = new Pair(i*this.tileWidth*this.scale,
                       j*this.tileHeight*this.scale);
            
            
            crop_dim = new Pair(this.tileWidth*this.scale,
                            this.tileHeight*this.scale);
            
            if(crop_tl.x + crop_dim.x > this.majorWidth){
                crop_dim.x = this.majorWidth - crop_tl.x;
            }
            
            if(crop_tl.y + crop_dim.y > this.majorHeight){
                crop_dim.y = this.majorHeight - crop_tl.y;
            }

            if(viewerType == "amztile") {
                tile.src = this._getAmzTileImageUrl(this.scaleLevel,tile.c,tile.r);
            } else {
                tile.src = this._getImageUrl(crop_tl,crop_dim,crop_dim.x/this.scale);
            }                
}

MediaServicesZoomImage.prototype.stopRepaint = function(){
    //this.imageQueue.splice(0,this.imageQueue.length);
    this.imageQueue = new Array();
    this.activeTiles = new Array();
    
}


//PRIVATE FUNCTIONS

MediaServicesZoomImage.prototype._repaintCheck = function(){
    var view = this.dlyr;
    
    if(view.wasPainting){
        //if there is an active image
        var open = view.PARALLEL_DOWNLOAD_SLOTS;
        
        for(i = 0; i < view.activeTiles.length;){
            tile = view.activeTiles[i];
            if(tile != null && !tile.img.complete){
                open--;
                i++;
            }else{
                if(tile != null){
                        // Using setNoFlickerSize causes errors here in Mozilla 
                        tile.image.setSize(tile.img.width,tile.img.height);
                    tile.image.setImage(tile.img);
                }
                view.activeTiles.splice(i,1);
            }
        }
        
        if(open < 1) return;
            
        //end if there's no work to be done
        if(view.imageQueue.length == 0){
            this.wasPainting = false;
            return;
        } 
        for(i = 0; i < open && view.imageQueue.length > 0; i++){
        
            //var tile = view.imageQueue.shift();    
            var idx = Math.floor(view.imageQueue.length*Math.random());
            var tile = view.imageQueue[idx];
            
            if(tile != undefined){
                view.imageQueue.splice(idx,1);
                //otherwise, pull the first item of the queue into the active slot
                tile.img =  DynImage.getImage(tile.src)
                view.activeTiles.push(tile);
            }
        }
    } 
        
}

MediaServicesZoomImage.prototype._hideTiles = function(){
    for(i = 0; i < this.tilePool.length; i++){
        this.tilePool[i].image.setImage(MediaServicesZoomImage.BLANK_TILE,true);
        this.tilePool[i].moveTo(-1*this.tileWidth,0);
    }
}


// Updates precalculated constants
MediaServicesZoomImage.prototype._rescale = function(){
    this._rescaleAndMove();
}

// Updates precalculated constants
MediaServicesZoomImage.prototype._rescaleAndMove = function(x,y){

    if(this.flipBackground == undefined || this.flipBackground == 0) {
      this.flipBackground = 1;
    } else {
      this.flipBackground = 0;
        }

    if(this.majorWidth/this.scale < this.width){
        this.macroLayer.moveTo((this.width - this.majorWidth/this.scale)/2.0,this.macroLayer.y);
    } else
        this.macroLayer.moveTo(0,this.macroLayer.y);
    
    if(this.majorHeight/this.scale < this.height){
        this.macroLayer.moveTo(this.macroLayer.x,(this.majorHeight/this.scale - this.height)/-2.0);
    } else
        this.macroLayer.moveTo(this.macroLayer.x,0);

    this.layer.setNoFlickerSize(this.majorWidth/this.scale,this.majorHeight/this.scale);

    if(this.next_scale == undefined) {
      this.next_scale = this.scale;
    }    

    var imgWidth = this.majorWidth/this.next_scale;
    var imgHeight = this.majorHeight/this.next_scale;

    if(this.flipBackground) {
      this.background2.setZIndex(this.ZINDEX+1);

      this.background.setZIndex(this.ZINDEX);
      this.background.setNoFlickerSize(imgWidth,imgHeight);
    } else {
      this.background.setZIndex(this.ZINDEX+1);

      this.background2.setZIndex(this.ZINDEX);
      this.background2.setNoFlickerSize(imgWidth,imgHeight);
    }

    if(this.resetBackground) {
      this.resetBackground = 0;
      this.background.setNoFlickerSize(imgWidth,imgHeight);
      this.background2.setNoFlickerSize(imgWidth,imgHeight);
    }

    this.wRadius = this.width/2.0 - this.macroLayer.x;
    this.hRadius = this.height/2.0 - this.macroLayer.y;
    
    this.xBorder = Math.ceil(this.scale*this.wRadius);
    this.yBorder = Math.ceil(this.scale*this.hRadius); 

    if(x != undefined && y != undefined) {
      pt = new Pair(x,y);
      this._restrictToBoundary(pt);
      this.centerX = pt.x;
      this.centerY = pt.y;    

      var newLayerXPos = -1*(this.centerX - this.wRadius*this.scale)/this.scale;
      var newLayerYPos = -1*(this.centerY - this.hRadius*this.scale)/this.scale;

      newLayerXPos = Math.round(newLayerXPos);
      newLayerYPos = Math.round(newLayerYPos);

      this.layer.moveTo(newLayerXPos,newLayerYPos);
    }

}


//@modifies p
MediaServicesZoomImage.prototype._restrictToBoundary = function(p){
    if(p.x < this.xBorder) p.x = this.xBorder;
    if(p.x >= this.majorWidth - this.xBorder)  p.x = this.majorWidth - this.xBorder;
    
    if(p.y < this.yBorder) p.y = this.yBorder;
    if(p.y >= this.majorHeight - this.yBorder)  p.y = this.majorHeight - this.yBorder;
}

MediaServicesZoomImage.prototype._getAmzTileImageUrl=function(scale, col, row, resize){
    var dyn_rend_tag = "";
    
    if(resize != undefined) {
        dyn_rend_tag += "_SCR("+scale+","+col+","+row+","+resize+")_";
    } else {
        dyn_rend_tag += "_SCR("+scale+","+col+","+row+")_";
    }    
    
        var keySep = "=";
        var pairSep = "+";

        var url = "http://" + this.vip + "/R/1/a" + keySep + this.asin;

        if(this.customerID) {
                url += pairSep + "c" + keySep + this.customerID;
        }

        url += pairSep + "d" + keySep + dyn_rend_tag + pairSep + "o" + keySep + this.ou + pairSep + "s" + keySep + this.size + pairSep + "va" + keySep + this.variant + pairSep + "ve" + keySep + this.version + pairSep + "e" + keySep + this.ext;

    return url;
}

MediaServicesZoomImage.prototype._getImageUrl=function(crop_tl, crop_dim,resize_width, quality){
    var param = "";
    
    if(crop_tl != undefined && crop_dim != undefined) {
                param += "_CR"+Math.round(crop_tl.x)+","+Math.round(crop_tl.y)+","+Math.round(crop_dim.x)+","+Math.round(crop_dim.y);
    }
    
    if(resize_width != undefined){
            param += "_SX"+Math.round(resize_width);
    }
    
    if(quality != undefined){
        param += "_FMgif_BD"+quality;
    }
    

        var url;

        if(this.asin) {
          url = "http://" + this.vip + "/images/P/" + this.asin + "." + this.ou;

          if(this.customerID) {
            url += "-" + this.customerID;
          }

          url += ".";

          if(!(this.variant === "MAIN" || this.variant === "")) {
            url += this.variant + ".";
          }
        } else {
          url = this.urlStem;
        }

        if(param) {
                url += param;
        }

    // If this is a AmzTile type
        if(this.asin) {
            url += "_SCLZZZZZZZ_";
    } else {
            url += "_SCRMZZZZZZ_";
    }   

        if(this.version) {
                url += "V" + this.version + "_";
        }

        url += ".jpg";

    return url;
}


/*
  Amazoom Internal Class: MediaServicesZoomMotion
*/


MediaServicesZoomMotion.prototype = new Thread;

function MediaServicesZoomMotion(target,interval){
    this.Thread = Thread;
    this.Thread(target);

    this.target = target;
    this.interval = interval;

    this.v_x = 0;
    this.v_y = 0;

    this.scrolling = 0;
}

MediaServicesZoomMotion.prototype.setVelocity = function(x,y){
    if(x != undefined)
        this.v_x = x;

    if(y != undefined)
        this.v_y = y;
}

MediaServicesZoomMotion.prototype.scrollTo = function(x,y,scale,image,scaleLevel){

    // If any argument required argument is undefined or if we are already
    // scrolling, return immediatly
    if(x == undefined || 
       y == undefined || 
       scale == undefined ||
       image == undefined ||
       this.scrolling == 1) {
      return;
    }                       
    
    if(image.viewerType == "amztile") {
        image.scaleLevel = scaleLevel;
    }

    this.scroll_to_x = x;
    this.scroll_to_y = y;
    this.scroll_to_scale = scale;
    this.scroll_image = image;

    this.scroll_orig_x = image.centerX;
    this.scroll_orig_y = image.centerY;
    this.scroll_orig_scale = image.scale;

    this.scroll_counter = 0;

        if(Math.abs(this.scroll_to_x - this.scroll_orig_x) > 1 ||
           Math.abs(this.scroll_to_y - this.scroll_orig_y) > 1 ||
           this.scroll_to_scale != this.scroll_orig_scale) {
           this.scrolling = 1;
        }
}

MediaServicesZoomMotion.prototype.run = function(){
    var ANIM_FRAME_COUNT = 30.0;
    var view = this.dlyr;

        if(this.scrolling) {

      var event = new DynEvent();

      var x_pos = this.scroll_orig_x;
      var y_pos = this.scroll_orig_y;
      var scale_pos = this.scroll_orig_scale;

      var x_dif = (this.scroll_to_x - x_pos);
      var y_dif = (this.scroll_to_y - y_pos);

      var scale_dif = (this.scroll_to_scale - scale_pos);
      var next_scale_dif = (this.scroll_to_scale - scale_pos);

      var mult = this.scroll_counter / ANIM_FRAME_COUNT;
      var multplusone = (this.scroll_counter+1) / ANIM_FRAME_COUNT;

      x_dif *= mult;
      y_dif *= mult;
      scale_dif *= mult;
      if(this.scroll_counter+1 <= ANIM_FRAME_COUNT) {
        next_scale_dif *= multplusone;
      } else {
        next_scale_dif = scale_dif;
      }

      event.x = x_pos + x_dif;
      event.y = y_pos + y_dif;
      event.scale = scale_pos + scale_dif;
      event.anim = 1;      
      event.next_scale = scale_pos + next_scale_dif;

      // If this is the first frame in the animation
      if(this.scroll_counter == 0) {
        var width = this.scroll_image.majorWidth/event.scale;
        var height = this.scroll_image.majorHeight/event.scale;
        this.scroll_image.background.setNoFlickerSize(width,height);
        this.scroll_image.background2.setNoFlickerSize(width,height);
          this.scroll_image._hideTiles();
      }

      view.invokeEvent("setscaleandmove",event);
      this.scroll_counter++;

      if(this.scroll_counter > ANIM_FRAME_COUNT) 
      {
        this.scrolling = 0;
        event.x = this.scroll_to_x;
        event.y = this.scroll_to_y;
        event.scale = this.scroll_to_scale;        
        event.next_scale = this.scroll_to_scale;        
        event.anim = 0;

        view.invokeEvent("setscaleandmove",event);
        view.invokeEvent("repaint");
      }
    }
}


/*
  Amazoom Internal Class: MediaServicesZoomView
*/

MediaServicesZoomView.prototype = new DynLayer;

MediaServicesZoomView.prototype.BG_COLOR = "#ddd";
MediaServicesZoomView.prototype.GUIDE_BUTTONS = false;
MediaServicesZoomView.prototype.BUTTONS = true;
MediaServicesZoomView.prototype.DRAG = true;

function MediaServicesZoomView(urlStem,width,height,majorWidth,majorHeight,version,viewerType,scaleLevels){

    this.DynLayer = DynLayer;
    this.DynLayer(null,0,0,width,height,this.BG_COLOR);

    this.width = width;
    this.height = height;

    // Set zoom image
    this.setZoomImage(urlStem,majorWidth,majorHeight,version,viewerType,scaleLevels);
    
    // Event Listeners
    var eL = new EventListener(this);

    eL.onmoveabsolute=function(e){
        var view = e.getTarget();
        view.image.moveAbsolute(e.x,e.y);
    }

    eL.onmoverelative=function(e){
        var view = e.getTarget();
        view.image.moveRelative(e.x,e.y);
    }

    eL.onsetscale=function(e){
        var view = e.getTarget();
        view.image.setScale(e.scale,e.anim);
    }

    eL.onsetscaleandmove=function(e){
        var view = e.getTarget();
        view.image.setScaleAndMove(e.scale,e.next_scale,e.anim,e.x,e.y);
    }

    eL.onrepaint=function(e){
        var view = e.getTarget();
        view.image.repaint();
    }

    eL.onstoprepaint=function(e){
        var view = e.getTarget();
        view.image.stopRepaint();
    }

    eL.onsetvelocity=function(e){
        var view = e.getTarget();
        view.motion.setVelocity(e.x,e.y);
    }
    
    eL.onscrollto=function(e){ 
        var view = e.getTarget();
        view.motion.scrollTo(e.x,e.y,e.scale,e.image,e.scaleLevel);
    }

    this.addEventListener(eL);

    this.motion = new MediaServicesZoomMotion(this,20);
    this.motion.start();

    // Set zoom image again here to prevent flickering
///    this.setZoomImage(urlStem,majorWidth,majorHeight,version,viewerType,scaleLevels);
    
}

/**
 * Initialize the new zoom viewer after creating, sets up click and
 * drag events
 */
MediaServicesZoomView.prototype.initialize = function(width, height){
    this.drag= new MediaServicesZoomDrag(this,width,height);
    this.drag.setZIndex(5);
    this.addChild(this.drag);
        if(topLayerId == undefined)
        {
            topLayerId = this.DynObject.Count - 1;
        }
}

/**
 * Set a new Zoom image to view
 */
MediaServicesZoomView.prototype.setZoomImage = function(urlStem, majorWidth, majorHeight, version, viewerType, scaleLevels){

    this.invokeEvent("stoprepaint");

    this.majorWidth = majorWidth;
    this.majorHeight = majorHeight;

    if(this.motion) {
      this.motion.scrolling = 0;
    }
    
    // Remove old image if it exists
    if(this.image) {
        this.removeChild(this.image);
        this.image = null;    
    }

    this.image = new MediaServicesZoomImage(urlStem,this.width,this.height,majorWidth,majorHeight,version,viewerType,scaleLevels);

    this.addChild(this.image);

    this.invokeEvent("repaint");

//    this.image.repaint();
}

/**
 * Zoom in half-way
 */
MediaServicesZoomView.prototype.zoomIn = function(){

        if(this.image.scale > 1) {
      var event = new DynEvent();
      event.x = this.image.centerX;
      event.y = this.image.centerY;
      event.image = this.image;
      event.scale = this.image.scale/2.0;

      if(this.image.viewerType == "amztile") {
          if(this.image.scaleLevel < this.image.maxScaleLevel) {
          event.scaleLevel = this.image.scaleLevel + 1;
          } else {
              event.scaleLevel = this.image.scaleLevel;
          }
            event.scale = this.image.majorWidth / this.image.scaleLevels[event.scaleLevel].width;          
      }
      
      this.invokeEvent("scrollto",event);
        }
}

/**
 * Zoom in by Levels
 */
MediaServicesZoomView.prototype.zoomInByLevel = function(zoomInCount){
       
       if(this.image.scale > 1) {
      var event = new DynEvent();
      event.x = this.image.centerX;
      event.y = this.image.centerY;
      event.image = this.image;
      event.scale = this.image.scale/2.0;

      if(this.image.viewerType == "amztile") {
          if(this.image.scaleLevel + zoomInCount <= this.image.maxScaleLevel) {
          event.scaleLevel = this.image.scaleLevel + zoomInCount;
          } else {
              event.scaleLevel = this.image.scaleLevel;
          }
            event.scale = this.image.majorWidth / this.image.scaleLevels[event.scaleLevel].width;          
      }
      
      this.invokeEvent("scrollto",event);
        }
}

/**
 * Zoom out half-way
 */
MediaServicesZoomView.prototype.zoomOut = function(){
        if(this.image.scale < this.image.primeScale) {

      var newScale = this.image.primeScale;

      while( (newScale / 2.0) > this.image.scale) {
        newScale /= 2.0;
      }

      var event = new DynEvent();
      event.x = this.image.centerX;
      event.y = this.image.centerY;
      event.scale = newScale;
      event.image = this.image;

      if(this.image.viewerType == "amztile") {
          if(this.image.scaleLevel > 0) {
          event.scaleLevel = this.image.scaleLevel - 1;
          } else {
              event.scaleLevel = this.image.scaleLevel;
          }
          if(event.scaleLevel == 0) {
              event.scale = this.image.primeScale;
          } else {
                  event.scale = this.image.majorWidth / this.image.scaleLevels[event.scaleLevel].width;          
          }
      }

      this.invokeEvent("scrollto",event);
    }
}

/**
 * Zoom out by Levels
 */
MediaServicesZoomView.prototype.zoomOutByLevel = function(zoomOutCount){
        if(this.image.scale < this.image.primeScale) {

      var newScale = this.image.primeScale;

      while( (newScale / 2.0) > this.image.scale) {
        newScale /= 2.0;
      }

      var event = new DynEvent();
      event.x = this.image.centerX;
      event.y = this.image.centerY;
      event.scale = newScale;
      event.image = this.image;

      if(this.image.viewerType == "amztile") {
          if(this.image.scaleLevel - zoomOutCount >= 0) {
          event.scaleLevel = this.image.scaleLevel - zoomOutCount;
          } else {
              event.scaleLevel = this.image.scaleLevel;
          }
          if(event.scaleLevel == 0) {
              event.scale = this.image.primeScale;
          } else {
                  event.scale = this.image.majorWidth / this.image.scaleLevels[event.scaleLevel].width;          
          }
      }

      this.invokeEvent("scrollto",event);
    }
}

/**
 * Reset zoom viewer
 */
MediaServicesZoomView.prototype.reset = function(){
        if(this.image.scale != this.image.primeScale) {

      var event = new DynEvent();
      event.x = this.image.centerX;
      event.y = this.image.centerY;
      event.scale = this.image.primeScale;
      event.image = this.image;

      if(this.image.viewerType == "amztile") {
          event.scaleLevel = 0;
          }

      this.invokeEvent("scrollto",event);
        }
}

/**
 *  Determine whether we are at MIN, MIDDLE, or MAX zoom level
 *  Returns -1 for MIN, 0 for MIDDLE, and 1 for MAX
 */
MediaServicesZoomView.prototype.getZoomLevel = function(){
        if(this.image.scale <= 1) {
      return 1;
    } else if (this.image.scale > 1 && this.image.scale < this.image.primeScale) {
      return 0;
    } else {
      return -1;
    }
}

/**
 * Hide Viewer
 */

MediaServicesZoomView.prototype.hide = function(){
    this.setVisible(0);
    this.setNoFlickerSize(0,0);
}

/**
 * Show Viewer
 */
MediaServicesZoomView.prototype.show = function(){
    this.setVisible(1);
    this.setNoFlickerSize(this.width,this.height);
}


//@modifies p
MediaServicesZoomView.prototype._screenToMajor = function(p){
    p.x = this.image.centerX - this.image.scale*(this.image.wRadius - p.x);
    p.y = this.image.centerY - this.image.scale*(this.image.hRadius - p.y);
}

/**
 * Media Services Zoom Drag
 */

MediaServicesZoomDrag.prototype = new DynImage;

MediaServicesZoomDrag.prototype.COVER_IMAGE = DynImage.getImage("http://images.amazon.com/images/G/01/richmedia/images/cover.gif");

function MediaServicesZoomDrag(target,width,height){
    this.DynImage = DynImage;
    this.DynImage(this.COVER_IMAGE);

    this.setNoFlickerSize(width,height);

    var dragListener = new EventListener(target);

    DragEvent.enableDragEvents(this);

    dragListener.onclick = function(e){
        var view = e.getTarget();        

        // Return if currently scrolling
        if(view.motion && view.motion.scrolling == 1) {
            return;
        }

        // Return if currently dragging
        if(this.dragging) {
            return;
        }

        //larpente: removing to enable click navigation
//              // If zoomed in all the way, do not do anything
//        if(view.image.scale <= 1) {   
//          return;
//        }

        var pair = new Pair(e.x,e.y);

        pair.x = view.image.centerX - view.image.scale*((view.width/2.0) - pair.x);
        pair.y = view.image.centerY - view.image.scale*((view.height/2.0) - pair.y);

        var event = new DynEvent();

        event.x = pair.x;
        event.y = pair.y;
        event.scale = view.image.scale/2.0;
        event.image = view.image;

            if(view.image.viewerType == "amztile") {
                if(view.image.scaleLevel < view.image.maxScaleLevel) {
                event.scaleLevel = view.image.scaleLevel + 1;
                } else {
                    event.scaleLevel = view.image.scaleLevel;
                }
                    event.scale = view.image.majorWidth / view.image.scaleLevels[event.scaleLevel].width;
            }

        view.invokeEvent("scrollto",event);        
    }
    
    dragListener.ondragmove = function(e){
        var view = e.getTarget();

        // Return if currently scrolling
        if(view.motion && view.motion.scrolling == 1) {
            return;
        }

        // Return if not dragging
        if(!this.dragging) {
          return;
        }
    
        var event = new DynEvent();
        event.x = -1*view.image.scale*(view.drag.x - this.oldX);
        event.y = -1*view.image.scale*(view.drag.y - this.oldY);

        view.invokeEvent("moverelative",event);
                    
        this.oldX = view.drag.x;
        this.oldY = view.drag.y;
    }
    
    dragListener.ondragstart = function(e){
        var view = e.getTarget();

        // Return if currently scrolling
        if(view.motion && view.motion.scrolling == 1) {
            return;
        }

        this.dragging = 1;

        view.invokeEvent("stoprepaint");
        //view.image.stopRepaint();
        this.oldX = 0;
        this.oldY = 0;
    }
    
    dragListener.ondragend = function(e){
        var view = e.getTarget();

        this.dragging = 0;

        // Return if currently scrolling
        if(view.motion && view.motion.scrolling == 1) {
            return;
        }

        view.invokeEvent("repaint");
        view.drag.moveTo(0,0);
    }
    
    this.addEventListener(dragListener);

}


MediaServicesRect.prototype = new DynImage;

MediaServicesRect.prototype.COVER_IMAGE = DynImage.getImage("http://images.amazon.com/images/G/01/richmedia/images/cover.gif");

function MediaServicesRect(x,y,w,h,color,t) {
     this.setWidth(w);
     this.setHeight(h);
     this.setX(x);
     this.setY(y);

     this.lyr1 = new DynLayer('currentRect1',0,0,w,t,color);
     this.lyr2 = new DynLayer('currentRect2',0,0,t,h,color);
     this.lyr3 = new DynLayer('currentRect3',w-t,0,t,h,color);
     this.lyr4 = new DynLayer('currentRect4',0,h-t,w,t,color);
     this.addChild( this.lyr1 );
     this.addChild( this.lyr2 );
     this.addChild( this.lyr3 );
     this.addChild( this.lyr4 );
}

MediaServicesRect.prototype.resize = function(x,y,w,h,color,t){
     this.setWidth(w);
     this.setHeight(h);
     this.setX(x);
     this.setY(y);

     this.lyr1.setX(0);
     this.lyr1.setY(0);
     this.lyr1.setWidth(w);
     this.lyr1.setHeight(t);

     this.lyr2.setX(0);
     this.lyr2.setY(0);
     this.lyr2.setWidth(t);
     this.lyr2.setHeight(h);

     this.lyr3.setX(w-t);
     this.lyr3.setY(0);
     this.lyr3.setWidth(t);
     this.lyr3.setHeight(h);

     this.lyr4.setX(0);
     this.lyr4.setY(h-t);
     this.lyr4.setWidth(w);
     this.lyr4.setHeight(t);
}
