
function dHTMLElement(sElementID, sRefElementID)
{
    this.oElement = document.getElementById(sElementID);
    this.oRefElement = document.getElementById(sRefElementID);
    if (!this.oElement || !this.oRefElement) {
        return;
    }

    this.iTargetX = null, this.iTargetY = null, this.iTargetT = null;
    this.iTargetR = null, this.iTargetB = null, this.iTargetL = null;
    this.blClipActive = false, this.blSlideActive = false;

    this.oCss = this.oElement.style;

    var aRefCds = this.getNodeCoordinates(this.oRefElement);
    this.iRefInitX = aRefCds[0];
    this.iRefInitY = aRefCds[1];
    this.oCss.left = this.iRefInitX + 'px';
    this.oCss.top = this.iRefInitY + 'px';

    var aCds = this.getNodeCoordinates(this.oElement);
    this.iInitX = this.iX = aCds[0] || 0;
    this.iInitY = this.iY = aCds[1] || 0;
    this.iW = aCds[2] || 0;
    this.iH = aCds[3] || 0;

    if (this.oCss.clip) {
        var aC = this.oCss.clip.replace(/[^0-9,]+/g, '').split(',');
        if (aC.length == 4) {
            this.sCT = parseInt(aC[0]) || 0;
            this.sCR = parseInt(aC[1]) || 0;
            this.sCB = parseInt(aC[2]) || 0;
            this.sCL = parseInt(aC[3]) || 0;
        }
    }
    this.iInitT = this.sCT = this.sCT || 0;
    this.iInitR = this.sCR = this.sCR || this.iW || 0;
    this.iInitB = this.sCB = this.sCB || this.iH || 0;
    this.iInitL = this.sCL = this.sCL || 0;

    this.oObject = sElementID + "_object";
    eval(this.oObject + "=this");

    return this;
}

dHTMLElement.prototype.refreshDHTMLElement = function()
{
    var aRefCds = this.getNodeCoordinates(this.oRefElement);
    var iDifX = this.iRefInitX-aRefCds[0];
    var iDifY = this.iRefInitY-aRefCds[1];
    this.iRefInitX = aRefCds[0];
    this.iRefInitY = aRefCds[1];

    this.iInitX -= iDifX;
    this.iInitY -= iDifY;
    this.iTargetX -= iDifX;
    this.iTargetY -= iDifY;
    this.iX -= iDifX;
    this.iY -= iDifY;

    this.moveTo(this.iX, this.iY);
}

dHTMLElement.prototype.getNodeCoordinates = function(mElement)
{
    var oElement = typeof mElement == 'string' ? document.getElementById(mElement) : mElement;
    if (!oElement) {
        return;
    }

    function getOffsetPosition(oElement)
    {
        var iLeft = 0;
        var iTop  = 0;
        if (typeof oElement.offsetParent == 'undefined') {
            return [iLeft, iTop];
        }

        while (oElement && oElement.nodeName != 'HTML') {
            iLeft += oElement.offsetLeft;
            iTop  += oElement.offsetTop;
            oElement = oElement.offsetParent;
        }

        return [iLeft, iTop];
    }

    var aPos = getOffsetPosition(oElement);
    var iLeft = oElement.style.left || oElement.style.pixelLeft || aPos[0] || 0;
    var iTop = oElement.style.top || oElement.style.pixelTop || aPos[1] || 0;
    var iWidth = oElement.offsetWidth || oElement.style.pixelWidth || 0;
    var iHeight = oElement.offsetHeight || oElement.style.pixelHeight || 0;

    return [parseInt(iLeft), parseInt(iTop), parseInt(iWidth), parseInt(iHeight)];
}

dHTMLElement.prototype.showIt = function()
{
    this.oCss.visibility = 'visible';
}

dHTMLElement.prototype.hideIt = function()
{
    this.oCss.visibility = 'hidden';
}

dHTMLElement.prototype.moveTo = function(iX, iY)
{
    this.iX = iX;
    this.iY = iY;
    this.oCss.left = this.iX + 'px';
    this.oCss.top = this.iY + 'px';
}

dHTMLElement.prototype.moveBy = function(iX, iY)
{
    this.moveTo(this.iX+iX, this.iY+iY);
}

dHTMLElement.prototype.slide = function(iDX, iDY, iEndX, iEndY, iSpeed)
{
    if (this.blSlideActive
        && (Math.floor(Math.abs(iDX)) < Math.floor(Math.abs(iEndX-this.iX))
            || Math.floor(Math.abs(iDY)) < Math.floor(Math.abs(iEndY-this.iY)))) {
        this.moveBy(iDX, iDY);
        setTimeout(this.oObject + '.slide(' + iDX + ',' + iDY + ',' + iEndX + ',' + iEndY + ',' + iSpeed + ')', iSpeed);
    } else {
        this.moveTo(iEndX, iEndY);
        this.blSlideActive = false;
    }
}

dHTMLElement.prototype.slideIt = function(iEndX, iEndY, iStep, iSpeed)
{
    if (!this.blSlideActive) {
        iStep = iStep || 10;
        iSpeed = iSpeed || 10;
        this.blSlideActive = true;
        var iDistX = iEndX-this.iX;
        var iDistY = iEndY-this.iY;
        var iNum = Math.sqrt(Math.pow(iDistX, 2)+Math.pow(iDistY, 2))/iStep;
        var iDX = iDistX/iNum;
        var iDY = iDistY/iNum;
        this.slide(iDX, iDY, iEndX, iEndY, iSpeed);
    }
}

dHTMLElement.prototype.clipTo = function(iT, iR, iB, iL, blSetWidth)
{
    this.sCT = iT = iT < 0 ? 0 : iT;
    this.sCR = iR = iR < 0 ? 0 : iR;
    this.sCB = iB = iB < 0 ? 0 : iB;
    this.sCL = iL = iL < 0 ? 0 : iL;
    this.oCss.clip = 'rect(' + iT + 'px, ' + iR + 'px, ' + iB + 'px, ' + iL + 'px)';
    if (blSetWidth) {
        this.oCss.width = iR + 'px';
        this.oCss.height = iB + 'px';
    }
}

dHTMLElement.prototype.clipBy = function(iT, iR, iB, iL, blSetWidth)
{
    this.clipTo(this.sCT+iT, this.sCR+iR, this.sCB+iB, this.sCL+iL, blSetWidth);
}

dHTMLElement.prototype.clip = function(iT, iR, iB, iL, iTS, iRS, iBS, iLS, iTStep, iAStep, iSpeed)
{
    if (iAStep < iTStep) {
        iAStep++;
        this.clipBy(iTS, iRS, iBS, iLS, true);
        setTimeout(this.oObject + '.clip(' + iT + ',' + iR + ',' + iB + ',' + iL + ',' + iTS + ',' + iRS + ','
                   + iBS + ',' + iLS + ',' + iTStep + ',' + iAStep + ',' + iSpeed + ')', iSpeed);
    } else {
        this.clipTo(iT, iR, iB, iL, true);
        this.blClipActive = false;
    }
}

dHTMLElement.prototype.clipIt = function(iT, iR, iB, iL, iStep, iSpeed)
{
    if (!this.blClipActive) {
        iStep = iStep || 10;
        iSpeed = iSpeed || 10;
        this.blClipActive = true;
        var iTStep = Math.max(Math.max(Math.abs((iT-this.sCT)/iStep), Math.abs((iR-this.sCR)/iStep))
                              , Math.max(Math.abs((iB-this.sCB)/iStep), Math.abs((iL-this.sCL)/iStep)));
        this.clip(iT, iR, iB, iL, (iT-this.sCT)/iTStep, (iR-this.sCR)/iTStep
                  , (iB-this.sCB)/iTStep, (iL-this.sCL)/iTStep, iTStep, 0, iSpeed);
    }
}
