function SwapImageClass(container)
{
    var container;
    var theDoc;
    var currentLatch = null;
    var currentOver = null;
    var me = this;
    
    this.autoLatch = true;

    var addEventHandler = function(obj,eventType, fn, args)
    {
        if(window.addEventListener)
            obj.addEventListener(eventType, (function(obj){return function(e){me[fn](e,obj,args)}})(obj), false);
        else
            obj.attachEvent('on' + eventType, (function(obj){return function(e){if(!e)e=window.event;me[fn](e,obj,args)}})(obj));
    }

    var getEventTarget = function(e, theClass)
    {
        var tgt;
        if (!e) var e = window.event;
        tgt = e.target ? e.target : e.srcElement;
        if (tgt.nodeType == 3) tgt = tgt.parentNode; // defeat Safari bug
        return tgt;
    }

    var getParentById = function(obj, theId)
    {
        if(!obj || !theId) return false;
        while((' ' + obj.id + ' ').indexOf(' ' + theId + ' ') == -1 && obj.nodeName != 'BODY') obj = obj.parentNode;
        if(obj.nodeName == 'BODY') return false;
        return obj;
    }

    var checkChildToParent = function(objChild, objParent)
    {
        if(!objChild || !objParent) return false;
        try{
            while(objChild != objParent && objChild.nodeName != 'BODY') objChild = objChild.parentNode;
            if(objChild.nodeName == 'BODY') return false;
            return true;
        }
        catch(err){}
    }

    // ----------------------------------------------------------- //


    // Note: it is not necessary to use 'e' to get the image object as it is already passed into 'img'
    this.swapOver = function(e,img,proxy)
    {
        var fromObj = e.relatedTarget || e.fromElement;

        if(!proxy || !checkChildToParent(fromObj,proxy))
        {
            if(img != currentLatch)
            {
                img.src = img.src.replace(/(_over|)(\.)(jpg|gif|jpeg|png)/g, '_over.$3');
                currentOver = img;
            }
        }
    }

    this.swapOut = function(e,img,proxy)
    {
        var toObj = e.relatedTarget || e.toElement;

        if(!proxy || !checkChildToParent(toObj,proxy))
          if(img != currentLatch) img.src = img.src.replace(/(_over\.)(jpg|gif|jpeg|png)/g, '.$2');
    }

    this.forceCurrentOut = function(incLatch)
    {
        if(currentOver && (currentOver != currentLatch || incLatch))
        {
            currentOver.src = currentOver.src.replace(/((_over|_latch)?\.)(jpg|gif|jpeg|png)/g, '.$3');
            if(incLatch && currentOver == currentLatch) currentLatch = null;
            currentOver = null;
        }
    }

    this.unLatch = function()
    {
        if(currentLatch != null)
        {
            currentLatch.src = currentLatch.src.replace(/((_over|_latch)?\.)(jpg|gif|jpeg|png)/g, '.$3');
            currentLatch = null;
        }
    }

    this.latch = function(e,img)
    {
        if(img != currentLatch)
        {
            var classNm = (' ' + img.className + ' ').toLowerCase();
            if(classNm.indexOf(' latch ') != -1 || classNm.indexOf(' latchswap ') != -1)
            {
                this.unLatch();
                currentLatch = img;
                if(classNm.indexOf(' latchswap ') != -1)
                  img.src = img.src.replace(/((.*)_over|(.*))\.(jpg|gif|jpeg|png)/g, '$2$3_latch.$4');
            }
        }
    }

    this.latchById = function(imgId)
    {
        var img = document.getElementById(imgId);
        if(img)
        {
            if(currentLatch != img) setTimeout(function(){
                me.latch(null,img);

                // We may need to force a latched rollover but the latch() function wont do it
                if((' ' + img.className + ' ').toLowerCase().indexOf(' latch ') != -1)
                {
                    if(!img.src.match(/(_over\.)(jpg|gif|jpeg|png)/))
                      img.src = img.src.replace(/(\.)(jpg|gif|jpeg|png)/g, '_over.$2');
                }
              }, 250);
        }
    }

    this.preLoad = function()
    {
        if(typeof Image != 'undefined')
        {
            var i = new Image;

            if(arguments.length == 1)
              var files = arguments[0].split(',');
            else
              var files = arguments;

            for(var x = 0,xLen = files.length; x < xLen; x++) i.src = files[x];
        }
    }

    this._proxySwapOver = function(e,proxy,img)
    {
        this.swapOver(e,img,proxy);
    }

    this._proxySwapOut = function(e,proxy,img)
    {
        this.swapOut(e,img,proxy);
    }

    this._proxyLatch = function(e,proxy,img)
    {
        this.latch(e,img,proxy);
    }

    this.assignProxy = function(proxyId,imgId)
    {
        var proxy = theDoc.getElementById(proxyId);
        var img = theDoc.getElementById(imgId);

        if(img && proxy)
        {
            addEventHandler(proxy, 'mouseover', '_proxySwapOver', img);
            addEventHandler(proxy, 'mouseout', '_proxySwapOut', img);
            addEventHandler(proxy, 'click', '_proxyLatch', img);
        }
    }

    this.assignProxyOut = function(obj)
    {
        addEventHandler(obj, 'mouseover', '_proxySwapOut');
    }

    this.assignUnLatch = function(ids,evt)
    {
        ids = ids.split(',');
        for(var n = 0, nLength = ids.length;n < nLength; n++)
        {
            var obj = document.getElementById(ids[n]);
            if(obj) addEventHandler(obj, evt, 'unLatch');
        }
    }

    this.init = function(ct)
    {
        if('x'.replace)
        {
            if(!ct)
              container = document;
            else
              container = typeof ct == 'object' ? ct : document.getElementById(ct);

            theDoc = container.ownerDocument || container.document || container;

            var imgs = container.getElementsByTagName('img');
            for(var i = 0, iLength = imgs.length; i < iLength; i++)
            {
                var classNm = (' ' + imgs[i].className + ' ').toLowerCase();

                if(classNm.indexOf(' imageswap ') != -1)
                {
                    addEventHandler(imgs[i], 'mouseover', 'swapOver');
                    addEventHandler(imgs[i], 'mouseout', 'swapOut');
                    addEventHandler(imgs[i], 'click', 'latch');
                }

                if(classNm.indexOf(' selected ') != -1)
                {
                    currentLatch = imgs[i];
                    if(!imgs[i].src.match(/_latch\.(jpg|gif|jpeg|png)/))
                        imgs[i].src = imgs[i].src.replace(/((.*)_over|(.*))\.(jpg|gif|jpeg|png)/g, '$2$3_latch.$4');
                }

                if(classNm.indexOf(' selectedover ') != -1)
                {
                    currentLatch = imgs[i];
                    if(!imgs[i].src.match(/_over\.(jpg|gif|jpeg|png)/))
                        imgs[i].src = imgs[i].src.replace(/((.*)_latched|(.*))\.(jpg|gif|jpeg|png)/g, '$2$3_over.$4');
                }

                if(this.autoLatch) if(imgs[i].src.match(/(_latch|_over)\.(jpg|gif|jpeg|png)/)) currentLatch = imgs[i];
                //if(currentLatch == null && imgs[i].src.match(/_over\.(jpg|gif|jpeg|png)/)) currentLatch = imgs[i];
            }
        }
    }
}