﻿function checkAuth(str)
{
    if(str == "NotAuth")
    {
        window.location.href = "Home.aspx?msg=You%20have%20been%20logged%20out%20due%20to%20inactivity!&showlogin=true";        
        return false;
    }
    else
    {
        return true;
    }
}

function jsonDeserializeIfAuth(jsonObj, wrap)
{
    if(checkAuth(jsonObj))
    {
        if(wrap)
        {         
            return Sys.Serialization.JavaScriptSerializer.deserialize("(" + jsonObj + ")");
        }
        else
        {
            return Sys.Serialization.JavaScriptSerializer.deserialize(jsonObj);
        }
    }
    
    return null;
}

function columnObj(_column, _saveObj)
{
    this.column = _column;
    this.saveObj = _saveObj;
    this.setHeight  = function(h)
    {        
        this.column.style.height = h;
    };
    
    this.setWidth = function(w)
    {
        if(w < 0)
            w = w * -1;
        
        if(this.getWidth("%") != roundNumIfIE(w))
        {
            this.column.style.width = w + "%";
            categoryMgr.doSave = true;
        }
    };
    
    
    this.getWidth = function(raw)
    {

        if(typeof raw == "undefined")
            return parseInt(this.column.offsetWidth, 10);
        else
            return parseFloat(this.column.style.width.replace(/%/, ""));
    };
    
    this.getHeight  = function() { return parseInt(this.column.offsetHeight, 10); };
    this.getTop     = function() { return getOffsetTop(this.column); };
    this.getLeft    = function() { return getOffsetLeft(this.column); };
    this.getBottom  = function() { return this.getTop() + this.getHeight(); };
    this.getRight   = function() { return this.getLeft() + this.getWidth(); };
}

function dropletObj(_saveObj, _droplet, _content, _setBtn, _minBtn, _medBtn, _maxBtn, _sizeS, _sizeSW, _sizeSE)
{
    // Quick accessors to elements of the droplet
    this.droplet = _droplet;
    this.content = _content;
    this.setBtn  = _setBtn;
    this.minBtn  = _minBtn;
    this.medBtn  = _medBtn;
    this.maxBtn  = _maxBtn;
    this.sizeS   = _sizeS;
    this.sizeSW  = _sizeSW;
    this.sizeSE  = _sizeSE;
    
    // Settings
    this.saveObj  = _saveObj;
    this.doSave   = false;
    this.deleted = false;
    
    this.setHeight = function(h)
    {
        var midH = h - 33;
        midH = (midH < 1) ? 1 : midH;
        
        this.content.style.height = midH + "px";
        
        midH = (this.saveObj != null) ? midH + 16 : midH + 6;
        
        this.content.parentNode.style.height = midH + "px";
        
        if(this.saveObj != null && this.saveObj.DropletModeId == 2 && this.saveObj.StandardHeight != h)
        {
            this.saveObj.StandardHeight = h;
            this.doSave = true;
        }
    };
    
    this.setWidth = function(w, unit)
    {
        if(typeof unit == "undefined")
            unit = "px";
        

        // Set IFrame widths if IE6
        if(isIE6 && this.saveObj == null)
        {
            this.content.childNodes[0].style.width = "180px";
            this.content.childNodes[1].style.width = "100%";
            this.content.childNodes[0].style.height = "150px";
            this.content.childNodes[1].style.height = "150px";
        }


        this.droplet.style.width = (unit == "px") ? w + unit : "auto";

        if((isIE6 && (unit != "px") && typeof this.droplet.parentNode.offsetWidth != "undefined" && (this.droplet.parentNode.offsetWidth - 17 > 0)))
            this.content.style.width = (this.droplet.parentNode.offsetWidth - 17) + "px";
        else if(isIE6)
            this.content.style.width = "auto";

        if(this.getWidth() > 100)
        {
            // Set title width
            if(this.saveObj != null)
			{
                this.droplet.childNodes[0].childNodes[1].style.width = (this.getWidth() - 100) + "px";
				if(isIE6 && unit == "px")
				{
					this.droplet.childNodes[0].childNodes[1].style.width = (w - 100) + "px";
					this.content.style.width = (w - 11) + "px";
				}
		    }
            
            if(this.saveObj == null)
            {
                this.content.childNodes[0].style.width = "180px";
                this.content.childNodes[0].style.marginLeft = (((this.getWidth() - 15) - 180) / 2) + "px";
                this.content.childNodes[1].style.width = (this.getWidth() - 15) + "px";
            }
        }

    };
    
    this.setPlacement = function(h,w,l,t)
    {
        if(h != null)
            this.setHeight(h);

        if(w != null)
            this.setWidth(w);

        if(l != null)
        {
            var left = parseInt(l[0] + l[1], 10);
            this.droplet.style.left = left + "px";
        }
        else if(this.saveObj != null && this.saveObj.DropletModeId != 3)
        {
            this.droplet.style.left = "0px";
        }
        
        
        if(t != null)
        {
            var top = parseInt(t[0] + t[1], 10);
            this.droplet.style.top = top + "px";
        }
    };
    
    // Getters / setters
    this.setDroplet = function(d) { this.droplet = d; };

    this.getWidth   = function() { return this.droplet.offsetWidth; };
    this.getHeight  = function() { return this.droplet.offsetHeight; };
    this.getTop     = function() { return getOffsetTop(this.droplet); };
    this.getLeft    = function() { return getOffsetLeft(this.droplet); };
    this.getBottom  = function() { return this.getTop() + parseInt(this.droplet.offsetHeight, 10); };
    this.getRight   = function() { return this.getLeft() + parseInt(this.droplet.offsetWidth, 10); };
    this.getX       = function() { return (this.droplet.style.left == 0) ? this.getLeft() : parseInt(this.droplet.style.left, 10); };
    this.getY       = function() { return (this.droplet.style.top == 0) ? this.getTop() : parseInt(this.droplet.style.top, 10); };
}

function dropletMgrObj()
{
    // Private member variables
    var _this = this;
    
    this.activated = null;
    this.activatedFor = null;
    this.maxdroplet = null;
    this.placeholder = null;
    this.dropletOverlay = null;
    this.dropletArea = null;
    this.catId = 0;
    this.start = new Array();
    
    // Public member variables
    this.droplets = new Array();
    this.columns = new Array();
    this.sizers = new Array();
    this.isMax = false;
    this.swfs = new Array();

    // Public methods
    this.setZIndex = function(e)
    {
        zIndexMgr.setzIndexOf(_this.getDroplet(this).droplet);
    };
    
    this.refreshDroplet = function(rslt, dropInfo)
    {
        if(dropInfo.categoryId == dropletMgr.droplets[dropInfo.dropIdx].saveObj.CategoryId)
        {
            _this.droplets[dropInfo.dropIdx].content.innerHTML = "Loading...";
            PageMethods.GetDropletContent(_this.droplets[dropInfo.dropIdx].saveObj.Id, dropletMgr.populateDropletContent, null, dropInfo);
        }    
    };
    
    this.populateDropletContent = function(cnt, dropInfo)
    {        
        if(checkAuth(cnt) && _this.droplets.length > 0 && _this.droplets[dropInfo.dropIdx] != null && dropInfo.categoryId == dropletMgr.droplets[dropInfo.dropIdx].saveObj.CategoryId)
        {
            if(dropletMgr.droplets[dropInfo.dropIdx].saveObj.DropletTypeId != 2)
            {
                cnt = cnt.replace(/(<(form|font)([^>]+)>)/gi, "").replace(/\n/,"");
                _this.droplets[dropInfo.dropIdx].content.innerHTML = cnt;
            }
            else
            {
                var flashInfo = jsonDeserializeIfAuth(cnt, false);
                _this.droplets[dropInfo.dropIdx].content.replaceChild(makeElement("div", {id:flashInfo.id}, null, null, "You need Adobe Flash Player 9.0.124 or newer for this content to display correctly, <a href='http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash' target='_blank'>click here</a> to download the latest version."), _this.droplets[dropInfo.dropIdx].content.childNodes[0]);
                
                if(swfobject.getFlashPlayerVersion().major > 0)
                {
                    swfobject.embedSWF(flashInfo.att.data, flashInfo.id, flashInfo.att.width, flashInfo.att.height, "9.0.124","/assets/flash/expressInstall.swf", null, flashInfo.par, {name:flashInfo.id});
                    _this.swfs[_this.swfs.length] = flashInfo.id;
                }
            }
            
            if(typeof dropInfo.callBack != "undefined" && dropInfo.callBack != null)
                dropInfo.callBack.func(dropInfo.callBack.params);
        }
    };
    
    this.updateProperties = function(_callingElement, _properties, _refresh, _callbackObject)
    { // Initiates property update for droplet
        var _dropIdx = dropletMgr.getDroplet(_callingElement, true);
        var _saveProperties = jsonDeserializeIfAuth(dropletMgr.droplets[_dropIdx].saveObj.Properties, true);
        
        if(typeof _callbackObject == "undefined")
            _callbackObject = null;
        
        for(prop in _properties)
            if(_properties[prop] != null)
                _saveProperties[prop.toString()] = _properties[prop];
        
        _saveProperties = Sys.Serialization.JavaScriptSerializer.serialize(_saveProperties);
        
        if(_this.droplets[_dropIdx].saveObj.Properties.toString() != _saveProperties.toString())
        {
            _this.droplets[_dropIdx].saveObj.Properties = _saveProperties;
            _this.droplets[_dropIdx].doSave = true;
            
            if(typeof _refresh != "undefined" && _refresh)
                _this.save(dropletMgr.refreshDroplet, {dropIdx:_dropIdx,categoryId:dropletMgr.droplets[_dropIdx].saveObj.CategoryId,callBack:_callbackObject});
            else
                _this.save();
        }
    };
    
    this.clearSwfs = function()
    {
        for(var s = 0; s < _this.swfs.length; s++)
            swfobject.removeSWF(_this.swfs[s]);
        
        _this.swfs = new Array();
    };
    
    // Adds a droplets placeable column
    this.addColumn = function(width)
    {
        var cIdx = this.columns.length;
        this.columns[cIdx] = new columnObj(makeElement("div", {id:'column-' + cIdx,cn:'dropletColumn'}, "\u0020"));
        
        this.dropletArea.insertBefore(this.columns[cIdx].column, this.dropletArea.childNodes[this.dropletArea.childNodes.length - 1]);
        this.columns[cIdx].setWidth(width);
    };
    
    this.addColumnSizer = function(afterCol)
    {
        var sIdx = _this.sizers.length;
        
        this.sizers[sIdx] = makeElement("div", {id:'cr-' + afterCol + '_' + (afterCol + 1),cn:'colSizer'}, "\u0020");        
        this.dropletArea.insertBefore(this.sizers[sIdx], this.columns[afterCol].column.nextSibling);
        
        addEvent(this.sizers[sIdx], "mousedown", dropletMgr.resizeColumnStart);
        addEvent(this.sizers[sIdx], "mouseover", dropletMgr.resizeColumnOver);
        addEvent(this.sizers[sIdx], "mouseout", dropletMgr.resizeColumnOut);
        this.sizers[sIdx].onselectstart = returnFalse;
    };
    
    // Adds a droplet to the managed collection
    this.addDroplet = function(width, saveObj)
    {
        var dIdx = this.droplets.length;
        var isAd = (typeof saveObj == "undefined");
        
        var height = 35;
        
        var droplet = makeElement("div", {id:'droplet-' + dIdx,cn:'droplet'});
        
        var hdr = makeElement("div", {cn:'hdr'});

        var content = makeElement("div", {cn:'cnt'});
        content.appendChild(makeElement("div", {cn:'dropContent'}, "Loading..."));
        
        
        //<div class="droplet">
        //    <div class="hdr">
        //        <div class="headico"></div>
        //        <div class="title"></div>
        //        <div class="tools">
        //            <div class="drop"></div>
        //            <div class="size">
        //                <div class="min"></div>
        //                <div class="med"></div>
        //                <div class="max"></div>
        //            </div>
        //        </div>
        //    </div>
        //    <div class="cnt">
        //        <div class="dropletContent"></div>
        //        <div class="s-resize">
        //            <div class="sw-resize"></div>
        //            <div class="se-resize"></div>
        //        </div>
        //    </div>        
        //</div>
         
        if(!isAd)
        {
            height = saveObj.StandardHeight;
            
            var styleObj = jsonDeserializeIfAuth(saveObj.Style, true);
            var props = jsonDeserializeIfAuth(saveObj.Properties, true);
            
            var dropType = "";
            
            switch(saveObj.DropletTypeId)
            {
                case 1:
                    dropType = " rss";
                    break;
                case 2:
                    dropType = " weather";
                    break;
                case 5:
                    dropType = " blog";
                    break;
                case 6:
                    dropType = " video";
                    break;
                case 7:
                    dropType = " photos";
                    break;
            }

            if(styleObj.color == "theme")
            {
                hdr.className += " clr-theme" + dropType;
            }
            else
            {
                hdr.className += dropType;
                hdr.style.backgroundColor = styleObj.color;
            }

            hdr.appendChild(makeElement("div", {cn:'headico'}, "\u0020"));
            hdr.appendChild(makeElement("div", {cn:'title'}, saveObj.Title));
            hdr.appendChild(makeElement("div", {cn:'tools'}));
            hdr.setAttribute("title", saveObj.Title);
            
            hdr.childNodes[1].style.color = setForecolor(hdr.style.backgroundColor);
            
            if(styleObj.size < 50)
                styleObj.size = styleObj.size * 100;
            
            content.childNodes[0].style.fontSize = styleObj.size + "%";
            
            var font = (typeof styleObj.font == "undefined") ? fonts[0][1] : fonts[styleObj.font][1];
            
            content.childNodes[0].style.fontFamily = font;
            
            this.droplets[dIdx] = new dropletObj(saveObj, droplet, content.childNodes[0],
                                                 makeElement("div", {cn:'drop',title:'Click to change settings'}, "\u0020"),
                                                 makeElement("div", {cn:'min',title:'Minimize'}, "\u0020"),
                                                 makeElement("div", {cn:'med',title:'Normalize'}, "\u0020"),
                                                 makeElement("div", {cn:'max',title:'Maximize'}, "\u0020"),
                                                 makeElement("div", {cn:'s-resize'}),
                                                 makeElement("div", {cn:'sw-resize'}, "\u0020"),
                                                 makeElement("div", {cn:'se-resize'}, "\u0020"));
            
            hdr.childNodes[2].appendChild(this.droplets[dIdx].setBtn);            
            hdr.childNodes[2].appendChild(makeElement("div", {cn:'size'}));
            hdr.childNodes[2].childNodes[1].appendChild(this.droplets[dIdx].minBtn);
            hdr.childNodes[2].childNodes[1].appendChild(this.droplets[dIdx].medBtn);
            hdr.childNodes[2].childNodes[1].appendChild(this.droplets[dIdx].maxBtn);
            hdr.childNodes[2].childNodes[1].appendChild(makeElement("div", {cn:'clr'}, null, "clr"));
            hdr.childNodes[2].appendChild(makeElement("div", {cn:'clr'}, null, "clr"));
            
            this.droplets[dIdx].sizeS.appendChild(this.droplets[dIdx].sizeSE);
            this.droplets[dIdx].sizeS.appendChild(this.droplets[dIdx].sizeSW);
            this.droplets[dIdx].sizeS.appendChild(makeElement("div", {cn:'clr'}, null, "clr"));

            content.appendChild(this.droplets[dIdx].sizeS);
            
            addEvent(this.droplets[dIdx].setBtn, "click", dropletSettings.open);
            addEvent(this.droplets[dIdx].sizeS, "mousedown", dropletMgr.resizeStart);
            addEvent(this.droplets[dIdx].sizeSW, "mousedown", dropletMgr.resizeStart);
            addEvent(this.droplets[dIdx].sizeSE, "mousedown", dropletMgr.resizeStart);
            addEvent(hdr.childNodes[1], "mousedown", dropletMgr.dragStart);        

            this.droplets[dIdx].sizeS.onselectstart = function() { window.onselectstart = returnFalse; return false; };
            this.droplets[dIdx].sizeSW.onselectstart = function() { window.onselectstart = returnFalse; return false; };
            this.droplets[dIdx].sizeSE.onselectstart = function() { window.onselectstart = returnFalse; return false; };
        }
        else // Insert Ad
        {
            hdr.className += " clr-theme";
            hdr.appendChild(makeElement("div", {cn:'title',style:{color:setForecolor(hdr.style.backgroundColor),width:'95%'}}, "Advertisement"));
            
            var adTypes = new Array();
            // Add new add types to be chosen at random by passing in provider as well as height of advertisment droplet
            adTypes[0] = new Array("google", 150);
            
            var rndAd = Math.floor(Math.random() * adTypes.length);
            
            var iframe = makeElement("iframe", {src:'ad.aspx?provider=' + adTypes[rndAd][0] + '&nocache=' + (new Date).getTime().toString(),frameborder:0,style:{margin:"0 auto"}});
            iframe.style.height = adTypes[rndAd][1] + "px";
            
            var sheild = makeElement("div", {cn:'hide',style:{height:adTypes[rndAd][1] + 'px'}}, "\u0020");
            
            content.childNodes[0].style.height = adTypes[rndAd][1] + "px";
            content.childNodes[0].replaceChild(iframe, content.childNodes[0].childNodes[0]);
            content.childNodes[0].appendChild(sheild);
            
            this.droplets[dIdx] = new dropletObj(null, droplet, content.childNodes[0], null, null, null, null, null, null, null);

            height = adTypes[rndAd][1] + 55;
            
            addEvent(hdr, "mousedown", dropletMgr.dragStart);        
        }

        hdr.appendChild(makeElement("div", {cn:'clr'}, null, "clr"));

        droplet.appendChild(hdr);
        droplet.appendChild(content);
        
        this.droplets[dIdx].setPlacement(height, width - 8, null, null);

        zIndexMgr.setzIndexOf(droplet);
        addEvent(droplet, "mousedown", dropletMgr.setZIndex);
        hdr.onselectstart = function() { window.onselectstart = returnFalse; return false; };        
    };
    
    // Called when page loads or category changes
    this.init = function(jsonDroplets, categoryId)
    {
        jsonDroplets = jsonDeserializeIfAuth(jsonDroplets, false);
        
        if(jsonDroplets != null && categoryId == categoryMgr.categories[categoryMgr.currentCategory].Id)
        {
            _this.droplets = new Array();
            _this.columns = new Array();

            clearTree(_this.dropletArea);

            if(jsonDroplets.length > 0)
            {
                _this.dropletOverlay = makeElement("div", {id:'dropletOverlay',cn:'hide'}, "\u0020");
                _this.dropletArea.appendChild(_this.dropletOverlay);

                var unusableArea = _this.getPercentUnusable(categoryMgr.propertiesObj.columns.length) / categoryMgr.propertiesObj.columns.length;
                
                var totalUsed = 0;
                var w = 0;
                
                _this.dropletArea.appendChild(makeElement("div", {cn:'clr'}, null, "clr"));
                
                for(var col = 0; col < categoryMgr.propertiesObj.columns.length; col++)
                {
                    w = categoryMgr.propertiesObj.columns[col] - unusableArea;
                    totalUsed = totalUsed + w + unusableArea;
                    
                    if(col == categoryMgr.propertiesObj.columns.length - 1 && totalUsed != 100)
                    {
                        w = w + (100 - totalUsed);
                    }
                    
                    _this.addColumn(w);
                    
                    if(col < categoryMgr.propertiesObj.columns.length - 1)
                    {
                        _this.addColumnSizer(col);
                    }
                }
                
                var adCount = 0;
                
                for(var jd = 0; jd < jsonDroplets.length; jd++)
                {
                    var col = (jsonDroplets[jd].Column >= _this.columns.length) ? _this.columns.length - 1 : jsonDroplets[jd].Column;
                    
                    _this.addDroplet(_this.columns[col].getWidth(), jsonDroplets[jd]);                    
                    _this.columns[col].column.appendChild(_this.droplets[jd].droplet);
                    
                    if(jd % 5 == 0)
                    {
                        adCount++;
                    }
                }
                
                // determine where ad will be placed
                for(var ads = 0; ads < adCount; ads++)
                {
                    var adPlacement = new Array();
                    adPlacement[0] = Math.floor(Math.random() * categoryMgr.propertiesObj.columns.length); // Ad Column
                    adPlacement[1] = Math.floor(Math.random() * (_this.columns[adPlacement[0]].column.childNodes.length + 1)); // Ad row
                    _this.addDroplet(_this.columns[adPlacement[0]].getWidth());
                    
                    if(_this.columns[adPlacement[0]].column.childNodes.length == adPlacement[1])
                    {
                        _this.columns[adPlacement[0]].column.appendChild(_this.droplets[_this.droplets.length-1].droplet);
                    }
                    else
                    {
                        _this.columns[adPlacement[0]].column.insertBefore(_this.droplets[_this.droplets.length-1].droplet, _this.columns[adPlacement[0]].column.childNodes[adPlacement[1]]);
                    }
                }

                var maxxed = null;
                
                for(var d = 0; d < _this.droplets.length; d++)
                {   
                    if(_this.droplets[d].saveObj != null)
                    {
                        _this.maxdroplet = _this.droplets[d];

                        switch(_this.maxdroplet.saveObj.DropletModeId)
                        {
                            case 1:
                                _this.minimize(null, true);                
                                break;
                            case 2:
                                _this.normalize(null, true);                    
                                break;                
                            case 3:
                                if(maxxed == null)
                                    maxxed = _this.maxdroplet;
                                else
                                    _this.normalize(null, true);
                                    
                                break;
                        }
                        _this.maxdroplet = null;
                        
                        PageMethods.GetDropletContent(_this.droplets[d].saveObj.Id, dropletMgr.populateDropletContent, null, {dropIdx:d,categoryId:_this.droplets[d].saveObj.CategoryId});
                    }

                    _this.droplets[d].droplet.className = "droplet";
                }
                
                if(maxxed != null)
                {
                    _this.maxdroplet = maxxed;
                    _this.maximize(null, true);
                }
                    
                _this.determinePositions(true);
            }
            else
            {
                clearTree(_this.dropletArea);
                _this.dropletArea.appendChild(makeElement("div", {cn:'noDroplets'}, null, null, "This group is empty.<br /><br />Go to the <a href='DropZone.aspx' style='color:white'>dropzone</a> or drag droplets over from other groups."));
            }
        }
        
        _this.redraw();
    };
    
    this.getDroplet = function(node, returnIndex)
    {
        while(node.className != null && !node.className.toString().match("droplet"))
        {
            node = (node.parentNode != "undefined") ? node.parentNode : null;
        }

        if(node && node.getAttribute)
        {
            if(typeof returnIndex != "undefined")
            {
                return parseInt(node.getAttribute("id").toString().replace(/droplet-/, ""), 10);
            }
            else
            {
                return this.droplets[parseInt(node.getAttribute("id").toString().replace(/droplet-/, ""), 10)];
            }
        }

        return null;
    };
    
    this.getColumn = function(node)
    {
        while(node.className != null && !node.className.toString().match("dropletColumn"))
        {
            node = (node.parentNode != "undefined") ? node.parentNode : null;
        }
        
        if(node && node.getAttribute)
        {
            return this.columns[parseInt(node.getAttribute("id").toString().replace(/column-/, ""), 10)];
        }
        
        return null;
    };
    
    this.save = function(callBack, params)
    {
        _this.determinePositions();

        var saveObjects = new Array();

        for(var d = 0; d < _this.droplets.length; d++)
        {
            if((_this.droplets[d].doSave && _this.droplets[d].saveObj != null))
            {
                saveObjects[saveObjects.length] = _this.droplets[d].saveObj;                
                _this.droplets[d].doSave = false;
            }
        }
        
        

        if(categoryMgr.doSave)
        {
            categoryMgr.save();
            categoryMgr.doSave = false;
        }
        
        if(saveObjects.length > 0)
        {
            if(typeof callBack == "undefined")
                callBack = null;
            
            if(typeof params == "undefined")
                params = null;
                
            PageMethods.SaveDroplets(Sys.Serialization.JavaScriptSerializer.serialize(saveObjects), callBack, null, params);
        }
    };
    
    this.fix = function(enforceHide)
    {
        for(var d = 0; d < this.droplets.length; d++)
        {
            if(this.droplets[d].saveObj == null)
            {
                var cn = this.droplets[d].content.childNodes[1].className;
                this.droplets[d].content.childNodes[1].className = cn.match("hide") || enforceHide ? "sheild" : "hide";
                this.droplets[d].content.childNodes[1].style.height = this.droplets[d].content.childNodes[0].offsetHeight + "px";
                this.droplets[d].content.childNodes[1].style.width = this.droplets[d].content.childNodes[0].offsetWidth + "px";
            }
        }
    };

    // Create the dotted "placeholder" element.    
    this.createPlaceholder = function(droplet)
    {
        this.placeholder = makeElement("div", {cn:'placeholder',style:{marginBottom:'10px',width:'auto',height:(droplet.getHeight() - 2) + 'px'}});
        droplet.droplet.parentNode.insertBefore(this.placeholder, droplet.droplet);
    };
    
    this.saveMaxPosition = function()
    {
        var areaLeft = getOffsetLeft(this.dropletArea.parentNode.parentNode);
        var areaTop = getOffsetTop(this.dropletArea.parentNode);        
        var offset = Sys.Services.AuthenticationService.get_isLoggedIn() ? 28 : 0;
        
        if(this.maxdroplet.saveObj != null && (
           this.maxdroplet.saveObj.MaximizedWidth != this.maxdroplet.getWidth() ||
           this.maxdroplet.saveObj.MaximizedHeight != this.maxdroplet.getHeight() ||
           this.maxdroplet.saveObj.MaximizedXOffset != (this.maxdroplet.getLeft() - areaLeft) ||
           this.maxdroplet.saveObj.MaximizedYOffset != (this.maxdroplet.getTop() - (areaTop + offset))
          ))
        {
            this.maxdroplet.saveObj.MaximizedWidth = this.maxdroplet.getWidth();
            this.maxdroplet.saveObj.MaximizedHeight = this.maxdroplet.getHeight();
            this.maxdroplet.saveObj.MaximizedXOffset = (this.maxdroplet.getLeft() - areaLeft);
            this.maxdroplet.saveObj.MaximizedYOffset = (this.maxdroplet.getTop() - (areaTop + offset));
            this.maxdroplet.doSave = true;
        }    
    };
    
    // Set size
    this.setSize = function(e)
    {
        var cn = this.className.toString();
        
        _this.maxdroplet = null;
        _this.maxdroplet = _this.getDroplet(this);
        
        switch(cn)
        {
            case "min":
                _this.minimize(e);
                break;
            case "med":
                _this.normalize(e);
                break;
            case "max":
                _this.maximize(e);
                break;
        }
        _this.redraw();        
    };
    
    this.reset = function(e)
    {
        _this.dropletOverlay.className = "hide";
        _this.start["left"] = _this.maxdroplet.getLeft() - 10;
        _this.start["top"] = _this.maxdroplet.getTop();
        _this.maxdroplet.content.parentNode.style.display = "";
        _this.maxdroplet.sizeS.style.display = "block";
        _this.maxdroplet.minBtn.className = "min";
        _this.maxdroplet.medBtn.className = "med";
        _this.maxdroplet.maxBtn.className = "max";
        removeEvent(_this.maxdroplet.minBtn, "click", dropletMgr.setSize);
        removeEvent(_this.maxdroplet.medBtn, "click", dropletMgr.setSize);
        removeEvent(_this.maxdroplet.maxBtn, "click", dropletMgr.setSize);
        _this.redraw();        
    };
    
    this.minimize = function(e, noSave)
    {    
        _this.demaximize(e);
        _this.reset(e);
    
        var h = _this.maxdroplet.saveObj.MinimizesToHeader ? 24 : 100;
        
        _this.maxdroplet.saveObj.DropletModeId = 1;
        
        _this.maxdroplet.setPlacement(h, null, null, null);
        _this.maxdroplet.setWidth(null, "auto");
        
        _this.maxdroplet.content.parentNode.style.display = _this.maxdroplet.saveObj.MinimizesToHeader ? "none" : "";
        _this.maxdroplet.sizeS.style.display = "none";
        _this.maxdroplet.minBtn.className = "minon";
        _this.isMax = false;

        addEvent(_this.maxdroplet.medBtn, "click", dropletMgr.setSize);
        addEvent(_this.maxdroplet.maxBtn, "click", dropletMgr.setSize);
        removeEvent(_this.dropletOverlay, "click", dropletMgr.normalize);
        addEvent(_this.dropletOverlay, "click", dropletMgr.minimize);
        
        if(typeof noSave == "undefined")
        {
            _this.maxdroplet.doSave = true;
            _this.save();
        }
        
        _this.maxdroplet = null;
        _this.redraw();
    };
    
    this.normalize = function(e, noSave)
    {    
        _this.demaximize(e);
        _this.reset(e);
        _this.maxdroplet.saveObj.DropletModeId = 2;
        
        _this.maxdroplet.droplet.style.position = "relative";
        _this.maxdroplet.medBtn.className = "medon";
        
        _this.maxdroplet.setPlacement(_this.maxdroplet.saveObj.StandardHeight, null, null, null);
        _this.maxdroplet.setWidth(null, "auto");
        _this.isMax = false;

        addEvent(_this.maxdroplet.minBtn, "click", dropletMgr.setSize);
        addEvent(_this.maxdroplet.maxBtn, "click", dropletMgr.setSize);
        removeEvent(_this.dropletOverlay, "click", dropletMgr.minimize);
        addEvent(_this.dropletOverlay, "click", dropletMgr.normalize);

        if(typeof noSave == "undefined")
        {
            _this.maxdroplet.doSave = true;
            _this.save();
        }
        
        _this.maxdroplet = null;
        _this.redraw();
    };

    // Maximize
    this.maximize = function(e, noSave)
    {    
        var maxHit = (_this.maxdroplet != null);
        
        if(_this.activated != null)
        {
            _this.maxdroplet = _this.activated;
        }
        
        _this.fix(true);
        
        toggleSelects("hide");
        toggleSelects("show", _this.maxdroplet.droplet);
        
        toggleOverflowsOnClass("dropContent", document.body, "hide");
        toggleOverflowsOnClass("dropContent", _this.maxdroplet.droplet, "show");
        
        _this.reset(e);
        
        _this.isMax = true;
        
        var areaLeft = getOffsetLeft(_this.dropletArea.parentNode.parentNode);
        var areaTop = getOffsetTop(_this.dropletArea);
        
        _this.dropletOverlay.style.left = areaLeft + "px";
        _this.dropletOverlay.style.top = (areaTop) + "px";
        _this.dropletOverlay.style.height = (_this.dropletArea.offsetHeight) + "px";
        _this.dropletOverlay.style.width = _this.dropletArea.offsetWidth + "px";
        _this.dropletOverlay.className = "";
        
        zIndexMgr.setzIndexOf(_this.dropletOverlay);
        _this.createPlaceholder(_this.maxdroplet);
        
        _this.dropletArea.appendChild(_this.maxdroplet.droplet);
        zIndexMgr.setzIndexOf(_this.maxdroplet.droplet);
        
        _this.maxdroplet.droplet.style.position = "absolute";
        _this.maxdroplet.maxBtn.className = "maxon";
        _this.maxdroplet.saveObj.DropletModeId = 3;

        if(maxHit)
        {
            if(_this.maxdroplet.saveObj.MaximizesToFullscreen || (!_this.maxdroplet.saveObj.MaximizesToFullscreen && (_this.maxdroplet.saveObj.MaximizedWidth < 130 || _this.maxdroplet.saveObj.MaximizedHeight < 100)))
            {
                _this.maxdroplet.setPlacement(_this.dropletOverlay.offsetHeight-20, _this.dropletOverlay.offsetWidth-20, new Array(0, areaLeft), new Array(0, areaTop + 5));
            }
            else
            {                
                _this.maxdroplet.setPlacement(_this.maxdroplet.saveObj.MaximizedHeight, _this.maxdroplet.saveObj.MaximizedWidth, new Array(_this.maxdroplet.saveObj.MaximizedXOffset, areaLeft - 3), new Array(_this.maxdroplet.saveObj.MaximizedYOffset, areaTop - 2));
            }
        }
        else
        {
            _this.maxdroplet.setPlacement(null, null, new Array(_this.start["left"], 7), new Array(_this.start["top"], 0));
        }
        
        addEvent(_this.maxdroplet.minBtn, "click", dropletMgr.setSize);
        addEvent(_this.maxdroplet.medBtn, "click", dropletMgr.setSize);

        if(typeof noSave == "undefined")
        {
            _this.maxdroplet.doSave = true;
            _this.save();
        }
        _this.redraw();
    };
    
    this.demaximize = function(e)
    {
        if(_this.isMax)
        {
            _this.saveMaxPosition();
            _this.maxdroplet.droplet.style.position = "";
            _this.maxdroplet.droplet.style.top = "";
            _this.maxdroplet.droplet.className = "droplet";
            if (_this.placeholder != null)
            {
                _this.placeholder.parentNode.replaceChild(_this.maxdroplet.droplet, _this.placeholder);
                _this.placeholder = null;
            }            
            _this.dropletOverlay.className = "hide";
            _this.maxdroplet.setWidth(null, "auto");
            
            toggleSelects("show");

            _this.redraw();
        }
    };
    
    // Functionality behind dropping event.
    this.dropTarget = function(droplet, e)
    {
        if(this.activatedFor == "move" && !this.isMax)
        {
            if (this.placeholder == null)
            {
                this.createPlaceholder(droplet);
                droplet.droplet.className = "droplet translucent";
            }
            else
            {
                var target = this.findHit(droplet.droplet, e);
                
                if(target != null)
                {
                    var col = this.getColumn(target);
                    
                    if(col != null)
                    {   
                        this.placeholder.style.width = (col.getWidth() - 8) + "px";
                    }
                    
                    if (target.className.toString() == "droplet")
                    {
                        var y = e.clientY + document.documentElement.scrollTop;
                        // Insert before if mouse is within (n) pixels from the top of target
                        if(y < (getOffsetTop(target) + 30))
                        {
                            target.parentNode.insertBefore(this.placeholder.parentNode.removeChild(this.placeholder), target);
                        }
                        else
                        {
                            target.parentNode.insertBefore(this.placeholder.parentNode.removeChild(this.placeholder), target.nextSibling);
                        }
                    }
                    else if (target.className.toString().match("dropletColumn"))
                    {
                        this.placeholder.parentNode.removeChild(this.placeholder);
                        target.appendChild(this.placeholder);
                    }
                }
            }
        }       
    };
    
    // Find droplet or column to perform a potential drop as dragging is occuring.
    this.findHit = function(drop, e)
    {
        var x = e.clientX;
        var y = e.clientY + document.documentElement.scrollTop;
        
        var r; // Right
        var l; // Left
        var t; // Top
        var b; // Bottom
        
        var head = drop.childNodes[0].childNodes[0].className.toString();
        
        if(categoryMgr.catTabs != null && head == "headico")
        {
            for (var c = 0; c < categoryMgr.catTabs.childNodes[0].childNodes[0].childNodes.length; c++)
            {
                if(c != categoryMgr.currentCategory && categoryMgr.catTabs.childNodes[0].childNodes[0].childNodes[c].className != "hide")
                {
                    l = getOffsetLeft(categoryMgr.catTabs.childNodes[0].childNodes[0].childNodes[c]);
                    r = l + categoryMgr.catTabs.childNodes[0].childNodes[0].childNodes[c].offsetWidth;
                    t = getOffsetTop(categoryMgr.catTabs.childNodes[0].childNodes[0].childNodes[c]);
                    b = t + categoryMgr.catTabs.childNodes[0].childNodes[0].childNodes[c].offsetHeight;

                    if (x >= l && x <= r && y >= t && y <= b)
                    {
                        categoryMgr.catTabs.childNodes[0].childNodes[0].childNodes[c].className = "transfer";
                    }
                    else
                    {
                        categoryMgr.catTabs.childNodes[0].childNodes[0].childNodes[c].className = "";
                    }
                }        
            }
        }
        
        for (var d = 0; d < _this.droplets.length; d++)
        {
            if(!_this.droplets[d].droplet != this.placeholder && _this.droplets[d].droplet.id != drop.id)
            {
                l = _this.droplets[d].getLeft() - 2;
                r = _this.droplets[d].getRight() + 2;
                t = _this.droplets[d].getTop() - 20;
                b = _this.droplets[d].getBottom() + 20;

                if (x > l && x < r && y > t && y < b)
                {
                    return _this.droplets[d].droplet;
                }
            }
        }

        for (var c = 0; c < _this.columns.length; c++)
        {
            l = _this.columns[c].getLeft();
            r = _this.columns[c].getRight();
            t = _this.columns[c].getTop() + 30;
            b = _this.columns[c].getBottom();
            
            if (x >= l && x <= r && y >= t && y <= b)
            {
                return _this.columns[c].column;
            }
        }
        return null;
    };
    
    this.determinePositions = function(noSave)
    {
        for(var c = 0; c < this.columns.length; c++)
        {
            var dropletsInColumn = getElementsByClassName("droplet", "div", this.columns[c].column);
            var adOffset = 0;
            
            for(var t = 0; t < dropletsInColumn.length; t++)
            {
                for(var d = 0; d < this.droplets.length; d++)
                {
                    if(dropletsInColumn[t] == this.droplets[d].droplet && this.droplets[d].droplet.parentNode == this.columns[c].column)
                    {
                        if(this.droplets[d].saveObj == null || this.droplets[d].deleted)
                        {
                            adOffset++;
                        }
                        
                        if(this.droplets[d].saveObj != null)
                        {
                            if(this.droplets[d].saveObj.Row != (t - adOffset))
                            {
                                this.droplets[d].saveObj.Row = (t - adOffset);
                                this.droplets[d].doSave = (typeof noSave == "undefined");
                            }
                            
                            if(this.droplets[d].saveObj.Column != c)
                            {
                                this.droplets[d].saveObj.Column = c;
                                this.droplets[d].doSave = (typeof noSave == "undefined");
                            }
                        }
                    }
                }
            }
        }
    };
    
    this.getDefaultWidth = function(droplet)
    {
        var col = (droplet.saveObj.Column == this.columns.length) ? droplet.saveObj.Column - 1 : droplet.saveObj.Column;
        return this.columns[col].getWidth() - 8;
    };
    
    // Performs functionality for "dragging"
    this.move = function(e)
    {
        if (_this.activated != null)
        {
            emptySelection();
            var areaLeft = getOffsetLeft(_this.dropletArea);
            var areaTop = getOffsetTop(_this.dropletArea);
        
            var l = _this.start["left"] + (e.clientX - _this.start["x"]) - areaLeft;
            var t = _this.start["top"] + (e.clientY - _this.start["y"]) - areaTop;
            
            
            _this.activated.droplet.style.position = "absolute";
            
            var fromTop = Sys.Services.AuthenticationService.get_isLoggedIn() ? 140 : 110;
            
            
            if((t + areaTop) > fromTop)
            {
                _this.activated.setPlacement(null, null, new Array(l, areaLeft), new Array(t, areaTop));
            }
            else
            {
                _this.activated.setPlacement(null, null, new Array(l, areaLeft), new Array(0, fromTop));
            }
            
            
            if(!_this.isMax)
            {
                _this.dropTarget(_this.activated, e);
            }
        }
    };
    
    // Performs functionality for start of "dragging" event.
    this.dragStart = function(e)
    {   
        // 'this' within the context of this method refers to the DOM 
        // node to which the event that called this action is attached
        
        _this.fix(false);
        
        var d = _this.getDroplet(this);
        _this.activated = (_this.isMax) ? d : new dropletObj(d.saveObj, d.droplet, d.content, d.setBtn, d.minBtn, d.medBtn, d.maxBtn, d.sizeS, d.sizeSW, d.sizeSE);
        
        if(!_this.isMax)
            _this.activated.setWidth(d.getWidth()-2);

        _this.activatedFor = "move";
        
        _this.start["x"] = _this.activated.getX() + (e.clientX - _this.activated.getX());
        _this.start["y"] = _this.activated.getTop() + (e.clientY - _this.activated.getTop());
        
        _this.start["left"] = _this.activated.getLeft() - 3;
        _this.start["top"] = _this.activated.getTop();
        
        addEvent(window, "mouseup", dropletMgr.drop);
        addEvent(document.body, "mouseup", dropletMgr.drop);
        addEvent(document.body, "mousemove", dropletMgr.move);
    };

    // Performs functionality for "dropping" event.
    this.drop = function(e)
    {
        if(_this.activatedFor == "move")
        {
            _this.fix(false);
            
            removeEvent(document.body, "mousemove", dropletMgr.move);
            removeEvent(window, "mouseup", dropletMgr.drop);
            removeEvent(document.body, "mouseup", dropletMgr.drop);
            
            window.onselectstart = returnTrue;
            
            var droplet = _this.activated.droplet;
            _this.activated = null;
            _this.activatedFor = null;
            
            if(!_this.isMax)
            {
                var dropObj = _this.getDroplet(droplet);
                droplet.style.position = "";
                droplet.style.top = "";
                droplet.style.left = "";
                droplet.className = "droplet";
                
                if (_this.placeholder != null)
                {   
                    dropObj.setPlacement(null, _this.placeholder.offsetWidth - 2, null, null);
                    _this.placeholder.parentNode.replaceChild(droplet.parentNode.removeChild(droplet), _this.placeholder);
                    _this.placeholder = null;
                }
                
                // Determine if droplet was dropped on a tab, if so move droplet to that group and remove from dom and droplet array
                if(categoryMgr.catTabs != null)
                {
                    for (var c = 0; c < categoryMgr.catTabs.childNodes[0].childNodes[0].childNodes.length; c++)
                    {
                        if(categoryMgr.catTabs.childNodes[0].childNodes[0].childNodes[c].className.toString().match("transfer"))
                        {
                            dropObj.saveObj.CategoryId = categoryMgr.categories[parseInt(categoryMgr.catTabs.childNodes[0].childNodes[0].childNodes[c].getAttribute("id").toString().replace(/cat-/, ""), 10)].Id;
                            dropObj.doSave = true;
                            dropObj.deleted = true;
                            dropObj.droplet.style.display = "none";
                            categoryMgr.catTabs.childNodes[0].childNodes[0].childNodes[c].className = "";
                            break;
                        }
                    }
                }
                
                _this.redraw();
            }

            _this.save();
        }
    };

    // Performs functionality for "resizing"
    this.resize = function(e)
    {
        if (_this.activated != null)
        {
            emptySelection();
            var areaLeft = (this.isMax) ? getOffsetLeft(_this.dropletArea) : 0;
            var areaTop = (this.isMax) ? new Array(0, getOffsetTop(_this.dropletArea)) : null;
            var diffHeight = parseInt(e.clientY - _this.start["y"], 10);
            var height = parseInt(_this.start["height"] + diffHeight, 10);
            var h = (height > 100) ? height : 100;
            var l = _this.start["left"] - areaLeft;
            var dw = 123;
            
            
            var diffWidth = 0;
            var width = _this.start["width"];
            
            if(_this.activatedFor == "sw-resize")
            {
                l = parseInt(e.clientX - 10, 10) - areaLeft;
                width = parseInt(_this.start["right"] - e.clientX, 10);

                if(width < dw)
                {
                    l = _this.start["right"] - dw - 10;
                }  
            }
            else if(_this.activatedFor == "se-resize")
            {
                diffWidth = parseInt(e.clientX - _this.start["x"], 10);
                width = parseInt(_this.start["width"] + diffWidth, 10);
            }
            else if(!_this.isMax)
            {
                l = 0;
            }

            var w = (width > dw) ? width : dw;
            _this.activated.setPlacement(h,w, new Array(l, areaLeft),areaTop);            
        }
    };    
    // Performs functionality for start of resizing
    this.resizeStart = function(e)
    {
        if(_this.activatedFor == null)
        {
            _this.fix(true);
            _this.activated = _this.getDroplet(this);
            
            _this.activated.droplet.parentNode.style.height = "auto";
            
            _this.activatedFor = this.className.toString();

            if(!_this.isMax && _this.activatedFor != "s-resize")
            {
                _this.activated.setWidth(_this.activated.getWidth());
                _this.maximize(e, true);
            }

            _this.start["width"] = _this.activated.getWidth() - 2;
            _this.start["height"] = _this.activated.getHeight() - 9;
            _this.start["x"] = e.clientX;
            _this.start["y"] = e.clientY;
            _this.start["left"] = _this.activated.getLeft() - 3;
            _this.start["top"] = _this.activated.getTop();
            _this.start["right"] = _this.activated.getRight() + 5;

            addEvent(_this.activated.droplet, "mouseup", dropletMgr.resizeStop);
            addEvent(document.body, "mouseup", dropletMgr.resizeStop);
            addEvent(document.body, "mousemove", dropletMgr.resize);
        }
    };    
    
    this.resizeStop = function(e)
    {
        if(_this.activatedFor != null)
        {
            if(_this.isMax)
                _this.saveMaxPosition();
            
            _this.fix(false);                
            _this.activated.doSave = true;

            window.onselectstart = returnTrue;
            
            removeEvent(document.body, "mousemove", dropletMgr.resize);
            removeEvent(document.body, "mouseup", dropletMgr.resizeStop);
            removeEvent(_this.activated.droplet, "mouseup", dropletMgr.resizeStop);
            
            _this.activated = null;
            _this.activatedFor = null;
            
            _this.save();
            
            if(!_this.isMax)
                _this.redraw();
            
        }
    };
    
    this.col1 = null;
    this.col2 = null;
    this.affectedDroplets = new Array();
    
    this.resizeColumn = function(e)
    {
        emptySelection();
        var offset = ((e.clientX - _this.start["x"]) / _this.start["width"]) * 100;
        var newCol1Width = (_this.start["width1"] + offset);
        var newCol2Width = (_this.start["width2"] - offset);
        
        if(newCol1Width < _this.start["minwidth"])
        {
            newCol2Width = newCol2Width + (newCol1Width - _this.start["minwidth"]);
            newCol1Width = _this.start["minwidth"];            
        }
        
        if(newCol2Width < _this.start["minwidth"])
        {
            newCol1Width = newCol1Width + (newCol2Width - _this.start["minwidth"]);
            newCol2Width = _this.start["minwidth"];
        }
        
        _this.col1.setWidth(newCol1Width);
        _this.col2.setWidth(newCol2Width);

        for(var d = 0; d < _this.affectedDroplets.length; d++)
            _this.affectedDroplets[d].setWidth(null, "auto");
    };
    
    this.resizeColumnStart = function(e)
    {
        var cols = this.getAttribute("id").replace(/cr-/, "").split("_");

        _this.fix(true);
        
        _this.col1 = _this.columns[parseInt(cols[0], 10)];
        _this.col2 = _this.columns[parseInt(cols[1], 10)];
        _this.start["x"] = e.clientX;
        _this.start["width1"] = _this.col1.getWidth("%");
        _this.start["width2"] = _this.col2.getWidth("%");
        _this.start["width"] = _this.dropletArea.offsetWidth - _this.getPixelUnusable(_this.columns.length);
        _this.start["minwidth"] = (130 / _this.start["width"]) * 100;
        _this.activatedFor = "colSizer";
        _this.activated = this;

        _this.affectedDroplets = new Array();
        for(var d = 0; d < _this.droplets.length; d++)
            if(_this.droplets[d].droplet.parentNode == _this.col1.column || _this.droplets[d].droplet.parentNode == _this.col2.column)
                _this.affectedDroplets[_this.affectedDroplets.length] = _this.droplets[d];

        addEvent(document.body, "mouseup", dropletMgr.resizeColumnStop);
        addEvent(document.body, "mousemove", dropletMgr.resizeColumn);
    };
    
    this.resizeColumnStop = function(e)
    {
        if(_this.activated != null)
        {
            _this.fix();
            _this.activated.className = "colSizer";
            _this.activatedFor = null;
            _this.activated = null;
            
            removeEvent(document.body, "mousemove", dropletMgr.resizeColumn);
            removeEvent(document.body, "mouseup", dropletMgr.resizeColumnStop);

            for(var d = 0; d < _this.affectedDroplets.length; d++)
                _this.affectedDroplets[d].setWidth(null, "auto");

            _this.save();
        }
    };
    
    this.resizeColumnOver = function(e)
    {
        if(_this.activatedFor == null)
        {
            this.className = "colSizerOver";
        }
    };

    this.resizeColumnOut = function(e)
    {
        if(_this.activatedFor != "colSizer")
        {
            this.className = "colSizer";
        }
    };

    this.getPixelUnusable = function(columnsLength)
    {    
        // Returns width taken by column sizers
        return ((columnsLength - 1) * 3);
    };

    this.getPercentUnusable = function(columnsLength)
    {
        // Returns the percentage of the total available width that the 
        return (_this.getPixelUnusable(columnsLength) / _this.dropletArea.offsetWidth) * 100;
    };
    
    this.redraw = function(e)
    {
        if(_this.activatedFor == null && !_this.isMax)
        {
            var w = 0;
            var unusableArea = _this.getPercentUnusable(_this.columns.length) / _this.columns.length;
            
            var minWidth = (130 / _this.dropletArea.offsetWidth) * 100;
            var totalUsed = 0;

            for(var col = 0; col < _this.columns.length; col++)
            {
                w = categoryMgr.propertiesObj.columns[col] - unusableArea;
                if(w < minWidth)
                    w = minWidth;

                totalUsed = totalUsed + w + unusableArea;

                if(col == _this.columns.length - 1 && totalUsed != 100)
                    w = w + (100 - totalUsed);

                _this.columns[col].setWidth(w);
                _this.columns[col].setHeight("auto");
            }
            
            for(var s = 0; s < _this.sizers.length; s++)
                _this.sizers[s].style.height = "auto";

            for(var d = 0; d < _this.droplets.length; d++)
            {
                if(!_this.droplets[d].deleted)
                {
                    _this.droplets[d].setWidth(null, "auto");
                    
                    // IE6 whiteout fix
                    if(isIE6)
                    {
                        _this.droplets[d].droplet.style.display = "none";
                        _this.droplets[d].droplet.style.display = "block";
                    }
                }
            }

            if(wcFooter == null)
                wcFooter = document.getElementById("wc-footer-bg");

            wcFooter.className = "hide";

            _this.dropletArea.style.height = "auto";
            
            var offset = Sys.Services.AuthenticationService.get_isLoggedIn() ? 264 : 226;
            
            if(_this.droplets.length == 0 && !isIE)
                offset = parseInt(offset + 50);
            
            var winHeight = getWindowHeight();

            if(_this.dropletArea.offsetHeight <= (winHeight - offset))
                _this.dropletArea.style.height = parseInt(winHeight - offset) + "px";

            wcFooter.className = "";

            var dropletAreaHeight = _this.dropletArea.offsetHeight;
            
            for(var c = 0; c < _this.columns.length; c++)
                _this.columns[c].setHeight((dropletAreaHeight - 10) + "px");

            for(var s = 0; s < _this.sizers.length; s++)
                _this.sizers[s].style.height = (dropletAreaHeight) + "px";
        }
    };
}

var dropletMgr = new dropletMgrObj();

function categoryMgrObj()
{
    var _this = this;
    this.categories = new Array();
    this.catTabs = null;
    this.groupList = null;
    this.settingsList = null;
    this.currentCategory = null;
    this.propertiesObj = new Object();
    this.doSave = false;
    this.editNameTimeout = null;    
    this.getCatCount = function()
    {
        var avail = 0;
        for(var c = 0; c < _this.categories.length; c++)
            if(_this.categories[c] != null)
                avail++;
        
        return avail;    
    };
    
    this.scrollTimeout = null;
    this.scrollOffset = 0;
    this.scrollDirection = null;
    
    this.isFurthestLeft = function() { return !(_this.catTabs.childNodes[0].childNodes[0].offsetLeft < 0); };
    this.isFurthestRight = function() { return !(_this.catTabs.childNodes[0].childNodes[0].offsetLeft > (-(_this.catTabs.childNodes[0].childNodes[0].offsetWidth) + _this.catTabs.childNodes[0].offsetWidth)); };
    
    this.toggleScrollButtons = function(e)
    {
        var ifl = _this.isFurthestLeft();
        var ifr = _this.isFurthestRight();
        
        if(_this.isFurthestRight())
            _this.catTabs.childNodes[0].childNodes[0].style.left = (-(_this.catTabs.childNodes[0].childNodes[0].offsetWidth) + _this.catTabs.childNodes[0].offsetWidth) + "px";        
        
        if(_this.isFurthestLeft())
            _this.catTabs.childNodes[0].childNodes[0].style.left = "0px";

        _this.catTabs.childNodes[1].childNodes[0].className = _this.isFurthestLeft() ? "scrollLeft disabled" : "scrollLeft";        
        _this.catTabs.childNodes[2].childNodes[1].className = _this.isFurthestRight() ? "scrollRight disabled" : "scrollRight";
    };
    
    this.startScrolling = function(e)
    {
        if(!this.className.match("disabled"))
        {
            _this.scrollDirection = this.className.match("scrollLeft") ? "l" : "r";
            
            if(_this.scrollDirection == "l" && !_this.isFurthestLeft())
                _this.scrollOffset = 35;    
            else if(_this.scrollDirection == "r" && !_this.isFurthestRight())
                _this.scrollOffset = -35;

            _this.scrollTimeout = setTimeout(_this.scrollTabs, 50);
        }
    
    };
    
    this.endScrolling = function(e)
    {
        clearTimeout(_this.scrollTimeout);
        _this.scrollOffset = 0;
    };
    
    this.scrollTabs = function()
    {
        clearTimeout(_this.scrollTimeout);
        if((_this.scrollDirection == "l" && !_this.isFurthestLeft()) || (_this.scrollDirection == "r" && !_this.isFurthestRight()))
        {
            _this.catTabs.childNodes[0].childNodes[0].style.left = _this.catTabs.childNodes[0].childNodes[0].offsetLeft + _this.scrollOffset + "px";
            _this.scrollTimeout = setTimeout(_this.scrollTabs, 50);
        }
        
        _this.toggleScrollButtons();
    };
    
    this.sizeTabArea = function()
    {
    
        var tabs = this.catTabs.childNodes[0].childNodes[0].childNodes;        
        var w = 0;
        for(var t = 0; t < tabs.length; t++)
            w += tabs[t].offsetWidth;
            
        w = w + (12 * (tabs.length + 1));

        this.catTabs.childNodes[0].childNodes[0].style.width = w + "px";
        this.toggleScrollButtons();
    };
    
    this.sizeTab = function(content, div, textbox)
    {
        var a = "";        
        content = (content.length > 50) ? content.substring(0, 50) : content;
        div.innerHTML = content.replace(/\s/g, "\u00a0");
        div.className = "txt";
        textbox.style.width = div.offsetWidth + "px";
        div.className = "hide";
        this.sizeTabArea();
    };
    
    this.scrollToTab = function(e)
    {
        _this.catTabs.childNodes[0].childNodes[0].style.left = (-(_this.catTabs.childNodes[0].childNodes[0].childNodes[_this.currentCategory].offsetLeft)) + "px";
        _this.sizeTabArea();
    };
    
    this.nameKeydown = function(e)
    {
        var curTab = _this.catTabs.childNodes[0].childNodes[0].childNodes[_this.currentCategory];
        
        var val = keyIsCommon(e) && getKeyCode(e) != 8 ? this.value : getKeyCode(e) == 8 ? this.value.substring(0, this.value.length - 1) : this.value + String.fromCharCode(getKeyCode(e));

        _this.sizeTab(val, curTab.childNodes[0].childNodes[1], curTab.childNodes[0].childNodes[0]);
    };
    
    this.nameKeyup = function(e)
    {
        var curTab = _this.catTabs.childNodes[0].childNodes[0].childNodes[_this.currentCategory];

        if(keyIsCommon(e) || (curTab.childNodes[0].childNodes[0] != this))
        {
            if(curTab.childNodes[0].childNodes[0] != this)
            {
               curTab.childNodes[0].childNodes[0].value = this.value;
               _this.categories[_this.currentCategory].Name = this.value;
               _this.groupList.childNodes[_this.currentCategory].replaceChild(document.createTextNode(this.value), _this.groupList.childNodes[_this.currentCategory].childNodes[0]);
            }
               
            _this.sizeTab(this.value, curTab.childNodes[0].childNodes[1], curTab.childNodes[0].childNodes[0]);
        }
    };

    this.nameKeypress = function(e)
    {
        if(getKeyCode(e) == 13)
        {
            this.blur();
            return false;
        }
        
        return true;
    };
    
    this.startNameChange = function(e)
    {
        this.className = "edit";
        addEvent(this, "selectstart", returnTrue);
        addEvent(this, "blur", categoryMgr.finishNameChange);
    };
    
    this.finishNameChange = function(e)
    {
        this.className = "";
            
        removeEvent(this, "selectstart", returnTrue);
        removeEvent(this, "blur", categoryMgr.finishNameChange);
        
        if(this.value != _this.categories[_this.currentCategory].Name && this.value != "")
        {
            _this.categories[_this.currentCategory].Name = this.value;
            _this.groupList.childNodes[_this.currentCategory].replaceChild(document.createTextNode(this.value), _this.groupList.childNodes[_this.currentCategory].childNodes[0]);
            _this.save();
        }
        else
        {
            this.value = _this.categories[_this.currentCategory].Name;
        }
    };
    
    this.deleteCategory = function(e)
    {
        if(_this.getCatCount() > 1)
        {
            dialogMgr.closeEvent = returnFalse;
            dialogMgr.close();
            if(confirm("Are you sure you want to delete the group '" + _this.categories[_this.currentCategory].Name + "'?\n\n All of your droplets within will be lost"))
            {
                PageMethods.DeleteCategory(Sys.Serialization.JavaScriptSerializer.serialize(_this.categories[_this.currentCategory]));            

                _this.categories[_this.currentCategory] = null;
                removeEvent(_this.catTabs.childNodes[0].childNodes[0].childNodes[_this.currentCategory].childNodes[0].childNodes[0], "click", categoryMgr.startNameChange);
                _this.catTabs.childNodes[0].childNodes[0].childNodes[_this.currentCategory].className = "hide";
                _this.groupList.childNodes[_this.currentCategory].className = "hide";

                var idx = 0;

                while(_this.categories[idx] == null)
                    idx++;

                _this.setCategory(null, idx);
            }
        }
        else
        {
            alert("You are required to retain a one group minimum.");
        }
    };
    
    this.appendCategory = function(jsonCategory, notNew, idx)
    {
//	    <li id="cat-idx">
//	        <div class="tab">
//	            <input type="text" />
//                <a href="#" class="drop">&nbsp;</a>
//	        </div>
//          <div class="notch">&nbsp;</div>
//	    </li>
        if(!notNew)
        {
            jsonCategory = jsonDeserializeIfAuth(jsonCategory, true);
            idx = _this.categories.length;
            _this.categories[idx] = jsonCategory;
        }

        // Add tab to main tab area
        _this.catTabs.childNodes[0].childNodes[0].appendChild(makeElement("li", {id:'cat-' + idx}));
        var li = _this.catTabs.childNodes[0].childNodes[0].childNodes[idx];
        li.appendChild(makeElement("div", {cn:'tab'}));
        li.appendChild(makeElement("div", {cn:'notch'}));
        li.childNodes[0].appendChild(makeElement("input", {value:jsonCategory.Name,type:'text'}));
        li.childNodes[0].appendChild(makeElement("div", {cn:'txt'}, jsonCategory.Name));        
        li.childNodes[0].childNodes[0].style.width = li.childNodes[0].childNodes[1].offsetWidth + "px";
        li.childNodes[0].childNodes[1].className = "hide";
        li.childNodes[0].appendChild(makeElement("a", {cn:'drop',href:'javascript:void(0)'},"\u0020"));
        li.childNodes[0].appendChild(makeElement("div", {cn:'clr'}, null, "clr"));

        li.childNodes[0].childNodes[0].readOnly = true;
        li.childNodes[0].childNodes[0].maxLength = 50;
        addEvent(li.childNodes[0].childNodes[2], "click", categoryMgr.showSettings);
        addEvent(li.childNodes[0].childNodes[0], "keypress", categoryMgr.nameKeypress);
        addEvent(li.childNodes[0].childNodes[0], "keydown", categoryMgr.nameKeydown);
        addEvent(li.childNodes[0].childNodes[0], "keyup", categoryMgr.nameKeyup);
        addEvent(li, "click", categoryMgr.setCategory);
        addEvent(li, "mouseover", toggleOver);
        addEvent(li, "mouseout", toggleOut);

        _this.sizeTabArea();

        // Add tab to drop down list of all available tabs
        _this.groupList.appendChild(makeElement("li", {id:'drpcat-' + idx,cn:'hand'}, jsonCategory.Name));
        addEvent(_this.groupList.childNodes[_this.groupList.childNodes.length-1], "click", categoryMgr.setCategory);
        addEvent(_this.groupList.childNodes[_this.groupList.childNodes.length-1], "click", categoryMgr.scrollToTab);
    };
    
    this.createCategory = function()
    {
        if(_this.getCatCount() < 30)
            PageMethods.CreateNewCategory(_this.appendCategory, null, false);
		else
			alert("Group limit reached.");
    };
    
    this.setCategory = function(e, idx)
    {
        if(e == 0 && idx == null)
            idx = _this.currentCategory;

        if(e != null)
            idx = parseInt(this.getAttribute("id").toString().replace(/cat-/, "").replace(/drp/,""), 10);

        if(_this.currentCategory != idx)
        {
            if(Sys.Services.AuthenticationService.get_isLoggedIn())
            {   
                var ul = _this.catTabs.childNodes[0].childNodes[0];
                if(_this.currentCategory != null && _this.categories[_this.currentCategory] != null)
                {
                    removeEvent(ul.childNodes[_this.currentCategory].childNodes[0].childNodes[0], "click", categoryMgr.startNameChange);

                    ul.childNodes[_this.currentCategory].className = "";
                    ul.childNodes[_this.currentCategory].childNodes[0].childNodes[0].readOnly = true;
                    ul.childNodes[_this.currentCategory].childNodes[0].childNodes[0].title = "";

                    addEvent(ul.childNodes[_this.currentCategory], "mouseover", toggleOver);
                    addEvent(ul.childNodes[_this.currentCategory], "mouseout", toggleOut);
                    addEvent(ul.childNodes[_this.currentCategory], "click", categoryMgr.setCategory);
                    
                    _this.groupList.childNodes[_this.currentCategory].style.fontWeight = "normal";
                    addEvent(_this.groupList.childNodes[_this.currentCategory], "click", categoryMgr.setCategory);
                }

                addEvent(ul.childNodes[idx].childNodes[0].childNodes[0], "click", categoryMgr.startNameChange);

                ul.childNodes[idx].childNodes[0].childNodes[0].readOnly = false;
                ul.childNodes[idx].childNodes[0].childNodes[0].blur();
                ul.childNodes[idx].childNodes[0].childNodes[0].title = "Click to edit title";
                ul.childNodes[idx].className = "sel";

                removeEvent(ul.childNodes[idx], "mouseover", toggleOver);
                removeEvent(ul.childNodes[idx], "mouseout", toggleOut);
                removeEvent(ul.childNodes[idx], "click", categoryMgr.setCategory);
                
                _this.groupList.childNodes[idx].style.fontWeight = "bold";
                removeEvent(_this.groupList.childNodes[idx], "click", categoryMgr.setCategory);
            }

            _this.currentCategory = idx;

            _this.deserializeProperties(null, idx);
            
            dropletMgr.placeholder = null;
            dropletMgr.clearSwfs();
            clearTree(dropletMgr.dropletArea);
            dropletMgr.dropletArea.appendChild(makeElement("div", {cn:'noDroplets'}, null, null, "<b>Loading...</b>"));

            PageMethods.GetJsonDroplets(_this.categories[idx].Id, dropletMgr.init, null, _this.categories[idx].Id);
        }
    };

	this.initializeTabs = function()
	{
//	    <div class="dropletGroups">
//	        <div class="tabs">
//	            <ul>
//	                <li id="cat-idx">
//	                    <div class="tab">
//	                        <input type="text" />
//                            <a href="#" class="drop">&nbsp;</a>
//	                    </div>
//                      <div class="notch">&nbsp;</div>
//	                </li>
//	            </ul>
//	        </div>
//	        <div class="leftTools">
//	            <a href="#" class="scrollLeft">&nbsp;</a>
//	        </div>
//	        <div class="rightTools">
//              <a href="#" class="newGroup">Add Tab</a>
//	            <a href="#" class="scrollRight">&nbsp;</a>
//	            <a href="#" class="showGroups">&nbsp;</a>
//	        </div>
//	    </div>
	
        _this.catTabs = makeElement("div", {cn:'dropletGroups'});
        _this.catTabs.appendChild(makeElement("div", {cn:'tabs'}));
        _this.catTabs.appendChild(makeElement("div", {cn:'leftTools'}));
        _this.catTabs.appendChild(makeElement("div", {cn:'rightTools'}));
        _this.catTabs.childNodes[0].appendChild(makeElement("ul"));
        _this.catTabs.childNodes[1].appendChild(makeElement("a", {cn:'scrollLeft disabled',href:'javascript:void(0)'}, "\u0020"));
        _this.catTabs.childNodes[2].appendChild(makeElement("a", {cn:'newGroup',href:'javascript:void(0)'}, "Add Group"));
        _this.catTabs.childNodes[2].appendChild(makeElement("a", {cn:'scrollRight',href:'javascript:void(0)'}, "\u0020"));
        _this.catTabs.childNodes[2].appendChild(makeElement("a", {cn:'showGroups',href:'javascript:void(0)'},"\u0020"));
        
        addEvent(_this.catTabs.childNodes[1].childNodes[0], "mousedown", categoryMgr.startScrolling);
        addEvent(_this.catTabs.childNodes[2].childNodes[1], "mousedown", categoryMgr.startScrolling);
        addEvent(_this.catTabs.childNodes[1].childNodes[0], "mouseup", categoryMgr.endScrolling);
        addEvent(_this.catTabs.childNodes[2].childNodes[1], "mouseup", categoryMgr.endScrolling);
        addEvent(_this.catTabs.childNodes[2].childNodes[0], "click", categoryMgr.createCategory);
        
        addEvent(_this.catTabs.childNodes[2].childNodes[2], "click", categoryMgr.showCategoryList);
        addEvent(window, "resize", categoryMgr.toggleScrollButtons);
        
        document.getElementById("dropletArea").parentNode.insertBefore(_this.catTabs, document.getElementById("dropletArea"));
        
        // Dropdown category list
        
        _this.groupList = makeElement("ul");        
	};
	
	this.showCategoryList = function(e)
	{
	    dialogMgr.open(_this.groupList, this, (getOffsetTop(this) + 10), (getOffsetLeft(this) - 180), false, returnFalse);
	};
	
	this.setColumns = function(e)
	{
	    if(dropletMgr.columns.length > 0)
	    {
	        switch(this.className)
	        {
	            case "up":
	                if(_this.propertiesObj.columns.length < 5)
	                {
	                    var newWidth = 100 / (_this.propertiesObj.columns.length + 1);
	                    var negateThis = parseFloat(newWidth / _this.propertiesObj.columns.length);
    	                
                        for(var col = 0; col < _this.propertiesObj.columns.length; col++)
                            _this.propertiesObj.columns[col] = _this.propertiesObj.columns[col] - negateThis;
                        
                        _this.propertiesObj.columns[_this.propertiesObj.columns.length] = newWidth;
                        
                        var unusableArea = dropletMgr.getPercentUnusable(_this.propertiesObj.columns.length) / _this.propertiesObj.columns.length;
                        
                        dropletMgr.addColumn(newWidth-unusableArea);
                        dropletMgr.addColumnSizer(_this.propertiesObj.columns.length - 2);
	                }
    	                
	                break;
	            case "down":
	                if(_this.propertiesObj.columns.length > 2)
	                {
	                    var addThis = parseFloat(_this.propertiesObj.columns[_this.propertiesObj.columns.length - 1] / (_this.propertiesObj.columns.length - 1));

                        for(var col = 0; col < _this.propertiesObj.columns.length - 1; col++)
                            _this.propertiesObj.columns[col] = _this.propertiesObj.columns[col] + addThis;
                            
                        for(var d = 0; d < dropletMgr.droplets.length; d++)
                        {
                            if(dropletMgr.droplets[d].droplet.parentNode == dropletMgr.columns[(categoryMgr.propertiesObj.columns.length - 1)].column)
                            {
                                dropletMgr.columns[(categoryMgr.propertiesObj.columns.length - 1)].column.removeChild(dropletMgr.droplets[d].droplet);
                                dropletMgr.columns[(categoryMgr.propertiesObj.columns.length - 2)].column.appendChild(dropletMgr.droplets[d].droplet);
                                
                                if(dropletMgr.droplets[d].saveObj != null)
                                    dropletMgr.droplets[d].saveObj.Column = (_this.propertiesObj.columns.length - 2);

                            }
                        }
                        
                        dropletMgr.sizers[dropletMgr.sizers.length - 1].parentNode.removeChild(dropletMgr.sizers[dropletMgr.sizers.length - 1]);
                        dropletMgr.sizers.pop();
                        dropletMgr.columns[dropletMgr.columns.length - 1].column.parentNode.removeChild(dropletMgr.columns[dropletMgr.columns.length - 1].column);
                        dropletMgr.columns.pop();
                        categoryMgr.propertiesObj.columns.pop();
	                }
	                break;
	        }
    	    
	        _this.settingsList.childNodes[2].childNodes[2].replaceChild(document.createTextNode(_this.propertiesObj.columns.length.toString()), _this.settingsList.childNodes[2].childNodes[2].childNodes[0]);
            this.parentNode.childNodes[1].className = (_this.propertiesObj.columns.length == 5) ? "disabled" : "up";
            this.parentNode.childNodes[3].className = (_this.propertiesObj.columns.length == 2) ? "disabled" : "down";
    	    
            dropletMgr.redraw();
	    }
	};
	
	this.initializeSettings = function()
	{
	    _this.settingsList = makeElement("ul");
	    
        _this.settingsList.appendChild(makeElement("li"));
        _this.settingsList.childNodes[0].appendChild(makeElement("div", {cn:'label'}, "Group Name"));
        _this.settingsList.appendChild(makeElement("li"));
        _this.settingsList.childNodes[1].appendChild(makeElement("input", {cn:'txt',type:'text',maxLength:50,style:{width:'165px',margin:'0 5px 0 5px'}}));
        _this.settingsList.appendChild(makeElement("li"));
        _this.settingsList.childNodes[2].appendChild(makeElement("div", {cn:'label',style:{float:'left'}}, "Columns"));
        _this.settingsList.childNodes[2].appendChild(makeElement("img", {cn:'up',title:'More',style:{float:'right'}}, null, null, _images["up"].src));
        _this.settingsList.childNodes[2].appendChild(makeElement("div", {cn:'option',style:{float:'right'}}, "3"));
        _this.settingsList.childNodes[2].appendChild(makeElement("img", {cn:'down',title:'Less',style:{float:'right'}}, null, null, _images["down"].src));
        _this.settingsList.childNodes[2].appendChild(makeElement("div", {cn:'clr'}, null, "clr"));
	    _this.settingsList.appendChild(makeElement("li"));
	    _this.settingsList.childNodes[3].appendChild(makeElement("a", {cn:'btn',href:'javascript:void(0)',style:{marginRight:'27px'}}, "Delete Group"));
        _this.settingsList.childNodes[3].appendChild(makeElement("div", {cn:'clr'}, null, "clr"));
	    
	    addEvent(_this.settingsList.childNodes[3].childNodes[0], "click", categoryMgr.deleteCategory);
	    addEvent(_this.settingsList.childNodes[1].childNodes[0], "keyup", categoryMgr.nameKeyup);
        addEvent(_this.settingsList.childNodes[2].childNodes[1], "click", categoryMgr.setColumns);
        addEvent(_this.settingsList.childNodes[2].childNodes[3], "click", categoryMgr.setColumns);
	};
	
	this.showSettings = function(e)
	{
	    if(_this.settingsList == null)
	        _this.initializeSettings();
	        
	    _this.settingsList.childNodes[1].childNodes[0].value = _this.categories[_this.currentCategory].Name;
	    
	    var colCount = _this.propertiesObj.columns.length;
	    
        _this.settingsList.childNodes[2].childNodes[1].className = (colCount == 5) ? "disabled" : "up";
        _this.settingsList.childNodes[2].childNodes[3].className = (colCount == 2) ? "disabled" : "down";

	    _this.settingsList.childNodes[2].childNodes[2].replaceChild(document.createTextNode(_this.propertiesObj.columns.length.toString()), _this.settingsList.childNodes[2].childNodes[2].childNodes[0]);
	        
	    dialogMgr.open(_this.settingsList, this, (getOffsetTop(this) + 13), getOffsetLeft(this), true, categoryMgr.save);
	};	

    this.parseJsonCategories = function(jsonCategories)
    {   
        jsonCategories = jsonDeserializeIfAuth(jsonCategories, false);
        
        if(Sys.Services.AuthenticationService.get_isLoggedIn())
        {
            if(_this.catTabs == null)
				_this.initializeTabs();
            else
                clearTree(_this.catTabs);
        }
        
        var select = 0;

        for(var jc = 0; jc < jsonCategories.length; jc++)
        {
            _this.categories[jc] = jsonCategories[jc];
            
            if(Sys.Services.AuthenticationService.get_isLoggedIn())
                _this.appendCategory(_this.categories[jc], true, jc);
            
            if(_this.categories[jc].IsSelected)
                select = jc;
        }
        
        _this.setCategory(null, select);
        
        if(Sys.Services.AuthenticationService.get_isLoggedIn())
        {
            _this.catTabs.appendChild(makeElement("div", {cn:'clr'}, null, "clr"));
            _this.scrollToTab();
            document.body.style.backgroundPosition = "0 205px";
        }
        else
        {
            document.body.style.backgroundPosition = "0 172px";
        }
    };
    this.init = function()
    {
        PageMethods.GetJsonCategories(this.parseJsonCategories);
    };
    this.deserializeProperties = function(x, catIdx)
    {
        if(_this.categories[catIdx].Properties != null)
            _this.propertiesObj = jsonDeserializeIfAuth(_this.categories[catIdx].Properties, true);
    };
    
    this.save = function()
    {
        if(_this.categories[_this.currentCategory] != null)
        {
            var unusableArea = (dropletMgr.getPercentUnusable(dropletMgr.columns.length) / dropletMgr.columns.length);
            var percent = 0;
            
            for(var c = 0; c < dropletMgr.columns.length; c++)
            {
                var width = dropletMgr.columns[c].getWidth("%") + unusableArea;
                percent += width;
                
                if(c == (dropletMgr.columns.length - 1) && percent != 100)
                    width = width + (100 - percent);
                
                categoryMgr.propertiesObj.columns[c] = width;
                dropletMgr.columns[c].doSave = false;
            }
            
            if(percent > 100)
            {
                var negate = (percent - 100) / categoryMgr.propertiesObj.columns.length;
                
                for(var c = 0; c < categoryMgr.propertiesObj.columns.length; c++)
                    categoryMgr.propertiesObj.columns[c] = categoryMgr.propertiesObj.columns[c] - negate;
                    
                dropletMgr.redraw();
            }
            
            categoryMgr.categories[categoryMgr.currentCategory].Properties = Sys.Serialization.JavaScriptSerializer.serialize(categoryMgr.propertiesObj);
            
            if(!categoryMgr.categories[categoryMgr.currentCategory].IsSelected)
                for(var c = 0; c < categoryMgr.categories.length; c++)
                    categoryMgr.categories[categoryMgr.currentCategory].IsSelected = (categoryMgr.categories[categoryMgr.currentCategory] == categoryMgr.categories[c]);

            PageMethods.SaveCategory(Sys.Serialization.JavaScriptSerializer.serialize(categoryMgr.categories[categoryMgr.currentCategory]), categoryMgr.deserializeProperties, null, categoryMgr.currentCategory);
        }
    };
}

var fonts = new Array();
fonts[0] = new Array("Sans-serif", "Verdana");
fonts[1] = new Array("Serif", "serif");
fonts[2] = new Array("Monospace", "monospace");
fonts[3] = new Array("Fancy", "cursive");

var categoryMgr = new categoryMgrObj();

function dropletSettingsObj()
{
    var _this = this;
    this.currentDroplet = null;
    this.settingsList = null;
    this.styleObj = null;
    this.properties = null;
    this.closeTimeout = null;
    
    this.maxToFull = function(e)
    {
        _this.currentDroplet.saveObj.MaximizesToFullscreen = !_this.currentDroplet.saveObj.MaximizesToFullscreen;
        _this.settingsList.childNodes[0].childNodes[0].src = (_this.currentDroplet.saveObj.MaximizesToFullscreen) ? _images["check"].src : _images["blank"].src;
    };
    
    this.minToTitle = function(e)
    {
        _this.currentDroplet.saveObj.MinimizesToHeader = !_this.currentDroplet.saveObj.MinimizesToHeader;
        _this.settingsList.childNodes[1].childNodes[0].src = (_this.currentDroplet.saveObj.MinimizesToHeader) ? _images["check"].src : _images["blank"].src;
        
        if(_this.currentDroplet.saveObj.DropletModeId == 1)
        {
            dropletMgr.maxdroplet = _this.currentDroplet;
            dropletMgr.minimize(e);            
        }
        
    };
    
    this.deleteDroplet = function(e)
    {
        this.blur();
        dialogMgr.closeEvent = returnFalse;
        dialogMgr.close();
    
        if(confirm("Are you sure you would like to delete '" + _this.currentDroplet.saveObj.Title + "'"))
        {
            if(Sys.Services.AuthenticationService.get_isLoggedIn())
                PageMethods.DeleteDroplet(Sys.Serialization.JavaScriptSerializer.serialize(_this.currentDroplet.saveObj));
                
            
            for(var d = 0; d < dropletMgr.droplets.length; d++)
            {
                if(dropletMgr.droplets[d].droplet == _this.currentDroplet.droplet)
                {
                    dropletMgr.droplets[d].droplet.style.display = "none";
                    dropletMgr.droplets[d].deleted = true;
                    break;
                }
            }
            
            _this.currentDroplet = null;
            dropletMgr.redraw();
        }
    };
    
    this.setColor = function(e)
    {
        if(this.className == "clr-theme")
        {
            _this.currentDroplet.droplet.childNodes[0].style.backgroundColor = null;
            _this.currentDroplet.droplet.childNodes[0].className = _this.currentDroplet.droplet.childNodes[0].className.replace("clr-" + _this.styleObj.color, "") + " " + this.className;
            _this.styleObj.color = this.className.replace("clr-", "");
        }
        else
        {            
            _this.currentDroplet.droplet.childNodes[0].className = _this.currentDroplet.droplet.childNodes[0].className.replace("clr-" + _this.styleObj.color, "");
            _this.currentDroplet.droplet.childNodes[0].style.backgroundColor = this.style.backgroundColor;
            _this.styleObj.color = ConvertToHex(this.style.backgroundColor);
            
            _this.currentDroplet.droplet.childNodes[0].childNodes[1].style.color = setForecolor(_this.styleObj.color);
        }
        _this.currentDroplet.saveObj.Style = Sys.Serialization.JavaScriptSerializer.serialize(_this.styleObj);

        this.blur();
    };
    
    this.overColor = function(e)
    {
        if(this.className == "clr-theme")
        {
            _this.settingsList.childNodes[2].childNodes[1].childNodes[0].style.backgroundColor = null;
            _this.settingsList.childNodes[2].childNodes[1].childNodes[0].className = "clr-theme";
        }
        else
        {
            _this.settingsList.childNodes[2].childNodes[1].childNodes[0].className = "";
            _this.settingsList.childNodes[2].childNodes[1].childNodes[0].style.backgroundColor = ConvertToHex(this.style.backgroundColor);
        }
    };
    
    this.outColor = function(e)
    {
        if(_this.styleObj.color == "theme")
        {
            _this.settingsList.childNodes[2].childNodes[1].childNodes[0].style.backgroundColor = null;
            _this.settingsList.childNodes[2].childNodes[1].childNodes[0].className = "clr-theme";
        }
        else
        {
            _this.settingsList.childNodes[2].childNodes[1].childNodes[0].style.backgroundColor = _this.styleObj.color;
        }
    };
    
    this.setSize = function(e)
    {
        switch(this.className)
        {
            case "up":
                if(_this.styleObj.size < 200)
                    _this.styleObj.size += 25;                

                break;
            case "down":
                if(_this.styleObj.size > 75)
                    _this.styleObj.size -= 25;

                break;
        }

        this.parentNode.childNodes[1].className = (_this.styleObj.size == 200) ? "disabled" : "up";
        this.parentNode.childNodes[3].className = (_this.styleObj.size == 75) ? "disabled" : "down";
        
        _this.currentDroplet.content.style.fontSize = _this.styleObj.size + "%";        
        _this.currentDroplet.saveObj.Style = Sys.Serialization.JavaScriptSerializer.serialize(_this.styleObj);
        
        this.parentNode.childNodes[2].innerHTML = _this.styleObj.size + "%";
    };
    
    this.resultSetRange = new Array(1, 3, 5, 10, 15, 25);
    
    this.setResults = function(e)
    {
        var setIndex = 2;
        
        for(var s = 0; s < _this.resultSetRange.length; s++)
            if(_this.resultSetRange[s] == _this.properties.ResultCount)
                setIndex = s;        
        
        switch(this.className)
        {
            case "up":
                if(setIndex < (_this.resultSetRange.length - 1))
                    setIndex++;
                
                break;
            case "down":
                if(setIndex > 0)
                    setIndex--;

                break;
        }
        
        this.parentNode.childNodes[1].className = (setIndex == (_this.resultSetRange.length - 1)) ? "disabled" : "up";
        this.parentNode.childNodes[3].className = (setIndex == 0) ? "disabled" : "down";
        
        _this.properties.ResultCount = _this.resultSetRange[setIndex];
        _this.currentDroplet.saveObj.Properties = Sys.Serialization.JavaScriptSerializer.serialize(_this.properties);
        dialogMgr.closeEvent = dropletSettings.saveAndRefresh;
        
        this.parentNode.childNodes[2].innerHTML = _this.properties.ResultCount;
    };
    
    this.saveAndRefresh = function()
    {
        dropletMgr.save(dropletMgr.refreshDroplet, new Array(dropletMgr.getDroplet(_this.currentDroplet.droplet, true), _this.currentDroplet.saveObj.CategoryId));
    };
    
    this.setFont = function(e)
    {
        switch(this.className)
        {
            case "up":
                if(_this.styleObj.font != null && _this.styleObj.font < fonts.length - 1)
                    _this.styleObj.font++;
                else
                    _this.styleObj.font = 0;

                break;
            case "down":
                if(_this.styleObj.font > 0)
                    _this.styleObj.font--;
                else
                    _this.styleObj.font = fonts.length - 1;

                break;
        }
            
        this.parentNode.childNodes[2].style.fontFamily = fonts[_this.styleObj.font][1];
        this.parentNode.childNodes[2].innerHTML = fonts[_this.styleObj.font][0];
        _this.currentDroplet.content.style.fontFamily = fonts[_this.styleObj.font][1];
        _this.currentDroplet.saveObj.Style = Sys.Serialization.JavaScriptSerializer.serialize(_this.styleObj);
    };
    
    this.addColor = function(to, color, swatch)
    {
        to.appendChild(makeElement("a", {href:'javascript:void(0)',style:{backgroundColor:'#' + color}}, "\u0020"));
        to.childNodes[to.childNodes.length-1].className = swatch ? "swatch" : "";
    };
    
    this.init = function()
    {
        this.settingsList = (makeElement("ul"));
        var ul = this.settingsList;
        
        ul.appendChild(makeElement("li"));
        ul.childNodes[0].appendChild(makeElement("img", {title:'Maximize to Full-Screen',width:_images["check"].width,height:_images["check"].height}, null, null, _images["check"].src));
        ul.childNodes[0].appendChild(makeElement("div", {cn:'option hand'}, "Maximize to Full-Screen"));
        ul.childNodes[0].appendChild(makeElement("div", {cn:'clr'}, null, "clr"));
        
        ul.appendChild(makeElement("li"));
        ul.childNodes[1].appendChild(makeElement("img", {title:'Minimize to Title Bar',width:_images["check"].width,height:_images["check"].height}, null, null, _images["check"].src));
        ul.childNodes[1].appendChild(makeElement("div", {cn:'option hand'}, "Minimize to Title Bar"));
        ul.childNodes[1].appendChild(makeElement("div", {cn:'clr'}, null, "clr"));
        
        ul.appendChild(makeElement("li"));
        ul.childNodes[2].appendChild(makeElement("div", {cn:'label'}, "Droplet Color"));
        
        ul.childNodes[2].appendChild(makeElement("div", {cn:'colors'}));
        
        var colors = ul.childNodes[2].childNodes[1];
        
        colors.appendChild(makeElement("div", {id:'dropletColor'}, "\u0020"));
        colors.appendChild(makeElement("div", {cn:'clr'}, null, "clr"));

        var clrs = new Array('00','11','22','33','44','55','66','77','88','99','aa','bb','cc','dd','ee','ff');
        var rgb = new Array(15,0,0);

        for (rgb[1] = 0; rgb[1] < clrs.length; rgb[1]++)
            this.addColor(colors, clrs[rgb[0]] + clrs[rgb[1]] + clrs[rgb[2]], false);

        rgb[1]--;

        for(rgb[0] = 15; rgb[0] > -1; rgb[0]--)
            this.addColor(colors, clrs[rgb[0]] + clrs[rgb[1]] + clrs[rgb[2]], false);

        rgb[0]++;

        for (rgb[2] = 0; rgb[2] < clrs.length; rgb[2]++)
            this.addColor(colors, clrs[rgb[0]] + clrs[rgb[1]] + clrs[rgb[2]], false);

        rgb[2]--;

        for (rgb[1] = 15; rgb[1] > -1; rgb[1]--)
            this.addColor(colors, clrs[rgb[0]] + clrs[rgb[1]] + clrs[rgb[2]], false);

        rgb[1]++;
        
        for (rgb[0] = 0; rgb[0] < clrs.length; rgb[0]++)
            this.addColor(colors, clrs[rgb[0]] + clrs[rgb[1]] + clrs[rgb[2]], false);

        rgb[0]--;
        
        for (rgb[2] = 15; rgb[2] >- 1; rgb[2]--)
            this.addColor(colors, clrs[rgb[0]] + clrs[rgb[1]] + clrs[rgb[2]], false);

        // Custom swatches
        this.addColor(colors, "64c8d0", true);this.addColor(colors, "0097a0", true);
        this.addColor(colors, "4baddc", true);this.addColor(colors, "2b82af", true);
        this.addColor(colors, "83b60f", true);this.addColor(colors, "577a19", true);
        this.addColor(colors, "d2dc28", true);this.addColor(colors, "eaae02", true);
        this.addColor(colors, "b68a17", true);this.addColor(colors, "ffa03c", true);
        this.addColor(colors, "f0640a", true);this.addColor(colors, "ff4b55", true);
        this.addColor(colors, "d31837", true);this.addColor(colors, "8f161f", true);

        colors.appendChild(makeElement("a", {cn:'clr-theme',title:'Current Theme',href:'javascript:void(0)'}, "\u0020"));

        for(var c = 2; c < colors.childNodes.length; c++)
        {
            addEvent(colors.childNodes[c], "click", _this.setColor);
            addEvent(colors.childNodes[c], "click", returnFalse);
            addEvent(colors.childNodes[c], "mouseover", _this.overColor);
            addEvent(colors.childNodes[c], "mouseout", _this.outColor);
        }

        colors.appendChild(makeElement("div", {cn:'clr'}, null, "clr"));

        ul.appendChild(makeElement("li"));
        ul.childNodes[3].appendChild(makeElement("div", {cn:'label',style:{paddingBottom:'0px'}}, "Font Options"));

        ul.appendChild(makeElement("li", {style:{paddingBottom:'5px'}}));
        ul.childNodes[4].appendChild(makeElement("div", {cn:'option',style:{paddingLeft:'15px'}}, "Size:"));
        ul.childNodes[4].appendChild(makeElement("img", {cn:'up',title:'Larger',style:{float:'right',paddingRight:'12px'}}, null, null, _images["up"].src));
        ul.childNodes[4].appendChild(makeElement("div", {cn:'option',style:{float:'right',width:'35px',textAlign:'center'}}));
        ul.childNodes[4].appendChild(makeElement("img", {cn:'down',title:'Smaller',style:{float:'right'}}, null, null, _images["down"].src));
        ul.childNodes[4].appendChild(makeElement("div", {cn:'clr'}, null, "clr"));

        ul.appendChild(makeElement("li", {style:{height:'20px'}}));
        ul.childNodes[5].appendChild(makeElement("div", {cn:'option',style:{paddingLeft:'15px'}}, "Font:"));
        ul.childNodes[5].appendChild(makeElement("img", {cn:'up',title:'Next',style:{float:'right',paddingRight:'12px'}}, null, null, _images["up"].src));
        ul.childNodes[5].appendChild(makeElement("div", {cn:'option',style:{float:'right',width:'65px',textAlign:'center'}}));
        ul.childNodes[5].appendChild(makeElement("img", {cn:'down',title:'Previous',style:{float:'right'}}, null, null, _images["down"].src));
        ul.childNodes[5].appendChild(makeElement("div", {cn:'clr'}, null, "clr"));
        
        // Allocated Items for additional droplet specific settings
        ul.appendChild(makeElement("li", {cn:'hide'}, "\u0020"));
        ul.appendChild(makeElement("li", {cn:'hide'}, "\u0020"));
        
        ul.appendChild(makeElement("li", {style:{paddingRight:'10px'}}));
        ul.childNodes[8].appendChild(makeElement("a", {cn:'btn',href:'javascript:void(0)'}, "Save"));
        addEvent(ul.childNodes[8].childNodes[0], "click", dialogMgr.close);
        if(Sys.Services.AuthenticationService.get_isLoggedIn())
        {
            ul.childNodes[8].appendChild(makeElement("a", {cn:'btn',href:'javascript:void(0)'}, "Delete"));
            addEvent(ul.childNodes[8].childNodes[1], "click", dropletSettings.deleteDroplet);
        }
        ul.childNodes[8].appendChild(makeElement("div", {cn:'clr'}, null, "clr"));

        addEvent(ul.childNodes[0], "click", dropletSettings.maxToFull);
        addEvent(ul.childNodes[1], "click", dropletSettings.minToTitle);
        
        addEvent(ul.childNodes[4].childNodes[1], "click", dropletSettings.setSize);        
        addEvent(ul.childNodes[4].childNodes[3], "click", dropletSettings.setSize);
        
        addEvent(ul.childNodes[5].childNodes[1], "click", dropletSettings.setFont);
        addEvent(ul.childNodes[5].childNodes[3], "click", dropletSettings.setFont);
        
    };
    
    this.open = function(e)
    {
        if(dropletMgr.activated == null)
        {
            _this.currentDroplet = dropletMgr.getDroplet(this);
            _this.styleObj = jsonDeserializeIfAuth(_this.currentDroplet.saveObj.Style, true);
            _this.properties = jsonDeserializeIfAuth(_this.currentDroplet.saveObj.Properties, true);
        
            if(_this.settingsList == null)
                _this.init();

            var ul = _this.settingsList;
            var colors = ul.childNodes[2].childNodes[1];

            if(_this.styleObj.color == "theme")
            {
                colors.childNodes[0].style.backgroundColor = null;
                colors.childNodes[0].className = "clr-theme";
            }
            else
            {
                colors.childNodes[0].style.backgroundColor = _this.styleObj.color;
            }

            ul.childNodes[0].childNodes[0].src = (_this.currentDroplet.saveObj.MaximizesToFullscreen) ? _images["check"].src : _images["blank"].src;
            ul.childNodes[1].childNodes[0].src = (_this.currentDroplet.saveObj.MinimizesToHeader) ? _images["check"].src : _images["blank"].src;
            
            if(_this.styleObj.size < 50)
                _this.styleObj.size = _this.styleObj.size * 100;

            ul.childNodes[4].childNodes[2].innerHTML = _this.styleObj.size + "%";

            ul.childNodes[4].childNodes[3].className = (_this.styleObj.size == 75) ? "disabled" : "down";
            ul.childNodes[4].childNodes[1].className = (_this.styleObj.size == 200) ? "disabled" : "up";

            _this.styleObj.font = (_this.styleObj.font != null) ? _this.styleObj.font : 0;

            ul.childNodes[5].childNodes[2].innerHTML = fonts[_this.styleObj.font][0];
            ul.childNodes[5].childNodes[2].style.fontFamily = fonts[_this.styleObj.font][1];
            
            // Droplet type specific settings
            ul.childNodes[6].className = "hide";
            ul.childNodes[7].className = "hide";
            clearTree(ul.childNodes[6]);
            
            var id = _this.currentDroplet.saveObj.DropletTypeId;
            
            if((id == 1 || id == 5 || id == 6 || id == 7))
            { // Blog, RSS, Video, Photos - get result count
                
                var setIndex = 2;
                
                for(var s = 0; s < _this.resultSetRange.length; s++)
                    if(_this.resultSetRange[s] == _this.properties.ResultCount)
                        setIndex = s;  
                
                ul.childNodes[6].className = "";    
                ul.childNodes[6].appendChild(makeElement("div", {cn:'label',style:{float:'left'}}, "Results:"));
                ul.childNodes[6].appendChild(makeElement("img", {cn:'up',style:{float:'right',paddingRight:'12px'}}, null, null, _images["up"].src));
                ul.childNodes[6].appendChild(makeElement("div", {cn:'option',style:{float:'right',width:'20px',textAlign:'center'}}, _this.resultSetRange[setIndex]));
                ul.childNodes[6].appendChild(makeElement("img", {cn:'down',style:{float:'right'}}, null, null, _images["down"].src));
                ul.childNodes[6].appendChild(makeElement("div", {cn:'clr'}, null, "clr"));

                ul.childNodes[6].childNodes[1].className = (setIndex == (_this.resultSetRange.length - 1)) ? "disabled" : "up";
                ul.childNodes[6].childNodes[3].className = (setIndex == 0) ? "disabled" : "down";


                addEvent(ul.childNodes[6].childNodes[1], "click", dropletSettings.setResults);        
                addEvent(ul.childNodes[6].childNodes[3], "click", dropletSettings.setResults);
            }            
            

            var offsetLeft = 0;
            var offsetTop = -15;
            
            if(_this.currentDroplet.saveObj.Column == categoryMgr.propertiesObj.columns.length - 1 || dropletMgr.isMax)
                offsetLeft = 180;
                
            if(getWindowHeight() - getOffsetTop(this) < 269)
                offsetTop = (typeof _this.properties.ResultCount == "undefined") ? 250 : 275;
            
            _this.currentDroplet.doSave = true;
            
            dialogMgr.open(_this.settingsList, this, (getOffsetTop(this) - offsetTop), (getOffsetLeft(this) - offsetLeft), true, dropletMgr.save);
        }
    };
}

var dropletSettings = new dropletSettingsObj();

dropletMgr.dropletArea = document.getElementById("dropletArea");

categoryMgr.init();

// Droplet type specific code below
function apNewsObj()
{
    var _this = this;
    this.ProductSelected = function(_callingElement, _productId)
    {
        dropletMgr.updateProperties(_callingElement, {ProductId:parseInt(_productId, 10),headlinesHidden:false}, true);
    };
    
    this.ArticleSelected = function(_callingElement, _articleId)
    {
        dropletMgr.updateProperties(_callingElement, {ArticleId:_articleId,headlinesHidden:false}, true, {func:apNews.anchorToArticle,params:_articleId});
    };
    
    this.anchorToArticle = function(_articleId)
    {
        document.getElementById("article_" + _articleId).parentNode.scrollTop = document.getElementById("article_" + _articleId).offsetTop - 24;
    };
    
    this.ToggleHeadlines = function(_callingElement)
    {
        if(_callingElement.childNodes[0].src.match("down"))
        {
            _callingElement.childNodes[0].src = "/assets/droplets/opt-up-wht.gif";
            _callingElement.replaceChild(document.createTextNode("Show Headlines"), _callingElement.childNodes[1]);
            getElementsByClassName("apHeadlines", "div", _callingElement.parentNode.parentNode)[0].className = "apHeadlines hide";
            dropletMgr.updateProperties(_callingElement, {headlinesHidden:true});
        }
        else
        {
            _callingElement.childNodes[0].src = "/assets/droplets/opt-down-wht.gif";
            _callingElement.replaceChild(document.createTextNode("Hide Headlines"), _callingElement.childNodes[1]);
            getElementsByClassName("apHeadlines", "div", _callingElement.parentNode.parentNode)[0].className = "apHeadlines";
            dropletMgr.updateProperties(_callingElement, {headlinesHidden:false});
        }
    };
}

var apNews = new apNewsObj();

function youTubeObj()
{
    var _this = this;
    this.showVideo = function(_callingElement, _videoUrl)
    {
        dropletMgr.updateProperties(_callingElement, {VideoUrl:_videoUrl}, true);
    };
    this.search = function(_callingElement, _searchString)
    {
        dropletMgr.updateProperties(_callingElement, {SearchString:_searchString}, true);
    };
    this.backToListing = function(_callingElement, _clearSearch)    
    {
        if(typeof _clearSearch != "undefined")
            dropletMgr.updateProperties(_callingElement, {VideoUrl:'',SearchString:''}, true);
        else
            dropletMgr.updateProperties(_callingElement, {VideoUrl:''}, true);
    };
}

var youTube = new youTubeObj();

function flickrObj()
{
    var _this = this;
    this.search = function(_callingElement, _searchString)
    {
        dropletMgr.updateProperties(_callingElement, {SearchString:_searchString}, true);
    };
    this.switchMode = function(_callingElement, _mode)
    {
        _mode = (_mode == "allPhotos") ? 0 : 1;
        
        dropletMgr.updateProperties(_callingElement, {Mode:_mode}, true);
    };
    this.backToListing = function(_callingElement, _clearSearch)    
    {
        if(typeof _clearSearch != "undefined")
            dropletMgr.updateProperties(_callingElement, {Mode:0,SearchString:''}, true);
        else
            dropletMgr.updateProperties(_callingElement, {Mode:0}, true);
    };
}

var flickr = new flickrObj();

function weatherMapObj()
{
    var _this = this;

    this.stateChanged = function(_callingElement, _jsonObj)
    {
        _jsonObj = jsonDeserializeIfAuth(_jsonObj, false);
        _callingElement = swfobject.getObjectById(_callingElement);
        dropletMgr.updateProperties(_callingElement, _jsonObj);
    };
    this.setState = function(_callingElement)
    {
        _callingElement = swfobject.getObjectById(_callingElement);
        _callingElement.setMapPosition(dropletMgr.getDroplet(_callingElement).saveObj.Properties);
    };
}

var weatherMap = new weatherMapObj();