/* $Id: toolbar.js,v 1.4 2011-12-08 11:06:10 lan Exp $ */
/*
 * Toolbars-related functions 
 */
var toolbarActions = new Array();
var dynamicToolbarActions = new Array();
var userToolbarActions = [];
var journalBox = null;
var contextToolbarActions = new Array();

/*
 * Init toolbar
 */
function initToolbar()
{
    // load actions
    queryBioUML("web/action", 
    {
        type: "toolbar"
    }, function(data)
    {
        var actions = data.actions;
        for (i = 0; i < actions.length; i++) 
        {
            var actionProperties = new Action();
            actionProperties.parse(actions[i]);
            toolbarActions[i] = actionProperties;
        }
        updateToolbar();
    });
    initJournals();
    initDynamicActions();
    initUserToolbarActions();
    createTreeItemDroppable($('#mainToolbar'), null, function(path)
	{
        for(var i in userToolbarActions)
    	{
    		if(userToolbarActions[i].path === path) return;
    	}
    	userToolbarActions.push(createUserToolbarAction(path));
        var userToolbarPreference = "";
        $.each(userToolbarActions, function(index, value){userToolbarPreference += value.path + ";";});
        setPreference("UserToolbar", userToolbarPreference); 
    	updateToolbar();
	});
	$(document.body).delegate(".fg-button:not(.ui-state-disabled)", "mouseover", function()
			{
				$(this).addClass("ui-state-hover");
			}).delegate(".fg-button:not(.ui-state-disabled)", "mouseout", function()
			{
				$(this).removeClass("ui-state-hover");
			}).delegate(".fg-button:not(.ui-state-disabled)", "mousedown", function()
		    {
		        $(this).parents('.fg-buttonset-single:first').find(".fg-button.ui-state-active").removeClass("ui-state-active");
		        if ($(this).is('.ui-state-active.fg-button-toggleable, .fg-buttonset-multi .ui-state-active')) 
		        {
		            $(this).removeClass("ui-state-active");
		        }
		        else 
		        {
		            $(this).addClass("ui-state-active");
		        }
		    }).delegate(".fg-button:not(.ui-state-disabled)", "mousedown", function()
		    {
		        if (!$(this).is('.fg-button-toggleable, .fg-buttonset-single .fg-button,  .fg-buttonset-multi .fg-button')) 
		        {
		            $(this).removeClass("ui-state-active");
		        }
		    });
}

function initUserToolbarActions()
{
    userToolbarActions = [];
    var toolbarPrefValue = getPreference("UserToolbar");
    if(toolbarPrefValue != null)
    {
        var toolbarActions = toolbarPrefValue.split(";");
        var addedActions = [];
        var callback = _.after(toolbarActions.length, function()
        {
        	_.each(addedActions, function(action)
        	{
        		if(action) userToolbarActions.push(action);
        	});
        	updateToolbar();
        });
        _.each(toolbarActions, function(action, idx)
        {
            if(action == "") callback();
            else
            {
                getDataCollection(getElementPath(action)).getElementInfo(getElementName(action), function(info)
                {
                    if (info != null) 
                    	addedActions[idx] = createUserToolbarAction(action);
                    callback();
                });
            }
        });
    } else updateToolbar();
}

function createUserToolbarAction(element)
{
	return {
	    id: "action_"+element,
	    path: element,
	    label: getElementName(element),
	    icon: getNodeIcon(getDataCollection(getElementPath(element)), getElementName(element)).replace(/^url\(\'/, "").replace(/\'\)/,""),
	    visible: function() { return true; },
	    action: function() { openDocument(element); },
	    doAction: function() { openDocument(element); }
	};
}

function initJournals()
{
	queryBioUML("web/journal", {action: "init"}, function(data){
        
        journalBox = $('<select id="journalComboBox" class="ui-state-default" style="font-size: 10pt;float:right;"></select>');
    	journalBox.width(150);
    	journalBox.height(24);
    	journalBox.children('option').remove();
    	journalBox.append('<option id="-">-</option>');
        var current = "-";
        if(data.values.current)
            current = data.values.current;
        var names = data.values.names;
        for (i = 0; i < names.length; i++) 
        {
        	if (names[i].length > 0) 
            {
                journalBox.append('<option id="' + names[i] + '">' + names[i] + '</option>');
            }
        }
        updateToolbar();
            
        if (journalBox != null) 
        {
            journalBox.val(current);
            // journalBox.trigger("change");
        }
    });
}

function getDefaultResearchPath()
{
    if ( journalBox != null ) 
    {
        var name = journalBox.val().match(/:\s*([^\s].+)$/);
        if( name != null && name.length > 1 )
            return path = createPath(appInfo.userProjectsPath, name[1]) + "/Data"; 
        else
            return null;
    }
}

/*
 * Update main toolbar actions
 */
function updateToolbar()
{
    var toolbar = $('#mainToolbar');
    toolbar.children('.fg-buttonset').remove();
    toolbar.children('.fg-rightcomponent').remove();
    
    var block = $('<div class="fg-buttonset ui-helper-clearfix"></div>');
    for (var i = 0; i < toolbarActions.length; i++) 
    {
        if (toolbarActions[i].id) 
        {
            var doc = getActiveDocument();
            var visible = toolbarActions[i].isVisible(doc);
            if (visible !== -1) 
            {
                var action = createToolbarButton(toolbarActions[i].label, toolbarActions[i].icon, toolbarActions[i].doAction);
                setToolbarButtonEnabled(action, visible);
                block.append(action);
            }
        }
        else 
        {
            toolbar.append(block);
            block = $('<div class="fg-buttonset ui-helper-clearfix"></div>');
        }
    }
    toolbar.append(block);
    
    block = $('<div class="fg-buttonset ui-helper-clearfix" id="dynamicToolbarBlock"></div>');
    toolbar.append(block);
    
    updateDynamicToolbar();
    
    var block2 = $('<div class="fg-rightcomponent ui-helper-clearfix"></div>');
    
    // Perspective selector
    if(perspectiveNames.length > 1)
    {
	    var perspectiveSelector = $('<select class="ui-state-default" style="font-size: 10pt;float:right;"/>').height(24);
	    for(var i=0; i<perspectiveNames.length; i++)
		{
	    	perspectiveSelector.append($('<option/>').text(perspectiveNames[i]));
		}
	    perspectiveSelector.val(perspective.name);
	    perspectiveSelector.change(function()
	    {
	    	queryBioUML("web/perspective", {name: perspectiveSelector.val()}, function(data)
	    	{
	    		setPerspective(data);
	    		updateRepositoryTabs();
	    		initTreeActions();
	    		updateViewParts();
	    		initIntro();
	    	});
	    });
	    block2.append(perspectiveSelector);
    }
    
    if(journalBox != null)
    {
    	block2.append(journalBox);
    }
    $("#userToolbarContextMenu").remove();
    var menuUL = $('<div id="userToolbarContextMenu" class="contextMenu"><ul><li id="remove_toolbar_item"><img src="icons/remove.gif">'+resources.commonTooltipRemoveUserButton+'</li></ul></div>');
    $('body').append(menuUL);
    for (var i = 0; i < userToolbarActions.length; i++) 
    {
        var action = $('<span class="fg-button ui-state-default fg-button-icon-solo  ui-corner-all"><span class="fg-button-icon-span" style="background: url(' + userToolbarActions[i].icon + ');"></span></span>');
        action.click(userToolbarActions[i].doAction);
        var path = userToolbarActions[i].path;
        action.attr("data-path", path).attr("title", path);
        createTreeItemDraggable(action);
        action.contextMenu('userToolbarContextMenu', {
            bindings: {
                'remove_toolbar_item': function(node)
                {
        			var path = $(node).attr("data-path");
		        	for(var i in userToolbarActions)
		        	{
		        		if(userToolbarActions[i].path === path)
		        		{
		        			userToolbarActions.splice(i, 1);
                            var userToolbarPreference = "";
                            $.each(userToolbarActions, function(index, value){userToolbarPreference += value.path + ";";});
                            setPreference("UserToolbar", userToolbarPreference); 
		        			updateToolbar();
		        			return;
		        		}
		        	}
                }
            }
        });
        block2.append(action);
    }

    toolbar.append(block2);
    
    setToolbarEvents();
}

/*
 * Init events for toolbars
 */
function setToolbarEvents()
{
    if (journalBox != null) 
    {
        journalBox.unbind('change');
        journalBox.change(function()
        {
            queryBioUML("web/journal", {
                action: "set",
                journalName: journalBox.val()
            }, function() {});
        });
    }
}

/*
 * Init context toolbar
 */
function initContextToolbar()
{
	// load actions
    queryBioUML("web/action", 
    {
        type: "tree"
    }, function(data)
    {
        var actions = data.actions;
        for (i = 0; i < actions.length; i++) 
        {
            var actionProperties = new Action();
            actionProperties.parse(actions[i]);
            contextToolbarActions[i] = actionProperties;
        }
        updateContextToolbar(null, null, null);
    });
}

/*
 * Update context toolbar actions
 */
function updateContextToolbar(node, treeObj, path)
{
    var nodePath = null;
    if (!node || node == null) 
    {
        nodePath = path;
    }
    else 
    {
        nodePath = getTreeNodePath(node);
    }
    
    var block = $('<div class="fg-buttonset ui-helper-clearfix"></div>');
    for (var i = 0; i < contextToolbarActions.length; i++) 
    {
        if (contextToolbarActions[i].id) 
        {
            var visibleType = contextToolbarActions[i].isVisible(nodePath == undefined ? null : nodePath);
            if (visibleType != -1) 
            {
                var action = $('<span class="fg-button ui-state-default fg-button-icon-solo  ui-corner-all" title="' + contextToolbarActions[i].label + '"><span class="fg-button-icon-span" style="background: url(' + contextToolbarActions[i].icon + ');"></span></span>');
                new function(actionHandler)
                {
                    action.click(function(event)
                    {
                        actionHandler(nodePath);
                    });
                }(contextToolbarActions[i].doAction);
                block.append(action);
            }
        }
    }
    var toolbar = $('#contextToolbar');
    toolbar.children('.fg-buttonset').remove();
    toolbar.append(block);
    setToolbarEvents();
}

/*
 * Update info toolbar actions
 */
function updateInfoToolbar(node, treeObj, path, templates)
{
    var nodePath = null;
    if (!node || node == null) 
    {
        nodePath = path;
    }
    else 
    {
        nodePath = getTreeNodePath(node);
    }
    
    $("#infoTabs").find('.fg-rightcomponent').remove();
    var block2 = $('<div class="fg-rightcomponent ui-helper-clearfix"></div>');
    var editAction = new Action();
    editAction.id = "info_edit";
    editAction.label = resources.commonTooltipEditElementInfo;
    editAction.icon = "icons/edit.gif";
    editAction.isVisible = function(path)
    {
        if (infoElementName != null) 
        {
            return true;
        }
        return false;
    };
    editAction.doAction = function(path)
    {
        if (infoElementName != null) 
        {
                    dc = getDataCollection(infoElementName);
                    dc.getBean(function(beanDPS)
                    {
                    	var propertyPane = new JSPropertyInspector();
                        
                        var dialogDiv = $('<div title="'+resources.commonEditElementInfoTitle+'"></div>');
                        var parentID = "property_inspector_dialog_" + rnd();
                        dialogDiv.append('<div id="' + parentID + '"></div>');
                        dialogDiv.dialog(
                        {
                            autoOpen: false,
                            width: 500,
                            height: 500,
                            buttons: 
                            {
                                "Cancel": function()
                                {
                                    $(this).dialog("close");
                                    $(this).remove();
                                },
                                "Save": function()
                                {
                                    var dps = propertyPane.getModel();
                                    dc.setBean(dps, function()
                                    {
                                        dc.getHtml(function(info)
                                        {
                                            $("#info_area").html(info);
                                        });
                                    });
                                    $(this).dialog("close");
                                    $(this).remove();
                                }
                            }
                        });
                        addDialogKeys(dialogDiv);
                        sortButtons(dialogDiv);
                        dialogDiv.dialog("open");
                        
                        propertyPane.setParentNodeId(parentID);
                        propertyPane.setModel(beanDPS);
                        propertyPane.generate();
                    });
        }
    };
    var action2 = $('<span class="fg-button ui-state-default fg-button-icon-solo  ui-corner-all" title="' + editAction.label + '"><span class="fg-button-icon-span" style="background: url(' + editAction.icon + ');"></span></span>');
    new function(actionHandler)
    {
        action2.click(function(event)
        {
        	actionHandler(nodePath);
        });
    }(editAction.doAction);
    block2.append(action2);
    
    var viewAction = new Action();
    viewAction.id = "info_view";
    viewAction.label = resources.commonTooltipViewElementInfo;
    viewAction.icon = "icons/view.gif";
    viewAction.isVisible = function(path)
    {
        if (infoElementName != null) 
        {
            return true;
        }
        return false;
    };
    viewAction.doAction = function(path)
    {
    	if (infoElementName != null) 
        {
            window.open(appInfo.serverPath+'web/html_page?'+
					toURI({templateName: templateBox.val(), de: infoElementName}));
        }
    };
    var action = $('<span class="fg-button ui-state-default fg-button-icon-solo  ui-corner-all" title="' + viewAction.label + '"><span class="fg-button-icon-span" style="background: url(' + viewAction.icon + ');"></span></span>');
    new function(actionHandler)
    {
        action.click(function(event)
        {
        	actionHandler(nodePath);
        });
    }(viewAction.doAction);
    block2.append(action);
    
    var templateBox = $('<select id="templateComboBox" class="ui-state-default" style="font-size: 10pt;float:right;"></select>');
    templateBox.width(150);
    templateBox.height(24);
    templateBox.children('option').remove();
    if (templates == null) 
    {
        templateBox.append('<option id="Default">Default</option>');
    }
    else 
    {
        for (i = 0; i < templates.length; i++) 
        {
            templateBox.append('<option id="' + templates[i] + '">' + templates[i] + '</option>');
        }
    }
    templateBox.change(function()
    {
        if (infoElementName != null) 
        {
            dc = getDataCollection(infoElementName);
            dc.getHtmlByTemplate(function(info)
            {
                $("#info_area").html(info);
            }, templateBox.val());
        }
    });
    
    block2.append(templateBox);
    $("#infoTabs").find('.ui-tabs-nav').append(block2);
    
    if($("#infoTabs").tabs('option', 'selected') != 1)//show only for Info tab
    {
    	block2.hide();
    }
    setToolbarEvents();
}

/**
 * Init dynamic actions
 */
function initDynamicActions()
{
    // load dynamic actions
    queryBioUML("web/action", 
    {
        type: "dynamic",
        action: "load"
    }, function(data)
    {
        var actions = data.actions;
        for (i = 0; i < actions.length; i++) 
        {
            var actionProperties = new DynamicAction();
            actionProperties.parse(actions[i]);
            dynamicToolbarActions[i] = actionProperties;
        }
        updateDynamicToolbar();
    });
}

/**
 * Update toolbar for dynamic actions
 */
function updateDynamicToolbar(block)
{
    var doc = getActiveDocument();
    if( doc == null )
        return;
    if(dynamicToolbarActions.length == 0)
        return;
    var block = $('#dynamicToolbarBlock');
    if(!block)
        return;
    var doUpdateToolbar = function(visibles)
    {
        for (var i = 0; i < dynamicToolbarActions.length; i++) 
        {
            if( visibles[dynamicToolbarActions[i].id] != undefined )
            {
                var curAction = dynamicToolbarActions[i];
                if( curAction.numSelected != curAction.selConstants.SELECTED_UNDEFINED && !doc.getSelection)
                    continue;
                var action = createToolbarButton(curAction.label, curAction.icon, curAction.doAction);
                if(doc.readOnly && !curAction.acceptReadOnly) setToolbarButtonEnabled(action, false);
                block.append(action);
            }
        }
        setToolbarEvents();
    }; 
    if(doc.visibleActions == null)
    {
        queryBioUMLWatched(doc.completeName + "_dynamicActions", "web/action", 
	    {
	        type: "dynamic",
	        action: "visibleall",
	        de: doc.completeName
	    }, function(data)
	    {
	        var visibles = data.values;
	        var converted = {};
	        var re = /^(.+)\.(\d+)$/;
	        for (var name in visibles)
	    	{
	        	var baseName = name;
	        	var index = 0;
	        	var m = baseName.match(re);
	        	if(m)
	    		{
	        		baseName = m[1];
	        		index = m[2];
	    		}
	        	if(converted[baseName] == undefined || index > converted[baseName][0])
	        	{
	        		if(converted[baseName]) delete visibles[converted[baseName][1]];
	        		converted[baseName] = [index, name];
	        	}
	        	else
	        		delete visibles[name];
	    	}
	        doc.visibleActions = visibles;
	        doUpdateToolbar(visibles);
	    });
    } else
    	doUpdateToolbar(doc.visibleActions);
}

/*
 * Action class
 */
function Action()
{
	var _this = this;
    this.id = null;
    this.label = null;
	this.visible = function(node) {
		if(!node || node.length != 1) return -1;
		return _this.isVisible(getTargetPath(getTreeNodePath(node[0])));
	};
	this.action = function(node) {
		if(!node || node.length != 1) return -1;
		return _this.doAction(getTargetPath(getTreeNodePath(node[0])));
	};
    this.icon = null;
    
    this.parse = function(action)
    {
        if (action.id) 
        {
            this.id = action.id;
            this.label = action.label;
            this.icon = action.icon;
            this.isVisible = evalFunction(action.visible, function(){return -1;});
            this.doAction = evalFunction(action.action);
        }
    };
}

/*
 * DynamicAction class
 */
function DynamicAction()
{
    this.selConstants = {
        SELECTED_ZERO: 0,
        SELECTED_ONE: 1,
        SELECTED_ANY: 2,
        SELECTED_UNDEFINED: -1
    };
    
    this.id = null;
    this.label = null;
    this.icon = null;
    this.parse = function(action)
    {
        if (action.id) 
        {
            this.id = action.id;
            this.label = action.label;
            this.icon = action.icon;
            this.acceptReadOnly = action.acceptReadOnly;
            this.numSelected = action.numSelected || this.selConstants.SELECTED_UNDEFINED;
        }
    };
    
    this.visible = function(node) {
        if(!node || node.length != 1) return -1;
        return _this.isVisible(node);
    };
    this.action = function(node) {
        if(!node || node.length != 1) return -1;
        return _this.doAction(node);
    };
    
    this.isVisible = function(node, callback)
    {
        if(!node)
            return false;
        var path = node.completeName;
        if(!path)
            return false;
        var params = {
            type: "dynamic",
            action: "visible",
            name: this.id,
            de: path,
            selectionBase: node.selectionBase
        };
        var _this = this;
        queryBioUML("web/action", params, function(data)
        {
            callback(true, _this);
        }, function(data)
        {
            callback(false);
        });
    };
    var _thisAction = this; 
    this.doAction = function(node)
    {
        var activeDocument = getActiveDocument();
        if(!activeDocument)
            return;
        var path = activeDocument.completeName;
        if(!path)
            return;
        var params = {
            type: "dynamic",
            action: "validate",
            name: _thisAction.id,
            selectionBase: activeDocument.selectionBase,
            de: path
        };
        if(_thisAction.numSelected != _thisAction.selConstants.SELECTED_UNDEFINED)
        {
            if( !activeDocument.getSelection )
                return;
            var selectedRows = activeDocument.getSelection();
            if(!_thisAction.checkNumSelected(selectedRows.length))
            {
                logger.error(_thisAction.getNumSelectedMessage());
                return;
            }
            else
            {
                params["jsonrows"] = $.toJSON(selectedRows);
            }
        }
        queryBioUML("web/action", params, function(data)
        {
            if(data.values)
            {
                if (data.values.confirm) 
                {
                    createConfirmDialog(data.values.confirm, function()
                    {
                        _thisAction.performAction(params["jsonrows"]);
                    })
                }
                else 
                {
                    var dialogDiv = $('<div title="' + resources.commonDynamicActionPropertiesTitle + '"></div>');
                    var propertyInspector = $('<div id="dynamic_action_pi_cont_' + rnd() + '"></div>');
                    dialogDiv.append(propertyInspector);
                    var beanDPS = convertJSONToDPS(data.values);
                    appendJSONToDictionaries(data.dictionaries);
                    var propertyPane = new JSPropertyInspector();
                    propertyPane.setParentNodeId(propertyInspector.attr('id'));
                    propertyPane.setModel(beanDPS);
                    dialogDiv.dialog({
                        autoOpen: false,
                        width: 500,
                        buttons: {
                            "Ok": function()
                            {
                                var dps = propertyPane.getModel();
                                var json = convertDPSToJSON(dps);
                                _thisAction.performAction(params["jsonrows"], json);
                                $(this).dialog("close");
                                $(this).remove();
                            },
                            "Cancel": function()
                            {
                                $(this).dialog("close");
                                $(this).remove();
                            }
                        }
                    });
                    addDialogKeys(dialogDiv);
                    sortButtons(dialogDiv);
                    dialogDiv.dialog("open");
                    propertyPane.generate();
                }
            }
            else
            {
                _thisAction.performAction(params["jsonrows"]);
            }
        });
    };
    
    this.checkNumSelected = function(selected)
    {
        switch(_thisAction.numSelected)
        {
            case _thisAction.selConstants.SELECTED_ZERO:
                return (selected == 0);
            case _thisAction.selConstants.SELECTED_ONE:
                return (selected == 1);
            case _thisAction.selConstants.SELECTED_ANY:
                return (selected >= 1);
        }
    };
    this.getNumSelectedMessage = function()
    {
        switch(_thisAction.numSelected)
        {
            case _thisAction.selConstants.SELECTED_ZERO:
                return resources.commonErrorActionNoSelectionRequired;
            case _thisAction.selConstants.SELECTED_ONE:
                return resources.commonErrorActionOneSelectedRowRequired;
            case _thisAction.selConstants.SELECTED_ANY:
                return resources.commonErrorActionSelectedRowsRequired;
            case _thisAction.selConstants.SELECTED_UNDEFINED:
                return resources.commonErrorActionUnknown;
            default:
                return "";
        }
    };
    
    this.performAction = function(rows, properties)
    {
        var activeDocument = getActiveDocument();
        if(!activeDocument)
            return;
        var path = activeDocument.completeName;
        if(!path)
            return;
        var jobID = rnd();
        var params = {
            type: "dynamic",
            action: "run",
            name: _thisAction.id,
            de: path,
            selectionBase: activeDocument.selectionBase,
            jobID: jobID
        };
        if(properties)
            params["properties"] = properties;
        if(rows)
            params["jsonrows"] = rows;
        queryBioUML("web/action", params
        , function(data)
        {
            if(data.values == "action finished")
        	{
        		// TODO: change this to something more appropriate like opening result
        		logger.message(_thisAction.label + " performed successfully");
        	} else
        		showProgressDialog(jobID, _thisAction.label, function(message, results) {
        			if(results != undefined)
        			{
        				for(var i=0; i<results.length; i++)
        				{
                            var id = allocateDocumentId(results[i]);
                            if( opennedDocuments[id] != undefined && opennedDocuments[id].refresh != undefined )
                                opennedDocuments[id].refresh();
                            else
                            {
            					refreshTreeBranch(getElementPath(results[i]));
        					    openDocument(results[i]);
                            }
        				}
        			}
        		});
        });
    };
}


