
function Paff_LoginPanel(varName, cssClass, position, zIndex, hideOnDocumentClick, initialContent)
{
    this._variableName = varName;
    this.CssClass = cssClass;
    this.Position = position;
    this.ZIndex = zIndex;
    this._isShown = false;
    this._initialized = false;
    this._lastPosition = null;
    this._initialContent = initialContent;
    this._panel = null;
    this._panelMask = null;
    this._animationHandle = null;
    this._originalDocumentOnClick = null;
    this._isOpening = false;
    this._hiddenSelects = null;
    this._checkForScrollResizeHandle = null;
    this._lastWindowInfo = null;
    this._panelMask = document.createElement('div');
    this._panelMask.style.position = 'absolute';
    this._panelMask.style.display = 'none';
    this._panel = document.createElement('div');
    this._panel.style.position = 'absolute';
    this._panel.style.display = 'none';
    this._panel.className = this.CssClass;
    this._panelMask.appendChild(this._panel);
    if (hideOnDocumentClick)
    {
        if (document.onclick)
            this._originalDocumentOnClick = document.onclick;
        document.onclick = new Function(this._variableName + '._documentOnClick();');
    }
}

Paff_LoginPanel.prototype.IsShown = function()
{
    return this._isShown;
}

Paff_LoginPanel.prototype._getElementInfo = function(element)
{
    var curleft = 0;
    var curtop = 0;
    var obj = element;
    if (obj.offsetParent)
    {
        while (obj)
        {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
            obj = obj.offsetParent;
        }
    }
    else
    {
        if (obj.x)
            curleft += obj.x;
        if (obj.y)
            curtop += obj.y;
    }
    var elementInfo = new Object();
    elementInfo.Left = curleft;
    elementInfo.Top = curtop;
    elementInfo.Width = element.offsetWidth;
    elementInfo.Height = element.offsetHeight;
    return elementInfo;
}

Paff_LoginPanel.prototype.ShowAtElement = function(element,
    ignoreHideAndAnimation)
{
    var elementInfo = this._getElementInfo(element);
    this.Show(elementInfo.Left, elementInfo.Top, elementInfo.Width,
        elementInfo.Height, ignoreHideAndAnimation);
}

Paff_LoginPanel.prototype._getWindowInfo = function()
{
    var scrollX = 0, scrollY = 0, width = 0, height = 0;
    if (typeof(window.pageXOffset) == 'number')
    {
        scrollX = window.pageXOffset;
        scrollY = window.pageYOffset;
    }
    else if (document.body && (document.body.scrollLeft ||
        document.body.scrollTop))
    {
        scrollX = document.body.scrollLeft;
        scrollY = document.body.scrollTop;
    }
    else if (document.documentElement && (document.documentElement.scrollLeft 
        || document.documentElement.scrollTop))
    {
        scrollX = document.documentElement.scrollLeft;
        scrollY = document.documentElement.scrollTop;
    }
    if (typeof(window.innerWidth) == 'number')
    {
        width = window.innerWidth;
        height = window.innerHeight;
    }
    else if (document.documentElement && (document.documentElement.clientWidth 
        || document.documentElement.clientHeight))
    {
        width = document.documentElement.clientWidth;
        height = document.documentElement.clientHeight;
    }
    else if (document.body && (document.body.clientWidth ||
        document.body.clientHeight))
    {
        width = document.body.clientWidth;
        height = document.body.clientHeight;
    }
    var rect = new Object();
    rect.ScrollX = scrollX;
    rect.ScrollY = scrollY;
    rect.Width = width;
    rect.Height = height;
    return rect;
}


Paff_LoginPanel.prototype.Show = function(x, y, positionWidth,
    positionHeight, ignoreHideAndAnimation)
{
    if (!this._initialized)
        this._initialize();
    if (!ignoreHideAndAnimation && this._isShown)
        this.Hide();
    else if (this._hiddenSelects)
    {
        for (var i = 0; i < this._hiddenSelects.length; i++)
        {
            if (this._hiddenSelects[i].Element.style.visibility == 'hidden')
                this._hiddenSelects[i].Element.style.visibility =
                    this._hiddenSelects[i].Visibility;
        }
        this._hiddenSelects = null;
    }
    this._panelMask.style.position = 'absolute';
    this._panelMask.style.zIndex = this.ZIndex;
    this._panelMask.style.display = 'block';
    this._panelMask.style.visibility = 'hidden';
    this._panelMask.style.overflow = 'visible';
    this._panel.style.position = 'absolute';
    this._panel.style.display = 'block';
    this._panel.style.visibility = 'hidden';
    this._panel.className = this.CssClass;
    this._panel.style.left = '0px';
    this._panel.style.top = '0px';
    this._panelMask.style.width = this._panel.offsetWidth + 'px';
    this._panelMask.style.height = this._panel.offsetHeight + 'px';
    this._lastWindowInfo = this._getWindowInfo();
    var panelWidth = this._panel.offsetWidth;
    var panelHeight = this._panel.offsetHeight;
    var animatePropertyName, animateTargetValue, animateNextValue;
    
    this._panelMask.style.left = (x - panelWidth + positionWidth) + "px";
    animatePropertyName = 'style.left';
    animateTargetValue = 0;
    animateNextValue = panelWidth;
    
    this._panelMask.style.top = y + "px";
    
    this._panel.style.visibility = 'visible';
    this._panelMask.style.visibility = 'visible';
    this._panelMask.style.overflow = 'hidden';
    if (this._panelMask.getClientRects)
    {
        var selectBoxes = document.getElementsByTagName('select');
        var maskLeft = parseInt(this._panelMask.style.left, 10) -
            this._lastWindowInfo.ScrollX;
        var maskTop = parseInt(this._panelMask.style.top, 10) -
            this._lastWindowInfo.ScrollY;
        var maskRight = maskLeft + this._panelMask.offsetWidth;
        var maskBottom = maskTop + this._panelMask.offsetHeight;
        this._hiddenSelects = new Array();
        for (var i = 0; i < selectBoxes.length; i++)
        {
            if (selectBoxes[i].getClientRects)
            {
                var rects = selectBoxes[i].getClientRects();
                for (var j = 0; j < rects.length; j++)
                {
                    if (rects[j].top < maskBottom && maskTop < rects[j].bottom
                        && rects[j].left < maskRight && maskLeft <
                        rects[j].right)
                    {
                        this._hiddenSelects[this._hiddenSelects.length] = 
                        {
                            Element: selectBoxes[i], Visibility:
                                selectBoxes[i].style.visibility
                        };
                        selectBoxes[i].style.visibility = 'hidden';
                        break;
                    }
                }
            }
        }
    }
    this._isOpening = true;
    if (ignoreHideAndAnimation)
        this._animationHandle = window.setTimeout(new Function
            (this._variableName + '._animate(\'' + animatePropertyName + '\',' 
            + animateTargetValue + ',' + animateTargetValue + ',0,0);'), 9);
    else
    {
        this._animate(animatePropertyName, animateTargetValue, animateNextValue,
            animateNextValue > animateTargetValue ?  - ((animateNextValue -
            animateTargetValue) / 3): ((animateTargetValue - animateNextValue)
            / 3), .67);
    }
    if (!this._isShown)
    {
        this._isShown = true;
        this._lastPosition = 
        {
            X: x, Y: y, Width: positionWidth, Height: positionHeight
        };
    }
}

Paff_LoginPanel.prototype._checkForScrollResize = function()
{
    if (this._checkForScrollResizeHandle)
        window.clearTimeout(this._checkForScrollResizeHandle);
    if (this._isShown && !this._isOpening && this._lastWindowInfo)
    {
        var windowInfo = this._getWindowInfo();
        if (windowInfo.Width != this._lastWindowInfo.Width || windowInfo.Height
            != this._lastWindowInfo.Height)
            this.Hide();
        else
            this._checkForScrollResizeHandle = window.setTimeout(new Function
                ('window.' + this._variableName + '._checkForScrollResize();'),
                999);
    }
}


Paff_LoginPanel.prototype.Hide = function()
{
    if (this._isShown)
    {
        if (!this._initialized)
            this._initialize();
            
        this._panel.style.position = 'absolute';
        this._panel.style.display = 'none';
        this._panelMask.style.position = 'absolute';
        this._panelMask.style.display = 'none';
        this._isShown = false;
        this._lastPosition = null;
        if (this._hiddenSelects)
        {
            for (var i = 0; i < this._hiddenSelects.length; i++)
            {
                if (this._hiddenSelects[i].Element.style.visibility == 'hidden')
                    this._hiddenSelects[i].Element.style.visibility =
                        this._hiddenSelects[i].Visibility;
            }
            this._hiddenSelects = null;
        }
    }
}

Paff_LoginPanel.prototype.ClearPanelContent = function()
{
    while (this._panel.childNodes.length > 0)
        this._panel.removeChild(this._panel.childNodes[0]);
}

Paff_LoginPanel.prototype.SetPanelContent = function(html)
{
    this.ClearPanelContent();
    this._panel.innerHTML = html;
    this.Refresh();
}

Paff_LoginPanel.prototype.AddNodeToPanel = function(node)
{
    this._panel.appendChild(node);
    this.Refresh();
}

Paff_LoginPanel.prototype.RemoveNodeFromPanel = function(node)
{
    this._panel.removeChild(node);
    this.Refresh();
}

Paff_LoginPanel.prototype.GetPanelNodes = function()
{
    return this._panel.childNodes;
}

Paff_LoginPanel.prototype.Refresh = function()
{
    if (this._animationHandle)
        window.clearTimeout(this._animationHandle);
    if (this._isShown && this._lastPosition)
        this.Show(this._lastPosition.X, this._lastPosition.Y,
            this._lastPosition.Width, this._lastPosition.Height, true);
}

Paff_LoginPanel.prototype._initialize = function()
{
    document.body.appendChild(this._panelMask);
    this._initialized = true;
    if (this._initialContent)
        this.SetPanelContent(this._initialContent);
}

Paff_LoginPanel.prototype.Dispose = function()
{
    if (this._initialized)
    {
        if (document && document.body)
            document.body.removeChild(this._panelMask);
    }
}

Paff_LoginPanel.prototype._animate = function(propertyName, targetValue, nextValue, step, acceleration)
{
    if (this._animationHandle)
        window.clearTimeout(this._animationHandle);
    var currValue = parseInt(eval('this._panel.' + propertyName));
    if ((step < 0 && currValue < targetValue) || (step > 0 && currValue >
        targetValue) || Math.abs(step) < 1)
    {
        if (this._hiddenSelects)
        {
            for (var i = 0; i < this._hiddenSelects.length; i++)
                this._hiddenSelects[i].Element.style.visibility = 'hidden';
        }
        eval('this._panel.' + propertyName + ' = targetValue + \'px\'');
        this._panel.style.position = 'static';
        this._panelMask.style.overflow = 'visible';
        this._animationHandle = null;
        this._isOpening = false;
        this._lastWindowInfo = this._getWindowInfo();
        this._checkForScrollResizeHandle = window.setTimeout(new Function
            ('window.' + this._variableName + '._checkForScrollResize();'), 999)
            ;
    }
    else
    {
        eval('this._panel.' + propertyName + ' = nextValue + \'px\'');
        nextValue = nextValue + step;
        if (step > 0 && nextValue > targetValue)
            nextValue = targetValue;
        else if (step < 0 && nextValue < targetValue)
            nextValue = targetValue;
        step = step * acceleration;
        this._animationHandle = window.setTimeout(new Function
            (this._variableName + '._animate(\'' + propertyName + '\',' +
            targetValue + ',' + nextValue + ',' + step + ',' + acceleration + ');'), 25);
    }
}

Paff_LoginPanel.prototype._documentOnClick = function()
{
    if (this._isShown && !this._isOpening)
        this.Hide();
    if (this._originalDocumentOnClick)
        this._originalDocumentOnClick();
}