﻿
/*
    ShoveWebPart 基本代码。
    作者：shove
    时间：2007-8-2
*/

// 获取所有 Part
function ShoveWebUI_ShoveWebPart_GetParts(isWithLocked, isWithHidden)
{
    var objParts = [];
    var objDivs = document.getElementsByTagName("div");

    for (var i = 0; i < objDivs.length; i++)
    {
        // 不是本类型控件，不处理
        var ShoveWebUITypeName = objDivs[i].getAttribute("ShoveWebUITypeName");

        if (ShoveWebUITypeName != "ShoveWebPart")
        {
            continue;
        }

        // 如果不包含锁定
        if (!isWithLocked)
        {
            var LockState = objDivs[i].getAttribute("Lock");

            if (LockState == "True")
            {
                continue;
            }
        }

        // 如果是不显示的控件，不处理
        if (!isWithHidden)
        {
            if (objDivs[i].style.visibility == "hidden")
            {
                continue;
            }
        }

        objParts.push(objDivs[i]);
    }

    return objParts;
}

function ShoveWebUI_ShoveWebPart_GetParentLeft(sender)
{
    var o_ParentDiv = sender.parentNode;
    var ParentLeft = "0px";
    
    if (o_ParentDiv)
    {
        ParentLeft = (o_ParentDiv.offsetLeft + o_ParentDiv.scrollLeft) + "px";
    }
  
    if (ParentLeft == "px")
    {
        ParentLeft = "0px";
    }
    
    return ParentLeft;
}

function ShoveWebUI_ShoveWebPart_GetParentTop(sender)
{
    var o_ParentDiv = sender.parentNode;
    var ParentTop = "0px";
    
    if (o_ParentDiv)
    {
        ParentTop = (o_ParentDiv.offsetTop + o_ParentDiv.scrollTop) + "px";
    }
    
    if (ParentTop == "px")
    {
        ParentTop = "0px";
    }
    
    return ParentTop;
}

function ShoveWebUI_ShoveWebPart_GetParentWidth(sender)
{
    var o_ParentDiv = sender.parentNode;
    var ParentWidth = "0px";

    if (o_ParentDiv)
    {
        ParentWidth = o_ParentDiv.style.width;
    }

    if ((ParentWidth == "") || (ParentWidth == "auto") || (ParentWidth == "0px"))
    {
        ParentWidth = (o_ParentDiv.offsetWidth) + "px";
        
        if (ParentWidth == "px")
        {
            ParentWidth = "0px";
        }
    }
    
    if (ParentWidth == "0px")
    {
        ParentWidth = (o_ParentDiv.scrollWidth) + "px";
        
        if (ParentWidth == "px")
        {
            ParentWidth = "0px";
        }
    }

    return ParentWidth;
}

function ShoveWebUI_ShoveWebPart_OffsetLeft(sender, ParentLeft)
{
    if (typeof(sender) == "string")
    {
        sender = document.getElementById(sender);
    }
    
    if (!sender)
    {
        return;
    }
    
    var OffsetLeft = sender.getAttribute("OffsetLeft");
 
    if (!OffsetLeft)
    {
        return;
    }

    if (OffsetLeft == "")
    {
        OffsetLeft = "0px";
    }

    if (!ParentLeft)
    {
        ParentLeft = ShoveWebUI_ShoveWebPart_GetParentLeft(sender);
    }

    if (ParentLeft != OffsetLeft)
    {
        sender.style.left = parseInt(sender.style.left.replace("px", "")) - (parseInt(OffsetLeft.replace("px", "")) - parseInt(ParentLeft.replace("px", "")));

        OffsetLeft = ParentLeft;
        
        sender.setAttribute("OffsetLeft", OffsetLeft);
    }
}

window.onresize = function ShoveWebUI_ShoveWebPart_OnResize(objParts)
{
    if (document.readyState != "complete")
    {
        return;
    }

    if (!objParts)
    {
        objParts = ShoveWebUI_ShoveWebPart_GetParts(true, false);
    }
    
    if (objParts.length < 1)
    {
        return;
    }
    
    var ParentLeft = ShoveWebUI_ShoveWebPart_GetParentLeft(objParts[0]);
    
    for (var i = 0; i < objParts.length; i ++)
    {
        ShoveWebUI_ShoveWebPart_OffsetLeft(objParts[i], ParentLeft);
    }
}

document.onreadystatechange = function ShoveWebUI_ShoveWebPart_OffsetTop()
{
    var objParts = ShoveWebUI_ShoveWebPart_GetParts(true, false).sort(Sort);

    // 调用偏移 Left。
    ShoveWebUI_ShoveWebPart_OnResize(objParts);

    function Sort(obj1, obj2)
    {
        var top1 = parseInt(obj1.style.top.replace("px", ""));
        var left1 = parseInt(obj1.style.left.replace("px", ""));
        var top2 = parseInt(obj2.style.top.replace("px", ""));
        var left2 = parseInt(obj2.style.left.replace("px", ""));
        
        if ((top1 > top2) || ((top1 == top2) && (left1 > left2)))
        {
            return 1;
        }
        
        return -1;
    }

    function FilterRepeated(objArray)
    {
        if (objArray == null)
        {
            return objArray;
        }
        
        var NewArray = [];
        
        for(var i = 0; i < objArray.length; i++)
        {
            var isExist = false;
            
            for(var j = 0; j < NewArray.length; j++)
            {
                if (objArray[i].id == NewArray[j].id)
                {
                    isExist = true;
                    break;
                }
            }
            
            if (!isExist)
            {
                NewArray.push(objArray[i]);
            }
        }
        
        return NewArray;
    }

    function GetHeight(sender)
    {
        var Height = sender.style.height;
        
        if (!Height)
        {
            return 0;
        }
        
        return parseInt(Height.replace("px", ""));
    }

    function GetPrimitiveHeight(sender)
    {
        var PrimitiveHeight = sender.getAttribute("PrimitiveHeight");
        
        if (!PrimitiveHeight)
        {
            return 0;
        }
        
        if (PrimitiveHeight == "")
        {
            return 0;
        }

        return parseInt(PrimitiveHeight.replace("px", ""));
    }

    function GetScrollHeight(sender)
    {
        var ScrollHeight = sender.scrollHeight;
        
        if (!ScrollHeight)
        {
            return 0;
        }
        
        return parseInt(ScrollHeight);
    }

    function GetRealityHeight(sender)
    {
        return IsAutoHeight(sender) ? GetScrollHeight(sender) : GetHeight(sender);
    }
    
    function GetTop(sender)
    {
        var Top = sender.style.top;
        
        if (!Top)
        {
            return 0;
        }
        
        return parseInt(Top.replace("px", ""));
    }

    function GetPrimitiveTop(sender)
    {
        var PrimitiveTop = sender.getAttribute("PrimitiveTop");
        
        if (!PrimitiveTop)
        {
            return 0;
        }
        
        return parseInt(PrimitiveTop);
    }

    function IsAutoHeight(sender)
    {
        return (sender.style.height == "auto");
    }

    function IsInfluenced(sender, higher)
    {
        var HigherBottom = GetTop(higher) + GetPrimitiveHeight(higher);

        // top不低于自己的情况，不受其影响
        if (GetTop(sender) <= HigherBottom)
        {
            return false;
        }

        var Left = parseInt(sender.style.left.replace("px", ""));
        var Right = Left + parseInt(sender.style.width.replace("px", ""));
        
        var HigherLeft = parseInt(higher.style.left.replace("px", ""));
        var HigherRight = Left + parseInt(higher.style.width.replace("px", ""));

        // 控件没有覆盖住，不受其影响
        if ((Right < HigherLeft) || (Left > HigherRight))
        {
            return false;
        }

        return true;
    }
    
    // 调整顶
    var StartOffsetLocate = -1;
    
    for (var i = 0; i < objParts.length; i ++)
    {
        if (IsAutoHeight(objParts[i]))
        {
            StartOffsetLocate = i;
            
            break;
        }
    }

    if (StartOffsetLocate > (objParts.length - 2))
    {
        return;
    }

    // 保存原始高度属性
    for (var i = 0; i < objParts.length; i ++)
    {
        objParts[i].setAttribute("PrimitiveTop", GetTop(objParts[i]));
    }

    // 开始调整
    for (var i = StartOffsetLocate + 1; i < objParts.length; i ++)
    {
        var objBestUnder = objParts[0];
        var objPrimitiveBestUnder = objParts[0];

        var isHasInfluenced = false;

        for (var j = 0; j < i; j++)
        {
            if (!IsInfluenced(objParts[i], objParts[j]))
            {
                continue;
            }

            isHasInfluenced = true;

            var BestUnder = GetTop(objBestUnder) + GetRealityHeight(objBestUnder);
            var CurrentUnder = GetTop(objParts[j]) + GetRealityHeight(objParts[j]);

            if (BestUnder < CurrentUnder)
            {
                objBestUnder = objParts[j];
            }

            BestUnder = GetPrimitiveTop(objPrimitiveBestUnder) + GetPrimitiveHeight(objPrimitiveBestUnder);
            CurrentUnder = GetPrimitiveTop(objParts[j]) + GetPrimitiveHeight(objParts[j]);

            if (BestUnder < CurrentUnder)
            {
                objPrimitiveBestUnder = objParts[j];
            }
        }

        if ((!isHasInfluenced) || (objBestUnder == objParts[i]))
        {
            continue;
        }
        
        var TopOffset = (GetTop(objBestUnder) + GetRealityHeight(objBestUnder)) - (GetPrimitiveTop(objBestUnder) + GetPrimitiveHeight(objBestUnder));

        if (TopOffset < 0)
        {
            if (objParts[i].getAttribute("TopUpLimit") == "True")
            {
                continue;
            }
        }

        if ((objBestUnder == objPrimitiveBestUnder) || (TopOffset < 0))
        {
            objParts[i].style.top = (GetTop(objParts[i]) + TopOffset) + "px";
            
            continue;        
        }

        var PrimitiveTopOffset = GetPrimitiveTop(objParts[i]) - (GetPrimitiveTop(objPrimitiveBestUnder) + GetPrimitiveHeight(objPrimitiveBestUnder));

        objParts[i].style.top = (GetTop(objBestUnder) + GetRealityHeight(objBestUnder) + PrimitiveTopOffset) + "px";
    }
}

