function myList(sListId, bAllowSorting, bByRank) {
    var oList = document.createElement("div");
    oList.className = "list";
    oList.id = sListId;
    oList.sortable = bAllowSorting;
    oList.byRank = bByRank;
    oList.sortTo = null;
    oList.iSelected = 0;


    oList.newOption = function(text, value, rank) {
        this.appendChild( myOption(text, value, rank) );
    }


    oList.addOptions = function(aOptions) {
        for(var i; i < aOptions.length;i++) {
            this.addOption(aOption[i]);
        }
    }

    oList.addOption = function(option) {
        try {
            this.appendChild(myOption(option.sText, option.sValue, option.iRank));
        }catch(e){ }
    }

    oList.insertOption = function(option){
        try{
            this.insertBefore(myOption(option.sText, option.sValue, option.iRank), this.sortTo);
        }catch(e){ }
    }

    oList.deleteOptions = function(aIndexs) {
        for(var i; i < aIndexs.length;i++) {
            this.deleteOption(aIndexs[i]);
        }
    }

    oList.deleteOption = function(node){
        try {
            this.removeChild(node);
        } catch(e) {
            window.status = e.message;
        }
    }

    oList.insertInOrder = function() {
        try {
            movedItems=0;
            for (var i = 0; i < oMover.activeList.childNodes.length; i++) {
                if (oMover.activeList.childNodes[i].selected) {
                    for (var a = 0; a < this.childNodes.length; a++) {
                        if (this.childNodes[a].iRank > oMover.activeList.childNodes[i].iRank) {
                            oMover.activeList.childNodes[i].setSelected();
                            var element = this.insertBefore(oMover.activeList.childNodes[i], this.childNodes[a]);
                            i--;
                            movedItems++;
                            break;
                        }
                    }
                }
                if (oMover.activeList.iSelected <= 0) {
                    break;
                } 
            }
        } catch(e) {
                window.status = e.description; 
        } 
        return;
    }

    oList.insertAtCursor = function() {
        var movedItems = 0;
        for(var i = 0; i < oMover.activeList.childNodes.length; i++) {
            if(oMover.activeList.childNodes[i].selected) {
                oMover.activeList.childNodes[i].setSelected();
                try {
                    var ele = this.insertBefore(oMover.activeList.childNodes[i], this.sortTo.nextSibling);
                } catch(e) {
                    var ele = this.appendChild(oMover.activeList.childNodes[i]);
                }
                i--;
                movedItems++;
            }
            if(oMover.activeList.iSelected <= 0) {
                break;
            } 
        }
        oMover.activeList.iSelected = 0;
        return;
    }


    oList.sort = function() {
        var sType = typeof this.sortTo;
        if (this.sortable && sType == "object" && this.sortTo) {
            oMover.reset();
            for (var a = 0; a < this.childNodes.length; a++) {
                if(this.childNodes[a].selected) {
                    oMover.newValue(this.childNodes[a].sText, this.childNodes[a].sValue, this.childNodes[a].iRank);
                    this.childNodes[a].remove = true;
                }
            }

            var sortTo = this.sortTo.nextSibling;
            for (var c = oMover.values.length - 1; c >= 0; c--) {
                try {
                    var oMyOption = myOption(oMover.values[c][0], oMover.values[c][1], oMover.values[c][2]);
                    try {
                        var ele = this.insertBefore(oMyOption, sortTo);
                        ele.setSelected();
                    } catch(e) {
                        this.appendChild(oMyOption);
                    }
                } catch(e) {
                    window.status = e.message;
                }
            }

            for(var b = this.childNodes.length - 1; b >= 0 ; b--) {
                if(this.childNodes[b].remove) {
                    this.removeChild( this.childNodes[b] );
                }
            }
            oMover.reset();
            this.sortTo = null;
        }
        return false;
    } 

    oList.resetAllOptions = function(ele) {
        for(var i = 0; i < this.childNodes.length; i++) {
            if(this.childNodes[i] != ele && this.childNodes[i].selected) {
                this.childNodes[i].setSelected();
            }
        }
        return;
    }

    oList.onmouseup = function(e) {
        var evt = (e ? e: window.event);
        oMover.drag = false;
        if(oMover.activeList.iSelected > 0) {
            var srcList = oMover.activeList;
            if(this.id != srcList.id) {
                if(this.byRank) {
                    window.status ="in Order";
                    this.insertInOrder();
                } else {
                    this.insertAtCursor();
                }
            } else {
                this.sort();
            }
        }
        this.sortTo = null;
        return false;
    }

    oList.onmousedown = function(e) {
        var evt = (e ? e: window.event);
        oMover.reset();
        oMover.activeList = this;
        oMover.drag = true;
        oMover.src = this.id;
        return false;
    }

    var oContainer = document.createElement("div");
    oContainer.className = "container";
    oContainer.appendChild(oList);

    oContainer.buildList = function(sValues, recordDelimiter, valueDelimiter) {
        var aValues = sValues.split(recordDelimiter);
        for (var i = 0; i < aValues.length; i++) {
            var aData = aValues[i].split(valueDelimiter);
            if(aData[0]) {
                this.childNodes[0].newOption(aData[1], aData[0], i);
            }
        }
        return false;
    } 
    return oContainer;
}

function myOption ( sText, sValue, iRank ) {
    var oOption = document.createElement("div");
    oOption.sText = sText;
    oOption.sValue = sValue;
    oOption.iRank = iRank
    oOption.selected = false;
    oOption.contentEditable = false;
    oOption.className = "option";
    oOption.innerHTML = sText;
    oOption.moved = false;
    oOption.sort = false;

    oOption.setSelected = function() {
        this.selected = !this.selected;
        this.className = ( this.selected ? "optionSelected" : "option");
        try {
            if(this.selected) {
                this.parentNode.iSelected++;
            } else {
                if (this.parentNode.iSelected > 0) {
                    this.parentNode.iSelected--;
                }
            }
        } catch(e){}
        return;
    }

    oOption.onmouseup = function(e) {
        this.parentNode.sortTo = this;
        if(oMover.drag && this.parentNode.sortable) {
            this.parentNode.drag = false;
            this.style.borderBottom = "0px none #000000";
        }
        return;
    }

    oOption.onmousedown = function(e) {
        var evt = (e ? e: window.event);
        if(this.parentNode.sortable) {
            this.parentNode.resetAllOptions(this);
        }
        this.setSelected();
        return;
    }

    oOption.onmouseover = function() {
        if(oMover.drag && this.parentNode.sortable) {
            this.style.borderBottom = "2px dashed #000000";
        }
        return;
    }

    oOption.onmouseout = function() {
        this.parentNode.sortTo = null;
        this.style.borderBottom = "0px none #000000";
        return;
    }
    return oOption;
}


function Util() {

    Util.prototype.removeAllChildren = function(oObj) {
        while(oObj.childNodes.length) {
            oObj.removeChild(oObj.childNodes[0]);
        }
        return false;
    }

    Util.prototype.resetForm = function(aList) {
        try {
            for(var x = 0 ; x < aList.length ; x++) {
                    var list = document.getElementById(aList[x]);
                    while(list.childNodes.length){
                    list.deleteOption(list.childNodes[0]);
                }
            }
        }catch(e) {
            window.status = e.description;
        }
        return;
    }

    Util.prototype.processSelectedList = function(sTextField, aList) {
        var aTextField = document.getElementById(sTextField);
        var items = "";
        for(var x = 0 ; x < aList.length; x++) {
	        var list = document.getElementById(aList[x]);	
	        for(var i = 0; i < list.childNodes.length; i++) {
		        if(i > 0)
		        items += ", ";		
		        items += list.childNodes[i].sValue; 		
	        }
        }
        aTextField.value = items;
        return;
    }

    Util.prototype.sort = function(sListId, direction) {
        var oList = document.getElementById(sListId);
        var iNumberSelected = 0;
        var iNodes = oList.childNodes.length;
        for (var a = 0; a < iNodes; a++) {
        if (oList.childNodes[a].selected) {
            iNumberSelected++;
        }
    }

    for(var b = 0; b < iNumberSelected; b++) {
        switch(direction) {
            case "up":
            case "end":
                for(var c = 0; c < iNodes; c++) {
                    if(oList.childNodes[c].selected) {
                        this.moveElement(oList, c, direction);
                        break;
                    }
                }
                break;
            default:
                for(var d = iNodes -1; d >=0; d--) {
                    if(oList.childNodes[d].selected) {
                        this.moveElement(oList, d, direction);
                        break;
                    }
                }
            break;
        }
    }

    for(var e = iNodes -1; e >= 0 ; e--) {
        if(oList.childNodes[e].sSelected) {
            oList.childNodes[e].setSelected();
            oList.childNodes[e].sSelected = false;
            }
        }
        return false;
    }

    Util.prototype.moveElement = function(l, i, direction) {
        l.childNodes[i].sSelected = true;
        l.childNodes[i].setSelected();
        try {
            if(direction == "up" && i > 0 ) { l.insertBefore(l.childNodes[i], l.childNodes[i].previousSibling); }
            if(direction == "down") { l.insertBefore(l.childNodes[i].nextSibling, l.childNodes[i]); }
            if(direction == "top") { l.insertBefore(l.childNodes[i],l.firstChild); }
            if(direction == "end") { l.appendChild(l.childNodes[i]); }
        } catch(e) {
            window.status = "moveElement();";
        }
        return false;
    }

    Util.prototype.add = function(listFrom , listTo) {
        var a = document.getElementById(listFrom);
        var b = document.getElementById(listTo);
        oMover.activeList = a;
        b.insertAtCursor();
        return;
    }

    Util.prototype.remove = function(listTo, listFrom) {
        this.add(listFrom, listTo);
    }
}


/* Object for hlding the objects to be sorted or drug to anoter list. */
function ObjectMover() {
    this.values = new Array();
    this.drag = false;
    this.src = "";
    this.activeList = "";

    ObjectMover.prototype.reset = function() {
        this.values = new Array();
        this.drag = false;
        this.src = null;
        var icon = document.getElementById("dragNdrop");
        //revisit
        //icon.style.display = "none";
        //icon.style.top = -1000;
        //icon.style.left = -1000;
        return false;
    }

    ObjectMover.prototype.newValue = function(name, value, rank) {
        this.values.push([name, value, rank]);
        return false;
    }
    return false;
}


// Custom Array Function for IE 5.0
// missing push, pop, Shift, Slice, Splice, Unshift
function isUndefined(a) {
    return typeof a == 'undefined';
}

if (isUndefined(Array.prototype.push) == true) {
    Array.prototype.push = function() {
        var currentLength = this.length;
        for (var i = 0; i < arguments.length; i++) {
            this[currentLength + i] = arguments[i];
        }
        return this.length;
    }
}
