BASE_SETUP_URL = "/dashboard/setup/"

var command = "";
var dashboard_id;

/**
 * Function to insegate the various actions on a dashboard
 */
function dashboardAction(requested_command, active_dashboard_id)
{
    // Set globals, command and dashboard_id so we can access them elsewhere
    command = requested_command;
    dashboard_id = active_dashboard_id;
    
    // Check dashboard command
    if (command == "copy" || command == "create") {
        // define notice areas and create appropriate url
        if (command == 'copy') {
            var error_notice = $('error_notice_copy');
            if (dashboard_id) {
                var url = BASE_SETUP_URL + command + "/" + dashboard_id + "/";
            } else {
                alert("Cannot determine which dashboard you want to copy");
            }
        } else if (command == 'create') {
            var error_notice = $('error_notice_create');
            var url = BASE_SETUP_URL + command + "/" ;
        }
        var notice = $('notice');
        
        // Ajax request to call python and redirect/display error as needed
        new Ajax.Request(url, {
            method: "post",
            asynchronous: true,
            onSuccess: function(transport) {
                if (transport.status == 200) {
                    // Follow redirect
                    window.location = transport.responseText;
                } else {
                    //display error msg
                    error_notice.update(transport.responseText).addClassName('status_problem').show();
                }
                
                Menu.postAjaxUpdate(transport);
            },
            onFailure: function(transport) {
               //display error msg
               error_notice.update(transport.responseText).addClassName('status_problem').show();
            }
        });
    } else if (dashboard_id || dashboard_id == 1) {
        
        var setup_url = BASE_SETUP_URL + command + "/" + dashboard_id  + "/";
        
        if (command == 'delete' || command == 'undo_delete') {
            window.location = setup_url;
        } else if (command == 'edit') {
            
            hideAll();
            $('setup').show();
            
            new Ajax.Updater("setup", setup_url, {
                method: 'GET',
                asynchronous: true,
                evalScripts: true,
                onSuccess: function (transport) {
                    Menu.postAjaxUpdate(transport);
                },
                onComplete: function (transport) {
                    if (document.getElementById('id_dashboard_name'))
                        $("id_dashboard_name").select();
                    if (typeof reinitializeDashboardView!= "undefined") {
                        reinitializeDashboardView();
                    }
                }
            });
        } else {
            alert("Cannot determine what you are trying to do");
        }
    } else {
        alert("Some information is missing to do that job");
    }
}

/**
 * This function just hides the setup screen, and shows the dashboard
 * Currently, it's not part of the history manager, so whatever calls this
 * 'breaks the back button'.
 */
function hideSetup()
{
    $('dashboard').show();
    $('setup').hide();
}

/**
 *
 * Get all list elements from layout in setup
 *
 */
function get_layout_list()
{
    var items = $('layout_area').childNodes;
    
    var widget_ordered_list = [];
    
    for (i=0; i<items.length; i++) {
        widget_ordered_list[i] = items[i].id;
    }
    
    return widget_ordered_list;
}

/**
 * This function comes in to add the selected widget to the list of widgets
 * on the dashboard.
 * command in the prototype library to do this type of thing. Or, build up the
 * DOM properly.
 */
function addToDashboard(widget_template_id, widget_template_name, widget_type_id)
{
    var layoutArea = $('layout_area');
    
    var newWidget = new Element('div', { 'class' : 'mini_widget', 'id' : 'new_widget_' + widget_template_id });
        newWidget.setStyle({
            width: "0px"
        });
        
    var newWidgetContent = new Element("div", {"class": "widgetLayout"}).update("<p>"+widget_template_name+"</p><div><img src='/images/previews/"+widget_type_id+".png'/></div>");
    var newWidgetRemover = new Element("div", {"class" : "widgetRemove"}).update("<div title='Remove this Widget' onclick=\"remove_from_layout('new_widget_" + widget_template_id + "')\">Remove This Widget</div>");
    
    newWidget.appendChild(newWidgetContent);
    newWidget.appendChild(newWidgetRemover);
    
    layoutArea.appendChild(newWidget);
    
    new Effect.Morph(newWidget, {
        style: "width: 228px",
        duration: 0.3,
        beforeStart: function(object) {
            object.element.style.display = "";
        },
        afterFinish: function() {
            createSortableWidgetList();
        }
    });
    
    // if there was an error box, hide it again
    $('error_notice').hide();
}

/**
 * Remove widget from list
 **/
function remove_from_layout(id)
{
    var element = $(id);
    
    new Effect.Morph(element, {
        style: "width: 0px; opacity: 0",
        duration: 0.2,
        afterFinish: function() {
            $("layout_area").removeChild(element);
        }
    })
}

/**
 * Ajax call to save new layout and name
 **/
function save_in_setup(dashboard_id)
{
    var widget_ordered_list = get_layout_list();
    var params = { }, i = 0;
    var dashboard_name = $('id_dashboard_name').getValue();
    
    // if there's no name, we've already failed
    if (dashboard_name.length < 1) {
        $('error_notice').update("<span>There were errors with your dashboard. See above for details.</span>").addClassName('problem').addClassName('status').addClassName('box').show();
        return;
    }
    
    var ok_button = $('guided_edit_ok');
    var cancel_button = $('guided_edit_cancel');
    
    // Disable the "OK" button
    ok_button.disabled = true;
    if (cancel_button) cancel_button.disabled = true;
    
    // create a parameter object with keys for the order, and values for the widgets
    for (; i < widget_ordered_list.length; i++) {
        params[i+1] = widget_ordered_list[i];
    }
    
    params["dashboard_name"] = dashboard_name;
    
    var url = "/dashboard/save_layout/" + dashboard_id + "/";
    new Ajax.Request(url, {
        method: 'POST',
        parameters: params,
        asynchronous: true,
        onSuccess: function(transport) {
            if (transport.status == 200)
                window.location = transport.responseText;
            else {
                // if we're here, re-enable the "OK" button
                ok_button.disabled = false;
                if (cancel_button) cancel_button.disabled = false;
                
                $('error_notice').update(transport.responseText).addClassName('problem').addClassName('status').addClassName('box').show();
            }
            Menu.postAjaxUpdate();
        },
        onFailure: function(transport) {
            // if we're here, re-enable teh "OK" button
            ok_button.disabled = false;
            if (cancel_button) cancel_button.disabled = false;
            
            var container = $('error_notice');
            
            //I'm fairly sure this is ugly but!!!
            if(transport.responseText.substring(0,4)=='<tr>') {
                // First, show the error message by updating the form,
                // then create a text message to alert the user about
                // the error you created. DRAFT 1!
                $('dashboard_name_form').update(transport.responseText);
                
                var newErrorElement = new Element("span").update("There were errors with your dashboard. See above for details.");
                
                // Remove any children
                while (container.firstChild) container.removeChild(container.firstChild);
                
                // And append the new guy in there
                container.appendChild(newErrorElement);
                
                // Finally, make it shine!
                new Effect.Appear(container, {duration: 0.3});
            } else {
                container.update(transport.responseText).addClassName('problem').addClassName('status').addClassName('box').show();
            }
        }
    });
}

/**
 * Enable the template selection mode
 */
function prepareTemplateMode(event)
{
    var clicked = Event.element(event);
    
    if (!clicked.hasClassName("selected")) {
        $$(".guided").each(function(f) {
            f.hide();
        });
        
        $('predefined_layout_area').update();
        
        $$(".predefined").each(function(f) {
            f.show();
        });
        
        $$("#mode_select li.selected").each(function(element) {
            element.removeClassName("selected")
        });
        
        clicked.up("li").addClassName("selected");
        
    }
}

/**
 * Enable the new dashboard creation mode
 */
function prepareNewDashboardMode(event)
{
    var clicked = Event.element(event);
    
    // Clear Selected...
    $$("#predefined_dashboard_links li.selected").each(function(element) {
        element.removeClassName("selected");
    });
    
    if (!clicked.hasClassName("selected")) {
        
        // Hide the message box
        $("predefined_message").hide();
        
        $$(".predefined").each(function(f) {
            f.hide();
        });
        
        currentBkey = null;
        
        $$(".guided").each(function(f) {
            f.show()
        });
        
        $$("#mode_select li.selected").each(function(element) {
            element.removeClassName("selected")
        });
        
        clicked.up("li").addClassName("selected");
        
        $("template_name").update("Select a Template Above");
        $("predefined_edit_ok").disabled = true;
    }
}

function showPredefinedDetailsFor(event, bkey)
{
    // Global variable for the selected predefined dashboard.
    currentlySelectedPredefined = null;
    var targetContainer = $('predefined_layout_area');
    var clicked = Event.element(event);
    var para = clicked.next('p');
    
    $$("#predefined_dashboard_links li.selected").each(function(element) {
        element.removeClassName("selected");
        if (element.down('p')) element.down('p').hide();
    });
    
    if (para) para.show();
    
    // remove the old ones & put in loading balls
    Menu.createLoadingImg(targetContainer.update());
    
    // show the message box
    var messageBox = $('predefined_message');
    if (!(messageBox.style.display == null || messageBox.style.display == "block")) {
        messageBox.appear();
    }
    
    new Ajax.Request("/dashboard/j/"+bkey+"/", {
        method: 'get',
        asynchronous: false,
        onSuccess: function(transport) {
            
            // Cleaning out any loading images, etc.
            Menu.removeLoadingImg(targetContainer);
            
            currentlySelectedPredefined = transport.responseText.evalJSON(true);
            currentBkey = bkey;
            
            var widgetListSize = currentlySelectedPredefined.widgets.length;
            for (var i = 0; i < widgetListSize; i++) {
                // Put each widget's sig. in the layoutArea box
                var widgetPreviewContainer = new Element('div', {'class': 'mini_widget no-move', 'id':'new_widget_'+i}),
                    widgetLayoutContainer = new Element('div', {'class': 'widgetLayout'}),
                    titleParagraph = new Element('p').update(currentlySelectedPredefined.widgets[i].data._display_title),
                    imageContainer = new Element('div'),
                    image = new Element('img', {'src':'/images/previews/'+currentlySelectedPredefined.widgets[i].data._widget_widget_type+'.png'});
                    
                    imageContainer.appendChild(image);
                    
                    widgetLayoutContainer.appendChild(titleParagraph);
                    widgetLayoutContainer.appendChild(imageContainer);
                    
                    widgetPreviewContainer.appendChild(widgetLayoutContainer);
                    
                    targetContainer.appendChild(widgetPreviewContainer);
                    
                    // Change labels and fields
                    $("template_name").update(clicked.innerHTML + " Layout Preview");
                    $("predefined_edit_ok").disabled = false;
            }
            
            targetContainer.appendChild(new Element("div", {"class": "clear"}));
        },
        onFailure: function(transport) {
            alert('Problem loading widgets. Please try again in a few moments.');
            
        }
    });
    
    clicked.up("li").addClassName("selected");
}

/**
 * This function is used to make the list of selected widgets able to be sorted
 */
function createSortableWidgetList()
{
    Sortable.create('layout_area', {
        tag: 'div',
        only: 'mini_widget',
        constraint: ''
    });
}

var BROWSER_WIDGET_COLUMN = 3,
    BROWSER_CATEGORY_Y_COLUMN = 2,
    BROWSER_CATEGORY_X_COLUMN = 1,
    BROWSWER_ANALYSIS_TYPE_COLUMN = 0;

/**
 * This function is written especially for menu to handle the clicking on the
 * analysis types (Top, Crosstab, Trend, etc.). It disables everything, then
 * figures out what should actually be shown. For non-analysis types (news, etc.)
 * it immediately gets the widgets.
 *
 * NOTE: fairly verbose, so it's easy to tweak until everyone makes up their minds.
 *
 * Returns nothing
 */
function analysisSelection(event)
{
    // find the item in question, based on the element's id
    var clicked = Event.element(event),
        pos = 0,
        colValue = null,
        params = {};
        
    for (; pos < this.items.length; pos++) {
        if (clicked.id == this.items[pos].machineName)
            break;
    }
    
    colValue = this.items[pos].value+"";
    
    // Disable the widget list ..
    widget_browser.columns[BROWSER_WIDGET_COLUMN].clearItems();
    widget_browser.columns[BROWSER_WIDGET_COLUMN].disable();
    widget_browser.columns[BROWSER_WIDGET_COLUMN].updateList();
    
    // .. X Category column, ..
    widget_browser.columns[BROWSER_CATEGORY_X_COLUMN].clearItems();
    widget_browser.columns[BROWSER_CATEGORY_X_COLUMN].disable();
    widget_browser.columns[BROWSER_CATEGORY_X_COLUMN].addItem(new ColumnItem("&rarr;", null, true, function(event){}));
    widget_browser.columns[BROWSER_CATEGORY_X_COLUMN].updateList();
    widget_browser.columns[BROWSER_CATEGORY_X_COLUMN].updateComplete();
    
    // .. and finally Y Category column
    widget_browser.columns[BROWSER_CATEGORY_Y_COLUMN].clearItems();
    widget_browser.columns[BROWSER_CATEGORY_Y_COLUMN].disable();
    
    /**
     * If the column value is the following, do the listed actions:
     * top(1) = set category x events to get the widget list, hide category y
     * crosstab(2) = set cat x events to load cat y, set y to get widget list
     * trend(3) = set cat x events to get the widget list, hide cat y
     * 5-8 = clicking the analysis type goes straight to the widget list.
     */
    switch (colValue) {
        case "1": // Top ID
        case "3": // Trend ID
            
            // Put the arrow in the second column
            widget_browser.columns[BROWSER_CATEGORY_Y_COLUMN].addItem(new ColumnItem("&rarr;", null, true, function(event){}));
            widget_browser.columns[BROWSER_CATEGORY_Y_COLUMN].updateList();
            widget_browser.columns[BROWSER_CATEGORY_Y_COLUMN].updateComplete();
            
            // tell the widget box to say "select a category"
            widget_browser.columns[BROWSER_WIDGET_COLUMN].clearItems();
            widget_browser.columns[BROWSER_WIDGET_COLUMN].setLabel("Widget Name");
            widget_browser.columns[BROWSER_WIDGET_COLUMN].disable();
            widget_browser.columns[BROWSER_WIDGET_COLUMN].addItem(new ColumnItem("Select A Category", "widget_info_msg", true, function(event){}));
            widget_browser.columns[BROWSER_WIDGET_COLUMN].updateList();
            widget_browser.columns[BROWSER_WIDGET_COLUMN].updateComplete();
            
            widget_browser.columns[BROWSER_CATEGORY_X_COLUMN].enable();
            widget_browser.columns[BROWSER_CATEGORY_X_COLUMN].clearItems();
            widget_browser.columns[BROWSER_CATEGORY_X_COLUMN].updateList();
            getCategoryList(BROWSER_CATEGORY_X_COLUMN, params, function(event){
                    var params = widget_browser.getColumnValues();
                    getWidgetList(BROWSER_WIDGET_COLUMN, params);
            });
            break;
        
        case "2": // Crosstab ID
            // Need to load up the other list only after something in the first
            // list is selected.
            
            // Empty this list out
            widget_browser.columns[BROWSER_WIDGET_COLUMN].clearItems();
            widget_browser.columns[BROWSER_WIDGET_COLUMN].setLabel("Row By Column Widget Name");
            widget_browser.columns[BROWSER_WIDGET_COLUMN].updateList();
            widget_browser.columns[BROWSER_WIDGET_COLUMN].updateComplete();
            
            // set the y-column with instructions
            widget_browser.columns[BROWSER_CATEGORY_Y_COLUMN].addItem(new ColumnItem("Select Row Category", "widget_info_msg", true, function(event){}));
            widget_browser.columns[BROWSER_CATEGORY_Y_COLUMN].updateList();
            widget_browser.columns[BROWSER_CATEGORY_Y_COLUMN].updateComplete();
            
            widget_browser.columns[BROWSER_CATEGORY_X_COLUMN].enable();
            widget_browser.columns[BROWSER_CATEGORY_X_COLUMN].clearItems();
            widget_browser.columns[BROWSER_CATEGORY_X_COLUMN].updateList();
            
            getCategoryList(BROWSER_CATEGORY_X_COLUMN, params, function(event){
                // First, clear out any y-values (in case another x-value is
                // selected)
                widget_browser.columns[BROWSER_CATEGORY_Y_COLUMN].clearItems();
                widget_browser.columns[BROWSER_CATEGORY_Y_COLUMN].updateList();
                
                // tell the widget column to say 'select another category'
                widget_browser.columns[BROWSER_WIDGET_COLUMN].clearItems();
                widget_browser.columns[BROWSER_WIDGET_COLUMN].disable();
                widget_browser.columns[BROWSER_WIDGET_COLUMN].addItem(new ColumnItem("Select Column Category", "widget_info_msg_another", true, function(event){}));
                widget_browser.columns[BROWSER_WIDGET_COLUMN].updateList();
                widget_browser.columns[BROWSER_WIDGET_COLUMN].updateComplete();
                
                var params = widget_browser.getColumnValues();
                getCategoryList(BROWSER_CATEGORY_Y_COLUMN, params,function(event){
                    var params = widget_browser.getColumnValues();
                    getWidgetList(BROWSER_WIDGET_COLUMN, params);
                    
                });
                
            });
            break;
        
        default: // Anything Else ID
            widget_browser.columns[BROWSER_WIDGET_COLUMN].setLabel("Widget Name");
            widget_browser.columns[BROWSER_CATEGORY_Y_COLUMN].addItem(new ColumnItem("&rarr;", null, true, function(event){}));
            widget_browser.columns[BROWSER_CATEGORY_Y_COLUMN].updateList();
            widget_browser.columns[BROWSER_CATEGORY_Y_COLUMN].updateComplete();
            
            params[widget_browser.columns[BROWSWER_ANALYSIS_TYPE_COLUMN].columnContainerId] = widget_browser.columns[BROWSWER_ANALYSIS_TYPE_COLUMN].value;
            getWidgetList(BROWSER_WIDGET_COLUMN, params);
            
            break;
    }
    
    return;
}

/**
 * This performs an AJAX request to retrieve the categories and load them based
 * on the following:
 *
 * forLocation - the offset for the column where the data is to be loaded
 * withParameters - any special values to give to the request (category and anal. types)
 * func - the thing the column items should do (on success)
 * 
 * Returns nothing
 */
function getCategoryList(forLocation, withParameters, func)
{
    new Ajax.Request("/dashboard/setup/edit/"+dashboard_id+"/get_categories/", {
        method: 'get',
        parameters: withParameters,
        asynchronous: true,
        onSuccess: function(transport) {
            
            var contents = transport.responseText.evalJSON(true),
                i = 0;
            
            // Turn on the widget browser column
            widget_browser.columns[forLocation].enable();
            widget_browser.columns[forLocation].clearItems();
            
            for(; i < contents.length; i++) {
                
                // mainly interested in .fields.category_name, and .pk
                var colItem = new ColumnItem(contents[i].fields.category_name.toString(), contents[i].pk, true, func);
                widget_browser.columns[forLocation].addItem(colItem);
                
            }
            
            // upate the list after the AJAX has completed. also remove loading class
            widget_browser.columns[forLocation].updateList();
            widget_browser.columns[forLocation].updateComplete();
        },
        onFailure: function (transport) {
            alert("There was a slight problem loading your category list. To continue, re-select your analysis type.");
        }
    });
    
}

/**
 * loads the widget list based on the specified parameters (via AJAX):
 * - forLocation - the offset for the column where the data is to be loaded
 * - withParams - an object hash containing all the pertinent parameters
 *
 * Returns nothing
 */
function getWidgetList(forLocation, withParameters)
{
    // Shortcut :if the two selected categories are the same, tell them to pick
    // something else
    var category_x, category_y;
    for (var value in withParameters ) {
        if (value == "category_x") {
            category_x = withParameters[value];
            
        } else if (value == "category_y") {
            category_y = withParameters[value];
        }
    }
    
    if (category_x == category_y && typeof category_x != 'undefined') {
        var emptyBi = new ColumnItem("No Widgets Match", null, true, function(event) {});
        widget_browser.columns[forLocation].disable();
        widget_browser.columns[forLocation].clearItems();
        widget_browser.columns[forLocation].addItem(emptyBi);
        widget_browser.columns[forLocation].updateList();
        return;
    }
    
    new Ajax.Request("/dashboard/setup/edit/"+dashboard_id+"/get_widgets/", {
        method: 'get',
        parameters: withParameters,
        asynchronous: true,
        onSuccess: function(transport) {
            
            var contents = transport.responseText.evalJSON(true);
            
            if (contents.length) {
                widget_browser.columns[forLocation].enable();
                widget_browser.columns[forLocation].clearItems();
                for(var i = 0; i < contents.length; i++) {
                    var widget_type_id = contents[i].fields.widget_type;
                    // mainly interested in .fields.widget_template_name, .fields.description and .pk (the ID)
                    var colItem = new ColumnItem(contents[i].fields.widget_template_name.toString(), contents[i].pk, true, function(event){
                        var clicked = Event.element(event),
                            pos = 0;
                        
                        for (; pos < this.items.length; pos++) {
                            if (clicked.id == this.items[pos].machineName)
                                break;
                        }
                        
                        // you have the position of the browser item. get it's data
                        // and populate
                        addToDashboard(this.items[pos].value, this.items[pos].name, widget_type_id);
                        
                        // flicker it
                        new Effect.Highlight(this.items[pos].machineName, {
                            duration: 0.3,
                            endcolor: "#DEE5D8",
                            beforeStart: function(object) {
                                object.element.style.color = "#000000";
                            },
                            afterFinish: function(object) {
                                object.element.style.backgroundColor = "";
                                object.element.style.color = "";
                            }
                        });
                    });
                    colItem.setDescription("Click to add this widget to your dashboard layout.")
                    widget_browser.columns[forLocation].addItem(colItem);
                }
            } else {
                var emptyBi = new ColumnItem("No Widgets Match", null, true, function(event) {});
                widget_browser.columns[forLocation].disable();
                widget_browser.columns[forLocation].clearItems();
                widget_browser.columns[forLocation].addItem(emptyBi);
            }
            
            // update the list after the AJAX is completed. remove any loading class
            widget_browser.columns[forLocation].updateList();
            widget_browser.columns[forLocation].updateComplete();
        },
        onFailure: function (transport) {
            alert("There was a slight problem loading your widget list. To continue, re-select your analysis type.");
        }
    });
}
