var dashboard = null, controls = null, editingDashboard = false;
var Dashboard = {
    config: {},
    observers: {},
    otherProperties: null,
    currentlyViewableClass: null,
    preloaded: false,
    widgetListURL: '/dashboard/widget/widgetlist.nn',    
    observer: function(eventname, func)
    {
        if(!this.observers[eventname])
        {
            this.observers[eventname] = [];    
        }
        
        this.observers[eventname].push(func);
    },
    triggerEvent: function(eventname, object)
    {
        var funcs = this.observers[eventname];
        
        if(funcs)
        {
            funcs.each(function(func)
                {
                    func(object);    
                });
        }
        
    },
    setOtherProperties: function(p)
    {
        this.otherProperties = p;       
    },
    setInheritedParameters: function(p)
    {
        this.config.inheritedParameters = p;    
    },
    toggleViewableWidgets: function(className)
    {
        if(!className) { return; }
        this.currentlyViewableClass = className;
        dashboard.select('li.widget').each(function(li)
            {
                if(li.hasClassName(className))
                {
                    li.setOpacity(1);    
                }
                else
                {
                    li.setOpacity(0.3);    
                }
                
            });
    },
    resetViewableWidgets: function()
    {
        this.toggleViewableWidgets(this.currentlyViewableClass);    
    },
    resetDashboard: function(button)
    {
        Cognoti.confirmBubble(button, new Element('div').update(Cognoti.getI18N('dashboard', 'reset_are_you_sure', 'You are about to reset this dashboard to the current system default for this type of dashboard. Doing so will remove any customization you have added to this dashboard, and the change will be saved immediately. Would you like to continue?')),
            false, ['Yes', 'No'], function(val)
            {
                if(val == 'Yes')
                {
                    Dashboard.config.form.down('input[name="process"]').setValue('resetdashboard');
                    Dashboard.config.form.submit();
                }
            });
        
    },
    submit: function(form, fakeforms)
    {
        try
        {
            form.hasChanged=false;
            
            
            var addFields = form.down('.additionalFields');
            
            addFields.update();
            
            fakeFormValues = [];
            fakeforms.each(function(ff)
            {
                if(ff = $(ff))
                {
                    fakeFormValues.push(ff.serializeElements(true));
                }
            });
            
            Cognoti.log(fakeFormValues);
            
            fakeFormValues.each(function (ffv)
            {
                for(var ffvKey in ffv)
                {
                    var items = ffv[ffvKey];
                    
                    items.each(function(i)
                    {
                        addFields.insertHiddenField(ffvKey, i);        
                    });
                }
            });
            
            return true; //change to true
        }
        catch(e)
        {
            Cognoti.log(e);
            
            return false;
        }
    }
    
}


var registerDashboard = function(dash, dashcontrols, category, inherited, preloadcallback)
{
    dashboard = $(dash);
    controls = $(dashcontrols);
    Dashboard.config.category = category;
    Dashboard.config.inheritedParameters = inherited;
    Dashboard.config.preloadCallback = preloadcallback;
    
    if(controls)
    {
        controls.show();
    }
}

var addWidgetWizard = function(toolbar)
{
    var tb = $(toolbar);  
    
    tb.update(new Element('img', { 'src': '/cognoti/img/spinner.gif', 'alt': 'Loading...' }));
    
    
    new Ajax.Request(Dashboard.widgetListURL, { 
            parameters: { view: 'listbycategory', category: Dashboard.config.category },
            onComplete: 
            function(t) 
            { 
                var xml = t.responseXML.documentElement;
                
                var widgets = {};
                
                var ul = new Element('ul', { 'class': 'toolbar'});
                
                $A(xml.childNodes).each(function (child)
                {
                    var w = xmlElementToJs(child);
                    
                    var li = new Element('li', {'class':'button'}).update(w.name);
                    li.info = w;
                    new Draggable(li, { revert: true, ghosting: true, scroll: window});
                    ul.insert(li);
                });
                
                tb.update(ul).insertClear();
            }
    });
}

var reloadWidget = function(widgetBlock)
{
    widgetBlock = $(widgetBlock);

    var params = widgetBlock.down('input[name=parameters]').getValue();
    var preferences = widgetBlock.down('input[name=preferences]').getValue();
    var widget = widgetBlock.down('input[name=widgetid]').getValue();
    var content = widgetBlock.down('div.widget_content');
    
    /* content.setStyle({height: content.getHeight()+'px'}); */
    content.update(new Element('img', { 'src': '/cognoti/img/spinner.gif', 'alt': 'Loading...' }));
    
    new Ajax.Updater(content, '/dashboard/widget/widgetrender.nn', { 
            parameters: { parameters: params, preferences: preferences, widget: widget, inherited: Dashboard.config.inheritedParameters },
            evalScripts: true,
            onComplete: function(t) { 
                content.setStyle({height: 'auto'}); 
                Dashboard.triggerEvent('layout-updated', null);
            }
    });
        
}

var toggleDashboard = function(dynamic)
{
    if(editingDashboard)
    {
        if(dashboard)
        {
            dashboard.addClassName('helpersoff');
        }
        
        if(controls)
        {
            controls.down('.dashboardtoolbar').hide();
        }
        
        editingDashboard = false;
    }
    else
    {
        if(!Dashboard.preloaded && Dashboard.config.preloadCallback)
        {
            Dashboard.config.preloadCallback();
            Dashboard.preloaded = true;
        }
        
        if(dashboard)
        {
            dashboard.removeClassName('helpersoff');
        }
        
        if(controls)
        {
            controls.down('.dashboardtoolbar').show();
            addWidgetWizard('dashboardWidgetToolbar');
            
            if (dynamic == true)
            {
                setupScrollingBox('scrollingDashboardControls');
            }
            else
            {
                 Event.observe(document, 'dom:loaded', function()
                {
                    setupScrollingBox('scrollingDashboardControls');
                });
            }
            
        }
        editingDashboard = true;
    }
}

var setupScrollingBox = function(box, spaceWrapper)
{
        var fw = $(box);

        if(spaceWrapper)
        {   
            fw.wrap('div').setStyle({ 'clear': 'both'});
        }
        
        var offset = fw.cumulativeOffset();
        fw.originalTop = offset[1];
        fw.originalLeft = offset[0];
        
        var scrollFunc = function()
            {
                var top = document.viewport.getScrollOffsets()[1];
                var setTop = top - fw.originalTop;

                if(top > fw.originalTop)
                {
                    fw.setStyle({'position': 'fixed', 'top': '0px', 'zIndex': 12});
                }
                else
                {
                    fw.setStyle({'position': 'static', 'top': null, 'zIndex': null});
                }
            }

        Event.observe(window, 'scroll', scrollFunc);
        scrollFunc();
}


var supportedBlocks = { portlet: 'portlet' };

var setSupportedBlocks = function(blocks)
{
    supportedBlocks = blocks;    
}

var doEdit = function(widgetblock, deleteOnCancel)
{
    widgetblock = $(widgetblock);
    var lbid = widgetblock.identify();
    var widgetid = widgetblock.down('input[name="widgetid"]').getValue();
    var params = widgetblock.down('input[name="parameters"]').getValue();
    var prefs = widgetblock.down('input[name="preferences"]').getValue();
    
    var params = {
        widgetid: widgetid,
        parameters: params,
        preferences: prefs,
        widgetblock: lbid,
        deleteoncancel: deleteOnCancel
    };
    
    Modalbox.show('/dashboard/widget/widgetproperties.nn', 
        {   
            title: Cognoti.getI18N('dashboard', 'modify_widget_properties', 'Modify Widget Properties'),
            width: 600,
            overlayClose: false,
            closeString: ' ',
            params: params,
            method: 'post',
            evalScripts: true,
            afterLoad: function() 
            {
                var wpo = $('widgetPropertyOthers');
                
                if(wpo && Dashboard.otherProperties)
                {
                    for(var i in Dashboard.otherProperties)
                    {
                        var div = new Element('div');
                        
                        var p = Dashboard.otherProperties[i];
                        
                        var fe = null;
                        
                        if(p.type == 'select')
                        {
                            fe = Cognoti.makeSelect(i,
                                p.selectOptions,
                                null);
                        }
                        else if(p.type == 'textbox')
                        {
                            fe = new Element('input', { 'type': 'textbox', 'name': i });
                        }
                        
                        
                        if(fe)
                        {
                            fe.addClassName('other');
                            div.appendFormElement(p.label, fe);    
                            
                            var val = widgetblock.down('input[name="'+i+'"]');
                            
                            if(val)
                            {
                                fe.setValue(val.getValue());    
                            }
                            
                            wpo.insert(div);
                        }
                        
                    }
                    
                    Modalbox.resizeToContent();
                }
            },
			beforeHide: function()
			{
				var textareas = $('widgetPropertyManager').select('textarea');
				for (i = 0; i < textareas.size(); i++)
				{
					closeTextArea(textareas[i].identify());
				}
			},
            afterHide: function()
            {
                completeEdit(widgetblock, null, deleteOnCancel);    
            }
        });
    
}

var completeEdit = function(widgetblock, propdiv, deleteOnCancel)
{
    var lb = $(widgetblock);
    propdiv = $(propdiv);

    if(!propdiv) //cancelled
    {
        if(deleteOnCancel.toString() == 'true')
        {
            lb.remove();                
        }
    }
    else
    {
        var parameters = new Hash();
        var preferences = new Hash();
        var others = new Hash();
        propdiv.select('input[type="text"]','select').each(function(item)
            {
                var name = item.name;
                var value = item.getValue();
                var isParameter = item.hasClassName('parameter');
                var isPreference = item.hasClassName('preference');
                var isOther = item.hasClassName('other');
                
                if(isParameter)
                {
                    parameters.set(name, value);
                }
                
                if(isPreference)
                {
                    preferences.set(name, value);
                }
                
                if(isOther)
                {
                    others.set(name, value);
                }
                
            });
        
        propdiv.select('textarea').each(function(item)
            {
                var name = item.name;
                var value = getWysiwygContent(item.identify());;
                var isParameter = item.hasClassName('parameter');
                var isPreference = item.hasClassName('preference');
                var isOther = item.hasClassName('other');
                
                
                if(isParameter)
                {
                    parameters.set(name, value);
                }
                
                if(isPreference)
                {
                    preferences.set(name, value);
                }
                
                if(!isOther)
                {
                    others.set(name, value);
                }
                
                if(!isParameter && !isPreference && !isOther) //wysiwyg clears out these classnames, we assume its parameter at this point
                {
                    parameters.set(name, value);    
                }
                
            });
        
        propdiv.select('input[type="checkbox"]', 'input[type="radio"]').each(function(item)
            {
                if(!item.checked) { return; }
                var name = item.name;
                var value = item.getValue();
                var isParameter = item.hasClassName('parameter');
                var isPreference = item.hasClassName('preference');
                var isOther = item.hasClassName('other');
                
                if(isParameter)
                {
                    var array = parameters.get(name);
                    array = (array != null && array.constructor == Array) ? array : []; 
                    array.push(value);
                    parameters.set(name, array);
                }
                
                if(isPreference)
                {
                    var array = preferences.get(name);
                    array = (array != null && array.constructor == Array) ? array : []; 
                    array.push(value);
                    preferences.set(name, array);
                }
                
                if(isOther)
                {
                    var array = others.get(name);
                    array = (array != null && array.constructor == Array) ? array : []; 
                    array.push(value);
                    others.set(name, array);
                }
                
            });
        
        var paramInput = lb.down('input[name="parameters"]');
        var prefInput = lb.down('input[name="preferences"]');
        lb.down('input[name="modified"]').setValue('1');
        
        paramInput.value = parameters.toQueryString();
        prefInput.value = preferences.toQueryString();
        
        others.each(function(pair)
            {
                var ib = lb.down('input[name="'+pair.key+'"]');
                
                if(ib)
                {
                    ib.setValue(pair.value);    
                }
                
            });
        
        reloadWidget(lb);
        Dashboard.triggerEvent('widget-edited', lb);
    }
    
    try
    {
        Modalbox.hide({afterHide: Prototype.emptyFunction });
    }
    catch(ex) { }
}

var setupDragAndDrop = function(form, toolbar, layout)
{
    Dashboard.config.form = $(form);
    Dashboard.config.form.down('input[name="process"]').setValue('savedashboard');
    var lo = $(layout);
    Dashboard.config.layout = lo;
    
    /* var tb = $(toolbar);
    var buttons = tb.select('.button');
    buttons.each(
        function(e)
        {
            new Draggable(e, { revert: true, ghosting: true, scroll: window });
        }); */
    
    var cols = lo.select('.dropzone');
    
    cols.each(function(col)
        {
            col.select('.widget').each(setupEditOnLayoutBox);
        });
    
    buildSortable(lo);
}

var setupEditOnLayoutBox = function(lb)
{
    var edit = new Element('div', { 'class': 'edit_dash_widget'});
	var edit2 = new Element('div', { 'class': 'edit_dash_widget'});
	var edit3 = new Element('div', { 'class': 'edit_dash_widget'});
    var reloadlink = new Element('a', { 'class': 'refresh'}).update('Refresh');
    var editlink = new Element('a', { 'class': 'edit_widget'}).update('Edit');
    var dellink = new Element('a', { 'class': 'removecol'}).update('');
    
    var clear = new Element('div', {'class': 'clear'});
    
    edit.insert({bottom: reloadlink});
    edit2.insert({bottom: editlink});
    edit3.insert({bottom: dellink});
    
    var blockdrag = lb.down('.blockdrag');
	var blockTitle = blockdrag.down('div.title');
    blockdrag.insert({bottom: edit3});
    blockdrag.insert({bottom: clear});
	blockdrag.insert({bottom: edit2});
	blockdrag.insert({bottom: edit});
    blockdrag.setAttribute('title', Cognoti.getI18N('dashboard', 'click_to_drag', 'Click to Drag'));
    
    //lb.observe('mouseover', function() { blockdrag.show(); });
    //lb.observe('mouseout', function() { blockdrag.hide(); });
	
    
    reloadlink.observe('click', function() { reloadWidget(lb); });
    editlink.observe('click', function(e) { doEdit(lb, false); Event.stop(e); return false; });
    dellink.observe('click', function(e) { 
        /* if(confirm('Are you sure you would like to remove this block?')) 
        {
            lb.remove(); 
        } */
        
        Cognoti.confirmBubble(dellink, new Element('div').update(Cognoti.getI18N('dashboard', 'remove_widget_confirm', 'Are you sure you would like to remove this widget?')), false,
            ['Yes', 'No'], 
            function(result)
            {
               if(result == 'Yes')
               {
                   new Effect.Puff(lb, {afterFinish: function() { lb.remove(); 
                       Dashboard.triggerEvent('layout-updated', null);
                       monitoredFormChanged(Dashboard.config.form);
                   }});
               }
            },
            {
                relativePlacement: false,
                /* relativePlacementElem: lb, */ 
                right: true
            });
        
        Event.stop(e); 
        return false; 
    });
}

var buildSortable = function(layout)
{
    var list = layout.select('.dropzone');
    
    list.each(function(e)
    {
        Sortable.create(e.identify(), {
            dropOnEmpty: true,
            containment: list,
            constraint: false,
            only: ['button', 'widget'],
            hoverclass: 'hover',
            handle: 'title',
            scroll: window,
            onUpdate: function(a)
            {
                a.highlight();
                
                var colId = a.next('input[name="col_id"]').getValue();
                
                
                a.select('input[name="region"]').each(function(input)
                {
                    input.value = colId;                        
                });
                
                monitoredFormChanged(Dashboard.config.form);
                
                Dashboard.triggerEvent('layout-updated', null);
            }
        });
        
        Droppables.add(e, {
            accept: 'button',
            hoverclass: 'hover',
            onDrop: function(item) {
                
                var info = item.info;
                
                var title = new Element('div').addClassName('blockdrag');//.hide();
                var title2 = new Element('div').addClassName('title').update(info.name);
                title.insert(title2);
                var content = new Element('div').addClassName('widget_content');
                var newitem = new Element('li').addClassName('widget');
                
                var regioninput = new Element('input', { type: 'hidden', name: 'region', value: e.id });
                var paraminput = new Element('input', { type: 'hidden', name: 'parameters', value: info.parameters });
                var prefinput = new Element('input', { type: 'hidden', name: 'preferences', value: info.preferences });
                var widgetidinput = new Element('input', { type: 'hidden', name: 'widgetid', value: info.id });
                var udwidinput = new Element('input', { type: 'hidden', name: 'dwiid', value: '0' });
                var modifiedinput = new Element('input', { type: 'hidden', name: 'modified', value: '1' });

                var clear = new Element('div', { style: 'clear: both' });
                title.insert({bottom: clear});
                
                newitem.insert({bottom: title})
                       .insert({bottom: content}) 
                       .insert({bottom: clear})
                       .insert({bottom: regioninput})
                       .insert({bottom: paraminput})
                       .insert({bottom: prefinput})
                       .insert({bottom: widgetidinput})
                       .insert({bottom: udwidinput})
                       .insert({bottom: modifiedinput});
                       
                if(Dashboard.otherProperties)
                {
                    for(var i in Dashboard.otherProperties)
                    {
                        otherInput = new Element('input', { type: 'hidden', name: i, value: '' });
                        newitem.insert({bottom: otherInput});
                    }
                }
                
                content.wrap('div', { 'class': 'content' });
                   
                e.insert({bottom: newitem});
                
                setupEditOnLayoutBox(newitem);
                
                buildSortable(layout);
                
                doEdit(newitem, true);
            }
        });
    });
}

var LayoutManager = {
    _newColumnCount: 1,
    _newRowCount: 1,
    minColumnWidth: 40,
	seperatorWidth: 5,
	maxColumns: 8,
    browserHackOffset: Prototype.Browser.WebKit ? -1 : 0,
    addRow: function()
    {
        this._addRow(this.rowList);
    },
    setupLayoutRows: function(id)
    {
        var thisObj = this;
        id = $(id);
        
        thisObj.rowList = id.down('.layoutbase');
        thisObj.layoutrows = id.select('.layoutrow'); 
        thisObj.layoutrows.each(function(layoutrow)
            {
                thisObj._configureRow(layoutrow);
            });
        
        thisObj._resetRowSorting();
        thisObj.layoutChanged();
        
        var monitorUpdated = function()
        {
            monitoredFormChanged(Dashboard.config.form);
        }
        
        Dashboard.observer('layout-updated', monitorUpdated);
        Dashboard.observer('widget-edited', monitorUpdated);
        
        Dashboard.observer('stop-column-resize', function() 
        { 
            if(Dashboard.colWidthPopups)
            {
                Dashboard.colWidthPopups.invoke('remove'); 
            }
            
            Dashboard.colWidthPopups = null; 
        });
        
        window.setInterval(thisObj.layoutChanged.bind(this), 1500);
        
    },
    layoutChanged: function()
    {
        var thisObj = LayoutManager;
        thisObj.layoutrows.each(function(layoutrow)
        {
            var maxHeight = layoutrow.dropzones.invoke('setStyle', {'height': 'auto'}).invoke('getHeight').max();
            
            layoutrow.dropzones.invoke('setStyle', { 'height': maxHeight+'px' });
            layoutrow.resizers.invoke('setStyle', { 'height': (maxHeight)+'px' });
        });
    },
    
    _resetRowSorting: function()
    {
        var thisObj = this;
        var s = Sortable.create(thisObj.rowList.identify(), {
            tag: 'div',
            handle: 'rowcontrols',
            scroll: window
        });
    },
    
    _addRow: function(rowparent) 
    {
        var thisObj = this;
        var newRow = new Element('div', { 'class': 'layoutrow' });
        
        var controls = new Element('div', { 'class': 'rowcontrols' })
        controls.insert(new Element('span', { 'class': 'title' }).update('Row'))
				.insert(new Element('span', { 'class': 'small_button_remove' })
				.insert(new Element('a', { 'class': 'removerow', 'href': '#', 'title': Cognoti.getI18N('dashboard', 'remove_row', 'Remove Row') }).update('X')))
				.insert(new Element('span', { 'class': 'small_button' })
                .insert(new Element('a', { 'class': 'addcolumn', 'href': '#', 'title': '+ ' + Cognoti.getI18N('dashboard', 'add_column', 'Add Column') }).update('+ ' + Cognoti.getI18N('dashboard', 'add_column', 'Add Column'))))
				.insert(new Element('div', { 'class': 'clear' }));
        
        var rowId = thisObj._newRowCount++;
        
        newRow.insert(controls)
            .insert(new Element('div', { 'class': 'columns' }))
            .insert(new Element('input', { 'type': 'hidden', 'name': 'row_id', 'value': 'newrow'+rowId }))
            .insert(new Element('div', { 'class': 'clear' }));
        
            
        rowparent.insert(newRow);
        
        thisObj._configureRow(newRow);
        thisObj._addColumn(newRow, true);
        
        thisObj._resetRowSorting();     
        
        thisObj.layoutrows = thisObj.rowList.select('.layoutrow'); 
        
        newRow.scrollTo();
        
    },
    
    _configureRow: function(layoutrow)
    {   
        var thisObj = this;
        var cols = layoutrow.select('.rowcolumn');
        var resizers = layoutrow.select('.rowcolumnsep');
        
        layoutrow.columns = cols;
        layoutrow.dropzones = [];
        
        layoutrow.columns.each(function(col)
            {
                col.dropzone = col.down('ul.dropzone');
                layoutrow.dropzones.push(col.dropzone);
            });
        
        layoutrow.resizers = resizers;
        layoutrow.columnDiv = layoutrow.down('.columns');
        layoutrow.width = layoutrow.columnDiv.getWidth(); // This will return 0 on IE7, unless the div has some sort of dimension set (min-height, etc)  
        layoutrow.controls = layoutrow.down('.rowcontrols');
        layoutrow.identifier = layoutrow.down('input[name="row_id"]').getValue();
        
        thisObj.setupColumns(layoutrow, layoutrow.columns);
        thisObj.setupResizers(layoutrow, layoutrow.resizers);
        
        layoutrow.controls.down('a.addcolumn').observe('click', function(e) { thisObj._addColumn(layoutrow); Event.stop(e); return false; });
        layoutrow.controls.down('a.removerow').observe('click', function(e) { thisObj._removeRow(layoutrow,'',this); Event.stop(e); return false; });

    },
    
    setupColumns: function(layoutrow, columns)
    {
        var thisObj = this;
        columns.each(function(c)
            {
                c.layoutrow = layoutrow;    
                thisObj._addRemoveColumnButton(c);
            });
    },
    
    startResizerFunction: function(draggable, event)
    {
        var layoutrow = draggable.element.layoutrow;
        
        Dashboard.colWidthPopups = [];
        
        var columns = layoutrow.select('.rowcolumn');
        
        var pointerOffset = Event.pointer(event);
        var layoutOffset = layoutrow.cumulativeOffset();
        
        var top = pointerOffset.y - layoutOffset.top;
        
        columns.each(function(c)
        {
            var popup = new Element('div', { 'class': 'colWidthPopup' });
            layoutrow.insert(popup);
            popup.column = c;
            Dashboard.colWidthPopups.push(popup);
            
            popup.setStyle({
                top: top+'px' 
            });
        });
    },
    resizerFunction: function(draggable)
    {
        var thisObj = this;
        var offset = draggable.currentDelta()[0];
        var resizer = draggable.element;
        
        var prev = resizer.previous('.rowcolumn');
        var next = resizer.next('.rowcolumn');
        var layoutrow = resizer.layoutrow;

        //limit offset
        
        var prevWidth = prev.getWidth();
        var nextWidth = next.getWidth();

        var mw = thisObj.minColumnWidth;
        
        if(prevWidth - mw + offset < 0)
        {
            offset = -(prevWidth - mw);
        }
        else if(nextWidth - mw < offset)
        {
            offset = nextWidth - mw;
        }
        
        var percentShift = (offset / layoutrow.width) * 100;

        if(prevWidth + offset > mw && nextWidth - offset > mw)
        {
            thisObj._setColWidth(prev, (prevWidth + offset), true);
            thisObj._setColWidth(next, (nextWidth - offset), true);
        }
        
        /* prev.setStyle({ width: ((prevWidth / layoutrow.width) * 100 + percentShift) + '%'});
        next.setStyle({ width: ((nextWidth / layoutrow.width) * 100 - percentShift) + '%'}); */
        
        resizer.setStyle({left: 0 });
        
        //column width popups

        Dashboard.colWidthPopups.each(function(popup)
        {
            var pctWidth = parseFloat(popup.column.down('input[name="col_width"]').getValue());
            var colWidth = popup.column.getWidth();
            
            popup.update((Math.round(pctWidth*10) / 10)+'%')
                .insertBreak()
                .insert(colWidth+'px');
            
            
            var offset = popup.column.positionedOffset();
            var popupWidth = popup.getWidth();
            
            
            var left = offset.left + ((colWidth - popupWidth) / 2);
            
            popup.setStyle({
                left: left+'px'
            });
            
        });
        
        
    },

    setupResizers: function(layoutrow, resizers)
    {
        var thisObj = this;
        var startResizerFunction = function(resizer, e) { thisObj.startResizerFunction(resizer, e) };
        var resizerFunction = function(resizer) { thisObj.resizerFunction(resizer) };
        resizers.each(function(r)
            {
                r.layoutrow = layoutrow;
                r.drag = new Draggable(r, { 
                    constraint: 'horizontal',
                onStart: startResizerFunction,
                change: resizerFunction,
                onEnd: function(d) { resizerFunction(d); Dashboard.triggerEvent('stop-column-resize'); Dashboard.triggerEvent('layout-updated', null); } 
                 });
                
            });
    },
    _addRemoveColumnButton: function(column)
    {
        var thisObj = this;
        var button = new Element('a', { 'class': 'removecolumn', 'href': '#', 'title': Cognoti.getI18N('dashboard', 'remove_column', 'Remove Column')}).insert(new Element('span').update(''));
        
        column.insert({top: button});
        
        button.observe('click', function(e) { thisObj._removeColumn(this, column); Event.stop(e); return false;});
        
    },

    _addColumn: function(layoutrow, first)
    {
		var thisObj = this;
		if(layoutrow.columns.length >= thisObj.maxColumns)
			return;
	
        var columnIdentifier = 'newcol'+thisObj._newColumnCount++;
        var newColumn = new Element('div', { 'class': columnIdentifier+' rowcolumn' })
            .insert(new Element('ul', { 'class': 'col main dropzone' }))
            .insert(new Element('input', { 'type': 'hidden', 'name': 'col_id', 'value': columnIdentifier }))
            .insert(new Element('input', { 'type': 'hidden', 'name': 'col_width' }))
            .insert(new Element('input', { 'type': 'hidden', 'name': 'col_row',  'value': layoutrow.identifier}));
        
            
        thisObj.setupColumns(layoutrow, [newColumn]);
            
        if(!first)
        {
            var newResizer = new Element('div', { 'class': 'rowcolumnsep' });
            thisObj.setupResizers(layoutrow, [newResizer]);
        }

        var stripValue = first ? 0 : Math.floor((thisObj.minColumnWidth + thisObj.seperatorWidth) / layoutrow.columns.length);
		var stripValueAdd = first ? 0 : (thisObj.minColumnWidth + thisObj.seperatorWidth) % layoutrow.columns.length;
		
		var pushOver = 0;
		var first = true;
        layoutrow.columns.each(function(col)
            {
                var width = col.getWidth();

				var chopValue = stripValue + pushOver;
				pushOver = 0;
				
				if(first == true)
				{
					chopValue = chopValue + stripValueAdd;
					first = false;
				}
				
				if (width < chopValue)
				{
					pushOver = chopValue - width;
					chopValue = width;
				}
				
				thisObj._setColWidth(col, width - chopValue, true);

            });
        
        thisObj._setColWidth(newColumn, first ? layoutrow.width : (thisObj.minColumnWidth), true);
        
        if(!first)
        {
            layoutrow.columnDiv.insert(newResizer);
            layoutrow.columnDiv.insert(new Element('div', { 'class': 'rowcolumnsep2' }));
        }
        layoutrow.columnDiv.insert(newColumn);
        
        if(!first)
        {
            layoutrow.resizers = layoutrow.select('.rowcolumnsep');
        }
        
        layoutrow.columns = layoutrow.select('.rowcolumn');
        layoutrow.dropzones = [];
        
        layoutrow.columns.each(function(col)
            {
                col.dropzone = col.down('ul.dropzone');
                layoutrow.dropzones.push(col.dropzone);
            });
        
        thisObj.layoutChanged();
        
        buildSortable(Dashboard.config.layout);
        
    },
	_redistributeColumns: function(layoutrow)
	{
		//Finds how far off the width of the columns is from the width of the row
		var thisObj = this;
		var totalWidth = layoutrow.width;
		layoutrow.columns.each(function(col)
        {
			totalWidth = totalWidth - col.getWidth();
		});
		totalWidth = totalWidth - thisObj.seperatorWidth * (layoutrow.columns.length - 1);
		//Add code to fix it, down here
	},
    _setColWidth: function(column, width, asPx)
    {
		column.setStyle({ 'width': width + 'px' });
        width = width / (column.layoutrow.width + this.browserHackOffset) * 100.0;
        column.down('input[name="col_width"]').setValue(width);
    },
    _removeColumn: function(button, column)
    {
        var thisObj = this;
        
        var layoutrow = column.layoutrow;
        
        if(layoutrow.columns.length == 1)
        {
            thisObj._removeRow(layoutrow, Cognoti.getI18N('dashboard', 'remove_column_row_confirm', 'Removing the last column will remove the entire row. Would you still like to remove this row?'), button);        
        }
        else if(!button.bubble || !button.bubble.visible())
        {
            button.bubble = confirmBubble(button, Cognoti.getI18N('dashboard', 'remove_column_confirm', 'Are you sure you would like to remove this column?'), ['Yes', 'No'],
                function(result)
                {
                    if(result == 'Yes')
                    {
						var width = column.getWidth() + thisObj.seperatorWidth;
                        //move items from columns into 'lost bin'
                        
                        var targetResizer = column.next('.rowcolumnsep') || column.previous('.rowcolumnsep');
                        targetResizer.drag.destroy();
                        targetResizer.remove();
                        
                        var rowSep2 = column.next('.rowcolumnsep2') || column.previous('.rowcolumnsep2');
                        if(rowSep2)
                        {
                            rowSep2.remove();
                        }
                        
                        var adjCol = column.next('.rowcolumn') || column.previous('.rowcolumn');
                        column.remove();
                        
                        layoutrow.resizers = layoutrow.select('.rowcolumnsep');
                        layoutrow.columns = layoutrow.select('.rowcolumn');
                        layoutrow.dropzones = [];

						thisObj._setColWidth(adjCol, adjCol.getWidth() + width, true);
                    }
                }
                );
        }
		
        thisObj.layoutChanged();
    },
    
    _removeRow: function(layoutrow, text, target)
    {
        var thisObj = this;
        target = target || layoutrow;
        
        if(!target.bubble || !target.bubble.visible())
        {
            target.bubble = confirmBubble(target, text || Cognoti.getI18N('dashboard', 'remove_row_confirm', 'Are you sure you would like to remove this row?'), ['Yes', 'No'],
                function(result)
                {
                    
                    if(result == 'Yes')
                    {
                        layoutrow.resizers.each(function(r)
                            {
                                //unset draggables
                                r.drag.destroy();    
                            });
                        
                        //move items from columns into 'lost bin'
                        
                        layoutrow.remove();
                        
                        thisObj.layoutrows = thisObj.rowList.select('.layoutrow'); 
                        
                    }
                });
        }
    }
    
}

