PLU = new Object();

PLU.Browser = function ()
{
    var ua = navigator.userAgent;
    var msie = ua.indexOf("MSIE") != -1;
    var gecko = ua.indexOf("Gecko") != -1 && navigator.userAgent.indexOf("like Gecko") == -1;
    var khtml = ua.indexOf("KHTML") != -1;
    var opera = ua.indexOf("Opera") != -1;
    var firefox = ua.indexOf("Firefox") != -1;
    var netscape = ua.indexOf("Netscape") != -1;
    
    var x11 = ua.indexOf("X11") != -1;
    var macos = ua.indexOf("Macintosh") != -1;
    var windows = ua.indexOf("Windows") != -1;
    var windowsNT = ua.indexOf("Windows NT") != -1;
    
    var version = 0.0;
    
    if(msie)
        var version = new Number(ua.substring(ua.indexOf("MSIE") + 5, ua.indexOf(";", ua.indexOf("MSIE") + 5)));
    else if(firefox)
        var version = new Number(ua.substring(ua.lastIndexOf("/") + 1, ua.indexOf(".", ua.lastIndexOf("/"))));
    else
        var version = navigator.appVersion;
        
    return {
        MSIE: msie,
        GECKO: gecko,
        KHTML: khtml,
        OPERA: opera,
        X11: x11,
        MACOS: macos,
        WINDOWS: windows,
        WINNT: windowsNT,
        VERSION: version
    };
}();

if(window.XMLHttpRequest)
    PLU.HttpRequest = window.XMLHttpRequest;
else if(window.ActiveXObject)
    PLU.HttpRequest = function () { return new ActiveXObject("Microsoft.XMLHTTP"); };

PLU.Event = function ()
{
    function copyEventData (evtMoz, evtIE)
    {
        if(evtMoz.target)
        {
            for(prop in evtMoz)
            {
                eval("PLU.Event." + prop + " = evtMoz." + prop);
            }
            PLU.Event.offsetX = 0;
            PLU.Event.offsetY = 0;
            PLU.Event.stopPropagation = function () { evtMoz.stopPropagation(); };
            PLU.Event.preventDefault = function () { evtMoz.preventDefault(); };
        }
        else if(evtIE.srcElement)
        {
            PLU.Event.target = evtIE.srcElement;
            PLU.Event.pageX = evtIE.clientX; // + document.body.scrollLeft + document.documentElement.scrollLeft;
            PLU.Event.pageY = evtIE.clientY; // + document.body.scrollTop + document.documentElement.scrollTop;
            
            for(prop in evtIE)
            {
                try
                {
                    eval("PLU.Event." + prop + " = evtIE." + prop);
                }
                catch(e)
                {
                }
            }
            
            PLU.Event.stopPropagation = function () { event.cancelBubble = true; };
            PLU.Event.preventDefault = function () { event.returnValue = false; };
        }
    }
    
    return {
        addListener: function (elem, evtName, handler)
        {
            if(PLU.SyntheticEvent.isRegisteredEvent(evtName))
            {
                PLU.SyntheticEvent.addListener(elem, evtName, handler);
            }
            else
            {
                if(!elem)
                    elem = window;
                    
                if(elem == window && evtName != "load" && navigator.userAgent.indexOf("MSIE") != -1)
                    elem = document;
                    
                if(elem.addEventListener)
                    elem.addEventListener(evtName, function (evt) { copyEventData(evt, window.event); handler(); }, false);
                else if(elem.attachEvent)
                    elem.attachEvent("on" + evtName, function (evt) { copyEventData(evt, window.event); handler(); });
                else
                {                
                    if(typeof(eval("elem.on" + evtName)) == "function")
                    {                    
                        existingHandler = eval("elem.on" + evtName);
                        
                        eval("elem.on" + evtName + " = function (evt) { if(evt.target) PLU.Event.target = evt.target; else if(window.event) PLU.Event.target = event.srcElement; existingHandler(); handler(); };");
                    }
                    else
                        eval("elem.on" + evtName + " = function (evt) { if(evt.target) PLU.Event.target = evt.target; else if(window.event) PLU.Event.target = event.srcElement; handler(); };");
                }                
            }
        }
    };
}();

PLU.SyntheticEvent = function ()
{
    var listeners = [];
    var registeredEvents = [];
    
    return {
        addListener: function (elem, evtName, handler)
        {
            if(this.isRegisteredEvent(evtName) && !this.isInitiated(evtName))
                this.initEvent(evtName);
                
            listeners[listeners.length] = {elem: elem, evtName: evtName, handler: handler};
        },
        
        fireEvent: function (evtName)
        {
            if(arguments.length > 1)
                elem = arguments[1];
            else
                elem = null;

            for(index = 0; index < listeners.length; index++)
            {
                if(listeners[index].evtName == evtName)
                {
                    if((!listeners[index].elem) || (listeners[index].elem && listeners[index].elem == elem))
                    {
                        PLU.Event.target = elem;
                        listeners[index].handler();
                    }
                }
            }
        },
        
        registerEvent: function (evtName, initFn)
        {
            registeredEvents[registeredEvents.length] = {evtName: evtName, initFn: initFn, initiated: initFn == null};
        },
        
        isRegisteredEvent: function (evtName)
        {
            for(var index = 0; index < registeredEvents.length; index++)
            {
                if(registeredEvents[index].evtName == evtName)
                    return true;
            }
            return false;
        },
        
        isInitiated: function (evtName)
        {
            for(var index = 0; index < registeredEvents.length; index++)
            {
                if(registeredEvents[index].evtName == evtName)
                    return registeredEvents[index].initiated;
            }
            return false;
        },
        
        initEvent: function (evtName)
        {
            for(var index = 0; index < registeredEvents.length; index++)
            {
                if(registeredEvents[index].evtName == evtName)
                {
                    if(!registeredEvents[index].initiated)
                    {
                        registeredEvents[index].initFn();
                        registeredEvents[index].initiated = true;
                    }
                }
            }
        }
    };
}();

PLU.Array = function ()
{
    return {
        indexOf: function (haystack, needle)
        {
            if(haystack.indexOf)
                return haystack.indexOf(needle);
            else
            {
                for(index = 0; index < haystack.length; index++)
                {
                    if(haystack[index] == needle)
                        return index;
                }
            }
            return -1;
        },
        
        merge: function (a1)
        {
            for(index = 1; index < arguments.length; index++)
            {
                a2 = arguments[index];
                
                for(a2_index = 0; a2_index < a2.length; a2_index++)
                {
                    a1[a1.length] = a2[a2_index];
                }
            }
            
            return a1;            
        }
    };
}();

PLU.DOM = function ()
{
    var parseSelector = function (selector)
    {
        dotIndex = selector.indexOf(".");
        hashIndex = selector.indexOf("#");
        if(dotIndex == -1)
            className = "";
        else
            className = selector.substring(dotIndex + 1);
            
        if(hashIndex == -1)
            id = "";
        else
        {
            if(dotIndex != -1)
                id = selector.substring(hashIndex + 1, dotIndex);
            else
                id = selector.substring(hashIndex + 1);
        }

        if(selector.charAt(0) != "#" && selector.charAt(0) != ".")
        {
            tagName = selector;
            if(dotIndex != -1)
                tagName = selector.substring(0, dotIndex);
            if(tagName.indexOf("#") != -1)
                tagName = tagName.substring(0, tagName.indexOf("#"));
        }
        else
            tagName = "*";
            
        return {tagName: tagName, id: id, className: className};
    };
    
    return {
        isParentOf: function (parentNode, childNode)
        {
            do
            {
                if(childNode.parentNode == parentNode)
                    return true;
            }while(childNode = childNode.parentNode);
            return false;
        },
        
        hasClass: function (elem, className)
        {
            if(!elem.getAttribute)
                return false;
  
            if(typeof(elem.getAttribute("class")) == "string")
                elemClass = elem.getAttribute("class");
            else
                elemClass = elem.className;

            var classList = elemClass.indexOf(" ") != -1 ? elemClass.split(" ") : [elemClass];
            return PLU.Array.indexOf(classList, className) != -1;
        },
        
        getElementById: function (id)
        {
            if(document.getElementById)
                return document.getElementById(id);
            else if(document.all)
                return document.all(id);
        },
        
        find: function (selector)
        {
            var baseElem;
            if(arguments.length > 1)
                baseElem = arguments[1];
            if(!baseElem)
                baseElem = document;

            var selectorParsed = parseSelector(selector);
            
            elems = baseElem.getElementsByTagName(selectorParsed.tagName);

            keep = [];
            for(var index = 0; index < elems.length; index++)
            {
                if(selectorParsed.id && elems[index].id != selectorParsed.id)
                    continue;
                if(selectorParsed.className && !this.hasClass(elems[index], selectorParsed.className))
                    continue;
                keep[keep.length] = elems[index];
            }            

            return keep;
        },
        
        findUp: function (selector, elem)
        {
            var selectorParsed = parseSelector(selector);
            var keep = [];
            do
            {
                if(selectorParsed.className && !PLU.DOM.hasClass(elem, selectorParsed.className))
                    continue;
                if(selectorParsed.id && elem.id != selectorParsed.id)
                    continue;
                if(selectorParsed.tagName != "*" && elem.nodeName.toUpperCase() != selectorParsed.tagName.toUpperCase())
                    continue;
                keep[keep.length] = elem;
            }while(elem = elem.parentNode);
            
            return keep;
        },
        
        elemOffsetX: function (elem)
        {
            var offset = 0;
            
            /*if(PLU.Browser.MSIE)
            {
                if(elem.style.position == "absolute")
                    return parseInt(elem.style.left);
                else
                    return elem.offsetLeft;
            }*/
            
            do
            {
                //alert(offset + " (" + elem + "#" + elem.id + " added " + elem.offsetLeft + ")");
                if(elem.style && elem.style.position == "absolute")
                {
                    offset += parseInt(elem.style.left);
                    return offset;
                }
                else
                {
                    if(typeof(elem.offsetLeft) == "number")
                        offset += elem.offsetLeft;
                }
            }while(elem = elem.offsetParent);
            
            return offset;
        },
        
        elemOffsetY: function (elem)
        {
            var offset = 0;
            
            /*if(PLU.Browser.MSIE)
            {
                if(elem.style.position == "absolute")
                    return parseInt(elem.style.top);
                else
                    return elem.offsetTop;
            }*/

            do
            {
                if(elem.style && elem.style.position == "absolute")
                {
                    offset += parseInt(elem.style.top);
                    return offset;
                }
                else
                {
                    if(typeof(elem.offsetTop) == "number")
                        offset += elem.offsetTop;
                }
            }while(elem = elem.offsetParent);
            
            return offset;
        }
    };
}();


PLU.DragDrop = function ()
{
    var dragging = false;
    var dragElem = null;
    var dragElemCopy = null;
    var dragOffsetX = 0;
    var dragOffsetY = 0;
    var dropSavedBorder = "";
    var canDrop = false;
    var dropElem = null;
    var dropInsertBefore = null;
    var lastDropTestElem = null;
    var defaultCursor;
    
    function setCursor (cursorStyle)
    {
        if(document.body)
            defaultCursor = document.body.style.cursor;
        document.body.style.cursor = cursorStyle;
    }
    
    function releaseCursor ()
    {
        document.body.style.cursor = defaultCursor;
    }
    
    function mouseOverHandler ()
    {
        var target = PLU.Event.target;
        
        if(dragging)
        {
            if(target.className.indexOf("plu_drop") != -1)
            {
                dropSavedBorder = target.style.border;
                target.style.border = "1px solid #000";
            }
        }
        else
        {
            if(target.className.indexOf("plu_drag") != -1)
                target.style.cursor = "move";
        }
    }
    
    function mouseOutHandler ()
    {
        var target = PLU.Event.target;
        
        if(dragging)
        {
        }
    }
    
    function mouseDownHandler ()
    {
        if(!dragging)
        {
            var target = PLU.Event.target;
            
            if(target.className.indexOf("plu_drag") != -1)
            {
                dragging = true;
                dragElem = target;
                
                setCursor("move");
                dragElemCopy = target.cloneNode(true);
                dragElemCopy.style.opacity = "0.5";
                dragElemCopy.style.position = "absolute";
                if(dragElem.style.left)
                {
                    dragElemCopy.style.left = (PLU.Event.pageX - PLU.Event.offsetX) + "px";
                    dragElemCopy.style.top = (PLU.Event.pageY - PLU.Event.offsetY) + "px";
                }
                else if(dragElem.style.pixelLeft)
                {
                    dragElemCopy.style.pixelLeft = (PLU.Event.pageX - PLU.Event.offsetX);
                    dragElemCopy.style.pixelTop = (PLU.Event.pageY - PLU.Event.offsetY);
                }
                dragElem.style.visibility = "hidden";
                document.body.appendChild(dragElemCopy);
                //PLUEvent.cancel();
                PLU.SyntheticEvent.fireEvent("dragstart", dragElem);
            }
        }
    }
    
    function mouseUpHandler ()    
    {
        var target = PLU.Event.target;
        
        if(dragging)
        {
            releaseCursor();
            
            if(canDrop)
            {
                dragElemMoved = dragElem.cloneNode(true);
                
                if(dropElem == dropInsertBefore)
                    dropElem.appendChild(dragElemMoved);
                else
                    dropElem.insertBefore(dragElemMoved, dropInsertBefore);
                    
                dragElemMoved.style.visibility = "visible";
                
                dragElem.parentNode.removeChild(dragElem);
                
                canDrop = false;
                dropElem = null;
            }
            
            dragElemCopy.parentNode.removeChild(dragElemCopy);
            dragElem.style.visibility = "visible";
            
            dragElemCopy = null;
            dragElem = null;
            dragging = false;
        }
    }
    
    function mouseMoveHandler ()
    {
        var target = PLU.Event.target;
        if(target == dragElemCopy)
        {
            return;
        }
        
        if(dragging)
        {
            if(typeof(dragElemCopy.style.left) == "string")
            {
                dragElemCopy.style.left = (PLU.Event.pageX) + "px";
                dragElemCopy.style.top = (PLU.Event.pageY) + "px";
            }
            
            if(lastDropTestElem == target)
                return;
            
            hoverElem = target;
            canDrop = false;
            dropElem = null;
            
            do
            {
                if(hoverElem.className && hoverElem.className.indexOf("plu_drop") != -1)
                {
                    canDrop = true;
                    dropElem = hoverElem;
                    break;
                }
            }while(hoverElem = hoverElem.parentNode);
            
            lastDropTestElem = target;
            dropInsertBefore = target;
            
            if(canDrop)
                document.title = "Can drop into " + dropElem + " before " + dropInsertBefore;
            else
                document.title = "Cannot drop";
        }
    }
    
    PLU.SyntheticEvent.registerEvent("dragstart", null);
    PLU.SyntheticEvent.registerEvent("dragdown", null);
    PLU.SyntheticEvent.registerEvent("dragover", null);
    PLU.SyntheticEvent.registerEvent("dragout", null);
    PLU.SyntheticEvent.registerEvent("dragmove", null);    
    PLU.SyntheticEvent.registerEvent("dragup", null);
    
    //PLU.Event.addListener(window, "mouseover", mouseOverHandler);
    //PLU.Event.addListener(window, "mouseout", mouseOutHandler);
    PLU.Event.addListener(window, "mousedown", mouseDownHandler);
    PLU.Event.addListener(window, "mouseup", mouseUpHandler);
    PLU.Event.addListener(window, "mousemove", mouseMoveHandler);
}();


PLU.FontResizeEvent = function ()
{
    var span = null;
    
    function init ()
    {
        if(!document.body)
        {
            setTimeout(init, 500);
            return;
        }
        
        span = document.createElement("span");
        span.style.position = "absolute";
        span.style.left = "0px";
        span.style.top = "0px";
        span.innerHTML = "&nbsp;";
        
        document.body.appendChild(span);
        
        PLU.FontResizeEvent.baseFontSize = span.offsetHeight;
        PLU.FontResizeEvent.currentFontSize = PLU.FontResizeEvent.baseFontSize;
        PLU.FontResizeEvent.fontSizeDelta = 0;
        
        setTimeout(fontSizeDetect, 500);
    }
    
    function fontSizeDetect ()
    {
        fontSize = span.offsetHeight;

        if(fontSize != PLU.FontResizeEvent.currentFontSize)
        {
            PLU.FontResizeEvent.fontSizeDelta = fontSize - PLU.FontResizeEvent.currentFontSize;
            PLU.FontResizeEvent.currentFontSize = fontSize;

            PLU.SyntheticEvent.fireEvent("fontresize");
        }
        setTimeout(fontSizeDetect, 250);           
    }
    
    PLU.SyntheticEvent.registerEvent("fontresize", init);
    
    return {
        baseFontSize: 0,
        currentFontSize: 0,
        fontSizeDelta: 0
    };
}();


PLU.Columns = function ()
{
    var allDivs;
    var colGroups;
    
    ColumnAdjustmentGroup = function (groupID)
    {
        this.groupID = groupID;
        this.divs = new Array();
        
        this.addDiv = function (div) { this.divs[this.divs.length] = div; };
    };
    
    return {
        init: function ()
        {
            allDivs = document.getElementsByTagName("div");
            colGroups = new Array();
            
            for(index = 0; index < allDivs.length; index++)
            {
                div = allDivs[index];
                
                if((offset = div.className.indexOf("col-group-")) != -1)
                {
                    remainder = div.className.substring(offset + 10, div.className.length);
                    if(remainder.indexOf(" ") != -1)
                        remainder = remainder.substring(0, remainder.indexOf(" "));
                    groupID = remainder;
                    groupIndex = -1;
                    
                    for(colIndex = 0; colIndex < colGroups.length; colIndex++)
                    {
                        if(colGroups[colIndex].groupID == groupID)
                        {
                            groupIndex = colIndex;
                            break;
                        }
                    }
                    if(groupIndex == -1)
                    {
                        groupIndex = colGroups.length;
                        colGroups[groupIndex] = new ColumnAdjustmentGroup(groupID);
                    }
                    
                    colGroups[groupIndex].addDiv(div);
                }
            }
            
            if(PLU.FontResizeEvent)
                PLU.Event.addListener(null, "fontresize", PLU.Columns.adjust);
            
            PLU.Columns.adjust();
        },
        
        adjust: function ()
        {
            for(index = 0; index < colGroups.length; index++)
            {
                maxHeight = 0;
                colGroup = colGroups[index];
                
                for(divIndex = 0; divIndex < colGroup.divs.length; divIndex++)
                {
                    colGroup.divs[divIndex].style.height = "auto";
                }
                
                for(divIndex = 0; divIndex < colGroup.divs.length; divIndex++)
                {
                    height = colGroup.divs[divIndex].offsetHeight;
        
                    if(height > maxHeight)
                        maxHeight = height;
                }
                
                for(divIndex = 0; divIndex < colGroup.divs.length; divIndex++)
                {
                    colGroup.divs[divIndex].style.height = maxHeight + "px";
                }
            }
        }
    };
}();

PLU.Event.addListener(window, "load", PLU.Columns.init);

PLU.DialogBox = function ()
{        
    var MODELESS = 0;
    var MODAL = 1;
    var HCENTER = 2;
    var VCENTER = 4;
    var OK = 8;
    var OKCANCEL = 16;
    
    var dialogs = [];
    var shade;
    
    PLU.SyntheticEvent.registerEvent("dialogclose", null);            

    getDlgObj = function (dlgObj)
    {
        return dialogs[dlgObj.id];
    };
    
    closeDlg = function (dlgObj)
    {
        dlg = getDlgObj(dlgObj);
        
        dlg.div.style.display = "none";
        
        if(shade)
        {
            shade.parentNode.removeChild(shade);
            shade = null;
        }
    };
    
    displayURL = function (url)
    {
        dlg = getDlgObj(this);
        
        iframe = document.createElement("iframe");
        iframe.src = url;
        iframe.style.border = "none";
        contentDiv = dlg.div.getElementsByTagName("div")[1];
        iframe.style.width = "100%";
        iframe.style.height = "100%";
        
        contentDiv.appendChild(iframe);
    };
    
    setContent = function (html)
    {
        dlg = getDlgObj(this);
        
        contentDiv = dlg.div.getElementsByTagName("div")[1];
        contentDiv.innerHTML = html;
    };
    
    move = function (x, y)
    {
        dlg = getDlgObj(this);
        
        dlg.x = x;
        dlg.y = y;
        
        dlg.div.style.left = dlg.x + "px";
        dlg.div.style.top = dlg.y + "px";
    };
    
    startDlgDrag = function (dlgObj)
    {
        dlg = getDlgObj(dlgObj);
        dlg.dragOffsetX = PLU.Event.pageX - dlg.x;
        dlg.dragOffsetY = PLU.Event.pageY - dlg.y;
        dlg.dragging = true;
    };
    
    endDlgDrag = function (dlgObj)
    {
        dlg = getDlgObj(dlgObj);
        dlg.dragging = false;
        dlg.dragOffsetX = 0;
        dlg.dragOffsetY = 0;
    };
    
    dlgMouseMove = function (dlgObj)
    {
        dlg = getDlgObj(dlgObj);
        
        if(dlg.dragging)
        {
            dlgObj.move(PLU.Event.pageX - dlg.dragOffsetX, PLU.Event.pageY - dlg.dragOffsetY);
        }
    }
    
    return {
        create: function (title, width, height, style)
        {
            obj = { id: dialogs.length, displayURL: displayURL, setContent: setContent, move: move};
            
            dlg = {title: title, x: 0, y: 0, width: width, height: height, style: style, div: document.createElement("div")};
            
            dlg.div.style.display = "none";
            dlg.div.style.position = "absolute";
            dlg.div.style.width = dlg.width + "px";
            dlg.div.style.height = dlg.height + "px";
            dlg.div.style.background = "Window";
            dlg.div.style.border = "2px outset WindowFrame";
            
            if(dlg.style & VCENTER)
                dlg.y = (document.getElementsByTagName("html")[0].clientHeight / 2) - (dlg.height / 2);
            if(dlg.style & HCENTER)
                dlg.x = (document.getElementsByTagName("html")[0].clientWidth / 2) - (dlg.width / 2);
            
            dlg.div.style.left = dlg.x + "px";
            dlg.div.style.top = dlg.y + "px";
            titlebar = document.createElement("div");
            titlebar.style.background = "ActiveCaption";
            titlebar.style.color = "CaptionText";
            titlebar.style.fontWeight = "bold";
            titlebar.style.cursor = "default";
            titlebar.innerHTML = dlg.title;            
            dlg.div.appendChild(titlebar);
            PLU.Event.addListener(titlebar, "mousedown", function () { startDlgDrag(obj); });
            PLU.Event.addListener(window, "mouseup", function () { endDlgDrag(obj); });
            PLU.Event.addListener(window, "mousemove", function () { dlgMouseMove(obj); });
            
            content = document.createElement("div");
            content.style.height = dlg.height - titlebar.offsetHeight - 50 + "px";
            
            dlg.div.appendChild(content);
            
            buttons = document.createElement("div");
            buttons.style.textAlign = "center";
            if(dlg.style & OK)
            {
                okBtn = document.createElement("button");
                okBtn.innerHTML = "<u>O</u>K";
                buttons.appendChild(okBtn);
            }
            if(dlg.style & OKCANCEL)
            {
                cancelBtn = document.createElement("button");
                cancelBtn.innerHTML = "Cancel";
                cancelBtn.style.width = "80px";
                cancelBtn.style.margin = "0 1.0em 0 1.0em";
                
                PLU.Event.addListener(cancelBtn, "click", function () { PLU.Event.param = PLU.DialogBox.CANCEL; PLU.SyntheticEvent.fireEvent("dialogclose", obj); closeDlg(obj); });
                
                buttons.appendChild(cancelBtn);

                okBtn = document.createElement("button");
                okBtn.innerHTML = "<u>O</u>K";
                okBtn.style.width = "80px";
                okBtn.style.margin = "0 1.0em 0 1.0em";

                PLU.Event.addListener(okBtn, "click", function () { PLU.Event.param = PLU.DialogBox.OK; PLU.SyntheticEvent.fireEvent("dialogclose", obj); closeDlg(obj); });

                buttons.appendChild(okBtn);                
            }
            dlg.div.appendChild(buttons);
            
            document.body.appendChild(dlg.div);
            
            index = dialogs.length;
            
            dialogs[obj.id] = dlg;
            return obj;
        },
        
        show: function (dlgObj)
        {
            dlg = getDlgObj(dlgObj);
            if(dlg.style & MODAL)
            {
                shade = document.createElement("div");
                shade.style.opacity = "0.5";
                if(PLU.Browser.MSIE)
                    shade.style.filter = "alpha(opacity=50)";
                shade.style.width = document.getElementsByTagName("html")[0].clientWidth + "px";
                shade.style.height = document.getElementsByTagName("html")[0].clientHeight + "px";
                shade.style.position = "absolute";
                shade.style.left = "0px";
                shade.style.top = "0px";
                shade.style.background = "#444";
                shade.style.zIndex = 1;
                dlg.div.style.zIndex = 2;
                document.body.appendChild(shade);
                PLU.Event.addListener(shade, "click", function () { PLU.Event.stopPropagation(); PLU.Event.preventDefault(); });
            }
            dlg.div.style.display = "block";
        },
        
        hide: closeDlg,
        
        createStyle: function (strStyle)
        {
            strStyle = strStyle.replace(/ /, "");
            attributes = strStyle.split(",");
            styleVal = 0;
            
            for(index = 0; index < attributes.length; index++)
            {
                styleVal |= eval(attributes[index]);
            }
            
            return styleVal;
        },
        
        OK: 1,
        CANCEL: -1
    };
}();

PLU.EventsCalendar = function ()
{
    var cals = [];
    var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
    var monthLengths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
    var daysAbbr = ["S", "M", "T", "W", "R", "F", "S"];
    
    var displayMode = 1;
    var browseMode = 1;
    var globalCalObj = null;

    var getCalObj = function (calObj)
    {
        return cals[calObj.id];
    };
    
    var setDate = function (calObj, date)
    {
        browseMode = 1;
        var cal = getCalObj(calObj);
        var elem = cal.elem;
        
        if(!(date.getFullYear() % 4) && date.getFullYear() % 100)
            monthLengths[1] = 29;
        else
            monthLengths[1] = 28;

        var monthSel = PLU.DOM.find("select#calendar-month", elem)[0];
        var yearSel = PLU.DOM.find("select#calendar-year", elem)[0];
        var monthOpts = PLU.DOM.find("option", monthSel);
        var yearOpts = PLU.DOM.find("option", yearSel);

        for(index = 0; index < monthOpts.length; index++)
        {
            if(monthOpts[index].value == date.getMonth())
            {
                monthOpts[index].setAttribute("selected", "selected");
                monthSel.selectedIndex = index;
            }
            else
            {
                //monthOpts[index].setAttribute("selected", "");
            }
        }
        for(index = 0; index < yearOpts.length; index++)
        {
            if(yearOpts[index].value == date.getFullYear())
            {
                yearOpts[index].setAttribute("selected", "selected");
                yearSel.selectedIndex = index;
            }
            else
            {
                //yearOpts[index].setAttribute("selected", "");                
            }
        }
            
        var tbody = PLU.DOM.find("tbody", elem)[0];
        
        while(PLU.DOM.find("tr", tbody).length > 1)
            tbody.removeChild(PLU.DOM.find("tr", tbody)[1]);
            
        date.setDate(1);
        var td;
        var tr = document.createElement("tr");
        var a;
        tbody.appendChild(tr);
        if(date.getDay())
        {
            if(date.getMonth())
            {
                var prevMonth = date.getMonth() - 1;
                var prevYear = date.getFullYear();
                var prevMonthLength = monthLengths[prevMonth];
            }
            else
            {
                var prevMonth = 11;
                var prevYear = date.getFullYear() - 1;
                var prevMonthLength = 31;
            }
            for(var index = prevMonthLength - (date.getDay() - 1); index <= prevMonthLength; index++)
            {
                td = document.createElement("td");
                a = document.createElement("a");
                a.setAttribute("href", "#");
                a.appendChild(document.createTextNode(index));
                var prevDate = new Date(months[prevMonth] + " " + new String(index) + ", " + prevYear);
                eval("var clickHandler = function () { viewDate(calObj, new Date('" + prevDate + "')); PLU.Event.preventDefault(); PLU.Event.stopPropagation(); };");
                PLU.Event.addListener(a, "click", clickHandler);
                td.appendChild(a);
                td.className = "other-month";
                tr.appendChild(td);
            }
        }

        for(var index = 1; index <= monthLengths[date.getMonth()]; index++)
        {
            date.setDate(index);

            if(!date.getDay())
            {
                tbody.appendChild(tr);
                tr = document.createElement("tr");
            }
            td = document.createElement("td");
            if(date.getFullYear() == new Date().getFullYear() && date.getMonth() == new Date().getMonth() && date.getDate() == new Date().getDate())
                td.className = "current-item";
            a = document.createElement("a");
            a.setAttribute("href", "#");
            a.appendChild(document.createTextNode(index));

            var currentDate = new Date(months[date.getMonth()] + " " + new String(index) + ", " + date.getFullYear());
            eval("var clickHandler = function () { viewDate(calObj, new Date('" + currentDate + "')); PLU.Event.preventDefault(); PLU.Event.stopPropagation(); };");
            PLU.Event.addListener(a, "click", clickHandler);                

            td.appendChild(a);
            tr.appendChild(td);
        }
        if(date.getDay() < 6)
        {
            if(date.getMonth() < 11)
            {
                var nextMonth = date.getMonth() + 1;
                var nextMonthLength = monthLengths[nextMonth];
                var nextYear = date.getFullYear();
            }
            else
            {
                var nextMonth = 0;
                var nextMonthLength = 31;
                var nextYear = date.getFullYear() + 1;
            }
            
            for(index = 1; index <= 6 - date.getDay(); index++)
            {
                td = document.createElement("td");
                td.className = "other-month";
                a = document.createElement("a");
                a.setAttribute("href", "#");
                a.appendChild(document.createTextNode(index));

                var nextDate = new Date(months[nextMonth] + " " + new String(index) + ", " + nextYear);
                eval("var clickHandler = function () { viewDate(calObj, new Date('" + nextDate + "')); PLU.Event.preventDefault(); PLU.Event.stopPropagation(); };");
                PLU.Event.addListener(a, "click", clickHandler);                

                td.appendChild(a);
                tr.appendChild(td);
            }
        }
        tbody.appendChild(tr);
        
        calObj.date = date;
    };
    
    var sqlDate = function (date)
    {
        return date.getFullYear() + "-" + (date.getMonth() < 9 ? "0" : "") + (date.getMonth() + 1) + "-" + (date.getDate() < 10 ? "0" : "") + date.getDate();
    };
    
    var loadEventTimeFrame = function (calObj, startDate, endDate)
    {
        var cal = getCalObj(calObj);
        
        reqUrl = "/dev/xml/events/search.php?sd=" + sqlDate(startDate) + "&ed=" + sqlDate(endDate);
        var req = new PLU.HttpRequest();
        req.onreadystatechange = function ()
        {
            if(req.readyState == 4 && req.status == 200)
            {
                if(resultsDiv = cal.eventWindow)
                {
                    var dayHeader = PLU.DOM.find("h4", resultsDiv)[0];
                    if(dayHeader)
                    {
                        while(dayHeader.childNodes.length)
                            dayHeader.removeChild(dayHeader.childNodes[0]);
                            
                        var today = new Date();
                        
                        if(startDate.getFullYear() == today.getFullYear() && startDate.getMonth() == today.getMonth() && startDate.getDate() == today.getDate())
                            var dateStr = "Today";
                        else
                        {
                            var dateStr = months[startDate.getMonth()] + " " + startDate.getDate();
                            if(startDate.getFullYear() != today.getFullYear())
                                dateStr += ", " + startDate.getFullYear();
                        }
                        dayHeader.appendChild(document.createTextNode(dateStr));
                    }
                    
                    var eventListDiv = PLU.DOM.find("#calendar-list", resultsDiv)[0];
                    
                    if(eventListDiv)
                    {
                        while(eventListDiv.childNodes.length)
                            eventListDiv.removeChild(eventListDiv.childNodes[0]);
                            
                        var eventData = PLU.DOM.find("event", req.responseXML);
                        
                        if(cal.eventDisplay == 2)
                        {
                            var ul = document.createElement("ul");
                            eventListDiv.appendChild(ul);
                        }
                        
                        if(eventData.length)
                        {
                            for(var index = 0; index < eventData.length; index++)
                            {
                                var eventItem = eventData[index];
                                switch(cal.eventDisplay)
                                {
                                case 1:
                                    var div = document.createElement("div");
                                    div.className = "item";
                                    var h5 = document.createElement("h5");
                                    var a = document.createElement("a");
                                    a.setAttribute("href", "http://events.plu.edu/show-event.php?event_id=" + PLU.DOM.find("id", eventItem)[0].firstChild.data);
                                    a.appendChild(document.createTextNode(PLU.DOM.find("title", eventItem)[0].firstChild.data));
                                    h5.appendChild(a);
                                    div.appendChild(h5);
                                    
                                    var h6 = document.createElement("h6");
                                    h6.innerHTML = "<em>Date:</em> " + PLU.DOM.find("date", eventItem)[0].firstChild.data + " <em>Time:</em> " + PLU.DOM.find("startTime", eventItem)[0].firstChild.data + " - " + PLU.DOM.find("endTime", eventItem)[0].firstChild.data;
                                    div.appendChild(h6);
                                    
                                    if(PLU.DOM.find("location", eventItem)[0].firstChild)
                                    {
                                        h6 = document.createElement("h6");
                                        h6.innerHTML = "<em>Location:</em> " + PLU.DOM.find("location", eventItem)[0].firstChild.data;
                                        div.appendChild(h6);
                                    }
                                    var p = document.createElement("p");
                                    a = document.createElement("a");
                                    a.setAttribute("href", "http://events.plu.edu/show-event.php?event_id=" + PLU.DOM.find("id", eventItem)[0].firstChild.data);
                                    a.appendChild(document.createTextNode(PLU.DOM.find("details", eventItem)[0].firstChild.data));
                                    p.appendChild(a);
                                    div.appendChild(p);
                                    
                                    eventListDiv.appendChild(div);
                                    break;
                                    
                                case 2:
                                    var li = document.createElement("li");
                                    var a = document.createElement("a");
                                    a.setAttribute("href", "http://events.plu.edu/show-event.php?event_id=" + PLU.DOM.find("id", eventItem)[0].firstChild.data);
                                    a.appendChild(document.createTextNode(PLU.DOM.find("title", eventItem)[0].firstChild.data));
                                    li.appendChild(a);
                                    ul.appendChild(li);
                                    break;
                                }
                            }
                            
                            eventListDiv.scrollTop = 0;
                        }
                        else
                        {
                            var em = document.createElement("em");
                            em.appendChild(document.createTextNode("There are no events currently scheduled for this date"));
                            eventListDiv.appendChild(em);
                        }
                    }
                }
            }
        };
        req.open("GET", reqUrl, true);
        req.send(null);
    };
    
    var catSearch = function ()
    {
        browseMode = 2;
        var catDropdown = PLU.DOM.getElementById("category");
        var subCatDropdown = PLU.DOM.getElementById("secondary-category");
        
        var catId = catDropdown.value;
        var subCatId = subCatDropdown.value;
        
        if(subCatId != 0)
            catId = subCatId;
        
        var reqUrl = "/dev/xml/events/search.php?cat=" + catId;
        var req = new PLU.HttpRequest();
        req.onreadystatechange = function ()
        {
            if(req.readyState == 4 && req.status == 200)
            {
                if(resultsDiv = PLU.DOM.getElementById("calendar-results"))
                {
                    var dayHeader = PLU.DOM.find("h4", resultsDiv)[0];
                    if(dayHeader)
                    {
                        while(dayHeader.childNodes.length)
                            dayHeader.removeChild(dayHeader.childNodes[0]);
                            
                        var catInfo = PLU.DOM.find("category", req.responseXML)[0];
                        var catTitle = PLU.DOM.find("title", catInfo)[0].firstChild.data;
                            
                        dayHeader.appendChild(document.createTextNode(catTitle));
                    }
                    
                    var eventListDiv = PLU.DOM.find("#calendar-list", resultsDiv)[0];
                    
                    if(eventListDiv)
                    {
                        while(eventListDiv.childNodes.length)
                            eventListDiv.removeChild(eventListDiv.childNodes[0]);
                            
                        var eventData = PLU.DOM.find("event", req.responseXML);
                        
                        if(eventData.length)
                        {
                            if(displayMode == 2)
                            {
                                var ul = document.createElement("ul");
                                eventListDiv.appendChild(ul);
                            }
                            
                            for(var index = 0; index < eventData.length; index++)
                            {
                                var eventItem = eventData[index];
                                switch(displayMode)
                                {
                                case 1:
                                    var div = document.createElement("div");
                                    div.className = "item";
                                    var h5 = document.createElement("h5");
                                    var a = document.createElement("a");
                                    a.setAttribute("href", "http://events.plu.edu/show-event.php?event_id=" + PLU.DOM.find("id", eventItem)[0].firstChild.data);
                                    a.appendChild(document.createTextNode(PLU.DOM.find("title", eventItem)[0].firstChild.data));
                                    h5.appendChild(a);
                                    div.appendChild(h5);
                                    
                                    var h6 = document.createElement("h6");
                                    h6.innerHTML = "<em>Date:</em> " + PLU.DOM.find("date", eventItem)[0].firstChild.data + " <em>Time:</em> " + PLU.DOM.find("startTime", eventItem)[0].firstChild.data + " - " + PLU.DOM.find("endTime", eventItem)[0].firstChild.data;
                                    div.appendChild(h6);
                                    
                                    if(PLU.DOM.find("location", eventItem)[0].firstChild)
                                    {
                                        h6 = document.createElement("h6");
                                        h6.innerHTML = "<em>Location:</em> " + PLU.DOM.find("location", eventItem)[0].firstChild.data;
                                        div.appendChild(h6);
                                    }
                                    var p = document.createElement("p");
                                    a = document.createElement("a");
                                    a.setAttribute("href", "http://events.plu.edu/show-event.php?event_id=" + PLU.DOM.find("id", eventItem)[0].firstChild.data);
                                    a.appendChild(document.createTextNode(PLU.DOM.find("details", eventItem)[0].firstChild.data));
                                    p.appendChild(a);
                                    div.appendChild(p);
                                    
                                    eventListDiv.appendChild(div);
                                    break;
                                    
                                case 2:
                                    var li = document.createElement("li");
                                    var a = document.createElement("a");
                                    a.setAttribute("href", "http://events.plu.edu/show-event.php?event_id=" + PLU.DOM.find("id", eventItem)[0].firstChild.data);
                                    a.appendChild(document.createTextNode(PLU.DOM.find("title", eventItem)[0].firstChild.data));
                                    li.appendChild(a);
                                    ul.appendChild(li);
                                    break;
                                }
                            }
                            
                            eventListDiv.scrollTop = 0;
                        }
                        else
                        {
                            var em = document.createElement("em");
                            em.appendChild(document.createTextNode("There are no events for this category"));
                            eventListDiv.appendChild(em);
                        }
                    }
                }
            }
        };
        req.open("GET", reqUrl, true);
        req.send(null);
    };
    
    var displayToday = function (calObj)
    {
        PLU.Event.stopPropagation();
        PLU.Event.preventDefault();
        viewDate(globalCalObj, new Date());
    };
    
    var displayThisWeek = function (calObj)
    {
        browseMode = 4;
        PLU.Event.stopPropagation();
        PLU.Event.preventDefault();

        var startDate = new Date();
        startDate.setDate(startDate.getDate() - startDate.getDay());
        var endDate = new Date();
        endDate.setDate(endDate.getDate() + (6 - endDate.getDay()));
        
        var eventListDiv = PLU.DOM.find("#calendar-list", resultsDiv)[0];
        while(eventListDiv.childNodes.length)
            eventListDiv.removeChild(eventListDiv.childNodes[0]);
            
        var em = document.createElement("em");
        em.appendChild(document.createTextNode("Loading..."));
        eventListDiv.appendChild(em);
        
        var reqUrl = "/dev/xml/events/search.php?sd=" + sqlDate(startDate) + "&ed=" + sqlDate(endDate);
        var req = new PLU.HttpRequest();
        
        req.open("GET", reqUrl, true);
        
        req.onreadystatechange = function ()
        {
            if(req.readyState == 4 && req.status == 200)
            {
                if(resultsDiv = PLU.DOM.getElementById("calendar-results"))
                {
                    var dayHeader = PLU.DOM.find("h4", resultsDiv)[0];
                    if(dayHeader)
                    {
                        while(dayHeader.childNodes.length)
                            dayHeader.removeChild(dayHeader.childNodes[0]);
                            
                        dayHeader.appendChild(document.createTextNode("This Week"));
                    }
                    
                    var eventListDiv = PLU.DOM.find("#calendar-list", resultsDiv)[0];
                    
                    if(eventListDiv)
                    {
                        while(eventListDiv.childNodes.length)
                            eventListDiv.removeChild(eventListDiv.childNodes[0]);
                            
                        var eventData = PLU.DOM.find("event", req.responseXML);
                        
                        if(displayMode == 2)
                        {
                            var ul = document.createElement("ul");
                            eventListDiv.appendChild(ul);
                        }
                        if(eventData.length)
                        {
                            for(var index = 0; index < eventData.length; index++)
                            {
                                var eventItem = eventData[index];
                                switch(displayMode)
                                {
                                case 1:
                                    var div = document.createElement("div");
                                    div.className = "item";
                                    var h5 = document.createElement("h5");
                                    var a = document.createElement("a");
                                    a.setAttribute("href", "http://events.plu.edu/show-event.php?event_id=" + PLU.DOM.find("id", eventItem)[0].firstChild.data);
                                    a.appendChild(document.createTextNode(PLU.DOM.find("title", eventItem)[0].firstChild.data));
                                    h5.appendChild(a);
                                    div.appendChild(h5);
                                    
                                    var h6 = document.createElement("h6");
                                    h6.innerHTML = "<em>Date:</em> " + PLU.DOM.find("date", eventItem)[0].firstChild.data + " <em>Time:</em> " + PLU.DOM.find("startTime", eventItem)[0].firstChild.data + " - " + PLU.DOM.find("endTime", eventItem)[0].firstChild.data;
                                    div.appendChild(h6);
                                    
                                    if(PLU.DOM.find("location", eventItem)[0].firstChild)
                                    {
                                        h6 = document.createElement("h6");
                                        h6.innerHTML = "<em>Location:</em> " + PLU.DOM.find("location", eventItem)[0].firstChild.data;
                                        div.appendChild(h6);
                                    }
                                    var p = document.createElement("p");
                                    a = document.createElement("a");
                                    a.setAttribute("href", "http://events.plu.edu/show-event.php?event_id=" + PLU.DOM.find("id", eventItem)[0].firstChild.data);
                                    a.appendChild(document.createTextNode(PLU.DOM.find("details", eventItem)[0].firstChild.data));
                                    p.appendChild(a);
                                    div.appendChild(p);
                                    
                                    eventListDiv.appendChild(div);
                                    break;
                                    
                                case 2:
                                    var li = document.createElement("li");
                                    var a = document.createElement("a");
                                    a.setAttribute("href", "http://events.plu.edu/show-event.php?event_id=" + PLU.DOM.find("id", eventItem)[0].firstChild.data);
                                    a.appendChild(document.createTextNode(PLU.DOM.find("title", eventItem)[0].firstChild.data));
                                    li.appendChild(a);
                                    ul.appendChild(li);
                                    break;
                                }
                            }
                            
                            eventListDiv.scrollTop = 0;
                        }
                        else
                        {
                            var em = document.createElement("em");
                            em.appendChild(document.createTextNode("There are no events this week"));
                            eventListDiv.appendChild(em);
                        }
                    }
                }
            }
        };
        req.send(null);
    };
    
    var displayThisMonth = function (calObj)
    {
        browseMode = 5;
        PLU.Event.stopPropagation();
        PLU.Event.preventDefault();

        var startDate = new Date();
        startDate.setDate(1);
        var endDate = new Date();
        endDate.setDate(monthLengths[endDate.getMonth()]);
        
        //startDate.setTime(0);
        //endDate.setTime(0);
        
        var eventListDiv = PLU.DOM.find("#calendar-list", resultsDiv)[0];
        while(eventListDiv.childNodes.length)
            eventListDiv.removeChild(eventListDiv.childNodes[0]);
            
        var em = document.createElement("em");
        em.appendChild(document.createTextNode("Loading..."));
        eventListDiv.appendChild(em);
        
        var reqUrl = "/dev/xml/events/search.php?sd=" + sqlDate(startDate) + "&ed=" + sqlDate(endDate);
        var req = new PLU.HttpRequest();
        
        req.open("GET", reqUrl, true);
        
        req.onreadystatechange = function ()
        {
            if(req.readyState == 4 && req.status == 200)
            {
                if(resultsDiv = PLU.DOM.getElementById("calendar-results"))
                {
                    var dayHeader = PLU.DOM.find("h4", resultsDiv)[0];
                    if(dayHeader)
                    {
                        while(dayHeader.childNodes.length)
                            dayHeader.removeChild(dayHeader.childNodes[0]);
                            
                        dayHeader.appendChild(document.createTextNode("This Month"));
                    }
                    
                    var eventListDiv = PLU.DOM.find("#calendar-list", resultsDiv)[0];
                    
                    if(eventListDiv)
                    {
                        while(eventListDiv.childNodes.length)
                            eventListDiv.removeChild(eventListDiv.childNodes[0]);
                            
                        var eventData = PLU.DOM.find("event", req.responseXML);
                        
                        if(displayMode == 2)
                        {
                            var ul = document.createElement("ul");
                            eventListDiv.appendChild(ul);
                        }
                        if(eventData.length)
                        {
                            for(var index = 0; index < eventData.length; index++)
                            {
                                var eventItem = eventData[index];
                                switch(displayMode)
                                {
                                case 1:
                                    var div = document.createElement("div");
                                    div.className = "item";
                                    var h5 = document.createElement("h5");
                                    var a = document.createElement("a");
                                    a.setAttribute("href", "http://events.plu.edu/show-event.php?event_id=" + PLU.DOM.find("id", eventItem)[0].firstChild.data);
                                    a.appendChild(document.createTextNode(PLU.DOM.find("title", eventItem)[0].firstChild.data));
                                    h5.appendChild(a);
                                    div.appendChild(h5);
                                    
                                    var h6 = document.createElement("h6");
                                    h6.innerHTML = "<em>Date:</em> " + PLU.DOM.find("date", eventItem)[0].firstChild.data + " <em>Time:</em> " + PLU.DOM.find("startTime", eventItem)[0].firstChild.data + " - " + PLU.DOM.find("endTime", eventItem)[0].firstChild.data;
                                    div.appendChild(h6);
                                    
                                    if(PLU.DOM.find("location", eventItem)[0].firstChild)
                                    {
                                        h6 = document.createElement("h6");
                                        h6.innerHTML = "<em>Location:</em> " + PLU.DOM.find("location", eventItem)[0].firstChild.data;
                                        div.appendChild(h6);
                                    }
                                    var p = document.createElement("p");
                                    a = document.createElement("a");
                                    a.setAttribute("href", "http://events.plu.edu/show-event.php?event_id=" + PLU.DOM.find("id", eventItem)[0].firstChild.data);
                                    a.appendChild(document.createTextNode(PLU.DOM.find("details", eventItem)[0].firstChild.data));
                                    p.appendChild(a);
                                    div.appendChild(p);
                                    
                                    eventListDiv.appendChild(div);
                                    break;
                                    
                                case 2:
                                    var li = document.createElement("li");
                                    var a = document.createElement("a");
                                    a.setAttribute("href", "http://events.plu.edu/show-event.php?event_id=" + PLU.DOM.find("id", eventItem)[0].firstChild.data);
                                    a.appendChild(document.createTextNode(PLU.DOM.find("title", eventItem)[0].firstChild.data));
                                    li.appendChild(a);
                                    ul.appendChild(li);
                                    break;
                                }
                            }
                            
                            eventListDiv.scrollTop = 0;
                        }
                        else
                        {
                            var em = document.createElement("em");
                            em.appendChild(document.createTextNode("There are no events this week"));
                            eventListDiv.appendChild(em);
                        }
                    }
                }
            }
        };
        req.send(null);
    };
    
    var keywordSearch = function ()
    {
        browseMode = 3;
        var keywords = PLU.DOM.getElementById("calendar-keywords").value;
        
        var reqUrl = "/dev/xml/events/search.php?q=" + keywords;
        var req = new PLU.HttpRequest();
        req.onreadystatechange = function ()
        {
            if(req.readyState == 4 && req.status == 200)
            {
                if(resultsDiv = PLU.DOM.getElementById("calendar-results"))
                {
                    var dayHeader = PLU.DOM.find("h4", resultsDiv)[0];
                    if(dayHeader)
                    {
                        while(dayHeader.childNodes.length)
                            dayHeader.removeChild(dayHeader.childNodes[0]);
                            
                        dayHeader.appendChild(document.createTextNode("Search Results"));
                    }
                    
                    var eventListDiv = PLU.DOM.find("#calendar-list", resultsDiv)[0];
                    
                    if(eventListDiv)
                    {
                        while(eventListDiv.childNodes.length)
                            eventListDiv.removeChild(eventListDiv.childNodes[0]);
                            
                        var eventData = PLU.DOM.find("event", req.responseXML);
                        
                        if(displayMode == 2)
                        {
                            var ul = document.createElement("ul");
                            eventListDiv.appendChild(ul);
                        }
                        if(eventData.length)
                        {
                            for(var index = 0; index < eventData.length; index++)
                            {
                                var eventItem = eventData[index];
                                switch(displayMode)
                                {
                                case 1:
                                    var div = document.createElement("div");
                                    div.className = "item";
                                    var h5 = document.createElement("h5");
                                    var a = document.createElement("a");
                                    a.setAttribute("href", "http://events.plu.edu/show-event.php?event_id=" + PLU.DOM.find("id", eventItem)[0].firstChild.data);
                                    a.appendChild(document.createTextNode(PLU.DOM.find("title", eventItem)[0].firstChild.data));
                                    h5.appendChild(a);
                                    div.appendChild(h5);
                                    
                                    var h6 = document.createElement("h6");
                                    h6.innerHTML = "<em>Date:</em> " + PLU.DOM.find("date", eventItem)[0].firstChild.data + " <em>Time:</em> " + PLU.DOM.find("startTime", eventItem)[0].firstChild.data + " - " + PLU.DOM.find("endTime", eventItem)[0].firstChild.data;
                                    div.appendChild(h6);
                                    
                                    if(PLU.DOM.find("location", eventItem)[0].firstChild)
                                    {
                                        h6 = document.createElement("h6");
                                        h6.innerHTML = "<em>Location:</em> " + PLU.DOM.find("location", eventItem)[0].firstChild.data;
                                        div.appendChild(h6);
                                    }
                                    var p = document.createElement("p");
                                    a = document.createElement("a");
                                    a.setAttribute("href", "http://events.plu.edu/show-event.php?event_id=" + PLU.DOM.find("id", eventItem)[0].firstChild.data);
                                    a.appendChild(document.createTextNode(PLU.DOM.find("details", eventItem)[0].firstChild.data));
                                    p.appendChild(a);
                                    div.appendChild(p);
                                    
                                    eventListDiv.appendChild(div);
                                    break;
                                    
                                case 2:
                                    var li = document.createElement("li");
                                    var a = document.createElement("a");
                                    a.setAttribute("href", "http://events.plu.edu/show-event.php?event_id=" + PLU.DOM.find("id", eventItem)[0].firstChild.data);
                                    a.appendChild(document.createTextNode(PLU.DOM.find("title", eventItem)[0].firstChild.data));
                                    li.appendChild(a);
                                    ul.appendChild(li);
                                    break;
                                }
                            }
                            
                            eventListDiv.scrollTop = 0;
                        }
                        else
                        {
                            var em = document.createElement("em");
                            em.appendChild(document.createTextNode("There are no events that match your query"));
                            eventListDiv.appendChild(em);
                        }
                    }
                }
            }
        };
        req.open("GET", reqUrl, true);
        req.send(null);
    };

    var showEventList = function (calObj, list)
    {
    };
    
    var loadDayEvents = function (calObj, date)
    {
        var endDate = new Date(date.toString());
        endDate.setDate(date.getDate() + 1);
        
        loadEventTimeFrame(calObj, date, endDate);
    };
    
    var nextMonth = function ()
    {
        var cal = getCalObj(this);
        var date = cal.date;
        
        date.setDate(32);
        this.setDate(date);
    };
    
    var prevMonth = function ()
    {
        var cal = getCalObj(this);
        var date = cal.date;
        
        date.setDate(-1);
        this.setDate(date);
    };
    
    var setEventWindow = function (calObj, elem)
    {
        var cal = getCalObj(calObj);
        
        cal.eventWindow = elem;
    };
    
    var browse = function (calObj, date)
    {
        loadDayEvents(calObj, date);
    };
    
    var viewDate = function (calObj, date)
    {
        var cal = getCalObj(calObj);
        cal.date = date;
        
        if(cal.eventWindow)
        {
            switch(cal.browseMode)
            {
            case 1:
                loadDayEvents(calObj, cal.date);
                break;
            case 2:
                loadWeekEvents(calObj, cal.date);
                break;
            case 3:
                loadMonthEvents(calObj, cal.date);
                break;
            }            
        }        
    }
    
    var setBrowseMode = function (calObj, mode)
    {
        var cal = getCalObj(calObj);
        
        cal.browseMode = mode;
        viewDate(calObj, cal.date);
    };
    
    var setEventDisplay = function (calObj, mode)
    {
        displayMode = mode;
        var cal = getCalObj(calObj);
        
        cal.eventDisplay = mode;
        
        var modeUl = PLU.DOM.find("ul.calendar-views")[0];
        if(modeUl)
        {
            var lis = PLU.DOM.find("li", modeUl);
            
            for(var index = 0; index < lis.length; index++)
            {
                var img = PLU.DOM.find("img", lis[index])[0];
                if(img)
                {
                    if(mode == lis[index].id.substring(lis[index].id.lastIndexOf("-") + 1))
                        img.src = img.src.replace(/-inactive.gif/, "-active.gif");
                    else
                        img.src = img.src.replace(/-active.gif/, "-inactive.gif");
                }
            }
        }
        
        switch(browseMode)
        {
        case 1:
            viewDate(calObj, cal.date);
            break;
        case 2:
            catSearch();
            break;
        case 3:
            keywordSearch();
            break;
        case 4:
            displayThisWeek();
            break;
        case 5:
            displayThisMonth();
            break;
        }
    };
    
    var changeSubCats = function ()
    {
        var target = PLU.Event.target;
        
        var subjId = target.value;
        
        if(subjId && subjId != "0")
        {
            var reqUrl = "/dev/xml/events/categories.php?p=" + subjId;
            var req = new PLU.HttpRequest();
            
            req.onreadystatechange = function ()
            {
                if(req.readyState == 4 && req.status == 200)
                {
                    var xml = req.responseXML;
                    
                    var subCats = PLU.DOM.find("category", xml);
                    
                    var subCatDropdown = PLU.DOM.getElementById("secondary-category");
                    
                    while(subCatDropdown.childNodes.length)
                        subCatDropdown.removeChild(subCatDropdown.childNodes[0])
                        
                    var option = document.createElement("option");
                    option.value = "0";
                    option.appendChild(document.createTextNode("ALL"));
                    subCatDropdown.appendChild(option);
                    
                    for(var index = 0; index < subCats.length; index++)
                    {
                        option = document.createElement("option");
                        option.value = PLU.DOM.find("id", subCats[index])[0].firstChild.data;
                        option.appendChild(document.createTextNode(PLU.DOM.find("title", subCats[index])[0].firstChild.data.replace(/&amp;/, "&")));
                        subCatDropdown.appendChild(option);
                    }
                }
            };
            
            req.open("GET", reqUrl, true);
            req.send(null);
        }
        else
        {
            var subCatDropdown = PLU.DOM.getElementById("secondary-category");
            while(subCatDropdown.childNodes.length)
                subCatDropdown.removeChild(subCatDropdown.childNodes[0])
                
            var option = document.createElement("option");
            option.value = "0";
            option.appendChild(document.createTextNode("ALL"));
            subCatDropdown.appendChild(option);
        }
    };
 
    return {
        init: function ()
        {
            if(calElem = PLU.DOM.getElementById("calendar-options"))
            {
                if(!/translate_c/.test(location.href))
                {
                    var cal = PLU.EventsCalendar.createLight(calElem);
    
                    if(eventWindow = PLU.DOM.getElementById("calendar-results"))
                    {
                        cal.setEventWindow(eventWindow);
                        cal.browse(new Date());
                    }
                    
                    var catDropdown = PLU.DOM.getElementById("category");
                    if(catDropdown)
                    {
                        PLU.Event.addListener(catDropdown, "change", changeSubCats);
                    }
                    
                    var catSearchBtn = PLU.DOM.getElementById("calendar-category-submit");
                    PLU.Event.addListener(catSearchBtn, "click", catSearch);
                    
                    var keywSearchBtn = PLU.DOM.getElementById("calendar-keywords-submit");
                    PLU.Event.addListener(keywSearchBtn, "click", keywordSearch);
                }
                else
                    PLU.DOM.getElementById("calendar-no-translate").style.display = "block";
            }
        },
        
        create: function (elem)
        {
            if(arguments.length > 1)
                calDate = arguments[1];
            else
                calDate = new Date();

            var calObj = { id: cals.length, setDate: function (date) { setDate(this, date); }, nextMonth: nextMonth, prevMonth: prevMonth, setEventWindow: function (elem) { setEventWindow(this, elem); }, browse: function (date) { browse(this, date); }, setBrowseMode: function (mode) { setBrowseMode(this, mode); }, setEventDisplay: function (mode) { setEventDisplay(this, mode); } };
            var cal = { elem: elem, date: calDate, eventWindow: null, browseMode: 1, eventDisplay: 1 };

            cals[calObj.id] = cal;
            
            var optionsDiv = document.createElement("div");
            var headerDiv = document.createElement("div");
            
            var table = document.createElement("table");
            var thead = document.createElement("thead");
            var tbody = document.createElement("tbody");
            var tfoot = document.createElement("tfoot");
            var tr = document.createElement("tr");
            var th = document.createElement("th");
            var a;
            
            headerDiv.setAttribute("id", "calendar-options-header");
            headerDiv.setAttribute("class", "tab-header");
            var ul = document.createElement("ul");
            ul.setAttribute("class", "tabs");

            var li = document.createElement("li");
            li.setAttribute("class", "current-item");
            a = document.createElement("a");
            a.setAttribute("href", "#");
            a.appendChild(document.createTextNode("Date"));
            li.appendChild(a);
            
            ul.appendChild(li);
            
            li = document.createElement("li");
            a = document.createElement("a");
            a.setAttribute("href", "#");
            a.appendChild(document.createTextNode("Category"));
            li.appendChild(a);
            ul.appendChild(li);
            
            li = document.createElement("li");
            a = document.createElement("a");
            li.setAttribute("class", "last-item");
            a.setAttribute("href", "#");
            a.appendChild(document.createTextNode("Search"));
            li.appendChild(a);
            ul.appendChild(li);
            
            headerDiv.appendChild(ul);

            table.setAttribute("border", 1);
            optionsDiv.setAttribute("id", "calendar-options-body");
            optionsDiv.setAttribute("class", "tab-body");
            table.setAttribute("id", "calendar");            
            th.setAttribute("colSpan", 8);
            
            var form = document.createElement("form");
            var select = document.createElement("select");
            select.setAttribute("id", "calendar-month");
            select.setAttribute("size", 1);
            for(var index = 0; index < months.length; index++)
            {
                var option = document.createElement("option");
                option.setAttribute("value", index);
                if(calDate.getMonth() == index)
                    option.setAttribute("selected", "selected");
                option.appendChild(document.createTextNode(months[index]));
                select.appendChild(option);
            }
            
            PLU.Event.addListener(select, "change", function () { setDate(calObj, new Date(months[PLU.Event.target.value] + " 01, " + PLU.DOM.getElementById("calendar-year").value)); });
            
            form.appendChild(select);
            form.appendChild(document.createTextNode(" "));
            select = document.createElement("select");
            select.setAttribute("id", "calendar-year");
            select.setAttribute("size", 1);
            for(var index = calDate.getFullYear() - 1; index < calDate.getFullYear() + 3; index++)
            {
                var option = document.createElement("option");
                option.setAttribute("value", index);
                if(calDate.getFullYear() == index)
                    option.setAttribute("selected", "selected");
                option.appendChild(document.createTextNode(index));                
                select.appendChild(option);
            }

            PLU.Event.addListener(select, "change", function () { setDate(calObj, new Date(months[PLU.DOM.getElementById("calendar-month").value] + " 01, " + PLU.Event.target.value)); });

            form.appendChild(select);
            form.appendChild(document.createTextNode(" "));
            var button = document.createElement("input");
            button.setAttribute("id", "calendar-submit");
            button.setAttribute("type", "button");
            button.setAttribute("value", "GO");
            button.setAttribute("name", "GO");
            
            form.appendChild(button);
            form.appendChild(document.createTextNode(" "));
            th.appendChild(form);
            tr.appendChild(th);
            thead.appendChild(tr);
            table.appendChild(thead);
            table.appendChild(tbody);
            table.appendChild(tfoot);
            
            tr = document.createElement("tr");
            for(var index = 0; index < days.length; index++)
            {
                th = document.createElement("th");
                th.setAttribute("class", "day");
                th.appendChild(document.createTextNode(daysAbbr[index]));
                
                tr.appendChild(th);
            }
            tbody.appendChild(tr);
            
            tr = document.createElement("tr");
            th = document.createElement("th");
            th.setAttribute("colSpan", 8);
            th.appendChild(document.createTextNode(" "));
            tr.appendChild(th);
            tfoot.appendChild(tr);
            
            while(cal.elem.childNodes.length)
                cal.elem.removeChild(cal.elem.childNodes[0]);

            optionsDiv.appendChild(table);
            
            ul = document.createElement("ul");
            ul.setAttribute("class", "calendar-dates");
            li = document.createElement("li");
            a = document.createElement("a");
            a.setAttribute("href", "#");
            a.appendChild(document.createTextNode("Today"));
            li.appendChild(a);
            ul.appendChild(li);
            
            li = document.createElement("li");
            a = document.createElement("a");
            a.setAttribute("href", "#");
            a.appendChild(document.createTextNode("This Week"));
            li.appendChild(a);
            ul.appendChild(li);
            
            li = document.createElement("li");
            a = document.createElement("a");
            a.setAttribute("href", "#");
            a.appendChild(document.createTextNode("This Month"));
            li.appendChild(a);
            ul.appendChild(li);
            
            optionsDiv.appendChild(ul);
            
            cal.elem.appendChild(headerDiv);
            cal.elem.appendChild(optionsDiv);
            calObj.setDate(calDate);

            return calObj;
        },
        
        createLight: function (elem)
        {
            var calDate = new Date();
            var calObj = { id: cals.length, setDate: function (date) { setDate(this, date); }, nextMonth: nextMonth, prevMonth: prevMonth, setEventWindow: function (elem) { setEventWindow(this, elem); }, browse: function (date) { browse(this, date); }, setBrowseMode: function (mode) { setBrowseMode(this, mode); }, setEventDisplay: function (mode) { setEventDisplay(this, mode); }, displayToday: function () { displayToday(this); }, displayThisWeek: function () { displayThisWeek(this); }, displayThisMonth: function () { displayThisMonth(); } };
            var cal = { elem: elem, date: calDate, eventWindow: null, browseMode: 1, eventDisplay: 1 };

            cals[calObj.id] = cal;
            
            var monthSelect = PLU.DOM.find("select#calendar-month", cal.elem)[0];
            var yearSelect = PLU.DOM.find("select#calendar-year", cal.elem)[0];
            
            if(monthSelect)
                PLU.Event.addListener(monthSelect, "change", function () { setDate(calObj, new Date(months[PLU.Event.target.value] + " 01, " + PLU.DOM.getElementById("calendar-year").value)); });
            if(yearSelect)
                PLU.Event.addListener(yearSelect, "change", function () { setDate(calObj, new Date(months[PLU.DOM.getElementById("calendar-month").value] + " 01, " + PLU.Event.target.value)); });
                
            calObj.setDate(new Date());
            
            var viewUl = PLU.DOM.find("ul.calendar-views")[0];
            if(viewUl)
            {
                var lis = PLU.DOM.find("li", viewUl);
                
                for(var index = 0; index < lis.length; index++)
                {
                    if(/calendar-view-mode-/.test(lis[index].id))
                    {
                        var viewMode = lis[index].id.substring(lis[index].id.lastIndexOf("-") + 1);
                        var a = PLU.DOM.find("a", lis[index])[0];
                        eval("var clickHandler = function () { calObj.setEventDisplay(" + viewMode + "); PLU.Event.stopPropagation(); PLU.Event.preventDefault(); };");
                        PLU.Event.addListener(a, "click", clickHandler);
                    }
                }
            }
            
            var dateUl = PLU.DOM.find("ul.calendar-dates")[0];
            var optionLis = PLU.DOM.find("li", dateUl);
            
            PLU.Event.addListener(optionLis[0], "click", calObj.displayToday);
            PLU.Event.addListener(optionLis[1], "click", calObj.displayThisWeek);
            PLU.Event.addListener(optionLis[2], "click", calObj.displayThisMonth);
            
            globalCalObj = calObj;
            
            return calObj;
        },
        
        getCategories: function ()
        {
            var req = new PLU.HttpRequest();
            req.open("GET", "/dev/xml/events/categories.php", false);
            req.send(null);
            var categories = [];
            for(var index = 0; index < PLU.DOM.find("category", req.responseXML).length; index++)
            {
                var catElem = PLU.DOM.find("category", req.responseXML)[index];
                var titleElem = PLU.DOM.find("title", catElem)[0];
                var idElem = PLU.DOM.find("id", catElem)[0];
                
                if(PLU.Browser.MSIE)
                    categories[categories.length] = { title: titleElem.innerText, id: idElem.innerText };
                else
                    categories[categories.length] = { title: titleElem.textContent, id: idElem.textContent };
            }
            alert(categories[0].title);
            return categories;
        }
    };
}();

if(PLU.Event)
    PLU.Event.addListener(window, "load", PLU.EventsCalendar.init);

PLU.Tabs = function ()
{
    var showTab = function ()
    {
        var target = PLU.Event.target;
        PLU.Event.preventDefault();
        PLU.Event.stopPropagation();
        var id = target.href.substring(target.href.indexOf("#") + 1);
        var tabDiv = PLU.DOM.getElementById(id);
        if(tabDiv.className.indexOf("current") != -1)
            return;

        var container = PLU.DOM.findUp("div.tab-content", tabDiv)[0];

        var divs = PLU.DOM.find("div.tab-data", container);
        tabDiv.className += " current";
        for(var index = 0; index < divs.length; index++)
        {
            if(divs[index].parentNode == container && divs[index] != tabDiv)
                divs[index].className = divs[index].className.replace(/current/, "");
            //else
            //    divs[index].className += " current";
        }
        
        var tabsUl = PLU.DOM.findUp("ul.plu-tabs", target)[0];
        if(!tabsUl)
            return;
            
        var lis = PLU.DOM.find("li", tabsUl);
        
        for(var index = 0; index < lis.length; index++)
        {
            if(lis[index] == target.parentNode)
                lis[index].className += " current-item";
            else
                lis[index].className = lis[index].className.replace(/current\-item/, "");
        }
    };
    
    return {
        init: function ()
        {
            var tabsUls = PLU.DOM.find("ul.plu-tabs");

            for(var index = 0; index < tabsUls.length; index++)
            {
                var ul = tabsUls[index];
                var lis = PLU.DOM.find("li", ul);
                for(var liIndex = 0; liIndex < lis.length; liIndex++)
                {
                    var a = PLU.DOM.find("a", lis[liIndex])[0];
                    
                    if(a)
                        PLU.Event.addListener(a, "click", showTab);
                }
            }
        }
    };
}();

PLU.Event.addListener(window, "load", PLU.Tabs.init);

PLU.MyPLU = function ()
{
    var timeoutId = null;
    var currentControls = null;
    var targetControls = null;
    var dragging = false;
    var dragOffsetX = 0;
    var dragOffsetY = 0;
    var dragLink = null;
    var dragLinkCopy = null;
    var dropTarget = null;
    var insertNode = null;
    var linkLists = [];
    var deleteNode = null;
    var savedBgColor = "";
    
    var killEvent = function ()
    {
        PLU.Event.stopPropagation();
        PLU.Event.preventDefault();
    };
    
    var mouseMoveHandler = function ()
    {
        PLU.Event.stopPropagation();
        
        var target = PLU.Event.target;
        if(dragging)
        {
            dragLinkCopy.style.left = PLU.Event.pageX - dragOffsetX + "px";
            dragLinkCopy.style.top = PLU.Event.pageY - dragOffsetY + "px";
            
            var mouseX = parseInt(dragLinkCopy.style.left);
            var mouseY = parseInt(dragLinkCopy.style.top);
            
            for(var index = 0; index < linkLists.length; index++)
            {
                var linkTotal = linkLists[index].links.length;

                if(mouseX >= linkLists[index].x && mouseX <= linkLists[index].x + linkLists[index].width && mouseY >= linkLists[index].y && mouseY <= linkLists[index].y + linkLists[index].height)
                {
                    for(var linkIndex = 0; linkIndex < linkLists[index].links.length; linkIndex++)
                    {
                        var linkElem = linkLists[index].links[linkIndex];
                        if(mouseX >= linkElem.x && mouseX <= linkElem.x + linkElem.width && mouseY >= linkElem.y && mouseY <= linkElem.y + linkElem.height)
                        {
                            if(linkIndex == linkTotal - 1)
                            {
                                if(linkElem.elem.nextSibling && linkElem.elem.nextSibling == insertNode)
                                    break;
                                else
                                {
                                    if(insertNode)
                                        insertNode.parentNode.removeChild(insertNode);

                                    insertNode = createInsertNode(dragLinkCopy);
                                    linkElem.elem.parentNode.appendChild(insertNode);
                                }
                            }
                            else
                            {
                                if(linkElem.elem.previousSibling && linkElem.elem.previousSibling == insertNode)
                                    break;
                                else
                                {
                                    if(insertNode)
                                        insertNode.parentNode.removeChild(insertNode);
                                        
                                    insertNode = createInsertNode(dragLinkCopy);
                                    linkElem.elem.parentNode.insertBefore(insertNode, linkElem.elem.nextSibling);
                                }
                            }
                            break;
                        }
                    }
                }
            }
        }
        else
        {
            if(PLU.DOM.hasClass(target, "__myplu_link_a"))
            {
                var containerDiv = PLU.DOM.findUp("div.__myplu_link_div", target)[0];
                targetControls = PLU.DOM.find("div.__myplu_link_controls", containerDiv)[0];
                if(targetControls && targetControls != currentControls)
                {
                    if(timeoutId)
                        window.clearTimeout(timeoutId);
                    timeoutId = window.setTimeout(showControls, 50);
                }            
            }
            else if(PLU.DOM.findUp("div.myplu-category", target)[0])
            {
                var catDiv = PLU.DOM.findUp("div.myplu-category", target)[0];
                targetControls = PLU.DOM.find("div.__myplu_cat_controls", catDiv)[0];
                if(timeoutId)
                    window.clearTimeout(timeoutId);
                timeoutId = window.setTimeout(showControls, 50);
            }
            else
            {
                if(timeoutId)
                {
                    window.clearTimeout(timeoutId);
                    timeoutId = null;
                }
                
                if(currentControls && !(PLU.DOM.findUp("div.__myplu_link_div", target)[0] || PLU.DOM.findUp("div.myplu-category", target)[0]))
                {
                    hideControls();
                }
            }
        }
    };
    
    var elemBgColor = function (elem)
    {
        do
        {
            if(elem.style && elem.style.backgroundColor && elem.style.backgroundColor != "transparent")
                return elem.style.backgroundColor;
        }while(elem = elem.parentNode);
        
        return "";
    };
    
    var showControls = function ()
    {
        if(!targetControls)
            return;
        if(currentControls && currentControls != targetControls)
            hideControls();

        targetControls.style.display = "block";

        if(PLU.Browser.MSIE && PLU.Browser.VERSION >= 7)
        {
            var a = PLU.DOM.find("a.__myplu_link_a", targetControls)[0];
            if(a)
            {
                savedBgColor = a.style.backgroundColor;
                a.style.backgroundColor = elemBgColor(a);
            }
        }
        currentControls = targetControls;
        targetControls = null;
    };
    
    var hideControls = function ()
    {
        if(currentControls)
        {
            if(savedBgColor)
            {
                var a = PLU.DOM.find("a.__myplu_link_a", currentControls)[0];
                if(a)
                    a.style.backgroundColor = savedBgColor;
                savedBgColor = "";
            }
            currentControls.style.display = "none";
            currentControls = null;
        }
    };
    
    var beginLinkDrag = function ()
    {
        PLU.Event.stopPropagation();
        PLU.Event.preventDefault();
        
        var target = PLU.Event.target;
        var linkElem = PLU.DOM.findUp("div.__myplu_link_div", target)[0];

        if(linkElem)
        {
            dragLink = linkElem.cloneNode(true);
            dragOffsetX = PLU.Event.pageX - PLU.DOM.elemOffsetX(linkElem);
            dragOffsetY = PLU.Event.pageY - PLU.DOM.elemOffsetY(linkElem);
            dragLinkCopy = dragLink.cloneNode(true);
            insertNode = createInsertNode(linkElem);
            linkElem.parentNode.insertBefore(insertNode, linkElem);
            linkElem.style.display = "none";
            deleteNode = linkElem;
            //linkElem.parentNode.removeChild(linkElem); // deleting this node here crashes IE7 :(

            dragLinkCopy.style.position = "absolute";
            dragLinkCopy.style.left = PLU.Event.pageX - dragOffsetX + "px";
            dragLinkCopy.style.top = PLU.Event.pageY - dragOffsetY + "px";
            dragLinkCopy.style.opacity = "0.7";
            dragLinkCopy.style.zIndex = 100;
            document.body.appendChild(dragLinkCopy);
            findLinkElems();
            dragging = true;
        }        
    };
    
    var beginCatDrag = function ()
    {
        PLU.Event.stopPropagation();
        PLU.Event.preventDefault();
        
        var target = PLU.Event.target;
        var linkElem = PLU.DOM.findUp("div.myplu-category", target)[0];

        if(linkElem)
        {
            dragLink = linkElem.cloneNode(true);
            dragOffsetX = PLU.Event.pageX - PLU.DOM.elemOffsetX(linkElem);
            dragOffsetY = PLU.Event.pageY - PLU.DOM.elemOffsetY(linkElem);
            dragLinkCopy = dragLink.cloneNode(true);
            insertNode = createInsertNode(linkElem);
            linkElem.parentNode.insertBefore(insertNode, linkElem);
            linkElem.style.display = "none";
            deleteNode = linkElem;
            //linkElem.parentNode.removeChild(linkElem); // deleting this node here crashes IE7 :(

            dragLinkCopy.style.position = "absolute";
            dragLinkCopy.style.left = PLU.Event.pageX - dragOffsetX + "px";
            dragLinkCopy.style.top = PLU.Event.pageY - dragOffsetY + "px";
            dragLinkCopy.style.opacity = "0.7";
            dragLinkCopy.style.zIndex = 100;
            document.body.appendChild(dragLinkCopy);
            findCatElems();
            dragging = true;
        }                
    };
    
    var mouseUpHandler = function ()
    {
        if(dragging)
        {
            if(PLU.DOM.hasClass(dragLinkCopy, "__myplu_link_div"))
            {
                dragging = false;
                document.body.removeChild(dragLinkCopy);
                dragLinkCopy = null;
    
                var droppedElem = dragLink.cloneNode(true);
                if(savedBgColor)
                {
                    var a = PLU.DOM.find("a.__myplu_link_a", droppedElem)[0];
                    if(a)
                        a.style.backgroundColor = savedBgColor;
                    savedBgColor = "";
                }
                insertNode.parentNode.insertBefore(droppedElem, insertNode);            
                //droppedElem.style.visibility = "hidden";
                droppedElem.style.display = "block";
                
                controlDiv = PLU.DOM.find("div.__myplu_link_controls", droppedElem)[0];
                controlDiv.style.display = "none";
                
                if(PLU.Browser.GECKO)
                    addControlListeners(droppedElem);
                insertNode.parentNode.removeChild(insertNode);
                insertNode = null;
                if(deleteNode)
                {
                    deleteNode.parentNode.removeChild(deleteNode);
                    deleteNode = null;
                }
                
                var offsetDiv = PLU.DOM.findUp("div.__myplu_bookmark_container", droppedElem)[0];
                var bookmarkDivs = PLU.DOM.find("div.__myplu_link_div", offsetDiv);
                for(var index = 0; index < bookmarkDivs.length; index++)
                {
                    if(bookmarkDivs[index] == droppedElem)
                    {
                        var bookmarkA = PLU.DOM.find("a.myplu-bookmark", droppedElem)[0];
                        if(bookmarkA)
                            var bookmarkId = bookmarkA.id.substring(bookmarkA.id.lastIndexOf("_") + 1);
                        
                        var listDiv = PLU.DOM.findUp("div.myplu-link-list", droppedElem)[0];
                        if(listDiv)
                            var bookmarkCat = listDiv.id.substring(listDiv.id.lastIndexOf("-") + 1);
                        
                        var reqUrl = "/doorways/move-bookmark.php?id=" + bookmarkId + "&c=" + bookmarkCat + "&o=" + index;
                        var req = new PLU.HttpRequest();
                        req.open("GET", reqUrl, true);
                        req.send(null);
                    }
                }
            }
            else if(PLU.DOM.hasClass(dragLinkCopy, "myplu-category"))
            {
                dragging = false;
                document.body.removeChild(dragLinkCopy);
                dragLinkCopy = null;
    
                var droppedElem = dragLink.cloneNode(true);

                insertNode.parentNode.insertBefore(droppedElem, insertNode);            
                droppedElem.style.display = "block";
                
                controlDiv = PLU.DOM.find("div.__myplu_cat_controls", droppedElem)[0];
                controlDiv.style.display = "none";
                
                if(PLU.Browser.GECKO)
                    addCatControlListeners(droppedElem);
                insertNode.parentNode.removeChild(insertNode);
                insertNode = null;
                if(deleteNode)
                {
                    deleteNode.parentNode.removeChild(deleteNode);
                    deleteNode = null;
                }
                
                var offsetDiv = PLU.DOM.findUp("div.__myplu_bookmark_container", droppedElem)[0];
                var bookmarkDivs = PLU.DOM.find("div.__myplu_link_div", offsetDiv);

                var catId = droppedElem.id.substring(droppedElem.id.lastIndexOf("_") + 1);
                
                var containerDiv = PLU.DOM.find("div.__myplu_cat_container")[0];
                var cats = PLU.DOM.find("div.myplu-category", containerDiv);
                for(var index = 0; index < cats.length; index++)
                {
                    if(cats[index] == droppedElem)
                    {
                        var reqUrl = "/doorways/move-category.php?id=" + catId + "&o=" + index;
                        var req = new PLU.HttpRequest();
                        req.open("GET", reqUrl, true);
                        req.send(null);
                        
                        var bookmarksContainer = PLU.DOM.getElementById("myplu-bookmarks-body");
                        var bookmarkLists = PLU.DOM.find("div.myplu-link-list", bookmarksContainer);
                        var listDiv = PLU.DOM.getElementById("myplu-link-list-" + catId);

                        if(bookmarkLists[index - 1] != listDiv)
                        {
                            var listDivClone = listDiv.cloneNode(true);
                            var addLinkDiv = PLU.DOM.find("div.myplu-add-link", listDivClone)[0];
                            var addLinkA = PLU.DOM.find("a", addLinkDiv)[0];
                            var linkDivs = PLU.DOM.find("div.__myplu_link_div", listDivClone);
                            PLU.Event.addListener(addLinkA, "click", addLink)
                            
                            
                            for(var linkIndex = 0; linkIndex < linkDivs.length; linkIndex++)
                            {
                                addControlListeners(linkDivs[linkIndex]);
                            }
                            
                            //addCatControlListeners(listDivClone);
                            
                            while(listDiv.childNodes.length)
                                listDiv.removeChild(listDiv.childNodes[0]);
                                
                            listDiv.parentNode.removeChild(listDiv);                            
                            
                            if(bookmarkLists[index])
                                bookmarksContainer.insertBefore(listDivClone, bookmarkLists[index]);
                            else
                                bookmarksContainer.appendChild(listDivClone);
                            listDivClone.style.display = "block";
                        }
                        break;
                    }
                }                
            }

            //dragLink.parentNode.removeChild(dragLink);
        }
    };
    
    var createInsertNode = function (templateNode)
    {
        var node = document.createElement("div");
        node.style.height = templateNode.offsetHeight + "px";       
        node.style.width = "95%";
        node.style.border = "dotted 1px #000";
        node.style.display = "block";
        node.style.visibility = "visible";
        node.appendChild(document.createTextNode(" "));
        return node;
    };
    
    var findLinkElems = function ()
    {
        linkLists = [];
        
        var listDivs = PLU.DOM.find("div.myplu-link-list");
        for(var index = 0; index < listDivs.length; index++)
        {
            var linkElems = [];
            var linkDivs = PLU.DOM.find("div.__myplu_link_div", listDivs[index]);
            
            for(divIndex = 0; divIndex < linkDivs.length; divIndex++)
            {
                linkElems[linkElems.length] = { elem: linkDivs[divIndex], x: PLU.DOM.elemOffsetX(linkDivs[divIndex]), y: PLU.DOM.elemOffsetY(linkDivs[divIndex]), width: linkDivs[divIndex].offsetWidth, height: linkDivs[divIndex].offsetHeight };
            }
            
            linkLists[linkLists.length] = { elem: listDivs[index], x: PLU.DOM.elemOffsetX(listDivs[index]), y: PLU.DOM.elemOffsetY(listDivs[index]), width: listDivs[index].offsetWidth, height: listDivs[index].offsetHeight, links: linkElems };
        }
    };
    
    var findCatElems = function ()
    {
        linkLists = [];
        
        var listDiv = PLU.DOM.find("div.__myplu_cat_container")[0];

        var linkElems = [];
        var linkDivs = PLU.DOM.find("div.myplu-category", listDiv);
        
        for(divIndex = 0; divIndex < linkDivs.length; divIndex++)
        {
            linkElems[linkElems.length] = { elem: linkDivs[divIndex], x: PLU.DOM.elemOffsetX(linkDivs[divIndex]), y: PLU.DOM.elemOffsetY(linkDivs[divIndex]), width: linkDivs[divIndex].offsetWidth, height: linkDivs[divIndex].offsetHeight };
        }
        
        linkLists[linkLists.length] = { elem: listDiv, x: PLU.DOM.elemOffsetX(listDiv), y: PLU.DOM.elemOffsetY(listDiv), width: listDiv.offsetWidth, height: listDiv.offsetHeight, links: linkElems };

    };
    
    var addControlListeners = function (elem)
    {
        var moveA = PLU.DOM.find("a.__myplu_link_a_move", elem)[0];
        if(moveA)
            PLU.Event.addListener(moveA, "mousedown", beginLinkDrag);
            
        var deleteA = PLU.DOM.find("a.__myplu_link_a_delete", elem)[0];
        if(deleteA)
        {
            var bookmarkA = PLU.DOM.find("a.__myplu_link_a", elem)[0];
            var id = bookmarkA.id.substring(bookmarkA.id.lastIndexOf("_") + 1);
            eval("var clickHandler = function () { deleteBookmark(" + id + "); };");
            PLU.Event.addListener(deleteA, "click", clickHandler);
        }
        
        var editA = PLU.DOM.find("a.__myplu_link_a_edit", elem)[0];
        if(editA)
        {
            var bookmarkA = PLU.DOM.find("a.__myplu_link_a", elem)[0];
            var id = bookmarkA.id.substring(bookmarkA.id.lastIndexOf("_") + 1);
            eval("var clickHandler = function () { beginEditBookmark(" + id + "); };");
            PLU.Event.addListener(editA, "click", clickHandler);            
        }
    };
    
    var addCatControlListeners = function (elem)
    {
        var moveA = PLU.DOM.find("a.__myplu_cat_a_move", elem)[0];
        if(moveA)
            PLU.Event.addListener(moveA, "mousedown", beginCatDrag);
            
        var deleteA = PLU.DOM.find("a.__myplu_cat_a_delete", elem)[0];
        if(deleteA)
        {
            var id = elem.id.substring(elem.id.lastIndexOf("_") + 1);
            eval("var clickHandler = function () { deleteCategory(" + id + "); };");
            PLU.Event.addListener(deleteA, "click", clickHandler);
        }
        
        var editA = PLU.DOM.find("a.__myplu_cat_a_edit", elem)[0];
        if(editA)
        {
            var id = elem.id.substring(elem.id.lastIndexOf("_") + 1);
            eval("var clickHandler = function () { beginEditCategory(" + id + "); };");
            PLU.Event.addListener(editA, "click", clickHandler);
        }
    };
    
    var cancelEdit = function (id)
    {
        var editContainer = PLU.DOM.getElementById("__myplu_edit_" + id);
        while(editContainer.childNodes.length)
            editContainer.removeChild(editContainer.childNodes[0]);
            
        editContainer.parentNode.removeChild(editContainer);
            
        var bookmarkA = PLU.DOM.getElementById("myplu_bookmark_id_" + id);
        var containerDiv = PLU.DOM.findUp("div.__myplu_link_div", bookmarkA)[0];
        
        containerDiv.style.display = "block";
    };
    
    var cancelCatEdit = function (id)
    {
        var editContainer = PLU.DOM.getElementById("__myplu_edit_cat_" + id);
        while(editContainer.childNodes.length)
            editContainer.removeChild(editContainer.childNodes[0]);
            
        editContainer.parentNode.removeChild(editContainer);
            
        var catDiv = PLU.DOM.getElementById("myplu_category_id_" + id);
        
        catDiv.style.display = "block";
    };    
    
    var updateLink = function (id)
    {
        var editContainer = PLU.DOM.getElementById("__myplu_edit_" + id);
        var newTitle = PLU.DOM.getElementById("edit-link-title-" + id).value;
        var newUrl = PLU.DOM.getElementById("edit-link-url-" + id).value;
        
        while(editContainer.childNodes.length)
            editContainer.removeChild(editContainer.childNodes[0]);
            
        var bookmarkA = PLU.DOM.getElementById("myplu_bookmark_id_" + id);
        var containerDiv = PLU.DOM.findUp("div.__myplu_link_div", bookmarkA)[0];
        
        bookmarkA.innerHTML = newTitle;
        bookmarkA.href = newUrl;
        
        containerDiv.style.display = "block";
        
        var reqUrl = "/doorways/edit-bookmark.php?id=" + id + "&t=" + newTitle + "&u=" + escape(newUrl);
        var req = new PLU.HttpRequest();
        
        req.open("GET", reqUrl, true);
        req.send(null);
    };
    
    var updateCat = function (id)
    {
        var editContainer = PLU.DOM.getElementById("__myplu_edit_cat_" + id);
        var newTitle = PLU.DOM.getElementById("edit-cat-title-" + id).value;
        
        while(editContainer.childNodes.length)
            editContainer.removeChild(editContainer.childNodes[0]);
        editContainer.parentNode.removeChild(editContainer);
            
        var catDiv = PLU.DOM.getElementById("myplu_category_id_" + id);
        var catH4 = PLU.DOM.find("h4", catDiv)[0];
        var catA = PLU.DOM.find("a", catH4)[0];
        catA.innerHTML = newTitle;
        
        var linkListDiv = PLU.DOM.getElementById("myplu-link-list-" + id);
        var linkListH4 = PLU.DOM.find("h4", linkListDiv)[0];
        linkListH4.innerHTML = newTitle;
        
        catDiv.style.display = "block";
        
        var reqUrl = "/doorways/edit-category.php?id=" + id + "&t=" + newTitle;
        var req = new PLU.HttpRequest();
        
        req.open("GET", reqUrl, true);
        req.send(null);
    };
    
    var deleteBookmark = function (id)
    {
        PLU.Event.stopPropagation();
        PLU.Event.preventDefault();

        if(confirm("Are you sure you want to delete this bookmark?"))
        {
            var reqUrl = "/doorways/delete-bookmark.php?id=" + id;
    
            var req = new PLU.HttpRequest();
            req.onreadystatechange = function ()
            {
                if(req.readyState == 4 && req.status == 200)
                {
                    var bookmarkA = PLU.DOM.getElementById("myplu_bookmark_id_" + id);
                    var containerDiv = PLU.DOM.findUp("div.__myplu_link_div", bookmarkA)[0];
                    
                    while(containerDiv.childNodes.length)
                        containerDiv.removeChild(containerDiv.childNodes[0]);
                        
                    containerDiv.parentNode.removeChild(containerDiv);
                }
            };
            req.open("GET", reqUrl, true);
            req.send(null);
        }
    };
    
    var deleteCategory = function (id)
    {
        PLU.Event.stopPropagation();
        PLU.Event.preventDefault();

        if(confirm("Are you sure you want to delete this category?"))
        {
            var reqUrl = "/doorways/delete-category.php?id=" + id;
    
            var req = new PLU.HttpRequest();
            req.onreadystatechange = function ()
            {
                if(req.readyState == 4 && req.status == 200)
                {
                    var catDiv = PLU.DOM.getElementById("myplu_category_id_" + id);
                                        
                    while(catDiv.childNodes.length)
                        catDiv.removeChild(catDiv.childNodes[0]);
                        
                    catDiv.parentNode.removeChild(catDiv);
                    
                    catDiv = PLU.DOM.getElementById("myplu-link-list-" + id);

                    while(catDiv.childNodes.length)
                        catDiv.removeChild(catDiv.childNodes[0]);
                        
                    catDiv.parentNode.removeChild(catDiv);
                    
                }
            };
            req.open("GET", reqUrl, true);
            req.send(null);
        }
    };
    
    var beginEditBookmark = function (id)
    {
        PLU.Event.stopPropagation();
        PLU.Event.preventDefault();
        
        var bookmarkA = PLU.DOM.getElementById("myplu_bookmark_id_" + id);
        var linkTitle = bookmarkA.innerHTML;
        var linkUrl = bookmarkA.href;
        var containerDiv = PLU.DOM.findUp("div.__myplu_link_div", bookmarkA)[0];
        var editContainer = document.createElement("div");
        editContainer.id = "__myplu_edit_" + id;
        editContainer.className = "myplu-edit-link";
        
        //while(containerDiv.childNodes.length)
        //    containerDiv.removeChild(containerDiv.childNodes[0]);
            
        var label = document.createElement("label");
        label.appendChild(document.createTextNode("Title:"));
        editContainer.appendChild(label);
        editContainer.appendChild(document.createElement("br"));
        var titleInput = document.createElement("input");
        titleInput.setAttribute("id", "edit-link-title-" + id);
        titleInput.setAttribute("type", "text");
        titleInput.value = linkTitle;
        editContainer.appendChild(titleInput);       
        editContainer.appendChild(document.createElement("br"));
        
        label = document.createElement("label");
        label.appendChild(document.createTextNode("URL:"));
        editContainer.appendChild(label);
        editContainer.appendChild(document.createElement("br"));
        var urlInput = document.createElement("input");
        urlInput.setAttribute("id", "edit-link-url-" + id);
        urlInput.setAttribute("type", "text");
        urlInput.value = linkUrl;
        editContainer.appendChild(urlInput);
        
        editContainer.appendChild(document.createElement("br"));
        var btnSave = document.createElement("input");
        btnSave.setAttribute("type", "button");
        btnSave.setAttribute("value", "Save");
        btnSave.className = "edit-link-button";
        eval("var clickHandler = function () { updateLink(" + id+ "); };");
        PLU.Event.addListener(btnSave, "click", clickHandler);
        
        var btnCancel = document.createElement("input");
        btnCancel.setAttribute("type", "button");
        btnCancel.setAttribute("value", "Cancel");
        btnCancel.className = "edit-link-button";
        eval("var cancelHandler = function () { cancelEdit(" + id + "); };");
        PLU.Event.addListener(btnCancel, "click", cancelHandler);
        
        editContainer.appendChild(btnSave);
        editContainer.appendChild(btnCancel);
        
        containerDiv.parentNode.insertBefore(editContainer, containerDiv);
        containerDiv.style.display = "none";
        //containerDiv.parentNode.removeChild(containerDiv);
    };
    
    var beginEditCategory = function (id)
    {
        PLU.Event.stopPropagation();
        PLU.Event.preventDefault();
        
        var catDiv = PLU.DOM.getElementById("myplu_category_id_" + id);
        var catH4 = PLU.DOM.find("h4", catDiv)[0];
        var catA = PLU.DOM.find("a", catH4)[0];
        var catTitle = catA.innerHTML;
        var editContainer = document.createElement("div");
        editContainer.id = "__myplu_edit_cat_" + id;
        editContainer.className = "myplu-edit-link";
                    
        var label = document.createElement("label");
        label.appendChild(document.createTextNode("Title:"));
        editContainer.appendChild(label);
        editContainer.appendChild(document.createElement("br"));
        var titleInput = document.createElement("input");
        titleInput.setAttribute("id", "edit-cat-title-" + id);
        titleInput.setAttribute("type", "text");
        titleInput.value = catTitle;
        editContainer.appendChild(titleInput);       
        editContainer.appendChild(document.createElement("br"));
        
        var btnSave = document.createElement("input");
        btnSave.setAttribute("type", "button");
        btnSave.setAttribute("value", "Save");
        btnSave.className = "edit-link-button";
        eval("var clickHandler = function () { updateCat(" + id + "); };");
        PLU.Event.addListener(btnSave, "click", clickHandler);
        
        var btnCancel = document.createElement("input");
        btnCancel.setAttribute("type", "button");
        btnCancel.setAttribute("value", "Cancel");
        btnCancel.className = "edit-link-button";
        eval("var cancelHandler = function () { cancelCatEdit(" + id + "); };");
        PLU.Event.addListener(btnCancel, "click", cancelHandler);
        
        editContainer.appendChild(btnSave);
        editContainer.appendChild(btnCancel);
        
        catDiv.parentNode.insertBefore(editContainer, catDiv);
        catDiv.style.display = "none";
        //containerDiv.parentNode.removeChild(containerDiv);
    
    };
    
    var addLink = function ()
    {
        PLU.Event.stopPropagation();
        PLU.Event.preventDefault();
        
        var target = PLU.Event.target;
        
        var linkListDiv = PLU.DOM.findUp("div.myplu-link-list", target)[0];
        var catId = linkListDiv.id.substring(linkListDiv.id.lastIndexOf("-") + 1);
        var addDiv = PLU.DOM.findUp("div", target)[0];
        
        while(addDiv.childNodes.length)
            addDiv.removeChild(addDiv.childNodes[0]);
        
        var label = document.createElement("label");
        label.appendChild(document.createTextNode("Title:"));
        addDiv.appendChild(label);
        addDiv.appendChild(document.createElement("br"));
        var titleInput = document.createElement("input");
        titleInput.setAttribute("id", "add-link-title-" + catId);
        titleInput.setAttribute("type", "text");
        titleInput.className = "add-link-title";
        addDiv.appendChild(titleInput);
        addDiv.appendChild(document.createElement("br"));
        
        label = document.createElement("label");
        label.appendChild(document.createTextNode("URL:"));
        addDiv.appendChild(label);
        addDiv.appendChild(document.createElement("br"));
        var urlInput = document.createElement("input");
        urlInput.setAttribute("id", "add-link-url-" + catId);
        urlInput.setAttribute("type", "text");
        urlInput.className = "add-link-url";
        addDiv.appendChild(urlInput);
        addDiv.appendChild(document.createElement("br"));
        
        var btnAdd = document.createElement("input");
        btnAdd.setAttribute("type", "button");
        btnAdd.className = "add-link-button";
        btnAdd.setAttribute("value", "Add");
        eval("var clickHandler = function () { addCatLink(" + catId + ", PLU.DOM.getElementById('add-link-title-" + catId + "').value, PLU.DOM.getElementById('add-link-url-" + catId + "').value); };");
        PLU.Event.addListener(btnAdd, "click", clickHandler);
        addDiv.appendChild(btnAdd);
        
        var btnCancel = document.createElement("input");
        btnCancel.setAttribute("type", "button");
        btnCancel.className = "add-link-button";
        btnCancel.setAttribute("value", "Cancel");
        eval("var cancelHandler = function () { cancelAddLink(" + catId + "); };");
        PLU.Event.addListener(btnCancel, "click", cancelHandler);
        addDiv.appendChild(btnCancel);
    };
    
    var cancelAddLink = function (catId)
    {
        var addDiv = PLU.DOM.getElementById("myplu-add-link-" + catId);
        
        while(addDiv.childNodes.length)
            addDiv.removeChild(addDiv.childNodes[0]);
            
        var addA = document.createElement("a");
        addA.setAttribute("href", "#");
        addA.appendChild(document.createTextNode("Add Bookmark"));
        addDiv.appendChild(addA);
        PLU.Event.addListener(addA, "click", addLink);        
    };
    
    var cancelAddCat = function ()
    {
        var addDiv = PLU.DOM.find("div.myplu-add-cat")[0];
        
        while(addDiv.childNodes.length)
            addDiv.removeChild(addDiv.childNodes[0]);
            
        var addA = document.createElement("a");
        addA.setAttribute("href", "#");
        addA.appendChild(document.createTextNode("Add a category"));
        addDiv.appendChild(addA);
        PLU.Event.addListener(addA, "click", beginAddCat);     
    }
    
    var addCatLink = function (catId, linkTitle, linkUrl)
    {
        if(!linkTitle)
        {
            alert("You must enter a title for this bookmark!");
            return;
        }
        if(!linkUrl)
        {
            alert("You must enter a URL for this bookmark!");
            return;
        }
        
        var reqUrl = "/doorways/add-bookmark.php?c=" + catId + "&t=" + linkTitle + "&u=" + escape(linkUrl);
        var req = new PLU.HttpRequest();
        req.onreadystatechange = function ()
        {
            if(req.readyState == 4 && req.status == 200)
            {
                var resp = req.responseXML;
                //alert(req.responseText);
                //var error = PLU.DOM.find("error", resp)[0].firstChild.data;
                //if(!error)
                //{
                    var bookmarkId = PLU.DOM.find("id", resp)[0].firstChild.data;
                    addBookmark(catId, bookmarkId, linkTitle, linkUrl);
                //}
            }
        };
        req.open("GET", reqUrl, true);
        req.send(null);
    };
    
    var addBookmark = function (catId, bookmarkId, bookmarkTitle, bookmarkUrl)
    {
        var catDiv = PLU.DOM.getElementById("myplu-link-list-" + catId);
        var addDiv = PLU.DOM.find("div.myplu-add-link", catDiv)[0];
        var offsetDiv = PLU.DOM.find("div.__myplu_bookmarks_container", catDiv)[0];
        
        if(!/^(http:\/\/|https:\/\/)/.test(bookmarkUrl))
            bookmarkUrl = 'http://' + bookmarkUrl;
        
        var div = document.createElement("div");
        div.style.background = "#fff";
        //div.style.visibility = "hidden";
        //div.style.padding = "0.5em";
        div.style.position = "relative";
        div.className = "__myplu_link_div";
        
        var controlDiv = document.createElement("div");
        controlDiv.className = "__myplu_link_controls";
        controlDiv.style.position = "absolute";
        controlDiv.style.top = "0px";
        controlDiv.style.left = "-5.1em";
        controlDiv.style.display = "none";
        controlDiv.style.backgroundColor = "#fff";
        controlDiv.style.padding = "0.3em 0.45em 0.3em 0.3em";
        
        var deleteA = document.createElement("a");
        var deleteIcon = document.createElement("img");
        deleteIcon.setAttribute("src", "/dev/img/icons/delete.gif");
        deleteIcon.setAttribute("style", "border: none;");
        deleteA.appendChild(deleteIcon);
        deleteA.className = "__myplu_link_a_delete";
        //deleteA.style.fontSize = "10px";
        //deleteA.style.display = "block";
        deleteA.style.padding = "2px";
        deleteA.setAttribute("href", "#");
        controlDiv.appendChild(deleteA);
        //div.appendChild(deleteA);
        
        var editA = document.createElement("a");
        editA.appendChild(document.createTextNode("Edit"));
        editA.className = "__myplu_link_a_edit";
        editA.style.fontSize = "10px";
        //editA.style.display = "block";
        editA.style.padding = "0.15em";
        editA.setAttribute("href", "#");
        editA.style.color = "#333";
        controlDiv.appendChild(editA);                        
        //div.appendChild(editA);
        
        var moveA = document.createElement("a");
        var moveIcon = document.createElement("img");
        moveIcon.setAttribute("src", "/dev/img/icons/move.gif");
        moveIcon.setAttribute("style", "border: none;");
        moveA.appendChild(moveIcon);
        moveA.className = "__myplu_link_a_move";
        moveA.style.fontSize = "10px";
        //moveA.style.display = "block";
        moveA.style.padding = "2px";
        moveA.style.cursor = "move";
        moveA.setAttribute("href", "#");
        controlDiv.appendChild(moveA);
        //div.appendChild(moveA);
        
        //controlDiv.className;
        div.appendChild(controlDiv);

        var linkCopy = document.createElement("a");
        linkCopy.setAttribute("id", "myplu_bookmark_id_" + bookmarkId);
        linkCopy.setAttribute("href", bookmarkUrl);
        linkCopy.appendChild(document.createTextNode(bookmarkTitle));
        div.appendChild(linkCopy);
        linkCopy.style.visibility = "visible";
        linkCopy.style.display = "block";
        if(PLU.Browser.MSIE && PLU.Browser.VERSION >= 7)
            linkCopy.style.background = "transparent";
        //linkCopy.style.background = "auto";
        //linkCopy.style.width = "150px";
        linkCopy.className += "myplu-bookmark __myplu_link_a";
        linkCopy.setAttribute("title", linkCopy.href);
        //catDiv.insertBefore(div, addDiv);
        offsetDiv.appendChild(div);
        addControlListeners(div);
        
        while(addDiv.childNodes.length)
            addDiv.removeChild(addDiv.childNodes[0]);
            
        var addA = document.createElement("a");
        addA.setAttribute("href", "#");
        addA.appendChild(document.createTextNode("Add Bookmark"));
        addDiv.appendChild(addA);
        PLU.Event.addListener(addA, "click", addLink);
    };
    
    var beginEditCats = function ()
    {
        PLU.Event.stopPropagation();
        PLU.Event.preventDefault();
        
        PLU.DOM.getElementById("myplu-bookmarks").style.display = "none";
        PLU.DOM.getElementById("myplu-categories").style.display = "block";
    };
    
    var endEditCats = function ()
    {
        PLU.Event.stopPropagation();
        PLU.Event.preventDefault();
        
        PLU.DOM.getElementById("myplu-categories").style.display = "none";
        PLU.DOM.getElementById("myplu-bookmarks").style.display = "block";
    };
    
    var beginAddCat = function ()
    {
        PLU.Event.stopPropagation();
        PLU.Event.preventDefault();
        
        var addCatDiv = PLU.DOM.find("div.myplu-add-cat")[0];
        
        while(addCatDiv.childNodes.length)
            addCatDiv.removeChild(addCatDiv.childNodes[0]);
            
        var label = document.createElement("label");
        label.appendChild(document.createTextNode("Category Title:"));
        addCatDiv.appendChild(label);
        addCatDiv.appendChild(document.createElement("br"));
        var input = document.createElement("input");
        input.setAttribute("type", "text");
        input.id = "myplu-add-cat-title";
        addCatDiv.appendChild(input);
        addCatDiv.appendChild(document.createElement("br"));
        input = document.createElement("input");
        input.setAttribute("type", "button");
        input.setAttribute("value", "Add");
        input.className = "add-cat-button";        
        
        PLU.Event.addListener(input, "click", addCat);
        addCatDiv.appendChild(input);
        
        input = document.createElement("input");
        input.setAttribute("type", "button");
        input.setAttribute("value", "Cancel");
        input.className = "add-cat-button";     
        PLU.Event.addListener(input, "click", cancelAddCat);
        addCatDiv.appendChild(input);
    };
    
    var addCat = function ()
    {
        var catTitle = PLU.DOM.getElementById("myplu-add-cat-title").value;
        
        var reqUrl = "/doorways/add-category.php?t=" + catTitle;
        var req = new PLU.HttpRequest();
        
        req.onreadystatechange = function ()
        {
            if(req.readyState == 4 && req.status == 200)
            {
                var reqXml = req.responseXML;
                
                var newId = PLU.DOM.find("id", reqXml)[0].firstChild.data;
                insertCat(newId, catTitle);
            }
        };
        
        req.open("GET", reqUrl, true);
        req.send(null);
    };
    
    var insertCat = function (catId, catTitle)
    {
        var catListDiv = PLU.DOM.getElementById("myplu-cat-list");
        var containerDiv = PLU.DOM.find("div.__myplu_cat_container")[0];
        var addCatElem = PLU.DOM.find("div.myplu-add-cat", catListDiv)[0];
        var newDiv = document.createElement("div");
        var h4 = document.createElement("h4");
        var a = document.createElement("a");
        a.setAttribute("href", "#");
        a.appendChild(document.createTextNode(catTitle));
        PLU.Event.addListener(a, "click", killEvent);
        h4.appendChild(a);
        newDiv.appendChild(h4);
        newDiv.id = "myplu_category_id_" + catId;
        newDiv.className = "myplu-category";
        var controlDiv = document.createElement("div");
        
        newDiv.style.position = "relative";
        
        controlDiv.style.position = "absolute";
        controlDiv.style.top = "0px";
        controlDiv.style.left = "-5.2em";
        controlDiv.style.display = "none";
        controlDiv.style.backgroundColor = "#fff";
        controlDiv.style.padding = "0.3em 0.45em 0.3em 0.3em";
        controlDiv.className = "__myplu_cat_controls";
   
        var deleteA = document.createElement("a");
        var deleteIcon = document.createElement("img");
        deleteIcon.setAttribute("src", "/dev/img/icons/delete.gif");
        deleteIcon.setAttribute("style", "border: none;");
        deleteA.appendChild(deleteIcon);
        deleteA.className = "__myplu_cat_a_delete";
        deleteA.style.fontSize = "10px";
        deleteA.style.padding = "2px";
        deleteA.setAttribute("href", "#");
        controlDiv.appendChild(deleteA);
        
        var editA = document.createElement("a");
        editA.appendChild(document.createTextNode("edit"));
        editA.className = "__myplu_cat_a_edit";
        editA.style.fontSize = "10px";
        editA.style.padding = "2px";
        editA.style.color = "#333";
        editA.setAttribute("href", "#");
        controlDiv.appendChild(editA);
        
        var moveA = document.createElement("a");
        var moveIcon = document.createElement("img");
        moveIcon.setAttribute("src", "/dev/img/icons/move.gif");
        moveIcon.setAttribute("style", "border: none;");
        moveA.appendChild(moveIcon);
        moveA.className = "__myplu_cat_a_move";
        moveA.style.fontSize = "10px";
        moveA.style.padding = "2px";
        moveA.style.cursor = "move";
        moveA.setAttribute("href", "#");
        controlDiv.appendChild(moveA);
        newDiv.insertBefore(controlDiv, h4);
        addCatControlListeners(newDiv);
        //newDiv.innerHTML = catTitle;
        
        containerDiv.appendChild(newDiv);
        
        
        // Now do Bookmarks side
        
        var linkListDiv = document.createElement("div");
        linkListDiv.id = "myplu-link-list-" + catId;
        linkListDiv.className = "myplu-link-list";
        var titleDiv = document.createElement("div");
        titleDiv.className = "myplu-list-title";
        var titleH4 = document.createElement("h4");
        titleH4.appendChild(document.createTextNode(catTitle));
        titleDiv.appendChild(titleH4);
        linkListDiv.appendChild(titleDiv);
        
        var containerDiv = document.createElement("div");
        containerDiv.className = "__myplu_bookmarks_container";
        containerDiv.style.position = "relative";        
        
        var dummyDiv = document.createElement("div");
        dummyDiv.className = "__myplu_link_div";
        containerDiv.appendChild(dummyDiv);
        linkListDiv.appendChild(containerDiv);
        
        var addDiv = document.createElement("div");
        addDiv.id = "myplu-add-link-" + catId;
        addDiv.className = "myplu-add-link";
        var addA = document.createElement("a");
        addA.setAttribute("href", "#");
        addA.appendChild(document.createTextNode("Add a bookmark"));
        PLU.Event.addListener(addA, "click", addLink);
        addDiv.appendChild(addA);
        
        linkListDiv.appendChild(addDiv);
        
        var bookmarkBodyDiv = PLU.DOM.getElementById("myplu-bookmarks-body");
        bookmarkBodyDiv.appendChild(linkListDiv);
        
        while(addCatElem.childNodes.length)
            addCatElem.removeChild(addCatElem.childNodes[0]);
            
        var addA = document.createElement("a");
        addA.setAttribute("href", "#");
        addA.appendChild(document.createTextNode("Add a category"));
        
        PLU.Event.addListener(addA, "click", beginAddCat);
        addCatElem.appendChild(addA);
    };
    
    return {
        init: function ()
        {
            var linkLists = PLU.DOM.find("div.myplu-link-list");
            
            if(linkLists.length)
            {
                for(var index = 0; index < linkLists.length; index++)
                {
                    if(PLU.Browser.MSIE)
                        PLU.Event.addListener(linkLists[index], "dragstart", killEvent);

                    var links = PLU.DOM.find("a.myplu-bookmark", linkLists[index]);
                    
                    var offsetDiv = document.createElement("div");
                    var titleDiv = PLU.DOM.find("div.myplu-list-title", linkLists[index])[0];
                    offsetDiv.className = "__myplu_bookmarks_container";
                    if(titleDiv.nextSibling)
                        linkLists[index].insertBefore(offsetDiv, titleDiv.nextSibling);
                    else
                        linkLists[index].appendChild(offsetDiv);
                        
                    offsetDiv.style.position = "relative";
                    //offsetDiv.style.left = "-52px";
                    
                    var dummyDiv = document.createElement("div");
                    dummyDiv.className = "__myplu_link_div";
                    offsetDiv.appendChild(dummyDiv);
                    
                    for(var aIndex = 0; aIndex < links.length; aIndex++)
                    {
                        var div = document.createElement("div");
                        div.style.background = "#fff";
                        //div.style.visibility = "hidden";
                        //div.style.padding = "0.5em";
                        div.style.position = "relative";
                        div.className = "__myplu_link_div";
                        
                        var controlDiv = document.createElement("div");
                        controlDiv.className = "__myplu_link_controls";
                        controlDiv.style.position = "absolute";
                        controlDiv.style.top = "0px";
                        controlDiv.style.left = "-5.1em";
                        controlDiv.style.display = "none";
                        controlDiv.style.backgroundColor = "#fff";
                        controlDiv.style.padding = "0.3em 0.45em 0.3em 0.3em";
                        
                        var deleteA = document.createElement("a");
                        var deleteIcon = document.createElement("img");
                        deleteIcon.setAttribute("src", "/dev/img/icons/delete.gif");
                        deleteIcon.setAttribute("style", "border: none;");
                        deleteA.appendChild(deleteIcon);
                        deleteA.className = "__myplu_link_a_delete";
                        //deleteA.style.fontSize = "10px";
                        //deleteA.style.display = "block";
                        deleteA.style.padding = "2px";
                        deleteA.setAttribute("href", "#");
                        controlDiv.appendChild(deleteA);
                        //div.appendChild(deleteA);
                        
                        var editA = document.createElement("a");
                        editA.appendChild(document.createTextNode("Edit"));
                        editA.className = "__myplu_link_a_edit";
                        editA.style.fontSize = "10px";
                        //editA.style.display = "block";
                        editA.style.padding = "0.15em";
                        editA.style.color = "#333";
                        editA.setAttribute("href", "#");
                        controlDiv.appendChild(editA);
                        //div.appendChild(editA);
                        
                        var moveA = document.createElement("a");
                        var moveIcon = document.createElement("img");
                        moveIcon.setAttribute("src", "/dev/img/icons/move.gif");
                        moveIcon.setAttribute("style", "border: none;");
                        moveA.appendChild(moveIcon);
                        moveA.className = "__myplu_link_a_move";
                        moveA.style.fontSize = "10px";
                        //moveA.style.display = "block";
                        moveA.style.padding = "2px";
                        moveA.style.cursor = "move";
                        moveA.setAttribute("href", "#");
                        controlDiv.appendChild(moveA);
                        //div.appendChild(moveA);
                        
                        //controlDiv.className;
                        div.appendChild(controlDiv);

                        var linkCopy = links[aIndex].cloneNode(true);
                        linkCopy.setAttribute("title", linkCopy.href);
                        div.appendChild(linkCopy);
                        //linkCopy.style.visibility = "visible";
                        //linkCopy.style.display = "block";
                        //linkCopy.style.position = "relative";
                        if(PLU.Browser.MSIE && PLU.Browser.VERSION >= 7)
                            linkCopy.style.background = "transparent";
                            
                        linkCopy.className += " __myplu_link_a";

                        offsetDiv.appendChild(div);
                        linkLists[index].removeChild(links[aIndex]);
                        
                        
                        //div.style.position = "relative";
                        //div.parentNode.style.position = "relative";
                        
                        //controlDiv.style.position = "absolute";
                        //controlDiv.style.top = "0px";
                        //controlDiv.style.left = (deleteA.offsetWidth + editA.offsetWidth + moveA.offsetWidth) + "px";
                        addControlListeners(div);
                    }
                    
                    var addLinkDiv = PLU.DOM.find("div.myplu-add-link", linkLists[index])[0];
                    if(addLinkDiv)
                    {
                        var addLinkA = PLU.DOM.find("a", addLinkDiv)[0];
                        
                        PLU.Event.addListener(addLinkA, "click", addLink);
                    }
                }

                var catList = PLU.DOM.getElementById("myplu-cat-list");

                if(catList)
                {    
                    if(PLU.Browser.MSIE)
                        PLU.Event.addListener(catList, "dragstart", killEvent);
                        
                    var offsetDiv = document.createElement("div");
                    offsetDiv.className = "__myplu_cat_container";

                    var dummyDiv = document.createElement("div");
                    dummyDiv.className = "myplu-category";
                    offsetDiv.appendChild(dummyDiv);
                    
                    var catItems = PLU.DOM.find("div.myplu-category", catList);

                    for(var catIndex = 0; catIndex < catItems.length; catIndex++)
                    {
                        var div = catItems[catIndex].cloneNode(true);
                        var h4 = PLU.DOM.find("h4", div)[0];
                        var a = PLU.DOM.find("a", h4)[0];
                        PLU.Event.addListener(a, "click", killEvent);
                        var controlDiv = document.createElement("div");
                        
                        div.style.position = "relative";
                        
                        controlDiv.style.position = "absolute";
                        controlDiv.style.top = "0px";
                        controlDiv.style.left = "-5.2em";
                        controlDiv.style.display = "none";
                        controlDiv.style.backgroundColor = "#fff";
                        controlDiv.style.padding = "0.3em 0.45em 0.3em 0.3em";
                        controlDiv.className = "__myplu_cat_controls";
                   
                        var deleteA = document.createElement("a");
                        var deleteIcon = document.createElement("img");
                        deleteIcon.setAttribute("src", "/dev/img/icons/delete.gif");
                        deleteIcon.setAttribute("style", "border: none;");
                        deleteA.appendChild(deleteIcon);
                        deleteA.className = "__myplu_cat_a_delete";
                        deleteA.style.fontSize = "10px";                        
                        deleteA.style.padding = "2px";
                        deleteA.setAttribute("href", "#");
                        controlDiv.appendChild(deleteA);
                        
                        var editA = document.createElement("a");
                        editA.appendChild(document.createTextNode("Edit"));
                        editA.className = "__myplu_cat_a_edit";
                        editA.style.fontSize = "10px";
                        editA.style.padding = "2px";
                        editA.style.color = "#333";
                        editA.setAttribute("href", "#");
                        controlDiv.appendChild(editA);
                        
                        var moveA = document.createElement("a");
                        var moveIcon = document.createElement("img");
                        moveIcon.setAttribute("src", "/dev/img/icons/move.gif");
                        moveIcon.setAttribute("style", "border: none;");
                        moveA.appendChild(moveIcon);
                        moveA.className = "__myplu_cat_a_move";
                        moveA.style.fontSize = "10px";
                        moveA.style.padding = "2px";
                        moveA.style.cursor = "move";
                        moveA.setAttribute("href", "#");
                        controlDiv.appendChild(moveA);
                        div.insertBefore(controlDiv, h4);
                        addCatControlListeners(div);
                        offsetDiv.appendChild(div);
                        
                        while(catItems[catIndex].childNodes.length)
                            catItems[catIndex].removeChild(catItems[catIndex].childNodes[0]);
                            
                        catItems[catIndex].parentNode.removeChild(catItems[catIndex]);
                    }
                    
                    catList.insertBefore(offsetDiv, catList.firstChild);
                        
                    /*var addLinkDiv = PLU.DOM.find("div.myplu-add-link", linkLists[index])[0];
                    if(addLink)
                    {
                        var addLinkA = PLU.DOM.find("a", addLinkDiv)[0];
                        
                        PLU.Event.addListener(addLinkA, "click", addLink);
                    }*/
    
                }                
                
                PLU.Event.addListener(window, "mousemove", mouseMoveHandler);
                PLU.Event.addListener(window, "mouseup", mouseUpHandler);                
               
                var editCatsLink = PLU.DOM.getElementById("myplu-manage-cats");
                var bookmarksLink = PLU.DOM.getElementById("myplu-manage-bookmarks");
                
                PLU.Event.addListener(editCatsLink, "click", beginEditCats);
                PLU.Event.addListener(bookmarksLink, "click", endEditCats);
                
                var addCatElem = PLU.DOM.find("div.myplu-add-cat")[0];
                
                if(addCatElem)
                {
                    var addCatA = PLU.DOM.find("a", addCatElem)[0];
                    PLU.Event.addListener(addCatA, "click", beginAddCat);
                }
            }
        }
    };
}();

PLU.Event.addListener(window, "load", PLU.MyPLU.init);

