﻿//下拉列表框项目选中和未选中时的样式表名称
var DDLIS_SELECTED_CLASSNAME = "ddlis_selected";
var DDLIS_UNSELECTED_CLASSNAME = "ddlis_unselected";


function CDropDownList_CItem(itemText, itemValue)
{
    this.itemText = itemText;
    this.itemValue = itemValue;
}


//objStr 当前对象的名称，字符串类型
//targetID 装载 DropDownList 的 HTML 元素标签 ID 名称
function CDropDownList(objStr, targetID)
{
    this.objStr = objStr;
    
    /*下拉列表框相关对象开始*/
    this.target = document.getElementById(targetID);
    this.targetAsst = null; //为了兼容浏览器及各标准，而设置的辅助层
    
    this.titleBox = null;
    
    this.controller = null; //控制器
    this.controllerImg = null; //控制器图片对象
    this.collapsedImgURL = ""; //下拉列表框收起时控制器图片地址
    this.expandingImgURL = ""; //下拉列表框展开时控制器图片地址
    
    this.listBoard = null; //下拉列表框项目框
    this.listBoardAsst = null; //为了兼容浏览器及各标准，而设置的辅助层
    /*下拉列表框相关对象结束*/
    
    /*项目数据开始*/
    this.itemArr = new Array(); //项目数组
    this.selectedItemIndex = -1; //已经选中的项目数组索引
    /*项目数据结束*/
    
    this.ClearChildNodes = CDropDownList_ClearChildNodes;
    
    /*创建下拉列表框的相关函数开始*/
    this.Create = CDropDownList_Create;
    this.BindTarget = CDropDownList_BindTarget;
    this.BindTitleBox = CDropDownList_BindTitleBox;
    this.BindController = CDropDownList_BindController;
    this.BindListBoard = CDropDownList_BindListBoard;
    this.SetStyle = CDropDownList_SetStyle;
    /*创建下拉列表框的相关函数结束*/
    
    this.CreateItemID = CDropDownList_CreateItemID; //根据项目索引创建项目的 ID 值
    
    /*项目操作开始*/
    this.AddItem = CDropDownList_AddItem;
    this.AddItemFromItemData = CDropDownList_AddItemFromItemData;
    this.ModifyItem = CDropDownList_ModifyItem;
    this.DeleteItem = CDropDownList_DeleteItem;
    this.SelectItem = CDropDownList_SelectItem;
    this.GetSelectedItemIndex = CDropDownList_GetSelectedItemIndex;
    this.GetSelectedItemText = CDropDownList_GetSelectedItemText;
    this.GetSelectedItemValue = CDropDownList_GetSelectedItemValue;
    this.GetItemCnt = CDropDownList_GetItemCnt;
    /*项目操作结束*/
    
    this.skipDocumentBodyEvent = false; //在 document.body 上触发鼠标事件时，是否跳过该鼠标事件
    this.OnChngListBoard = CDropDownList_OnChngListBoard; //展开或收起下拉列表框项目框
    this.OnItemMouseOver = CDropDownList_OnItemMouseOver;
    this.OnItemMouseOut = CDropDownList_OnItemMouseOut;
    this.OnItemSelected = CDropDownList_OnItemSelected;
    this.SetEventState = CDropDownList_SetEventState;
    
    
    //为 document.body 设置鼠标事件
    //使 listBoard 在展开时，点击 document.body 时可以收起 listBoard
    var mousedownEvent = document.body.getAttribute("onmousedown");
    if (mousedownEvent == null)
    {
        mousedownEvent = this.objStr + ".OnChngListBoard('documentBody');";
    }
    else
    {
        mousedownEvent += ";" + this.objStr + ".OnChngListBoard('documentBody');";
    }
    
    if (window.attachEvent)
    {
        document.body.attachEvent("onmousedown", function (){eval(mousedownEvent);});
    }
    else
    {
        document.body.setAttribute("onmousedown", mousedownEvent);
    }
}


//消除 node 结点下的所有子结点
function CDropDownList_ClearChildNodes(node)
{
    while (node.hasChildNodes())
    {
        node.removeChild(node.childNodes[0]);
    }
}


//在 target 上创建控件
//collapsedImgURL 下拉列表框收起时控制器图片地址
//expandingImgURL 下拉列表框展开时控制器图片地址
function CDropDownList_Create(collapsedImgURL, expandingImgURL)
{
    var targetAsstID = this.target.id + "_asst";
    var titleBoxID = this.target.id + "_titleBox";
    var controllerID = this.target.id + "_controller";
    var listBoardID = this.target.id + "_listBoard";
    
    //不能拆开分步插入，那样会使先前插入的对象消失
    //浮动不能通过脚本的 style.float 指定，所以在这里指定
    //overflow、text-align 属性为固定值，所以在这里一并指定
    this.target.innerHTML = "<div id=\"" + targetAsstID + "\" class=\"Searchlist_frame\" style=\"float:left;overflow:hidden;text-align:left;\">" +
                            "  <div id=\"" + titleBoxID + "\" style=\"float:left;overflow:hidden;text-align:left;line-height: 22px;padding-left: 3px;\">" +
                            "  </div>" +
                            "  <div id=\"" + controllerID + "\" style=\"float:right;overflow:hidden;text-align:center;\">" +
                            "  </div>" +
                            "</div>";
    this.BindTarget(targetAsstID);
    this.BindTitleBox(titleBoxID);
    this.BindController(controllerID, collapsedImgURL, expandingImgURL);
    
    
    //创建下拉列表框项目框
    var listBoardAsst = document.createElement("div");
    listBoardAsst.style.textAlign = "left";
    
    var listBoard = document.createElement("div");
    listBoard.id = listBoardID;
    listBoard.style.display = "none"; //默认 listBoard 没有展开
    listBoard.appendChild(listBoardAsst);
    
    document.body.appendChild(listBoard);
    this.BindListBoard(listBoard, listBoardAsst);
}


function CDropDownList_BindTarget(targetAsstIDOrTargetAsst)
{
    this.targetAsst = (typeof(targetAsstIDOrTargetAsst) == "string") ? document.getElementById(targetAsstIDOrTargetAsst) : targetAsstIDOrTargetAsst;
    
    //设置鼠标事件，使点击 targetAsst 时，可以展开或收起下拉列表框项目框
    var targetAsstMouseDownEvent = this.objStr + ".SetEventState(true);" + this.objStr + ".OnChngListBoard('self');";
    var targetAsstMouseUpEvent = this.objStr + ".SetEventState(false);";
    if (window.attachEvent)
    {
        this.targetAsst.attachEvent("onmousedown", function (){eval(targetAsstMouseDownEvent);return false;});
        this.targetAsst.attachEvent("onmouseup", function (){eval(targetAsstMouseUpEvent);return false;});
    }
    else
    {
        this.targetAsst.setAttribute("onmousedown", targetAsstMouseDownEvent + "return false;");
        this.targetAsst.setAttribute("onmouseup", targetAsstMouseUpEvent + "return false;");
    }
}


function CDropDownList_BindTitleBox(titleBoxIDOrTitleBox)
{
    this.titleBox = (typeof(titleBoxIDOrTitleBox) == "string") ? document.getElementById(titleBoxIDOrTitleBox) : titleBoxIDOrTitleBox;
    this.titleBox.style.cursor = "default";
    this.ClearChildNodes(this.titleBox);
}


//绑定控制器，默认 listBoard 没有展开
function CDropDownList_BindController(controllerIDOrController, collapsedImgURL, expandingImgURL)
{
    this.controller = (typeof(controllerIDOrController) == "string") ? document.getElementById(controllerIDOrController) : controllerIDOrController;
    this.collapsedImgURL = collapsedImgURL;
    this.expandingImgURL = expandingImgURL;
    this.ClearChildNodes(this.controller);
    
    var img = document.createElement("IMG");
    img.src = collapsedImgURL; //因为默认 listBoard 没有展开
    img.style.cursor = "pointer";
    img.height = 20;
    img.width = 20;
    
    this.controllerImg = img;
    this.controller.appendChild(img);
}


//绑定 listBoard，默认 listBoard 没有展开
function CDropDownList_BindListBoard(listBoardIDOrListBoard, listBoardAsstIDOrListBoardAsst)
{
    this.listBoard = (typeof(listBoardIDOrListBoard) == "string") ? document.getElementById(listBoardIDOrListBoard) : listBoardIDOrListBoard;
    this.listBoardAsst = (typeof(listBoardAsstIDOrListBoardAsst) == "string") ? document.getElementById(listBoardAsstIDOrListBoardAsst) : listBoardAsstIDOrListBoardAsst;
    
    this.listBoard.style.display = "none"; //因为，默认 listBoard 没有展开，为避免与 BindController 中的指示不一致，即使前面已经设置，这里仍再设置一次
}


//targetWidth、targetHeight 包含 borderWidth
//targetWidth、targetHeight、borderWidth、titleBoxWidth，数字类型，其它控件的长宽由这四个参数计算得出
//borderClr 边框颜色
//bgClr 边框大小
function CDropDownList_SetStyle(targetWidth, targetHeight, borderWidth, titleBoxWidth, borderClr, bgClr)
{
    this.target.style.width = (targetWidth + 3) + "px";
    this.target.style.height = targetHeight + "px";
    this.targetAsst.style.borderWidth = borderWidth + "px";
//    this.targetAsst.style.borderStyle = "solid";
//    this.targetAsst.style.borderColor = borderClr;
    this.targetAsst.style.backgroundColor = bgClr;
    
    this.titleBox.style.width = titleBoxWidth + "px";
    this.titleBox.style.height = (targetHeight - borderWidth*2) + "px";
    
    this.controller.style.width = (targetWidth - borderWidth*2 - titleBoxWidth) + "px";
    this.controller.style.height = (targetHeight - borderWidth*2) + "px";
    
    this.listBoard.style.width = (targetWidth + 3) + "px";
    this.listBoardAsst.style.borderWidth = borderWidth + "px";
    this.listBoardAsst.style.borderStyle = "solid";
    this.listBoardAsst.style.borderColor = borderClr;
    this.listBoardAsst.style.backgroundColor = bgClr;
}


//根据项目索引创建项目的 ID 值
function CDropDownList_CreateItemID(itemIndex)
{
    return this.target.id + "_item_" + itemIndex;
}


//追加一个项目
function CDropDownList_AddItem(itemText, itemValue)
{
    var newItemIndex = this.itemArr.length;
    this.itemArr[newItemIndex] = new CDropDownList_CItem(itemText, itemValue);
    
    this.AddItemFromItemData(newItemIndex);
}


//将 itemArr 中的一项数据添加到下拉列表框项目框中
//此函数不应该公开，否则可能造成实际数据与显示的不一致
function CDropDownList_AddItemFromItemData(itemIndex)
{
    var itemText = this.itemArr[itemIndex].itemText;
    var itemValue = this.itemArr[itemIndex].itemValue;

    if (this.listBoardAsst)
    {
        var li = document.createElement("div");
        li.style.cursor = "default";
        li.style.width = "100%";
        li.className = DDLIS_UNSELECTED_CLASSNAME;
        li.id = this.CreateItemID(itemIndex);
        
        //设置鼠标事件
        var liMouseDownEvent = this.objStr + ".SetEventState(true);"; //阻止 listBoard 收起
        //onmouseup 时主动收起 listBoard，因为如果 listBoard 展开到了 body 的 margin 等不响应 document.body 鼠标事件的区域，就无法自动收起 listBoard 了。
        var liMouseUpEvent = this.objStr + ".OnItemSelected(" + itemIndex + ");" +
                             this.objStr + ".OnChngListBoard('self');" +
                             this.objStr + ".SetEventState(false);";
        var liMouseOverEvent = this.objStr + ".OnItemMouseOver(document.getElementById('" + li.id + "'));";
        var liMouseOutEvent = this.objStr + ".OnItemMouseOut(document.getElementById('" + li.id + "'));";
        if (window.attachEvent)
        {
            li.attachEvent("onmousedown", function (){eval(liMouseDownEvent);return false;});
            li.attachEvent("onmouseup", function (){eval(liMouseUpEvent);return false;});
            li.attachEvent("onmouseover", function (){eval(liMouseOverEvent);return false;});
            li.attachEvent("onmouseout", function (){eval(liMouseOutEvent);return false;});
        }
        else
        {
            li.setAttribute("onmousedown", liMouseDownEvent + "return false;");
            li.setAttribute("onmouseup", liMouseUpEvent + "return false;");
            li.setAttribute("onmouseover", liMouseOverEvent + "return false;");
            li.setAttribute("onmouseout", liMouseOutEvent + "return false;");
        }
        
        var t = document.createTextNode(itemText);
        li.appendChild(t);
        this.listBoardAsst.appendChild(li);
    }
}


//修改一个项目
function CDropDownList_ModifyItem(itemIndex, newItemText, newItemValue)
{
    if (itemIndex < 0 || itemIndex >= this.itemArr.length)
    {
        return;
    }
    
    var li = document.getElementById(this.CreateItemID(itemIndex)); //要修改的项目对象
    this.ClearChildNodes(li);
    var t = document.createTextNode(newItemText);
    li.appendChild(t);
    this.itemArr[itemIndex].itemText = newItemText;
    this.itemArr[itemIndex].itemValue = newItemValue;
    
    if (itemIndex == this.GetSelectedItemIndex())
    {
        //修改了的项目就是已经选中了的项目，要重新选中，以便更新显示选中项目的文字
        this.SelectItem(itemIndex);
    }
}


//删除一个项目
function CDropDownList_DeleteItem(itemIndex)
{
    if (itemIndex < 0 || itemIndex >= this.itemArr.length)
    {
        return;
    }
    
    this.itemArr.splice(itemIndex, 1);
    
    //由于下拉列表框项目框中的项目是与 this.itemArr 的索引相关的
    //而删除数组会引起索引的改变，故重新生成下拉列表框中的项目
    this.ClearChildNodes(this.listBoardAsst);
    for (var i = 0; i < this.itemArr.length; i++)
    {
        this.AddItemFromItemData(i);
    }
    
    if (itemIndex < this.GetSelectedItemIndex())
    {
        //删除的项目是在已经选中的项目的前面
        this.SelectItem(this.GetSelectedItemIndex() - 1);
    }
    else if (itemIndex == this.GetSelectedItemIndex())
    {
        //删除的项目就是已经选中的项目
        this.SelectItem(-1);
    }
}


//选中一个项目
function CDropDownList_SelectItem(itemIndex)
{
    if (itemIndex < 0 || itemIndex >= this.itemArr.length)
    {
        this.ClearChildNodes(this.titleBox);
        this.titleBox.appendChild(document.createTextNode(""));
        this.selectedItemIndex = -1;
    }
    else
    {
        this.ClearChildNodes(this.titleBox);
        var t = document.createTextNode(this.itemArr[itemIndex].itemText);
        this.titleBox.appendChild(t);
        this.selectedItemIndex = itemIndex;
    }
}


//返回选中项目的索引
function CDropDownList_GetSelectedItemIndex()
{
    return this.selectedItemIndex;
}


//返回选中项目的文字
function CDropDownList_GetSelectedItemText()
{
    if (this.selectedItemIndex < 0 || this.selectedItemIndex >= this.itemArr.length)
    {
        return null;
    }
    
    return this.itemArr[this.selectedItemIndex].itemText;
}


//返回选中项目的值
function CDropDownList_GetSelectedItemValue()
{
    if (this.selectedItemIndex < 0 || this.selectedItemIndex >= this.itemArr.length)
    {
        return null;
    }
    
    return this.itemArr[this.selectedItemIndex].itemValue;
}


//返回项目数
function CDropDownList_GetItemCnt()
{
    return this.itemArr.length;
}


//当改变下拉列表框项目框展开收起时
function CDropDownList_OnChngListBoard(sender)
{
    if (sender == "documentBody")
    {
        //事件来源于 document.body
        if (this.skipDocumentBodyEvent || this.listBoard.style.display == "none")
        {
            //如果需要跳过此事件（controller 也触发了该事件就该跳过）
            //或者 listBoard 本来就没有展开
            return;
        }
    }
    
    if (this.listBoard.style.display == "none")
    {
        //已经收起，展开之
        //确定展开位置
        var x = this.targetAsst.offsetLeft;
        var y = this.targetAsst.offsetTop + this.targetAsst.offsetHeight;
        var pe = this.targetAsst.offsetParent;
        while (pe)
        {
            x += pe.offsetLeft;
            y += pe.offsetTop;
            pe = pe.offsetParent;
        }
        this.listBoard.style.position = "absolute";
        this.listBoard.style.left = x + "px";
        this.listBoard.style.top = y + "px";
        this.listBoard.style.display = "block";
        
        this.controllerImg.src = this.expandingImgURL;
    }
    else
    {
        //已经展开，收起之
        this.listBoard.style.display = "none";
        this.controllerImg.src = this.collapsedImgURL;
    }
}


//当鼠标移到项目上时
function CDropDownList_OnItemMouseOver(sender)
{
    sender.className = DDLIS_SELECTED_CLASSNAME;
}


//当鼠标移出项目时
function CDropDownList_OnItemMouseOut(sender)
{
    sender.className = DDLIS_UNSELECTED_CLASSNAME;
}


function CDropDownList_OnItemSelected(selectedItemIndex)
{
    this.SelectItem(selectedItemIndex);
}


//skipDocumentBodyEvent 表示是否允许 document.body 事件，默认 false。
function CDropDownList_SetEventState(skipDocumentBodyEvent)
{
    this.skipDocumentBodyEvent = skipDocumentBodyEvent;
}