/*
Program:
Husky Mounted Detection System (HMDS)

Source:
EOIR Technologies
PO Box 1240
Spotsylvania, VA  22553

HMDS Development Team
USA CECOM Night Vision and Electronic Sensors Directorate (NVESD)
10221 Burbeck Rd., STE 430
Fort Belvoir, VA 22060

Conditions for Use:
This software is Copyright(C) EOIR Technologies, Inc.

EOIR Technologies has all commercial interest and rights.
NVESD has full rights, title, and interest.

This software is provided "as is", without warranty by 
EOIR Technologies, Inc and NVESD. In no event shall EOIR 
Technologies, Inc. or NVESD be liable for any loss or for
any indirect, special, punitive, exemplary, incidental, or 
consequential damages arising from the use, possession, or
performance of this software.
*/

var __USE_FLASH__ = false;
var __SILVERLIGHT_SUPPORTED__ = null;
var __CANVAS_SUPPORTED__ = null;

var EOIR = EOIR ? EOIR : function()
{
	var obj = 
	{
	};
	
	return obj;
} ();

EOIR.Image = function(strElem, bUseFlash, bEnableMask, cfg, params)
{
	var img = bUseFlash ? new EOIR.Image.Flash(strElem, params) : new EOIR.Image.HTML(strElem);

	try
	{
		if(bEnableMask)
		{
			var cfg = (cfg != null) ? cfg : EOIR.Config.getCurrent();
			img.setMask(cfg.getRedMask(), cfg.getGreenMask(), cfg.getBlueMask());
		}
	}
	catch(e)
	{
	}
	
	EOIR.Image._register(strElem, img);
	return img;
}

EOIR.Image.ht = [];

EOIR.Image.get = function(strName)
{
	return EOIR.Image.ht[strName];
}

EOIR.Image._register = function(strName, img)
{
	EOIR.Image.ht[strName] = img;
}

EOIR.Image._supportsSilverlight = function()
{
	if(__SILVERLIGHT_SUPPORTED__ == null)
	{
		var isSilverlightInstalled = false;
		try
		{
			//check on IE
			try
			{
				var slControl = new ActiveXObject('AgControl.AgControl');
				if(slControl != null && slControl.IsVersionSupported("3.0.0.0"))
				{
					isSilverlightInstalled = true;
				}
			}
			catch(e)
			{
				//either not installed or not IE. Check Firefox
				if(navigator.plugins["Silverlight Plug-In"])
				{
					isSilverlightInstalled = true;
				}
			}
		}
		catch(e)
		{
			//we don't want to leak exceptions. However, you may want
			//to add exception tracking code here.
		}

		__SILVERLIGHT_SUPPORTED__ = isSilverlightInstalled;
	}

	return __SILVERLIGHT_SUPPORTED__;
}

EOIR.Image._supportsCanvas = function()
{
    if(__CANVAS_SUPPORTED__ == null)
	{
	    var cnvElem = document.createElement("canvas");
        if (!cnvElem.getContext)
        {
            __CANVAS_SUPPORTED__ = false;
        }
        else
        {
            __CANVAS_SUPPORTED__ = true;
        }
	}
	return __CANVAS_SUPPORTED__;
}

EOIR.Image.create = function(strElem, type, bEnableMask, cfg, params)
{
	var img;
	switch(type)
	{
		case "auto":
			if(EOIR.Utils.isInROCBrowser())
			{
				return EOIR.Image.create(strElem, "html", bEnableMask, cfg, params);
			}
			else
			{
			    if(EOIR.Image._supportsCanvas())
			    {
			        return EOIR.Image.create(strElem, "canvas", bEnableMask, cfg, params);
			    }
				else if(EOIR.Image._supportsSilverlight())
				{
					return EOIR.Image.create(strElem, "silverlight", bEnableMask, cfg, params);
				}
				else
				{					
					return EOIR.Image.create(strElem, "flash", bEnableMask, cfg, params);
				}
			}
			return null;

		case "html":
			img = new EOIR.Image.HTML(strElem);
			break;

		case "canvas":
			img = new EOIR.Image.Canvas(strElem);
			break;

		case "flash":
			img = new EOIR.Image.Flash(strElem, params);
			break;

		case "silverlight":
			img = new EOIR.Image.Silverlight(strElem, params);
			break;
	}

	if(img != null)
	{
		EOIR.Image._register(strElem, img);
		
		try
		{
			if(bEnableMask)
			{
				var cfg = (cfg != null) ? cfg : EOIR.Config.getCurrent();
				img.setMask(cfg.getRedMask(), cfg.getGreenMask(), cfg.getBlueMask());
			}
		}
		catch(e)
		{
		}
	}
	return img;
}

EOIR.Image.HTML = function(strElem)
{
	var m_elem = $(strElem);
	if(m_elem.tagName.toLowerCase() != "div" && m_elem.tagName.toLowerCase() != "span")
	{
		var err = new Error();
		err.message = err.description = "Error: EOIR.Image element needs to be a <div>!";
		throw err;
	}

	this.m_strElemId = strElem;
	this.m_strInteriorElemId = strElem + "ID";
	this.m_bMaintainAspect = true;
	this.m_bScale = true;
	this.m_ht = [];

	this.m_imgLoader = new Image();
	this.m_tmrLoader = null;

	var img = document.createElement("img");
	img.id = this.m_strInteriorElemId;
	img.style.filter = "progid:DXImageTransform.Microsoft.BasicImage(Enabled=false) progid:DXImageTransform.EOIR.ArithFilter(Enabled=false)";
	img.style.width = "100%";
	img.style.height = "100%";
	img.style.left = "0px";
	img.style.top = "0px";

	img.style.position = "absolute";

	//	img.style.cursor = m_elem.style.cursor;
	//	alert(m_elem.style.cursor);
	//	m_elem.style.cursor = "default";


	/*	img.style.width = "auto";
	img.style.height = "auto";
	img.style.visibility = "hidden";
	*/

	// Not doing this here. Do this in a temp Image object.
	//	YAHOO.util.Event.addListener(img, "load", this._resizeImage, this, true);

	m_elem.appendChild(img);
	//img.style.width = m_elem.style.width;
	//img.style.height = m_elem.style.height;

};

EOIR.Image.HTML.prototype.set = function(key, val)
{
	this.m_ht[key] = val;
}

EOIR.Image.HTML.prototype.get = function(key)
{
	return this.m_ht[key];
}

//EOIR.Image.HTML._resizeImage = function(img, elem, bScale)

EOIR.Image.HTML.prototype._resizeImage = function()
{
	try
	{
		var img = this.m_imgLoader;
		var elem = $(this.m_strInteriorElemId);
		var bScale = this.m_bScale;

		var nImgWidth = img.naturalWidth || img.width;
		var nImgHeight = img.naturalHeight || img.height;

		var elemParent = elem.parentNode;

		var nParentWidth = elemParent.offsetWidth;
		var nParentHeight = elemParent.offsetHeight;

		if(nParentWidth == 0 || nParentHeight == 0 || nImgWidth == 0 || nImgHeight == 0)
		{
			this.m_tmrLoader = YAHOO.lang.later(50, this, "_resizeImage");
		}
		else
		{
			var fAspectImg = nImgWidth / nImgHeight;
			var fAspectParent = nParentWidth / nParentHeight;

			var nNewImgOffsetX = 0;
			var nNewImgOffsetY = 0;
			var nNewImgWidth;
			var nNewImgHeight;

			if(!bScale)
			{
				nNewImgWidth = nImgWidth;
				nNewImgHeight = nImgHeight;

				nNewImgOffsetX = (nParentWidth - nNewImgWidth) / 2;
				nNewImgOffsetY = (nParentHeight - nNewImgHeight) / 2;

				elem.style.width = (nNewImgWidth * 100. / nParentWidth) + "%";
				elem.style.height = (nNewImgHeight * 100. / nParentHeight) + "%";
			}
			else
			{
				if(fAspectImg < fAspectParent)
				{
					// Height driven
					nNewImgHeight = nParentHeight;
					nNewImgWidth = nNewImgHeight * fAspectImg;
					nNewImgOffsetX = (nParentWidth - nNewImgWidth) / 2;

					elem.style.width = "auto";
					elem.style.height = (nNewImgHeight * 100. / nParentHeight) + "%";
				}
				else
				{
					// Width driven.
					nNewImgWidth = nParentWidth;
					nNewImgHeight = nNewImgWidth / fAspectImg;
					nNewImgOffsetY = (nParentHeight - nNewImgHeight) / 2;

					elem.style.width = (nNewImgWidth * 100. / nParentWidth) + "%";
					elem.style.height = "auto";
				}
			}

			var oBrowser = EOIR.Utils.getBrowserInfo();
			if(!(oBrowser.name == "Microsoft Internet Explorer" && oBrowser.majver <= 6))
			{
				elem.style.left = (nNewImgOffsetX * 100. / nParentWidth) + "%";
				elem.style.top = (nNewImgOffsetY * 100. / nParentHeight) + "%";
			}

			elem.style.visibility = "inherit";
		}
	}
	catch(e)
	{
		//		alert("EOIR.Image.onload error: " + e.description + "\n\n" + nImgWidth + "x" + nImgHeight + "  " + nParentWidth + "x" + nParentHeight);
	}
}

EOIR.Image.HTML.prototype.getType = function()
{
	return "html";
}

EOIR.Image.HTML.prototype.setVisible = function(bShow)
{
	$(this.m_strElemId).style.visibility = bShow ? "inherit" : "hidden";
}

EOIR.Image.HTML.prototype.addListener = function(strEvt, fn, obj)
{
	YAHOO.util.Event.addListener(this.m_strInteriorElemId, strEvt,
		function(evt, objFn)
		{
			fn(evt, this.m_strElemId, objFn);
		}, obj, this);
}

EOIR.Image.HTML.prototype.getElement = function()
{
	return $(this.m_strInteriorElemId);
}

EOIR.Image.HTML.prototype.setImageSrc = function(strSrc)
{
	// Having m_bScale == false and m_bMaintainAspect == true doesn't make sense.
	// Basically, that's the image as it is.
	if(this.m_bMaintainAspect || !this.m_bScale)
	{
		// This doesn't work properly in IE6 for some reason.
		var imgElem = $(this.m_strInteriorElemId);
		imgElem.style.visibility = "hidden";

		imgElem.style.width = imgElem.style.height = "auto";
		this.m_imgLoader.width = this.m_imgLoader.height = "auto";

		if(this.m_tmrLoader != null)
		{
			this.m_tmrLoader.cancel();
			this.m_tmrLoader = null;
		}

		if(strSrc != null)
		{
			// Remove any existing load handlers. 
			// This is needed in the case where the loader never fires (ie, if there was a problem loading the image).
			YAHOO.util.Event.removeListener(this.m_imgLoader, "load");
			
			YAHOO.util.Event.addListener(this.m_imgLoader, "load", function()
			{
				imgElem.src = strSrc;
				//			EOIR.Image.HTML._resizeImage(this.m_imgLoader, imgElem, this.m_bScale);
				this._resizeImage();
				YAHOO.util.Event.removeListener(this.m_imgLoader, "load");
			}, this, true);
		}
		
		this.m_imgLoader.src = strSrc;
	}
	else
	{
		$(this.m_strInteriorElemId).src = strSrc;
	}
}

EOIR.Image.HTML.prototype.getImageSrc = function()
{
	return $(this.m_strInteriorElemId).src;
}

EOIR.Image.HTML.prototype.setMaintainAspect = function(bMaintainAspect)
{
	this.m_bMaintainAspect = bMaintainAspect;
}

EOIR.Image.HTML.prototype.setScale = function(bScale)
{
//	this.m_bScale = bScale;
}

EOIR.Image.HTML.prototype.getInvert = function()
{
	var elem = $(this.m_strInteriorElemId);
	if(elem.filters != null)
	{
		try
		{
			return elem.filters["DXImageTransform.Microsoft.BasicImage"].invert;
		}
		catch(e)
		{
		}
	}

	return false;
}

EOIR.Image.HTML.prototype.setInvert = function(bInvert)
{
	var elem = $(this.m_strInteriorElemId);
	if(elem.filters != null)
	{
		try
		{
			elem.filters["DXImageTransform.Microsoft.BasicImage"].invert = bInvert;
			EOIR.Utils.Filter.enableFilter(elem, "DXImageTransform.Microsoft.BasicImage", bInvert);
		}
		catch(e)
		{
			YAHOO.lang.later(100, this, function()
			{
				this.setInvert(bInvert);
			});
		}
	}
}

EOIR.Image.HTML.prototype.setMask = function(r, g, b)
{
	var elem = $(this.m_strInteriorElemId);
	if(elem.filters != null)
	{
		try
		{
//			if(r != 255 || g != 255 || b != 255)
//			{
				elem.filters["DXImageTransform.EOIR.ArithFilter"].RedMask = r;
				elem.filters["DXImageTransform.EOIR.ArithFilter"].GreenMask = g;
				elem.filters["DXImageTransform.EOIR.ArithFilter"].BlueMask = b;
				EOIR.Utils.Filter.enableFilter(elem, "DXImageTransform.EOIR.ArithFilter", true);
//			}
//			else
//			{
//				EOIR.Utils.Filter.enableFilter(elem, "DXImageTransform.EOIR.ArithFilter", false);
//			}
		}
		catch(e)
		{
		}
	}
}

EOIR.Image.HTML.prototype.enableI2SimMode = function(bEnable)
{
	var elem = $(this.m_strInteriorElemId);
	if(elem.filters != null)
	{
		try
		{
			elem.filters["DXImageTransform.EOIR.ArithFilter"].EnableI2Mode = bEnable;
			EOIR.Utils.Filter.enableFilter(elem, "DXImageTransform.EOIR.ArithFilter", true);
		}
		catch(e)
		{
		}
	}
}

EOIR.Image.HTML.prototype.increaseContrast = function()
{
	var elem = $(this.m_strInteriorElemId);
	if(elem.filters != null)
	{
		try
		{
			elem.filters["DXImageTransform.EOIR.ArithFilter"].Gain *= 1.1;
			EOIR.Utils.Filter.enableFilter(elem, "DXImageTransform.EOIR.ArithFilter", true);
		}
		catch(e)
		{
		}
	}
}

EOIR.Image.HTML.prototype.decreaseContrast = function()
{
	var elem = $(this.m_strInteriorElemId);
	if(elem.filters != null)
	{
		try
		{
			elem.filters["DXImageTransform.EOIR.ArithFilter"].Gain /= 1.1;
			EOIR.Utils.Filter.enableFilter(elem, "DXImageTransform.EOIR.ArithFilter", true);
		}
		catch(e)
		{
		}
	}
}

EOIR.Image.HTML.prototype.increaseBrightness = function()
{
	var elem = $(this.m_strInteriorElemId);
	if(elem.filters != null)
	{
		try
		{
			elem.filters["DXImageTransform.EOIR.ArithFilter"].Level += 10;
			EOIR.Utils.Filter.enableFilter(elem, "DXImageTransform.EOIR.ArithFilter", true);
		}
		catch(e)
		{
		}
	}
}

EOIR.Image.HTML.prototype.decreaseBrightness = function()
{
	var elem = $(this.m_strInteriorElemId);
	if(elem.filters != null)
	{
		try
		{
			elem.filters["DXImageTransform.EOIR.ArithFilter"].Level -= 10;
			EOIR.Utils.Filter.enableFilter(elem, "DXImageTransform.EOIR.ArithFilter", true);
		}
		catch(e)
		{
		}
	}
}

EOIR.Image.HTML.prototype.setContrastBrightness = function(contrast, brightness)
{
	var elem = $(this.m_strInteriorElemId);
	if(elem.filters != null)
	{
		try
		{
			elem.filters["DXImageTransform.EOIR.ArithFilter"].Gain = contrast;
			elem.filters["DXImageTransform.EOIR.ArithFilter"].Level = brightness;
			EOIR.Utils.Filter.enableFilter(elem, "DXImageTransform.EOIR.ArithFilter", true);
		}
		catch(e)
		{
		}
	}
}

EOIR.Image.HTML.prototype.getContrast = function()
{
	var elem = $(this.m_strInteriorElemId);
	if(elem.filters != null)
	{
		try
		{
			return elem.filters["DXImageTransform.EOIR.ArithFilter"].Gain;
		}
		catch(e)
		{
		}
	}
}

EOIR.Image.HTML.prototype.getBrightness = function()
{
	var elem = $(this.m_strInteriorElemId);
	if(elem.filters != null)
	{
		try
		{
			return elem.filters["DXImageTransform.EOIR.ArithFilter"].Level;
		}
		catch(e)
		{
		}
	}
}

EOIR.Image.HTML.prototype.resetContrastBrightness = function()
{
	this.setContrastBrightness(1, 0);
}

EOIR.Image.HTML.prototype.enableColorFilters = function(bEnable)
{
	var elem = $(this.m_strInteriorElemId);
	if(elem.filters != null)
	{
		try
		{
			EOIR.Utils.Filter.enableFilter(elem, "DXImageTransform.EOIR.ArithFilter", bEnable);
			EOIR.Utils.Filter.enableFilter(elem, "DXImageTransform.Microsoft.BasicImage", bEnable);
		}
		catch(e)
		{
		}
	}
}

EOIR.Image.Canvas = function(strElem)
{
    var m_elem = $(strElem);

	this.m_strElemId = strElem;
	this.m_strInteriorElemId = strElem + "ID";
	this.m_bMaintainAspect = true;
	this.m_ht = [];
	this.m_bReady = false;
	this.m_bI2SimMode = false;
	
	this.m_bInvert = false;
	this.m_fContrast = 1;
	this.m_nBrightness = 0;
	
	this.m_nRMask = 255;
	this.m_nGMask = 255;
	this.m_nBMask = 255;
	
	this.m_nMean = 0;
	this.m_bFiltersEnabled = true;
	
	this.m_imgLoader = new Image(); // this will be the image source for the canvas
	this.m_tmrLoader = null;
	
	this.m_objImgData = null; // this will hold the canvas's ImageData object
	
	this.m_bInitialized = false;
	
    var cnv = document.createElement("canvas");
    if (!cnv.getContext)
    {
        //canvas not supported
        var err = new Error();
		err.message = err.description = "Error: EOIR.Image canvas element is not supported by this browser!";
		throw err;
    }
    
    cnv.id = this.m_strInteriorElemId;
    cnv.style.position = "absolute";
    cnv.style.left = "0px";
	cnv.style.top = "0px";
	
	// set canvas size in _resizeImage() so that the size can change dynamically
	// set the canvas size, default is 300x150
    //cnv.width = m_elem.offsetWidth;
	//cnv.height = m_elem.offsetHeight;

	m_elem.appendChild(cnv);
	
	this.m_arrLUTRed = [];
	this.m_arrLUTRed.length = 256;
	
	this.m_arrLUTGreen = [];
	this.m_arrLUTGreen.length = 256;
	
	this.m_arrLUTBlue = [];
	this.m_arrLUTBlue.length = 256;
	
	for(var i = 0; i < 256; i++)
	{
	    this.m_arrLUTRed[i] = i;
	    this.m_arrLUTGreen[i] = i;
	    this.m_arrLUTBlue[i] = i;
	}
	
};


EOIR.Image.Canvas.prototype.set = function(key, val)
{
	this.m_ht[key] = val;
}

EOIR.Image.Canvas.prototype.get = function(key, def)
{
	var val = this.m_ht[key];
	if(val == null)
	{
		val = def;
	}
	return val;
}

EOIR.Image.Canvas.prototype.getType = function()
{
	return "canvas";
}

EOIR.Image.Canvas.prototype.setVisible = function(bShow)
{
	$(this.m_strElemId).style.visibility = bShow ? "inherit" : "hidden";
}

EOIR.Image.Canvas.prototype.addListener = function(strEvt, fn, obj)
{
	YAHOO.util.Event.addListener(this.m_strInteriorElemId, strEvt,
		function(evt, objFn)
		{
			fn(evt, this.m_strElemId, objFn);
		}, obj, this);
}

EOIR.Image.Canvas.prototype.getElement = function()
{
	return $(this.m_strInteriorElemId);
}

EOIR.Image.Canvas.prototype._resizeImage = function()
{
	try
	{
	    var img = this.m_imgLoader;
	    var cnv = $(this.m_strInteriorElemId);
	    var elemParent = $(this.m_strElemId);
	    
	    var nImgWidth = img.naturalWidth || img.width;
		var nImgHeight = img.naturalHeight || img.height;
		
	    var nParentWidth = elemParent.offsetWidth;
		var nParentHeight = elemParent.offsetHeight;
		
	    if(nParentWidth == 0 || nParentHeight == 0 || nImgWidth == 0 || nImgHeight == 0)
		{
			this.m_tmrLoader = YAHOO.lang.later(50, this, "_resizeImage");
		}
		else
		{
		    cnv.width = nParentWidth;
	        cnv.height = nParentHeight;
	        cnv.style.width = "100%";
	        cnv.style.height = "100%";
	
	        var ctx = cnv.getContext("2d");
	        var nCnvWidth = cnv.width;
	        var nCnvHeight =  cnv.height;
    	    
	        if(this.m_bMaintainAspect)
	        {
	            var nOffsetX, nOffsetY, nNewImgWidth, nNewImgHeight;
	            var fAspectSrc = nImgWidth / nImgHeight;
	            var fAspectDst = nCnvWidth / nCnvHeight;
	            if(fAspectSrc < fAspectDst)
		        {
			        // Height driven
			        nNewImgHeight = nCnvHeight;
			        nNewImgWidth = nNewImgHeight * fAspectSrc;
			        nOffsetX = (nCnvWidth - nNewImgWidth) / 2;
			        nOffsetY = 0;
		        }
		        else
		        {
			        // Width driven.
			        nNewImgWidth = nCnvWidth;
			        nNewImgHeight = nNewImgWidth / fAspectSrc;
			        nOffsetX = 0;
			        nOffsetY = (nCnvHeight - nNewImgHeight) / 2;
		        }
        		
		        this.set("::cnv_x", nOffsetX);
		        this.set("::cnv_y", nOffsetY);
		        this.set("::cnv_w", nNewImgWidth);
		        this.set("::cnv_h", nNewImgHeight);
	            ctx.drawImage(img, 0, 0, nImgWidth, nImgHeight, nOffsetX, nOffsetY, nNewImgWidth, nNewImgHeight);
	        }
	        else
	        {
	            // this basically scales the image to fit the canvas
	            this.set("::cnv_x", 0);
		        this.set("::cnv_y", 0);
		        this.set("::cnv_w", nCnvWidth);
		        this.set("::cnv_h", nCnvHeight);
	            ctx.drawImage(img, 0, 0, nCnvWidth, nCnvHeight);
	        }
        	
	        try
            {
                this.m_objImgData = ctx.getImageData(this.get("::cnv_x"),this.get("::cnv_y"),this.get("::cnv_w"),this.get("::cnv_h"));
            }
            catch(e)
            { 
                netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); //look into this more
                this.m_objImgData = ctx.getImageData(this.get("::cnv_x"),this.get("::cnv_y"),this.get("::cnv_w"),this.get("::cnv_h"));
            }
        	
        	if(!this.m_bInitialized)
        	{
        	    this._updateMean();
        	    this._updateLUTs();
        	    this.m_bInitialized = true;
        	}
        	this._updateImageData();
	        
	        elemParent.style.visibility = "inherit";
		}
	}
	catch(e)
	{
	}
}

EOIR.Image.Canvas.prototype.setImageSrc = function(strSrc)
{
    if(this.m_tmrLoader != null)
	{
		this.m_tmrLoader.cancel();
		this.m_tmrLoader = null;
	}
		
    if(strSrc != null)
	{
		// Remove any existing load handlers. 
		// This is needed in the case where the loader never fires (ie, if there was a problem loading the image).
		YAHOO.util.Event.removeListener(this.m_imgLoader, "load");
		
		YAHOO.util.Event.addListener(this.m_imgLoader, "load", function()
		{
			this._resizeImage();
			YAHOO.util.Event.removeListener(this.m_imgLoader, "load");
		}, this, true);
	}
	this.m_bInitialized = false;
	this.m_objImgData = null;
	this.m_imgLoader.src = strSrc;
}

EOIR.Image.Canvas.prototype.getImageSrc = function()
{
	return this.m_imgLoader.src;
}

EOIR.Image.Canvas.prototype.setMaintainAspect = function(bMaintainAspect)
{
	this.m_bMaintainAspect = bMaintainAspect;
}

EOIR.Image.Canvas.prototype.setScale = function(bScale)
{
}

EOIR.Image.Canvas.prototype._updateImageData = function()
{
    try
	{
	    var ctx = $(this.m_strInteriorElemId).getContext("2d");
	    
	    if(this.m_bFiltersEnabled)
	    {
	        var imgd;
	        if(ctx.createImageData)
	        {
	            imgd = ctx.createImageData(this.get("::cnv_w"),this.get("::cnv_h"));
	        }
	        else
	        {
	            imgd = ctx.getImageData(this.get("::cnv_x"),this.get("::cnv_y"),this.get("::cnv_w"),this.get("::cnv_h"));
	        }
    	    
    	    if(this.m_bI2SimMode)
    	    {
    	        for(var i = 0; i < imgd.data.length; i+=4)
			    { 
		            imgd.data[i] = 0; //red
		            imgd.data[i+1] = Math.floor((this.m_objImgData.data[i] * .11 + this.m_objImgData.data[i+1] * .59 + this.m_objImgData.data[i+2] * .11) * .85); //green
		            imgd.data[i+2] = 0; //blue
		            imgd.data[i+3] = 255;
			    }
			}
			else
			{
	            for(var i = 0; i < imgd.data.length; i+=4)
		        {
		            imgd.data[i] = this.m_arrLUTRed[this.m_objImgData.data[i]]; //red
		            imgd.data[i+1] = this.m_arrLUTGreen[this.m_objImgData.data[i+1]]; //green
		            imgd.data[i+2] = this.m_arrLUTBlue[this.m_objImgData.data[i+2]]; //blue
		            imgd.data[i+3] = 255;
		        }
		    }
		    ctx.putImageData(imgd, this.get("::cnv_x"),this.get("::cnv_y"));
		}
		else
		{
		    ctx.putImageData(this.m_objImgData, this.get("::cnv_x"),this.get("::cnv_y"));
		}
	}
	catch(e)
	{
	}
}

EOIR.Image.Canvas.prototype._updateLUTs = function()
{
    try
	{
	    for(var i = 0; i < 256; i++)
	    {
	        var nPixVal;
	        if(this.m_bInvert)
	        {   
	            nPixVal = Math.floor((((255 - i)-this.m_nMean) * this.m_fContrast) + this.m_nMean + this.m_nBrightness);
	        }
	        else
	        {
	            nPixVal = Math.floor(((i-this.m_nMean) * this.m_fContrast) + this.m_nMean + this.m_nBrightness);
	        }
	        nPixVal = Math.min(255, Math.max(0, nPixVal));
	        
	        this.m_arrLUTRed[i] = nPixVal & this.m_nRMask; 
			this.m_arrLUTGreen[i] = nPixVal & this.m_nGMask; 
			this.m_arrLUTBlue[i] = nPixVal & this.m_nBMask; 
	    }
	}
	catch(e)
	{
	}
}

EOIR.Image.Canvas.prototype._updateMean = function()
{
    try
	{
	    var nSum = 0;
	    for(var i = 0; i < this.m_objImgData.data.length; i+=4)
		{
		    nSum += this.m_objImgData.data[i];
		}
		this.m_nMean = Math.floor(nSum / (this.m_objImgData.width * this.m_objImgData.height));
	}
	catch(e)
	{
	}
	
}

EOIR.Image.Canvas.prototype._update = function()
{
    this._updateLUTs();
	this._updateImageData();
}

EOIR.Image.Canvas.prototype.getInvert = function()
{
	return this.m_bInvert;
}

EOIR.Image.Canvas.prototype.setInvert = function(bInvert)
{
    this.m_bInvert = bInvert;
	this._update();
}

EOIR.Image.Canvas.prototype.setMask = function(r, g, b)
{
    if(!isNaN(r) && !isNaN(g) && !isNaN(b))
	{
	    if(this.m_bI2SimMode)
        {
			this.set("::_rmask", r);
			this.set("::_gmask", g);
			this.set("::_bmask", b);
		}
		else
		{
	        this.m_nRMask = r;
	        this.m_nGMask = g;
	        this.m_nBMask = b;
	        this._update();
	    }
	}
}

EOIR.Image.Canvas.prototype.enableI2SimMode = function(bEnable)
{
    if(bEnable != this.m_bI2SimMode)
	{
	    this.m_bI2SimMode = bEnable;
		if(bEnable)
		{
		    // save previous values
		    this.set("::_enablefilters", this.m_bFiltersEnabled);
			this.set("::_rmask", this.m_nRMask);
			this.set("::_gmask", this.m_nGMask);
			this.set("::_bmask", this.m_nBMask);
			this.set("::_contrast", this.m_fContrast);
			this.set("::_brightness", this.m_nBrightness);

            this.m_bFiltersEnabled = true;
            //this.m_nRMask = 0;
	        //this.m_nGMask = 255;
	        //this.m_nBMask = 0;
	        //this.m_fContrast = .85;
            //this.m_nBrightness = -45;
			this._update();
		}
		else
		{
		    this.m_bFiltersEnabled = this.get("::_enablefilters", false);
            this.m_nRMask = this.get("::_rmask", 255);
	        this.m_nGMask = this.get("::_gmask", 255);
	        this.m_nBMask = this.get("::_bmask", 255);
	        this.m_fContrast = this.get("::_contrast", 1);
            this.m_nBrightness = this.get("::_brightness", 0);
			this._update();
		}
	}
}

EOIR.Image.Canvas.prototype.increaseContrast = function()
{
	try
	{
		this.m_fContrast *= 1.1;
		this._update();
	}
	catch(e)
	{
	}
}

EOIR.Image.Canvas.prototype.decreaseContrast = function()
{

	try
	{
	    this.m_fContrast /= 1.1;
		this._update();
	}
	catch(e)
	{
	}
}

EOIR.Image.Canvas.prototype.increaseBrightness = function()
{
	try
	{
	    this.m_nBrightness += 10;
		this._update();
	}
	catch(e)
	{
	}
}

EOIR.Image.Canvas.prototype.decreaseBrightness = function()
{
	try
	{
	    this.m_nBrightness -= 10;
		this._update();
	}
	catch(e)
	{
	}
}

EOIR.Image.Canvas.prototype.setContrastBrightness = function(contrast, brightness)
{
    this.m_fContrast = contrast;
    this.m_nBrightness = brightness;
    this._update();
}

EOIR.Image.Canvas.prototype.getContrast = function()
{
	return this.m_fContrast;
}

EOIR.Image.Canvas.prototype.getBrightness = function()
{
	return this.m_nBrightness;
}

EOIR.Image.Canvas.prototype.resetContrastBrightness = function()
{
	this.setContrastBrightness(1, 0);
}

EOIR.Image.Canvas.prototype.enableColorFilters = function(bEnable)
{
    if(this.m_bI2SimMode)
    {
        this.set("::_enablefilters", bEnable);
    }
    else
    {
        this.m_bFiltersEnabled = bEnable;
        this._update();
    }
}

EOIR.Image.Flash = function(strElem, params)
{
	var m_elem = $(strElem);

	this.m_strElemId = strElem;
	this.m_strInteriorElemId = strElem + "ID";
	this.m_ht = [];
	this.m_bReady = false;
	this.m_bI2SimMode = false;

	this.set("::listeners", []);
	this.set("::invert", false);
	this.set("::contrast", 1);
	this.set("::brightness", 0);
	this.set("::rmask", 255);
	this.set("::gmask", 255);
	this.set("::bmask", 255);
	this.set("::maskenable", true);
	this.set("::i2simmode", false);

	var strPath = EOIR.Utils.getPathFromMain("/swf/rocimage.swf");

	var strDownloadProtocol = window.location.protocol == "https:" ? "https:" : "http:";

	if(params == null)
	{
		params = [];
	}
	var paramsClone = [];
	for(var key in params)
	{
		paramsClone[key] = params[key];
	}

	if(paramsClone.windowless)
	{
		paramsClone["wmode"] = "opaque";
		delete paramsClone.windowless;
	}

	paramsClone["flashvars"] = "onready=EOIR.Image.Flash._ready&onreadyparam=" + strElem;

	if(paramsClone.initparams)
	{
		paramsClone["flashvars"] += "&" + paramsClone.initparams;
		delete paramsClone.initparams;
	}

	var strHTML;

	var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
	var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
	var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;

	if(isIE && isWin && !isOpera)
	{
		var strParams = "";
		for(var key in paramsClone)
		{
			strParams += "<param name='" + key + "' value='" + paramsClone[key] + "' />\n";
		}

		strHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ' +
					'id="' + this.m_strInteriorElemId + '" width="100%" height="100%" ' +
					'codebase="' + strDownloadProtocol + '://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab"> ' +
					'<param name="src" value="' + strPath + '" /> ' +
					strParams +
					'</object>';
	}
	else
	{
		var strParams = "";
		for(var key in paramsClone)
		{
			strParams += "'" + key + "=\"" + paramsClone[key] + "\" '";
		}

		strHTML = '<embed src="' + strPath + '" ' +
						'id="' + this.m_strInteriorElemId + '" ' +
						'play="true" ' +
						'loop="false" ' +
						'quality="high" ' +
						strParams +
						'type="application/x-shockwave-flash" ' +
						'width="100%" ' +
						'height="100%" ' +
						'pluginspage="' + strDownloadProtocol + '://www.adobe.com/go/getflashplayer"> ' +
					'</embed>';
	}

	$(strElem).innerHTML = strHTML;
};

EOIR.Image.Flash._ready = function(strElem)
{
	YAHOO.lang.later(100, this, function()
	{
		try
		{
			var img = EOIR.Image.get(strElem);
			img._initialize();
		}
		catch(e)
		{
			alert("Flash image ready error: " + e.description);
		}
	});
}

EOIR.Image.Flash.prototype._initialize = function()
{
	EOIR.External.debugWrite("Initializing " + this.m_strInteriorElemId + "\n");

	this.m_bReady = true;

	var ht = this.get("::listeners");
	for(var key in ht)
	{
		for(var i = 0; i < ht[key].length; i++)
		{
			this._addListener(key, ht[key][i].func, ht[key][i].param);
		}
	}

	if(this.m_imgHidden != null)
	{
		this.m_imgHidden["onerror"] = null;
		this.m_imgHidden["onload"] = null;
		this.m_imgHidden = null;
	}

	if(this.get("::image") != null)
	{
		this.setImageSrc(this.get("::image"));
	}
	else if(this.get("::video") != null)
	{
		this.setVideoSrc(this.get("::video"), this.get("::videoseek"));
	}

	var bI2SimMode = this.get("::i2simmode");
	this.enableI2SimMode(false);

	this.setInvert(this.get("::invert"));
	this.setContrastBrightness(this.get("::contrast"), this.get("::brightness"));
	this.enableColorFilters(this.get("::maskenable"));
	this.setMask(this.get("::rmask"), this.get("::gmask"), this.get("::bmask"));
	this.enableI2SimMode(bI2SimMode);
}

EOIR.Image.Flash.prototype.getType = function()
{
	return "flash";
}

EOIR.Image.Flash.prototype.getElement = function()
{
	return $(this.m_strInteriorElemId);
}

EOIR.Image.Flash.prototype._addListener = function(strEvt, fn, obj)
{
	try
	{
		if(this.m_bReady)
		{
			EOIR.External.debugWrite("_addListener " + fn + "  " + obj + "\n");
			$(this.m_strInteriorElemId).addListener(strEvt, fn, this.m_strElemId);
		}
		else
		{
			// Handle 'load'/'error' specially when not ready. This is b/c the flash object may not be fully ready until
			// it's visible which may not happen until an image has been loaded. In this instance, create a temp
			// image object and use its load/error handler.
			if(strEvt == "load" || strEvt == "error")
			{
				if(this.m_imgHidden == null)
				{
					this.m_imgHidden = new Image();
					this.m_imgHidden.assocElem = this.m_strElemId;
				}
				this.m_imgHidden["on" + strEvt] = function()
				{
					var img = EOIR.Image.get(this.assocElem);
					var ht = img.get("::listeners");

					for(var i = 0; i < ht[strEvt].length; i++)
					{
						try
						{
							eval(ht[strEvt][i].func + "('" + this.assocElem + "')");
						}
						catch(e) { }
					}
				}
			}
		}
	}
	catch(e)
	{
	}
}

EOIR.Image.Flash.prototype.addListener = function(strEvt, fn, obj)
{
	// Need to keep our own copy of this stuff b/c the Flash object may not be ready for it yet.
	var ht = this.get("::listeners");
	if(ht[strEvt] == null)
	{
		ht[strEvt] = [];
	}
	ht[strEvt].push({ func: fn, param: obj });
	this.set("::listeners", ht);

	this._addListener(strEvt, fn, obj);
}

EOIR.Image.Flash.prototype.setImageSrc = function(strSrc)
{
	this.set("::video", null);
	this.set("::image", strSrc);

	try
	{
		if(this.m_imgHidden != null)
		{
			this.m_imgHidden.src = strSrc;
		}

		if(this.m_bReady)
		{
			$(this.m_strInteriorElemId).setImage(strSrc);
		}
	}
	catch(e)
	{
	}
}

EOIR.Image.Flash._fixUpUrl = function(strUrl)
{
	strUrl = EOIR.Utils.replaceExtension(strUrl, "flv");

	try
	{
		if(EOIR.Utils.isInROCBrowser())
		{
			strUrl = EOIR.Utils.cacheUrl(strUrl);
			strUrl = strUrl.replace(/\\/g, "/");
			var nIndex = strUrl.lastIndexOf("/");
			if(nIndex != -1)
			{
				strUrl = strUrl.substr(0, nIndex + 1) + encodeURIComponent(strUrl.substr(nIndex + 1));
			}
			EOIR.External.debugWrite("Cached url " + strUrl + "\n");
		}

//		strUrl = strUrl.replace(/\\x/g, "/x").replace(/\\u/g, "/u");
	}
	catch(e)
	{
		//		alert("EOIR.Video.Flash._fixUpUrl error: " + e.description);
	}

	return strUrl;
}

EOIR.Image.Flash.prototype.setVideoSrc = function(strUrl, nVidSeek)
{
	try
	{
		EOIR.External.debugWrite("setVideoSrc Url = " + strUrl + "\n");
		this.set("::image", null);
		this.set("::video", strUrl);
		this.set("::videoseek", nVidSeek);

		if(this.m_bReady)
		{
			strUrl = EOIR.Image.Flash._fixUpUrl(strUrl);
			EOIR.External.debugWrite("setVideo Url = " + strUrl + "\n");
			$(this.m_strInteriorElemId).setVideo(strUrl, nVidSeek == null ? 0 : nVidSeek);
		}
	}
	catch(e)
	{
	}
}

EOIR.Image.Flash.prototype.getImageSrc = function()
{
	return this.get("::image");
}

EOIR.Image.Flash.prototype.getVideoSrc = function()
{
	return this.get("::video");
}

EOIR.Image.Flash.prototype.setInvert = function(bInvert)
{
	this.set("::invert", bInvert);

	try
	{
		$(this.m_strInteriorElemId).setInvert(bInvert);
	}
	catch(e)
	{
	}
}

EOIR.Image.Flash.prototype.getInvert = function()
{
	return this.get("::invert");
}

EOIR.Image.Flash.prototype._setMask = function(r, g, b)
{
	try
	{
		$(this.m_strInteriorElemId).setMask(r, g, b);
	}
	catch(e)
	{
	}
}

EOIR.Image.Flash.prototype.setMask = function(r, g, b)
{
	if(!isNaN(r) && !isNaN(g) && !isNaN(b))
	{
		if(this.get("::i2simmode"))
		{
			this.set("::_rmask", r);
			this.set("::_gmask", g);
			this.set("::_bmask", b);
		}
		else
		{
			this.set("::rmask", r);
			this.set("::gmask", g);
			this.set("::bmask", b);

			try
			{
				$(this.m_strInteriorElemId).setMask(r, g, b);
			}
			catch(e)
			{
			}
		}
	}
}

EOIR.Image.Flash.prototype.setVisible = function(bShow)
{
	$(this.m_strInteriorElemId).style.visibility = bShow ? "inherit" : "hidden";
}

EOIR.Image.Flash.prototype.enableI2SimMode = function(bEnable)
{
	if(bEnable != this.get("::i2simmode"))
	{
		this.set("::i2simmode", bEnable);
		if(bEnable)
		{
			this.set("::_rmask", this.get("::rmask"));
			this.set("::_gmask", this.get("::gmask"));
			this.set("::_bmask", this.get("::bmask"));
			this.set("::_maskenable", this.get("::maskenable"));
			this.set("::_contrast", this.get("::contrast"));
			this.set("::_brightness", this.get("::brightness"));

			this._enableColorFilters(true);
			this._setMask(0, 255, 0);
			this.setContrastBrightness(.85, -50);
		}
		else
		{
			this.enableColorFilters(this.get("::_maskenable", false));
			this.setMask(this.get("::_rmask", 255), this.get("::_gmask", 255), this.get("::_bmask", 255));
			this.setContrastBrightness(this.get("::_contrast", 1), this.get("::_brightness", 0));
		}
	}
}

EOIR.Image.Flash.prototype.increaseContrast = function()
{
	var elem = $(this.m_strInteriorElemId);
	try
	{
		var newContrast = this.get("::contrast") * 1.1;
		this.set("::contrast", newContrast);
		elem.setContrast(newContrast);
	}
	catch(e)
	{
	}
}

EOIR.Image.Flash.prototype.decreaseContrast = function()
{

	var elem = $(this.m_strInteriorElemId);
	try
	{
		var newContrast = this.get("::contrast") / 1.1;
		this.set("::contrast", newContrast);
		elem.setContrast(newContrast);
	}
	catch(e)
	{
	}
}

EOIR.Image.Flash.prototype.increaseBrightness = function()
{
	var elem = $(this.m_strInteriorElemId);
	try
	{
		var newBrightness = this.get("::brightness") + 10;
		this.set("::brightness", newBrightness);
		elem.setBrightness(newBrightness);
	}
	catch(e)
	{
	}
}

EOIR.Image.Flash.prototype.decreaseBrightness = function()
{
	var elem = $(this.m_strInteriorElemId);
	try
	{
		var newBrightness = this.get("::brightness") - 10;
		this.set("::brightness", newBrightness);
		elem.setBrightness(newBrightness);
	}
	catch(e)
	{
	}
}

EOIR.Image.Flash.prototype.setContrastBrightness = function(contrast, brightness)
{
	this.set("::contrast", contrast);
	this.set("::brightness", brightness);

	var elem = $(this.m_strInteriorElemId);
	try
	{
		elem.setContrast(contrast);
		elem.setBrightness(brightness);
	}
	catch(e)
	{
	}
}

EOIR.Image.Flash.prototype.getContrast = function()
{
	return this.get("::contrast");
}

EOIR.Image.Flash.prototype.getBrightness = function()
{
	return this.get("::brightness");
}

EOIR.Image.Flash.prototype.resetContrastBrightness = function()
{
	this.setContrastBrightness(1, 0);
}

EOIR.Image.Flash.prototype._enableColorFilters = function(bEnable)
{
	try
	{
		$(this.m_strInteriorElemId).enableFilters(bEnable);
	}
	catch(e)
	{
	}
}

EOIR.Image.Flash.prototype.enableColorFilters = function(bEnable)
{
	if(this.get("::i2simmode"))
	{
		this.set("::_maskenable", bEnable);
	}
	else
	{
		this.set("::maskenable", bEnable);
		this._enableColorFilters(bEnable);
	}
}

EOIR.Image.Flash.prototype.set = function(key, val)
{
	this.m_ht[key] = val;
}

EOIR.Image.Flash.prototype.get = function(key)
{
	return this.m_ht[key];
}

EOIR.Image.Flash.prototype.setScale = function(bScale)
{
}


EOIR.Image.Silverlight = function(strElem, params)
{
	var m_elem = $(strElem);

	this.m_strElemId = strElem;
	this.m_strInteriorElemId = strElem + "ID";
	this.m_ht = [];
	this.m_bReady = false;

	this.set("::listeners", []);
	this.set("::invert", false);
	this.set("::contrast", 1);
	this.set("::brightness", 0);
	this.set("::rmask", 255);
	this.set("::gmask", 255);
	this.set("::bmask", 255);
	this.set("::maskenable", true);
	this.set("::i2simmode", false);

	var strPath = EOIR.Utils.getPathFromMain("/xap/rocimage.xap");

	if(params == null)
	{
		params = [];
	}
	var paramsClone = [];
	for(var key in params)
	{
		paramsClone[key] = params[key];
	}
	if(paramsClone.windowless)
	{
		paramsClone.windowless = "-1";
	}
	paramsClone.onLoad = "EOIR_Image_Silverlight__ready"; //EOIR.Image.Silverlight._ready";

	var strHTML;
	var strParams = "";
	for(var key in paramsClone)
	{
		strParams += "<param name='" + key + "' value='" + paramsClone[key] + "' />\n";
	}

	strHTML = '<object width="100%" height="100%" ' +
				'id="' + this.m_strInteriorElemId + '" ' +
				'data="data:application/x-silverlight-2," ' +
				'type="application/x-silverlight-2" > ' +
				'<param name="source" value="' + strPath + '"/> ' +
				'<param name="Background" value="#00000000"/> ' +
				strParams +
				'</object>';
	$(strElem).innerHTML = strHTML;
};

// The Silverlight onload doesn't seem to like to call functions inside of a namespace.
function EOIR_Image_Silverlight__ready(sender, args)
{
	window.setTimeout(function() { EOIR.Image.Silverlight._ready(sender, args); }, 10);
}

EOIR.Image.Silverlight._ready = function(sender, args)
{
	try
	{
		var strId = sender.getHost().id;
		var img = EOIR.Image.get(strId.substring(0, strId.length - 2));
		img._initialize();
	}
	catch(e)
	{
		alert("EOIR.Image.Silverlight._ready: " + e.description);
	}
}

EOIR.Image.Silverlight.prototype._initialize = function()
{
	EOIR.External.debugWrite("Initializing " + this.m_strInteriorElemId + "\n");

	this.m_bReady = true;

	var ht = this.get("::listeners");
	for(var key in ht)
	{
		for(var i = 0; i < ht[key].length; i++)
		{
			this._addListener(key, ht[key][i].func, ht[key][i].param);
		}
	}

	if(this.m_imgHidden != null)
	{
		this.m_imgHidden["onerror"] = null;
		this.m_imgHidden["onload"] = null;
		this.m_imgHidden = null;
	}

	if(this.get("::image") != null)
	{
		this.setImageSrc(this.get("::image"));
	}

	var bI2SimMode = this.get("::i2simmode");
	this.enableI2SimMode(false);
	
	this.setInvert(this.get("::invert"));
	this.setContrastBrightness(this.get("::contrast"), this.get("::brightness"));
	this.enableColorFilters(this.get("::maskenable"));
	this.setMask(this.get("::rmask"), this.get("::gmask"), this.get("::bmask"));
	this.enableI2SimMode(bI2SimMode);
}

EOIR.Image.Silverlight.prototype.getType = function()
{
	return "silverlight";
}

EOIR.Image.Silverlight.prototype.getElement = function()
{
	return $(this.m_strInteriorElemId);
}

EOIR.Image.Silverlight.prototype._addListener = function(strEvt, fn, obj)
{
	try
	{
		if(this.m_bReady)
		{
			//			EOIR.External.debugWrite("_addListener " + fn + "  " + obj);

			// Note: Silverlight events are case sensitive!
			//			$(this.m_strInteriorElemId).Content.ImageControl.addEventListener("On" + strEvt.substring(0, 1).toUpperCase() + strEvt.substring(1), fn);

			var id = this.m_strElemId;
			$(this.m_strInteriorElemId).Content.ImageControl.addEventListener("On" + strEvt.substring(0, 1).toUpperCase() + strEvt.substring(1),
				function(sender, args)
				{
					fn(null, id, obj);
				});

		}
		else
		{
			// Handle 'load'/'error' specially when not ready. This is b/c the object may not be fully ready until
			// it's visible which may not happen until an image has been loaded. In this instance, create a temp
			// image object and use its load/error handler.
			if(strEvt == "load" || strEvt == "error")
			{
				if(this.m_imgHidden == null)
				{
					this.m_imgHidden = new Image();
					this.m_imgHidden.assocElem = this.m_strElemId;
				}
				this.m_imgHidden["on" + strEvt] = function()
				{
					var img = EOIR.Image.get(this.assocElem);
					var ht = img.get("::listeners");

					for(var i = 0; i < ht[strEvt].length; i++)
					{
						try
						{
							ht[strEvt][i].func(null, this.assocElem, obj);
						}
						catch(e) { }
					}
				}
			}
		}
	}
	catch(e)
	{
//		alert("EOIR.Image.Silverlight.prototype._addListener " + e.description);
	}
}

EOIR.Image.Silverlight.prototype.addListener = function(strEvt, fn, obj)
{
	// Need to keep our own copy of this stuff b/c the Flash object may not be ready for it yet.
	var ht = this.get("::listeners");
	if(ht[strEvt] == null)
	{
		ht[strEvt] = [];
	}
	ht[strEvt].push({ func: fn, param: obj });
	this.set("::listeners", ht);

	this._addListener(strEvt, fn, obj);
}

EOIR.Image.Silverlight.prototype.setImageSrc = function(strSrc)
{
	this.set("::video", null);
	this.set("::image", strSrc);

	try
	{
		if(this.m_imgHidden != null)
		{
			this.m_imgHidden.src = strSrc;
		}

		if(this.m_bReady)
		{
			$(this.m_strInteriorElemId).Content.ImageControl.Url = strSrc;
		}
	}
	catch(e)
	{
	}
}

EOIR.Image.Silverlight.prototype.getImageSrc = function()
{
	return this.get("::image");
}

EOIR.Image.Silverlight.prototype.setInvert = function(bInvert)
{
	this.set("::invert", bInvert);

	try
	{
		$(this.m_strInteriorElemId).Content.ImageControl.Invert = bInvert;
	}
	catch(e)
	{
	}
}

EOIR.Image.Silverlight.prototype.getInvert = function()
{
	return this.get("::invert");
}

EOIR.Image.Silverlight.prototype._setMask = function(r, g, b)
{
	try
	{
		$(this.m_strInteriorElemId).Content.ImageControl.SetMask(r, g, b);
	}
	catch(e)
	{
	}
}

EOIR.Image.Silverlight.prototype.setMask = function(r, g, b)
{
	if(!isNaN(r) && !isNaN(g) && !isNaN(b))
	{
		if(this.get("::i2simmode"))
		{
			this.set("::_rmask", r);
			this.set("::_gmask", g);
			this.set("::_bmask", b);
		}
		else
		{
			this.set("::rmask", r);
			this.set("::gmask", g);
			this.set("::bmask", b);

			this._setMask(r, g, b);
		}
	}
}

EOIR.Image.Silverlight.prototype.setVisible = function(bShow)
{
	$(this.m_strInteriorElemId).style.visibility = bShow ? "inherit" : "hidden";
}

EOIR.Image.Silverlight.prototype.enableI2SimMode = function(bEnable)
{
	if(bEnable != this.get("::i2simmode"))
	{
		this.set("::i2simmode", bEnable);
		if(bEnable)
		{
			this.set("::_rmask", this.get("::rmask"));
			this.set("::_gmask", this.get("::gmask"));
			this.set("::_bmask", this.get("::bmask"));
			this.set("::_maskenable", this.get("::maskenable"));
			this.set("::_contrast", this.get("::contrast"));
			this.set("::_brightness", this.get("::brightness"));

			this._enableColorFilters(true);
			this._setMask(0, 255, 0);
			this.setContrastBrightness(.85, -50);
		}
		else
		{
			this.enableColorFilters(this.get("::_maskenable", false));
			this.setMask(this.get("::_rmask", 255), this.get("::_gmask", 255), this.get("::_bmask", 255));
			this.setContrastBrightness(this.get("::_contrast", 1), this.get("::_brightness", 0));
		}
	}
}

EOIR.Image.Silverlight.prototype.increaseContrast = function()
{
	var elem = $(this.m_strInteriorElemId);
	try
	{
		var newContrast = this.get("::contrast") * 1.1;
		this.set("::contrast", newContrast);
		$(this.m_strInteriorElemId).Content.ImageControl.Contrast = newContrast;
	}
	catch(e)
	{
	}
}

EOIR.Image.Silverlight.prototype.decreaseContrast = function()
{

	var elem = $(this.m_strInteriorElemId);
	try
	{
		var newContrast = this.get("::contrast") / 1.1;
		this.set("::contrast", newContrast);
		$(this.m_strInteriorElemId).Content.ImageControl.Contrast = newContrast;
	}
	catch(e)
	{
	}
}

EOIR.Image.Silverlight.prototype.increaseBrightness = function()
{
	var elem = $(this.m_strInteriorElemId);
	try
	{
		var newBrightness = this.get("::brightness") + 10;
		this.set("::brightness", newBrightness);
		$(this.m_strInteriorElemId).Content.ImageControl.Brightness = newBrightness;
	}
	catch(e)
	{
	}
}

EOIR.Image.Silverlight.prototype.decreaseBrightness = function()
{
	var elem = $(this.m_strInteriorElemId);
	try
	{
		var newBrightness = this.get("::brightness") - 10;
		this.set("::brightness", newBrightness);
		$(this.m_strInteriorElemId).Content.ImageControl.Brightness = newBrightness;
	}
	catch(e)
	{
	}
}

EOIR.Image.Silverlight.prototype.setContrastBrightness = function(contrast, brightness)
{
	this.set("::contrast", contrast);
	this.set("::brightness", brightness);

	var elem = $(this.m_strInteriorElemId);
	try
	{
		$(this.m_strInteriorElemId).Content.ImageControl.SetContrastBrightness(contrast, brightness);
	}
	catch(e)
	{
	}
}

EOIR.Image.Silverlight.prototype.getContrast = function()
{
	return this.get("::contrast");
}

EOIR.Image.Silverlight.prototype.getBrightness = function()
{
	return this.get("::brightness");
}

EOIR.Image.Silverlight.prototype.resetContrastBrightness = function()
{
	this.setContrastBrightness(1, 0);
}

EOIR.Image.Silverlight.prototype._enableColorFilters = function(bEnable)
{
	try
	{
		$(this.m_strInteriorElemId).Content.ImageControl.EnableFilters = bEnable;
	}
	catch(e)
	{
	}
}

EOIR.Image.Silverlight.prototype.enableColorFilters = function(bEnable)
{
	if(this.get("::i2simmode"))
	{
		this.set("::_maskenable", bEnable);
	}
	else
	{
		this.set("::maskenable", bEnable);
		this._enableColorFilters(bEnable);
	}
}

EOIR.Image.Silverlight.prototype.set = function(key, val)
{
	this.m_ht[key] = val;
}

EOIR.Image.Silverlight.prototype.get = function(key, def)
{
	var val = this.m_ht[key];
	if(val == null)
	{
		val = def;
	}
	return val;
}

EOIR.Image.Silverlight.prototype.setScale = function(bScale)
{
}
