Subversion Repositories bacoAlunos

Rev

Rev 1816 | Blame | Compare with Previous | Last modification | View Log | RSS feed

<%@ taglib uri="/WEB-INF/tlds/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/tlds/struts-nested.tld" prefix="nested" %>
<%@ taglib uri="/WEB-INF/tlds/struts-logic.tld" prefix="logic" %>
<%@ taglib uri="/WEB-INF/tlds/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/tlds/struts-tiles.tld" prefix="tiles" %>
<%@ taglib uri="/WEB-INF/tlds/baco.tld" prefix="baco" %>
<%@ taglib uri="/WEB-INF/tlds/jomm.tld" prefix="jomm" %>
<%@ page import="jomm.dao.impl.AbstractDao" %>
<%@ page import="pt.estgp.estgweb.domain.*" %>
<%@ page import="pt.estgp.estgweb.domain.dao.DaoFactory" %>
<%@ page import="pt.estgp.estgweb.web.filters.UserRoleProxy" %>
<%@ page import="pt.estgp.estgweb.domain.bpmn.utils.TaskConstantVariablesUtils" %>
<%@ page import="pt.estgp.estgweb.domain.bpmn.utils.VariableTypeUtils" %>
<%@ page import="pt.estgp.estgweb.domain.typesgen.Todos" %>
<%@ page import="pt.estgp.estgweb.domain.typesgen.Argument" %>
<%@ page import="pt.estgp.estgweb.domain.typesgen.ConnectorSoa" %>
<%@ page import="pt.estgp.estgweb.domain.typesgen.OperationMethodCall" %>
<%@ taglib tagdir="/WEB-INF/tags" prefix="bacoTags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%

    Long processId = Long.parseLong(request.getParameter("id"));
    AbstractDao.getCurrentSession().beginTransaction();
    BpmnProcessImpl process = (BpmnProcessImpl) DaoFactory.getBpmnProcessDaoImpl().get(processId);


%>

<style>
    div.dirty
    {
        border: 3px dashed orangered !important;
    }
</style>


<link rel="stylesheet" href="<%=request.getContextPath()%>/js/angularjs/angular-ui-tree/angular-ui-tree.min.css">
<script type="text/javascript" src="<%=request.getContextPath()%>/js/angularjs/angular-ui-tree/angular-ui-tree.js"></script>


<div class="container-fluid"
     id="processEditorModule"
     ng-app="processEditorModule"
     ng-controller="processEditorModuleController"
     ng-init="initBuilder()">

<style>
    .has-error .chosen-container
    {
        border: 1px solid #a94442 !important;
    }
</style>

<script>



//DECLARACAO DA APLICACAO LOCAL EM ANGULAR
var processEditorModule = angular.module('processEditorModule', ['ui.tree']);
GLOBAL_BacoAngularAppDependencies.push('processEditorModule');

/**Fim de directiva reutilizavel**/





processEditorModule.controller('processEditorModuleController', function($scope,$interval,$filter)
{
    $scope.callServiceSync = function(service,parameters,callback)
    {
        widgetCallWithActionParameters(
                "<%=request.getContextPath()%>/admin/bpmn/bpmnController.do",
                service,
                parameters,
                "#processEditorModule",
                function(jsonAnswer)
                {
                    callback(jsonAnswer);
                    $scope.$apply();
                }
        );
    }
    $scope.callService = function(service,parameters,callback)
    {
        widgetCallWithActionParameters(
                "<%=request.getContextPath()%>/admin/bpmn/bpmnController.do",
                service,
                parameters,
                "#processEditorModule",
                function(jsonAnswer)
                {
                    callback(jsonAnswer);
                    $scope.$apply();
                }
        );
    }
    $scope.callSimpleService = function(service,parameters,callback)
    {
        widgetSimpleCallWithActionParameters(
                "<%=request.getContextPath()%>/admin/bpmn/bpmnController.do",
                service,
                parameters,
                "#processEditorModule",
                function()
                {
                    callback();
                    $scope.$apply();
                }
        );
    }

    /*
    * Variaveis e metodos auxiliares
    * */

    $scope.allFlowComponents = [];
    $scope.autoSavesObjects = [];
    $scope.idTemp = -1;
    $scope.jsps = [];
    $scope.newSoa = {};
    $scope.servicesSoa = []; //Tem Servicos e metodos os metodos sao apanhados do servico selecionado, quando muda o serviço os metodos mudam automaticamente, como o existente antigo não faz match com os do selecionado lodo chama o setNewArguments que opera sobre um metodo que nao faz match logo não há argumentos e ficam vazi-os

    $scope.newMethodCall = {}; //Uma so classe escolhida em vez de um array como nos servicos
    $scope.methodsClassSelected = []; //Os metodos sao apanhados em tempo real e tem de estar aqui

    //TEM APENAS AS NORMAIS CONSTANTES
    $scope.constantVariables = <%=TaskConstantVariablesUtils.obtainConstantBpmnVariablesRegularTask().toString()%>
    //TEM TODAS, AS NORMAIS E AS DE TAREFA ATOR
    $scope.constantVariablesActorTask = <%=TaskConstantVariablesUtils.obtainConstantBpmnVariablesActorTask().toString()%>;


    $scope.processVariableTypes = <%=VariableTypeUtils.obtainProcessSerializableVariableTypes().toString()%>;
    $scope.localVariableTypes = <%=VariableTypeUtils.obtainAllVariableTypes().toString()%>;


    $scope.initBuilder = function()
    {
        $scope.initServicesSoa();
        $scope.initJsps();
        $scope.inicializarSaves();
        $scope.copiaFlowComponentsDasActorPools();
        setTimeout(function() { $(".angularChosen").chosen(); }, 500);
    }


    $scope.initJsps = function()
    {
        $scope.callService("loadJspsPlugins",{},function(interfaces)
        {
            $scope.jsps = interfaces.jsps;
            $scope.$apply();
        });
    }

    $scope.initServicesSoa = function()
    {
        $scope.callService("loadServicesSoa",{},function(servicesSoa)
        {
            $scope.servicesSoa = servicesSoa.services;
            $scope.$apply();
        });
    }

    $scope.showMethodSign = function(method)
    {
        return method.name + " => " + method.simpleReturnType;
    }



    $scope.inicializarSaves = function()
    {
        $interval($scope.autoSaves,2000);
    }

    $scope.copiaFlowComponentsDasActorPools = function()
    {
        for(x in $scope.process.actorPools)
        {
            var pool = $scope.process.actorPools[x];
            for(y in pool.flowComponents)
            {
                var flowComponent = pool.flowComponents[y];
                $scope.allFlowComponents.push(flowComponent);
            }
        }
    }

    $scope.autoSaves = function()
    {
        for(var v in $scope.process.processVariables)
        {
            var variable = $scope.process.processVariables[v];
            if(variable.dirty == true)
            {
                var variableCall = variable;
                $scope.callSimpleService("updateVariable",{"object":BacoJS.stringifyOrdered(variableCall)},function()
                {
                    variableCall.dirty = false;
                    $scope.$apply();
                });

            }
        }
        for(var x in $scope.process.actorPools)
        {
            var pool = $scope.process.actorPools[x];
            if(pool.dirty == true)
            {
                var poolCall = pool;
                $scope.callSimpleService("updatePool",{"object":BacoJS.stringifyOrdered(pool)},function()
                {
                    poolCall.dirty = false;
                    //alert("Apagando dirty");
                    $scope.$apply();
                });
            }
            for(var y in pool.flowComponents)
            {
                var flowComponent = pool.flowComponents[y];
                if(flowComponent.dirty == true)
                {
                    //flowComponent.dirty = false;
                    //todo if para ver se é task pode ser gateway ou event
                    //so estou a meter as tasks nos flow components não estou a meter os gateways nem os eventos
                    var flowComponentCall = flowComponent;
                    $scope.callSimpleService("updateTask",{"object":BacoJS.stringifyOrdered(flowComponent)},function()
                    {
                        flowComponentCall.dirty = false;
                        //alert("Apagando dirty");
                        $scope.$apply();
                    });
                }
                for(var z in flowComponent.flowConnectors)
                {
                    var flowConnector = flowComponent.flowConnectors[z];
                    if(flowConnector.dirty == true)
                    {
                        var flowConnectorCall = flowConnector;
                        $scope.callSimpleService("updateConnector",{"object":BacoJS.stringifyOrdered(flowConnector)},function()
                        {
                            flowConnectorCall.dirty = false;
                            $scope.$apply();
                        });

                    }
                }
                for(var v in flowComponent.localVariables)
                {
                    var variable = flowComponent.localVariables[v];
                    if(variable.dirty == true)
                    {
                        var variableCall = variable;
                        $scope.callSimpleService("updateVariable",{"object":BacoJS.stringifyOrdered(variableCall)},function()
                        {
                            variableCall.dirty = false;
                            $scope.$apply();
                        });

                    }
                }
            }
        }
        for(var x in $scope.process.actorPools)
        {
            var obj = $scope.process.actorPools[x];
            if(obj.dirty == true)
            {

            }
        }
    }




    /** Funções que interagem com directiva reutilizavel **/
    $scope.save = function() {
        $scope.$broadcast('show-errors-check-validity');

        if (!$scope.processoForm.$invalid) {
            alert('User saved');
            //$scope.reset();
        }
        else
        {
            alert("Existem erros no form");
        }
    };
    $scope.reset = function() {
        $scope.$broadcast('show-errors-reset');
        $scope.user = { name: '', email: '' };
    }
    /** Fim de Funções que interagem com directiva reutilizavel **/


    /*
    * Funcoes e variaveis especificas do Processo
    *
    * */

    $scope.process = <%=process.toJson()%>;

    $scope.removeActorPool = function(poolId,$index)
    {
        var pool = $filter('filter')($scope.process.actorPools, {id: poolId })[0];
        if(pool.flowComponents && pool.flowComponents.length > 0)
        {
            alert("Não pode apagar esta pool com atividades no seu interior");
        }
        else
        {
            $scope.callSimpleService("removeActorPool",{"poolId":pool.id},function()
            {
                $scope.process.actorPools.splice($index,1);
            });
        }
    }

    $scope.removeTask = function (poolId,taskId,$index)
    {
        $scope.callSimpleService("removeTask",{"poolId":poolId,"taskId":taskId},function()
        {
            var pool = $filter('filter')($scope.process.actorPools, {id: poolId })[0];
            pool.flowComponents.splice($index,1);
            var taskInAllFlows = $filter('filter')($scope.allFlowComponents, {id: taskId })[0];
            var index = $scope.allFlowComponents.indexOf(taskInAllFlows );
            $scope.allFlowComponents.splice(index,1);
        });
    }

    $scope.removeConnector = function (connectorId,taskId,poolId,$index)
    {
        $scope.callSimpleService("removeConnector",{"taskId":taskId,"connectorId":connectorId},function()
        {
            var pool = $filter('filter')($scope.process.actorPools, {id: poolId })[0];
            var task = $filter('filter')(pool.flowComponents, {id: taskId })[0];
            task.flowConnectors.splice($index,1);
        });
    }

    $scope.setDirty = function(obj)
    {
        obj.dirty = true;
        $scope.autoSavesObjects.push(obj);
    }

    $scope.selected = null;
    $scope.select = function(node)
    {
        if($scope.selected)
        {
            delete $scope.selected.selected;
        }
        $scope.selected = node;
        node.selected = true;
    }


    $scope.startTooltips = function()
    {
        $("[data-toggle='tooltip']").tooltip();
    }

    $scope.newActorPool = function()
    {
        $scope.callService("addActorPool",{"processId":$scope.process.id},function(actorPool)
        {
            if($scope.process.actorPools == null)
                $scope.process.actorPools = [];
            $scope.process.actorPools.push(actorPool);
            $scope.$apply();
            invokeChosenSelects("#bpmnPools");
        });
    }

    $scope.addTaskActor = function(pool)
    {
        $scope.callService("addTaskActor",{"poolId":pool.id},function(taskActor)
        {
            if(pool.flowComponents == null)
                pool.flowComponents = [];
            pool.flowComponents.push(taskActor);
            $scope.allFlowComponents.push(taskActor);
            $scope.$apply();
            //invokeChosenSelects("#bpmnPools");
        });
    }

    $scope.addConnector = function(task)
    {
        $scope.callService("addConnector",{"taskId":task.id},function(connector)
        {
            //connector = orderKeys(connector);
            if(task.flowConnectors == null)
                task.flowConnectors = [];
            task.flowConnectors.push(connector);
            $scope.$apply();
            //invokeChosenSelects("#bpmnPools");
        });
    }

    /**
     *
     *
     *
     * OPERACOES PARA MODAL PARA CRIAR/EDITAR TODOS
     * Operacoes Comuns a Operações Todos
     *
     *
     *
     * *******/


    $scope.createNewTodo = function(a_class)
    {
        var methodCallTarget =
        {
            "@class": a_class
        };
        $scope.newMethodCallTarget = methodCallTarget;
        if(!$scope.selected.todos)
            $scope.selected.todos = {
                "@class": "<%=Todos.class.getName()%>"
            };
        if(!$scope.selected.todos.todos)
            $scope.selected.todos.todos = [];

        $scope.selected.todos.todos.push(methodCallTarget);
        return methodCallTarget;
    }

    $scope.createNewTodoAtor = function(a_class){
        var methodCallTarget =
        {
            "@class": a_class
        };
        if(!$scope.selected.afterUserTodos)
            $scope.selected.afterUserTodos =
            {
                "@class": "<%=Todos.class.getName()%>"
            };
        if(!$scope.selected.afterUserTodos.todos)
            $scope.selected.afterUserTodos.todos = [];

        $scope.selected.afterUserTodos.todos.push(methodCallTarget);
        return methodCallTarget;
    }

    /**
     * Recebe uma Operação de chamada de metodo ou soa previamente selecionada
     * e coloca na variavel auxiliar methodChoosed o método que estava escolhido
     * a partir da lista de metodos disponiveis no servico/classe selecionada
     */
    $scope.prepareTodoToEdit = function(selectedTodo,methods)
    {
        for(var m in methods)
        {
            var method = methods[m];
            if(method.name == selectedTodo.methodName &&
                    method.returnType == selectedTodo.checkReturnType)
            {
                var hasMethodArguments = method.arguments && method.arguments.length > 0;
                var hasSoaMethodArguments =  selectedTodo.arguments &&  selectedTodo.arguments.length > 0;
                if(!hasMethodArguments && !hasSoaMethodArguments)
                {
                    selectedTodo.methodChoosed = method;
                    break;
                }
                else if(hasMethodArguments != hasSoaMethodArguments)
                {
                    continue;
                }
                else if(selectedTodo.arguments.length != method.arguments.length)
                {
                    continue;
                }
                else
                {
                    //Methods are equal in arguments
                    var found = true;
                    for(var a in method.arguments)
                    {
                        var argumentMethod = method.arguments[a].className;
                        var soaArgument = selectedTodo.arguments[a].className;
                        if(argumentMethod != soaArgument)
                        {
                            found = false;
                            break;
                        }
                    }
                    if(found)
                    {
                        selectedTodo.methodChoosed = method;
                        break;
                    }
                }
            }
        }
    }
    $scope.salvarTodoEdit = function(modalId)
    {
        var modal = $("#" + modalId);
        var task = $scope.selected;
        $scope.setDirty(task);
        modal.modal("hide");
    }


     /**
     *
     *
     * OPERACOES PARA MODAL DE CHAMADA DE METODO SOBRE VARIAVEL
     *
     *
     * **/

    /* chamadas para abrir modal*/
    $scope.openMethodCallModal = function(methodCallTarget)
    {
        if(!methodCallTarget)
        {
            methodCallTarget = $scope.createNewTodo("<%=OperationMethodCall.class.getName()%>");
            $scope.newMethodCall = methodCallTarget;
            methodCallTarget.usaDadosAtorDoFormulario = false;
            $("#methodCallModalSelector").modal("show");
        }
        else
        {
            $scope.newMethodCall = methodCallTarget;
            $scope.callService("loadClassMethods",
                    { "className" : methodCallTarget.className},
                    function(classDescription){
                        $scope.methodsClassSelected = classDescription.methods;
                        $scope.prepareTodoToEdit(methodCallTarget,classDescription.methods);
                        methodCallTarget.usaDadosAtorDoFormulario = false;
                        $("#methodCallModalSelector").modal("show");
                    });
        }

    }

    $scope.openMethodCallModalAtor = function(methodCallTarget)
    {
        if(!methodCallTarget)
        {
            methodCallTarget = $scope.createNewTodoAtor("<%=OperationMethodCall.class.getName()%>");
            $scope.newMethodCall = methodCallTarget;
            methodCallTarget.usaDadosAtorDoFormulario = true;
            $("#methodCallModalSelector").modal("show");
        }
        else
        {
            $scope.newMethodCall = methodCallTarget;
            $scope.callService("loadClassMethods",
                    { "className" : methodCallTarget.className},
                    function(classDescription){
                        $scope.methodsClassSelected = classDescription.methods;
                        $scope.prepareTodoToEdit(methodCallTarget,classDescription.methods);
                        methodCallTarget.usaDadosAtorDoFormulario = true;
                        $("#methodCallModalSelector").modal("show");
                    });
        }

    }


    /**
     * Chamada do ng-change da combo da classe da variavel escolhida
     * O ciclo repeat da modal de metodos difere do ciclo da dos soa
     * porque irá fazer as options dos metodos com base directa nos
     * methodsClassSelected.methods em vez de os obter desta função
     * que foi feita a partir do $scope.getServiceMethods
     * */
    $scope.changeMethodClassTarget = function()
    {
        var varSelected = $filter('filter')($scope.getAllVariables(), {"name": $scope.newMethodCall.name },true)[0];
        $scope.methodsClassSelected = [];
        $scope.newMethodCall.className = varSelected.type.className;
        $scope.newMethodCall.methodName = "";
        $scope.callService("loadClassMethods",
                { "className" : $scope.newMethodCall.className},
                function(classDescription){
                    $scope.methodsClassSelected = classDescription.methods;
                    //$scope.prepareTodoToEdit(classDescription,classDescription.methods);
                    //methodCallTarget.usaDadosAtorDoFormulario = true;
                    //$("#methodCallModalSelector").modal("show");
                });
    }

    /**
     * chamada de mudanca de metodo
     */
    $scope.setArgumentsNewMethodCallMethod = function()
    {
        var method = $scope.newMethodCall.methodChoosed;
        var arguments = [];
        for(var a in method.arguments)
        {
            var newArgument =
                    {
                        "@class" : "<%=Argument.class.getName()%>",
                        "name" : method.arguments[a].name,
                        "varName" : "",
                        "className" : method.arguments[a].className
                    };
            if( method.arguments[a].classNameSuperClasses)
                newArgument.classNameSuperClasses = method.arguments[a].classNameSuperClasses;
            arguments.push(newArgument);
        }
        $scope.newMethodCall.methodName = method.name;
        $scope.newMethodCall.arguments = arguments;
        $scope.newMethodCall.checkReturnType = method.returnType;
        if(method.returnTypeSuperClasses)
            $scope.newMethodCall.checkReturnTypeSuperClasses = method.returnTypeSuperClasses;
    }


    /**
     *
     *
     * OPERACOES PARA MODAL DE CONNECTOR SOA
     *
     *
     * **/

    $scope.openSoaModal = function(soaTarget)
    {
        if(!soaTarget)
        {
            soaTarget = $scope.createNewTodo("<%=ConnectorSoa.class.getName()%>");
            $scope.newSoa = soaTarget;
        }
        else
        {
            $scope.newSoa = soaTarget;
            $scope.prepareTodoToEdit(soaTarget,$scope.getServiceMethods(soaTarget.className));
        }
        soaTarget.usaDadosAtorDoFormulario = false;
        $("#soaModalSelector").modal("show");
    }

    $scope.openSoaModalAtor = function(soaTarget)
    {
        if(!soaTarget)
        {
            soaTarget = $scope.createNewTodoAtor("<%=ConnectorSoa.class.getName()%>");
            $scope.newSoa = soaTarget;
        }
        else
        {
            $scope.newSoa = soaTarget;
            $scope.prepareTodoToEdit(soaTarget,$scope.getServiceMethods(soaTarget.className));
        }
        soaTarget.usaDadosAtorDoFormulario = true;
        $("#soaModalSelector").modal("show");
    }




    $scope.getService = function(classname)
    {
        if(classname)
        {
            var service = $filter('filter')($scope.servicesSoa, {"className": classname },true)[0];
            return service;
        }
    }
    $scope.getServiceMethods = function(classname)
    {
        if(classname)
        {
            var service = $filter('filter')($scope.servicesSoa, {"className": classname },true)[0];
            return service.methods;
        }
    }

    $scope.deleteTodo = function(task,index)
    {
        task.todos.todos.splice(index,1);
        $scope.setDirty(task);
    }
    $scope.deleteAfterUserTodo = function(task,index)
    {
        task.afterUserTodos.todos.splice(index,1);
        $scope.setDirty(task);
    }

    $scope.getServiceMethod = function()
    {
       return $scope.newSoa.methodChoosed;
    }

    $scope.setArgumentsNewSoa = function()
    {
        var method = $scope.newSoa.methodChoosed;
        var arguments = [];
        for(var a in method.arguments)
        {
            var newArgument = {
                "@class" : "<%=Argument.class.getName()%>",
                    "name" : method.arguments[a].name,
                    "varName" : "",
                    "className" : method.arguments[a].className
            }
            if( method.arguments[a].classNameSuperClasses)
                newArgument.classNameSuperClasses = method.arguments[a].classNameSuperClasses;
            arguments.push(newArgument);
        }
        $scope.newSoa.methodName = method.name;
        $scope.newSoa.arguments = arguments;
        $scope.newSoa.checkReturnType = method.returnType;
        if(method.returnTypeSuperClasses)
            $scope.newSoa.checkReturnTypeSuperClasses = method.returnTypeSuperClasses;
    }




    /**
     *
     *
     *
     * */


     $scope.getSimpleClassName = function(classname)
    {
        if(classname && classname != "")
        {
            var lastDot = classname.lastIndexOf(".");
            if(lastDot >= 0)
                return classname.substring(lastDot + 1);
            return classname;
        }
        return "";
    }

    $scope.soaServiceSelector = function()
    {
        setTimeout(function() { $("#SoaServiceSelector").chosen(); }, 500);
     //   $("#SoaServiceSelector").chosen();
    }



    $scope.newRoleForPool = function(item)
    {
        $scope.idTemp--;
        if(item.roles == null)
        {
            item.roles = [];
        }
        item.roles.push(
                {
                    "role" : "",
                    "trans" : ""
                }
        );
        //O chosen está off para que na primeira interação nao actue sobre
        //o option padrão que está sempre presente para preenchimento pelo Angular
        setTimeout(function() { invokeChosenSelects("#bpmnPools"); }, 100);
    }

    $scope.newProcessVar = function()
    {
        $scope.callService("newProcessVar",{"processId":$scope.process.id},function(processVariable)
        {
            if(!$scope.process.processVariables)
                $scope.process.processVariables = [];
            $scope.process.processVariables.push(processVariable);
            $scope.$apply();
        });
    }

    $scope.removeProcessVar = function(variableId,$index)
    {
        $scope.callSimpleService("removeProcessVar",{"processId":$scope.process.id,"variableId":variableId},function()
        {
            $scope.process.processVariables.splice($index,1);
            $scope.$apply();
        });
    }

    $scope.newLocalVar = function(task)
    {
        $scope.callService("newLocalVar",{"taskId":task.id},function(taskVariable)
        {
            if(!task.localVariables)
                task.localVariables = [];
            task.localVariables.push(taskVariable);
            $scope.$apply();
        });
    }

    $scope.removeLocalVar = function(variableId,$index)
    {
        $scope.callSimpleService("removeLocalVar",{"variableId":variableId,"taskId":$scope.selected.id},function()
        {
            var task = $scope.selected;
            task.localVariables.splice($index,1);
            $scope.$apply();
        });
    }

    $scope.pushArray = function(arrayDestiny,arraySource)
    {
        for(var a in arraySource)
        {
            arrayDestiny.push(arraySource[a]);
        }
    }

    $scope.getAllVariables = function()
    {
        var allVariables = [];
        if($scope.process.processVariables)
            $scope.pushArray(allVariables,$scope.process.processVariables);
        var task = $scope.selected;
        if(task)
        {
            if(task.localVariables)
                $scope.pushArray(allVariables,task.localVariables);
            var isActorTask = task["@class"].startsWith("<%=pt.estgp.estgweb.domain.BpmnFlowComponentTaskActor.class.getName()%>");
            if(isActorTask)
                $scope.pushArray(allVariables,$scope.constantVariablesActorTask);
            else
                $scope.pushArray(allVariables,$scope.constantVariables);
        }
        return allVariables;
    }

    /**
     * @classe class to match
     * @superClasses array of strings
     * */
    $scope.contains = function(superClasses,classe)
    {
        if(superClasses)
        {
            for(var i in superClasses)
            {
                if(classe == superClasses[i])
                    return true;
            }
        }
        return false;
    }


    /**
     *   Return variables that match the given attribute className
     *   If attribution = true means that readonly process variables are not allowded
     *

         A verificação de variáveis possíveis de Atribuir considera duas situações
         Chamado em duas Situações,
         1) a escolha de variável para a atribuição
         2) a escolha de variável para argumento de um método

         1) Definição com Exemplo
         User  metodo(…);
         returnType = User
         returnTypeSuperClasses = [SigesUser,GenericUser,DomainObject]

         var1 Teacher
         className=Teacher
         classNameSuperTypes =  [User,SigesUser,GenericUser,DomainObject,Object]
         var2 DomainObject
         className= DomainObject
         classNameSuperTypes =  [DomainObject,Object]

         Para poder ser feita uma atribuição, ou seja para a variável var1 e/ou var2 ser uma das possíveis
         tem de respeitar a seguinte condição
         returnType instanceOf varN é possivel
         O que significa executar o seguinte algoritmo com resposta positiva

         varN.className == returnType || returnTypeSuperClasses contains varN.className
         neste sentido a var 2 pode ser usada na atribuição e a var 1 não


         2) Definição com Exemplo
            ... metodo(User);
             argument.className = User
             argument.classNameSuperClasses = [SigesUser,GenericUser,DomainObject]

             var1 Teacher
             className=Teacher
             classNameSuperTypes =  [User,SigesUser,GenericUser,DomainObject,Object]
             var2 DomainObject
             className= DomainObject
             classNameSuperTypes =  [DomainObject,Object]

             Para poder ser feita uma atribuição, ou seja para a variável var1 e/ou var2 ser uma das possíveis
             tem de respeitar a seguinte condição

             varN instanceOf argument.className é possivel (A condicao é ao contrario da anterior em 1)

             O que significa executar o seguinte algoritmo com resposta positiva

             varN.className == argument.className || varN.classNameSuperClasses contains argument.className
             neste sentido a var 1 pode ser usada na atribuição e a var 2 não



     * */
    $scope.getPossibleVariables = function(className,classNameSuperClasses,forAttribution,afterUserCalls)
    {
        if(!$scope.selected || !className)
            return;
        var isActorTask = $scope.selected["@class"].startsWith("<%=pt.estgp.estgweb.domain.BpmnFlowComponentTaskActor.class.getName()%>");
        var possibleVars = [];
        var task = $scope.selected;

        for(var v in $scope.process.processVariables)
        {
            var processVariable = $scope.process.processVariables[v];
            if(className == processVariable.type.className)
            {
                possibleVars.push(processVariable);
            }
            else if(forAttribution && $scope.contains(classNameSuperClasses,processVariable.type.className))
            {
                possibleVars.push(processVariable);
            }
            else if(!forAttribution && $scope.contains(processVariable.type.classNameSuperClasses,className))
            {
                possibleVars.push(processVariable);
            }
        }
        for(var v in task.localVariables)
        {
            var taskVariable = task.localVariables[v];
            if(className == taskVariable.type.className)
            {
                possibleVars.push(taskVariable);
            }
            else if(forAttribution && $scope.contains(classNameSuperClasses,taskVariable.type.className))
            {
                possibleVars.push(taskVariable);
            }
            else if(!forAttribution && $scope.contains(taskVariable.type.classNameSuperClasses,className))
            {
                possibleVars.push(taskVariable);
            }
        }
        //Estas variaveis só podem ser usadas, nunca alteradas
        if(!forAttribution)
        {
            /*
            Ator Antes
            Ator Depois
            Normal
            */
            var atorMasAntesDoForm = !afterUserCalls;  // ATOR ANTES NAO VAI SER USADO SE QUISERMOS EXECUTAR TAREFAS EM BACKGROUND DEVERA SER CRIADA UmA TAREFA SERVIÇO PARA O EFEITO
            var tarefaServicoNormal = !isActorTask; // NORMAL
                                    /*|| atorMasAntesDoForm */
            if(tarefaServicoNormal                             ) // ve vars constantes normais de processo
            {
                for(var v in $scope.constantVariables)
                {
                    var variable = $scope.constantVariables[v];
                    if(className == variable.type.className)
                    {
                        possibleVars.push(variable);
                    }
                    else if($scope.contains(variable.type.classNameSuperClasses,className))
                    {
                        possibleVars.push(variable);
                    }
                }
            }
            else //ATOR DEPOIS Pode usar tudo
            {
                for(var v in $scope.constantVariablesActorTask)
                {
                    var variable = $scope.constantVariablesActorTask[v];
                    if(className == variable.type.className)
                    {
                        possibleVars.push(variable);
                    }
                    else if($scope.contains(variable.type.classNamexSuperClasses,className))
                    {
                        possibleVars.push(variable);
                    }
                }
            }
        }
        return possibleVars;
    }

});
/**
 Directiva showErrors reutilizavel para validação de forms groups
 Basta que um campo no form tenha a classe form-control*

 em cada campo onde quisermos validação é necessario colocar show-errors no container
 e dar um nome unico ao input a validar e também a directiva required

 é necessario dar o nome processoForm neste caso para o save atuar sobre a verificacao de validade da form
 é necessario definir a class .has-error .chosen-container com #a94442 e !important para se sobrebor nos selects do chosen
 */

/*
processEditorModule.directive('showErrors', function($timeout) {
    return {
        restrict: 'A',
        require:  '^form',
        link: function (scope, el, attrs, formCtrl)
        {
            scope.initOk = function(scope, el, attrs, formCtrl) {

                var inputEl   = el[0].querySelector("[name]");
                var inputNgEl = angular.element(inputEl);

                var inputName = inputNgEl.attr('name');

                var blurred = false;
                // only apply the has-error class after the user leaves the text box
                inputNgEl.bind('blur', function() {
                    blurred = true;
                    el.toggleClass('has-error', formCtrl[inputName].$invalid);
                });

                scope.$watch(function() {
                            return formCtrl[inputName].$invalid
                        },
                        function(invalid) {
                            // we only want to toggle the has-error class after the blur
                            // event or if the control becomes valid
                            if (!blurred && invalid) { return }
                            el.toggleClass('has-error', invalid);

                        });


                scope.$on('show-errors-check-validity', function() {
                    el.toggleClass('has-error', formCtrl[inputName].$invalid);
                });

                scope.$on('show-errors-reset', function() {
                    $timeout(function() {
                        el.removeClass('has-error');
                    }, 0, false);
                });
            }
            scope.initClean = function(scope, el, attrs, formCtrl) {


                var inputEl   = el[0].querySelector("[name]");
                var inputNgEl = angular.element(inputEl);

                //scope.$watch("processoForm", function( newValue, oldValue ) {
                if ( inputNgEl.attr('name').indexOf("{")>=0 ) {
                    console.log( "Sujo..." + inputNgEl.attr('name'));
                    $timeout(function() {
                                scope.initClean(scope, el, attrs, formCtrl);
                            }
                            , 100);
                    return;
                }
                else{
                    console.log("LIMPO..." + inputNgEl.attr('name'));
                    scope.initOk(scope, el, attrs, formCtrl);
                }
                //});
            };

            scope.initClean(scope, el, attrs, formCtrl);
        }
    }
});
*/

</script>

<%--#######################################################
    #######################################################
    MODAL PARA OPERACOES SOA
    #######################################################
    #######################################################
--%>
<div class="modal fade" id="soaModalSelector" role="dialog" >
    <div class="modal-dialog" data-width="1024" style="display: block; width: 1024px; margin-top: 50px;" aria-hidden="false">

        <!-- Modal content-->
        <div class="modal-content">
            <div class="modal-header clearfix">
                <h3 class="modal-title">
                    <label class="title-wrap">Selector de connector SOA</label>
                    <button type="button" class="btn btn-danger btn-xs pull-right" data-dismiss="modal"><span class="glyphicon glyphicon-remove small"></span></button>
                </h3>
            </div>
            <div class="modal-body">

                <div class="row">
                    <div class="col-md-5">
                        <div class="form-group">
                            <label class="control-label">Serviço SOA</label>
                            <div>
                                <select class="chosenOff form-control" ng-model="newSoa.className" ng-options="soa.className as soa.serviceRelativeName for soa in servicesSoa"></select>
                            </div>
                        </div>
                        <div ng-show="newSoa.className" class="form-group">
                            <label class="control-label">Método</label>
                            <div>
                                <select ng-change="setArgumentsNewSoa()" class="chosenOff form-control" ng-model="newSoa.methodChoosed" ng-options="m as showMethodSign(m) for m in getServiceMethods(newSoa.className)"></select>
                            </div>


                            <div ng-show="newSoa.methodName">
                                <div class="form-group">
                                    <label class="control-label">Resultado</label>
                                    <div>
                                        <select class="chosenOff form-control" ng-model="newSoa.localObjectHolderName" ng-options="v.name as v.name for v in getPossibleVariables(newSoa.checkReturnType,newSoa.checkReturnTypeSuperClasses,true,false)">

                                        </select>
                                    </div>
                                </div>
                                <table class="table">
                                    <thead>
                                        <tr>
                                            <th>Nome</th>
                                            <th>Variavel Valor</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr ng-repeat="arg in newSoa.arguments">
                                            <td><label class="control-label">{{arg.name}} = </label></td>
                                            <td>
                                                <select class="form-control chosenOff" ng-model="arg.varName" ng-options="v.name as v.name for v in getPossibleVariables(arg.className,arg.classNameSuperClasses,false,newSoa.usaDadosAtorDoFormulario)"></select>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>

                        </div>


                    </div>
                    <div class="col-md-7">
                        <label ng-show="newSoa.className" class="well well-sm">Módulo: {{getService(newSoa.className).serviceModule}}</label>
                        <label ng-show="newSoa.className" class="well well-sm">Serviço: {{getService(newSoa.className).subServiceName}}</label>
                        <label ng-show="newSoa.methodName" class="well well-sm">Método: {{newSoa.methodName}}</label>

                        <div ng-show="newSoa.methodName">
                            <pre ng-show="getServiceMethod().document" class="code">{{getServiceMethod().document}}</pre>
                            <table class="table">
                                <tbody>
                                    <tr>
                                        <td>Retorno</td>
                                        <td>{{getServiceMethod().returnType}}</td>
                                    </tr>
                                    </tbody>
                                </table>
                            <table class="table">
                                <thead>
                                    <tr>
                                        <th>Parametro</th>
                                        <th>Tipo</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr ng-repeat="a in getServiceMethod().arguments">
                                        <td>{{a.name}}</td>
                                        <td>{{a.className}}</td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
                <button ng-show="newSoa.methodName" ng-click="salvarTodoEdit('soaModalSelector')" class="btn btn-success">Salvar</button>
                <button type="button" class="btn btn-danger pull-right" data-dismiss="modal">Sair</button>
            </div>
        </div>
    </div>
</div>



<%--#######################################################
    #######################################################
    MODAL PARA OPERACOES CHAMADA DE FUNÇÃO
    #######################################################
    #######################################################
--%>
<div class="modal fade" id="methodCallModalSelector" role="dialog" >
    <div class="modal-dialog" data-width="1024" style="display: block; width: 1024px; margin-top: 50px;" aria-hidden="false">

        <!-- Modal content-->
        <div class="modal-content">
            <div class="modal-header clearfix">
                <h3 class="modal-title">
                    <label class="title-wrap">Chamada de um método sobre um Variavel</label>
                    <button type="button" class="btn btn-danger btn-xs pull-right" data-dismiss="modal"><span class="glyphicon glyphicon-remove small"></span></button>
                </h3>
            </div>
            <div class="modal-body">

                <div class="row">
                    <div class="col-md-5">
                        <div class="form-group">
                            <label class="control-label">Variavel</label>
                            <div>
                                <select class="chosenOff form-control" ng-change="changeMethodClassTarget()" ng-model="newMethodCall.name" ng-options="var.name as var.name for var in getAllVariables()"></select>
                            </div>
                        </div>
                        <div ng-show="newMethodCall.name" class="form-group">
                            <label class="control-label">Método</label>
                            <div>
                                <select ng-change="setArgumentsNewMethodCallMethod()" class="chosenOff form-control" ng-model="newMethodCall.methodChoosed" ng-options="m as showMethodSign(m) for m in methodsClassSelected"></select>
                            </div>


                            <div ng-show="newMethodCall.methodName">
                                <div class="form-group">
                                    <label class="control-label">Resultado</label>
                                    <div>
                                        <select class="chosenOff form-control" ng-model="newMethodCall.localObjectHolderName" ng-options="v.name as v.name for v in getPossibleVariables(newMethodCall.checkReturnType,newMethodCall.checkReturnTypeSuperClasses,true,false)">

                                        </select>
                                    </div>
                                </div>
                                <table class="table">
                                    <thead>
                                    <tr>
                                        <th>Nome</th>
                                        <th>Variavel Valor</th>
                                    </tr>
                                    </thead>
                                    <tbody>
                                    <tr ng-repeat="arg in newMethodCall.arguments">
                                        <td><label class="control-label">{{arg.name}} = </label></td>
                                        <td>
                                            <select class="form-control chosenOff" ng-model="arg.varName" ng-options="v.name as v.name for v in getPossibleVariables(arg.className,arg.classNameSuperClasses,false,newMethodCall.usaDadosAtorDoFormulario)"></select>
                                        </td>
                                    </tr>
                                    </tbody>
                                </table>
                            </div>

                        </div>


                    </div>
                    <div class="col-md-7">
                        <label ng-show="newMethodCall.name" class="well well-sm">Variável: {{newMethodCall.name}}</label>
                        <label ng-show="newMethodCall.className" class="well well-sm">Classe: {{newMethodCall.className}}</label>
                        <label ng-show="newMethodCall.methodName" class="well well-sm">Método: {{newMethodCall.methodName}}</label>

                        <div ng-show="newMethodCall.methodName">
                            <table class="table">
                                <tbody>
                                <tr>
                                    <td>Retorno</td>
                                    <td>{{newMethodCall.checkReturnType}}</td>
                                </tr>
                                </tbody>
                            </table>
                            <table class="table">
                                <thead>
                                <tr>
                                    <th>Parametro</th>
                                    <th>Tipo</th>
                                </tr>
                                </thead>
                                <tbody>
                                <tr ng-repeat="a in newMethodCall.arguments">
                                    <td>{{a.name}}</td>
                                    <td>{{a.className}}</td>
                                </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
                <button ng-show="newMethodCall.methodName" ng-click="salvarTodoEdit('methodCallModalSelector')" class="btn btn-success">Salvar</button>
                <button type="button" class="btn btn-danger pull-right" data-dismiss="modal">Sair</button>
            </div>
        </div>
    </div>
</div>


<!--TODO TIRAR DAQUI-->
<select ng-model="jsp" class="chosenOff angularChosen" ng-options="o for o in jsps"></select>

<style>
   body{ height: 100vh !important }
</style>
<div class="web-messages"></div>

<%--#######################################################
    #######################################################
    INTERFACE INICIO
    #######################################################
    #######################################################
--%>

<%--PAINEL PRINCIPAL--%>
<form  style="height: 80vh" class="row" name="processoForm">

<%-- #######################################################
     PAINEL PRINCIPAL ESQUERDA--%>
    <div  style="height: 80vh;overflow-y: auto;" class="col-md-6 form-horizontal">



        <div class="panel panel-info panel-block" id="bpmnPools">
            <div class="panel-heading clearfix">
                <span class="glyphicon glyphicon-users"></span>
                Pools de Atores
                <button class="btn btn-xs btn-success pull-right" type="button" ng-click="newActorPool()"><span class="glyphicon glyphicon-plus"></span></button>
            </div>

            <div ng-repeat="a in process.actorPools" class="panel-body gutter-0">
                <div class="panel panel-default" ng-class="{ dirty: a.dirty==true }">
                    <div class="panel-heading clearfix">
                        <a class="pull-right btn btn-default btn-xs bpmnTask" data-nodrag ng-click="addTaskActor(a)" style="margin-right: 8px;">
                            <span class="glyphicon glyphicon-user"></span><span class="bpmn-icon-task"></span></a>
                        <a class="pull-right btn btn-default btn-xs bpmnGateway" data-nodrag ng-click="newFlowComponent('bpmnGateway')" style="margin-right: 8px;">
                            <span class="bpmn-icon-gateway-none"></span></a>
                        <a class="pull-right btn btn-default btn-xs bpmnEndEvent" data-nodrag ng-click="newFlowComponent('bpmnEndEvent')" style="margin-right: 8px;">
                            <span class="bpmn-icon-end-event-none"></span></a>
                    </div>
                    <div class="panel-body">
                        <div class="col-md-1">
                            <span class="glyphicon glyphicon-user"></span>
                        </div>
                        <div class="col-md-5">
                            <input ng-keyup="setDirty(a)" placeholder="Coloque aqui o nome do ator" class="form-control" ng-model="a.name">
                        </div>
                        <div class="col-md-1">
                            <button class="btn btn-xs btn-success pull-right" type="button" ng-click="newRoleForPool(a)"><span class="glyphicon glyphicon-plus"></span>Papel</button>
                        </div>
                        <div class="col-md-4">
                            <label ng-if="a.roles.length == 0">Não obrigatórios</label>
                            <div ng-repeat="r in a.roles" class="gutter-0">
                                <div class="col-md-2">
                                    <a class="btn btn-danger btn-xs" data-nodrag ng-click="a.roles.splice($index, 1)"><span
                                            class="glyphicon glyphicon-remove"></span></a>
                                </div>
                                <div class="col-md-10">

                                    <select class="chosenOff" ng-model="r.role" class="form-control">
                                        <%
                                            for(String role: UserRoleProxy.getUserRoles())
                                            {
                                                request.setAttribute("role",role);
                                        %>
                                        <option value="${role}" ng-selected="{{r.role == '${role}'}}"><bean:message key="user.role.${role}"/></option>
                                        <%
                                            }
                                        %>
                                    </select>
                                </div>

                            </div>
                        </div>
                        <div class="col-md-1">
                            <bacoTags:confirm  msg="Tem a certeza que deseja remover a pool {{a.name}}" targetFunction="angular.element($('#processEditorModule')).scope().removeActorPool({{a.id}},{{$index}});angular.element($('#processEditorModule')).scope().$apply();" btnClass="btn btn-danger btn-xs pull-right" icon="glyphicon glyphicon-remove"/>

                        </div>
                    </div>
                    <div class="panel-body">
                        <div ui-tree="treeOptions" id="page-content-root">
                            <div class="form-group">
                                <label class="control-label"> Pesquisar:</label>
                                <div class="col-md-4">
                                    <input class="form-control" ng-model="a.searchText">
                                </div>
                            </div>

                            <ol ui-tree-nodes ng-model="a.flowComponents">
                                <li   ng-repeat="node in a.flowComponents | filter:a.searchText" ui-tree-node ng-include="'flowComponent_renderer.html'" ng-init="pool=a"></li>
                            </ol>
                        </div>
                    </div>
                </div>

            </div>

        </div>
    </div>


    <%--
    ################################################################################
        Painel DIREITA
        Painel de Propriedades
        ################################################################################
     --%>
    <div class="col-md-6" style="height: 80vh;overflow-y: auto;" >
        <ul class="nav nav-tabs">
            <li class="active"><a data-toggle="tab" href="#processo">Processo</a></li>
            <li><a data-toggle="tab" href="#operacoes">Operações</a></li>
            <li><a data-toggle="tab" href="#variaveis">Variaveis</a></li>
            <li><a data-toggle="tab" href="#debug">Debug</a></li>
        </ul>

        <%--PROCESSO--%>

        <div class="tab-content">
            <div id="processo" class="tab-pane fade in active">
                <div class="panel panel-primary">
                    <div class="panel-heading">
                        Identificação do Processo
                    </div>
                    <div class="panel-body">
                        <div class="form-group" show-errors>
                            <label class="col-md-2 control-label">Nome:</label>
                            <div class="col-md-10"><input name="process.name" required class="form-control" ng-model="process.name"></div>
                        </div>
                        <div class="form-group" show-errors>
                            <label class="col-md-2 control-label">Description:</label>
                            <div class="col-md-10"><textarea required rows="5" class="form-control" ng-model="process.description"></textarea></div>
                        </div>

                        <div id="controloAtividadeDocente" ng-if="process.class == 'BpmnProcessControloAtividadeDocenteImpl'">
                            <div class="well well-sm">
                                Controlo de Atividade Docente
                                <a class="pull-right btn btn-success btn-xs" data-nodrag ng-click="newAtividadePontuada()" style="margin-right: 8px;">
                                    <span class="glyphicon glyphicon-plus"></span></a>
                            </div>
                            <table class="table">
                                <thead>
                                <tr>
                                    <th>Chave ID</th>
                                    <th style="width: 50%">Papel Validador</th>
                                    <th>Pontos</th>
                                    <th>Tipo de Atividade</th>
                                </tr>
                                </thead>
                                <tbody>
                                <tr ng-repeat="a in process.esquemaPontos.atividades">
                                    <td show-errors><input name="process.esquemaPontos.atividades[{{$index}}].tipoAtividadeChave" required type="text" class="form-control" ng-model="a.tipoAtividadeChave"></td>
                                    <td show-errors>
                                        <select name="process.esquemaPontos.atividades[{{$index}}].papelValidador" required class="chosenOff form-control" ng-model="a.papelValidador" class="form-control">
                                            <%
                                                for(String role: UserRoleProxy.getUserRoles())
                                                {
                                                    request.setAttribute("role",role);
                                            %>
                                            <option value="${role}" ng-selected="{{a.papelValidador == '${role}'}}"><bean:message key="user.role.${role}"/></option>
                                            <%
                                                }
                                            %>
                                        </select>
                                    </td>
                                    <td show-errors><input name="process.esquemaPontos.atividades[{{$index}}].pontos" required type="text" class="form-control" ng-model="a.pontos"></td>
                                    <td show-errors><input name="process.esquemaPontos.atividades[{{$index}}].tipoAtividadeNome" required type="text" class="form-control" ng-model="a.tipoAtividadeNome"></td>
                                </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
            </div>

            <%--OPERACOES--%>
            <div id="operacoes" class="tab-pane fade">
                <div  ng-show="!selected" >
                    <div class="alert alert-warning">
                        Clique numa Tarefa para atribuir operações
                    </div>
                </div>
                <div ng-init="startTooltips()" ng-show="selected['@class'].startsWith('<%=BpmnFlowComponentTask.class.getName()%>')" class="panel panel-info panel-block bpmnActorTask" ng-class="{dirty: selected.dirty==true}" >
                    <div class="panel-heading clearfix">
                        <span class="glyphicon glyphicon-users"></span>
                        Tarefa de Utilizador <input ng-keyup="setDirty(selected)" data-nodrag class="form-control" ng-model="selected.title">
                    </div>
                    <div class="panel-body">
                        <div class="panel panel-default">
                            <div class="panel-heading clearfix">
                                Operações de entrada na tarefa
                                <button ng-init="startTooltips(this)" data-toggle="tooltip" title="Chamar Servico SOA" ng-click="openSoaModal()" class="btn btn-default pull-right"><span class="glyphicon glyphicon-cog"></span></button>
                                <button ng-init="startTooltips(this)" data-toggle="tooltip" title="Atribuir variável" ng-click="openMethodCallModal()" class="btn btn-default pull-right"><span class="glyphicon glyphicon-flag"></span></button>
                            </div>
                            <div class="panel-body">

                                <div class="panel panel-primary">
                                    <div class="panel-body">

                                    </div>
                                </div>


                                <div ng-repeat="todo in selected.todos.todos">
                                    <div ng-if="todo['@class']== '<%=ConnectorSoa.class.getName()%>'">
                                        <button ng-click="openSoaModal(todo)" class="btn btn-default">
                                            <span class="glyphicon glyphicon-cog"></span>
                                        </button>
                                        <label class="label label-primary" style="font-size: 1.0em">
                                            {{getSimpleClassName(todo.className)}}
                                        </label>
                                        <label class="label label-info" style="font-size: 1.0em">
                                            {{todo.methodName}}
                                        </label>
                                        <span class="glyphicon glyphicon-arrow-right"></span>
                                        <label class="label label-success" style="font-size: 1.0em">
                                            {{todo.localObjectHolderName}}
                                        </label>

                                        <button ng-click="deleteTodo(selected,$index)" type="button" class="btn btn-danger btn-xs pull-right">
                                            <span class="glyphicon glyphicon-remove small"></span>
                                        </button>
                                    </div>

                                    <div ng-if="todo['@class']== '<%=OperationMethodCall.class.getName()%>'">
                                        <button ng-click="openMethodCallModal(todo)" class="btn btn-default">
                                            <span class="glyphicon glyphicon-flag"></span>
                                        </button>
                                        <label class="label label-success" style="font-size: 1.0em">
                                            {{todo.name}}
                                        </label>
                                        <label class="label label-info" style="font-size: 1.0em">
                                            {{todo.methodName}}
                                        </label>
                                        (
                                            <span class="label-info" ng-repeat="arg in todo.arguments">
                                                {{arg.varName}}
                                            </span>
                                        )
                                        <span class="glyphicon glyphicon-arrow-right"></span>
                                        <label class="label label-success" style="font-size: 1.0em">
                                            {{todo.localObjectHolderName}}
                                        </label>

                                        <button ng-click="deleteTodo(selected,$index)" type="button" class="btn btn-danger btn-xs pull-right">
                                            <span class="glyphicon glyphicon-remove small"></span>
                                        </button>
                                    </div>

                                </div>
                            </div>
                        </div>
                        <div ng-if="selected['@class'].startsWith('<%=BpmnFlowComponentTaskActor.class.getName()%>')" class="panel panel-info panel-block" ng-class="{dirty: selected.dirty==true}" >
                            <div class="panel-heading clearfix">
                                <span class="glyphicon glyphicon-users"></span>
                                Operações de saida da tarefa
                                <button ng-init="startTooltips(this)" data-toggle="tooltip" title="Chamar Servico SOA" ng-click="openSoaModalAtor()" class="btn btn-default pull-right"><span class="glyphicon glyphicon-cog"></span></button>
                                <button ng-init="startTooltips(this)" data-toggle="tooltip" title="Atribuir variável" ng-click="openMethodCallModalAtor()" class="btn btn-default pull-right"><span class="glyphicon glyphicon-flag"></span></button>
                            </div>
                            <div class="panel-body">

                                <div ng-repeat="todo in selected.afterUserTodos.todos">
                                    <div ng-if="todo['@class']== '<%=ConnectorSoa.class.getName()%>'">
                                        <button ng-click="openSoaModalAtor(todo)" class="btn btn-default">
                                            <span class="glyphicon glyphicon-cog"></span>
                                        </button>
                                        <label class="label label-primary" style="font-size: 1.0em">
                                            {{getSimpleClassName(todo.className)}}
                                        </label>
                                        <label class="label label-info" style="font-size: 1.0em">
                                            {{todo.methodName}}
                                        </label>
                                        <span class="glyphicon glyphicon-arrow-right"></span>
                                        <label class="label label-success" style="font-size: 1.0em">
                                            {{todo.localObjectHolderName}}
                                        </label>

                                        <button ng-click="deleteAfterUserTodo(selected,$index)" type="button" class="btn btn-danger btn-xs pull-right">
                                            <span class="glyphicon glyphicon-remove small"></span>
                                        </button>
                                    </div>

                                    <div ng-if="todo['@class']== '<%=OperationMethodCall.class.getName()%>'">
                                        <button ng-click="openMethodCallModalAtor(todo)" class="btn btn-default">
                                            <span class="glyphicon glyphicon-flag"></span>
                                        </button>
                                        <label class="label label-success" style="font-size: 1.0em">
                                            {{todo.name}}
                                        </label>
                                        <label class="label label-info" style="font-size: 1.0em">
                                            {{todo.methodName}}
                                        </label>
                                        (
                                            <span class="label-info" ng-repeat="arg in todo.arguments">
                                                {{arg.varName}}
                                            </span>
                                        )
                                        <span class="glyphicon glyphicon-arrow-right"></span>
                                        <label class="label label-success" style="font-size: 1.0em">
                                            {{todo.localObjectHolderName}}
                                        </label>

                                        <button ng-click="deleteAfterUserTodo(selected,$index)" type="button" class="btn btn-danger btn-xs pull-right">
                                            <span class="glyphicon glyphicon-remove small"></span>
                                        </button>
                                    </div>

                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <%--VARIAVEIS--%>
                <div ng-if="selected['@class'].startsWith('<%=BpmnFlowConnector.class.getName()%>')" class="panel panel-info panel-block bpmnConnector" ng-class="{dirty: selected.dirty==true}">
                    <div class="panel-heading clearfix">
                        <span class="bpmn-icon-connection control-label"></span>
                        Connector -
                        <input ng-keyup="setDirty(selected)" data-nodrag class="form-control" ng-model="selected.nameConnection">
                    </div>


                    <div class="panel-body">

                    </div>
                </div>
            </div>
            <div id="variaveis" class="tab-pane fade">
                <div class="panel panel-primary panel-block">
                    <div class="panel-heading clearfix">
                        <span class="glyphicon glyphicon-flag"></span>
                        Variaveis de Processo

                        <button type="button" class="pull-right btn btn-success btn-xs" ng-click="newProcessVar()" style="margin-right: 8px;">
                            <span class="glyphicon glyphicon-plus"></span>
                        </button>
                    </div>
                    <div class="panel-body">
                        <table class="table">
                            <thead>
                                <tr>
                                    <th>Nome da variavel</th>
                                    <th>Tipo</th>
                                    <th></th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr ng-class="{ dirty: v.dirty==true }" ng-repeat="v in process.processVariables">
                                    <td>
                                        <input ng-keyup="setDirty(v)" ng-model="v.name" class="form-control"></td>
                                    <td>
                                        <select ng-change="setDirty(v)" class="form-control chosenOff" ng-model="v.type" ng-options="vT as vT.shortName for vT in processVariableTypes track by vT.className" >

                                        </select>
                                    </td>
                                    <td>
                                        <button ng-click="removeProcessVar(v.id,$index)" type="button" class="btn btn-danger btn-xs pull-right">
                                            <span class="glyphicon glyphicon-remove small"></span>
                                        </button>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>


                <div class="panel panel-info panel-block bpmnActorTask" ng-show="selected['@class'].startsWith('<%=BpmnFlowComponentTask.class.getName()%>')">
                    <div class="panel-heading clearfix">
                        <span class="glyphicon glyphicon-flag"></span>
                        Variaveis Locais {{selected.title}}
                        <button type="button" class="pull-right btn btn-success btn-xs" ng-click="newLocalVar(selected)" style="margin-right: 8px;">
                            <span class="glyphicon glyphicon-plus"></span>
                        </button>
                    </div>
                    <div class="panel-body">
                        <table class="table">
                            <thead>
                            <tr>
                                <th>Nome da variavel</th>
                                <th>Tipo</th>
                                <th></th>
                            </tr>
                            </thead>
                            <tbody>
                                <tr ng-class="{ dirty: v.dirty==true }" ng-repeat="v in selected.localVariables">
                                    <td>
                                        <input ng-keyup="setDirty(v)" ng-model="v.name" class="form-control"></td>
                                    <td>
                                        <select ng-change="setDirty(v)" class="form-control chosenOff" ng-model="v.type" ng-options="vT as vT.shortName for vT in localVariableTypes track by vT.className" >

                                        </select>
                                    </td>
                                    <td>
                                        <button ng-click="removeLocalVar(v.id,$index)" type="button" class="btn btn-danger btn-xs pull-right">
                                            <span class="glyphicon glyphicon-remove small"></span>
                                        </button>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>

            <%--DEBUG--%>
            <div id="debug" class="tab-pane fade">
                <h2>Debug</h2>

                <a href="#Tiposdevariaveldeprocesso">Tiposdevariaveldeprocesso</a>
                <a href="#Tiposdevariavellocal">Tiposdevariavellocal</a>
                <a href="#AllFlowComponents">AllFlowComponents</a>
                <a href="#ProcessoJson">ProcessoJson</a>
                <a href="#newSoa">newSoa</a>
                <a href="#ServicesSoa">ServicesSoa</a>
                <a href="#newMethodCall">newMethodCall</a>
                <a href="#methodsClassSelected">methodsClassSelected</a>
                <a href="#methodsClassSelected">methodsClassSelected</a>

                <a name="Tiposdevariaveldeprocesso"></a>
                <h2>Tipos de variavel de processo</h2>
                <pre class="code">{{ processVariableTypes | json }}</pre>

                <a name="Tiposdevariavellocal"></a>
                <h2>Tipos de variavel local</h2>
                <pre class="code">{{ localVariableTypes | json }}</pre>

                <a name="AllFlowComponents"></a>
                <h2>All Flow Components</h2>
                <pre class="code">{{ allFlowComponents | json }}</pre>

                <a name="ProcessoJson"></a>
                <h2>Processo Json</h2>
                <pre class="code">{{ process | json }}</pre>

                <a name="newSoa"></a>
                <h2>newSoa</h2>
                <pre class="code">{{ newSoa | json }}</pre>

                <a name="ServicesSoa"></a>
                <h2>Services Soa</h2>
                <pre class="code">{{ servicesSoa | json }}</pre>

                <a name="newMethodCall"></a>
                <h2>newMethodCall</h2>
                <pre class="code">{{newMethodCall | json}}</pre>

                <a name="methodsClassSelected"></a>
                <h2>methodsClassSelected</h2>
                <pre class="code">{{methodsClassSelected | json}}</pre>
            </div>
        </div>


    </div>
</form>




<style>
    table.tableHeading
    {
        border: 0;
        width: 100%;
    }
    table.tableHeading td
    {
        padding: 5px;

    }
    table.tableHeading td.headingTitle
    {
        width: 50%;
    }

</style>


<script type="text/ng-template" id="flowComponent_renderer.html">
    <!-- Coloquei aqui o predicado no NGClass que quando existe uma property nodrop = true o angular coloca nodrop na class o que faz o elemento ficar a vermelho e nao permite drop-->
    <div ng-click="select(node)" class="panel panel-default panel-block tree-node tree-node-content nodrop"  ng-class="{selected: node.selected == true, bpmnActorTask: node['@class'] == '<%=BpmnFlowComponentTaskActorImpl.class.getName()%>',dirty: node.dirty==true,nodrop: node.nodrop, nodrag: node.nodrag, moved: node.moved}">
        <!--<div class="panel-heading clearfix" ng-class="node.type">
            <div class="row gutter-0">
                <div class="col-md-12">






                </div>
            </div>
        </div>-->
        <div class="panel-body">
            <table class="tableHeading">
                <tr>
                    <td><i class="glyphicon glyphicon-resize-vertical" ui-tree-handle></i></td>
                    <td>
                        <span ng-if="node['@class'] == '<%=BpmnFlowComponentTaskActorImpl.class.getName()%>'">
                            <span class="glyphicon glyphicon-user"></span><span class="bpmn-icon-task"></span>
                        </span>
                        <span ng-if="node.type == 'bpmnGateway'" class="bpmn-icon-gateway-none"></span>
                        <span ng-if="node.type == 'bpmnEndEvent'" class="bpmn-icon-end-event-none"></span>
                        <label ng-if="node['@class'] == '<%=BpmnFlowComponentTaskActorImpl.class.getName()%>'" class="control-label">Tarefa Actor</label>
                        <label ng-if="node.type == 'bpmnGateway'" class="control-label">Gateway</label>
                        <label ng-if="node.type == 'bpmnEndEvent'" class="control-label">EventoFim</label>
                    </td>
                    <td class="headingTitle">
                        <input ng-keyup="setDirty(node)" data-nodrag class="form-control" ng-model="node.title">
                    </td>
                    <td>
                        <bacoTags:confirm  msg="Tem a certeza que deseja remover a atividade {{node.name}}" targetFunction="angular.element($('#processEditorModule')).scope().removeTask({{pool.id}},{{node.id}},{{$index}});angular.element($('#processEditorModule')).scope().$apply();" btnClass="btn btn-danger btn-xs pull-right" icon="glyphicon glyphicon-remove"/>
                    </td>
                </tr>
            </table>
            <%--
            <div class="form-group">
                <div class="col-md-2">
                    <span class="glyphicon glyphicon-user"></span> Actor Pool
                </div>
                <div class="col-md-10">
                    <select ng-change="setDirty(node)" class="chosenOff form-control" ng-model="node.actorPool" class="form-control">
                        <option ng-repeat="a in process.actorPools" value="{{a.id}}" ng-selected="{{a.id == node.actorPool}}">{{a.name}}</option>
                    </select>
                </div>
            </div>
            --%>
        </div>
        <div class="panel-footer clearfix">
            <a class="btn btn-success btn-xs" ng-if="node.flowConnectors && node.flowConnectors.length > 0" data-nodrag ng-click="toggle(this)">
                <span class="glyphicon" ng-class="{'glyphicon-chevron-right': collapsed,'glyphicon-chevron-down': !collapsed}"></span>
            </a>

            <a class="pull-right btn btn-default btn-xs" data-nodrag ng-click="addConnector(node)" style="margin-right: 8px;"><span
                    class="bpmn-icon-connection"></span></a>

        </div>
    </div>

    <ol ui-tree-nodes="" data-nodrop-enabled="true" ng-model="node.flowConnectors" ng-class="{hidden: collapsed}" ng-init="task=node">
        <li ng-repeat="node in node.flowConnectors" ui-tree-node ng-include="'connector_renderer.html'">
        </li>
    </ol>
</script>


<script type="text/ng-template" id="connector_renderer.html">
    <!-- Coloquei aqui o predicado no NGClass que quando existe uma property nodrop = true o angular coloca nodrop na class o que faz o elemento ficar a vermelho e nao permite drop-->


    <div ng-click="select(node)" class="panel panel-info panel-block tree-node tree-node-content bpmnConnector" data-nodrag ng-class="{dirty: node.dirty==true, selected: node.selected == true,nodrop: node.nodrop, nodrag: node.nodrag, moved: node.moved}">
        <div class="panel-heading clearfix" ng-class="node.type">
            <div class="row gutter-0">
                <table class="tableHeading">
                    <tr>
                        <!--<td><i class="glyphicon glyphicon-resize-vertical" ui-tree-handle></i></td>-->
                        <td>
                            <span class="bpmn-icon-connection control-label"></span> Conector
                        </td>
                        <td class="headingTitle">
                            <input ng-keyup="setDirty(node)" data-nodrag class="form-control" ng-model="node.nameConnection">
                        </td>
                        <td>
                            <bacoTags:confirm  msg="Tem a certeza que deseja remover o connector {{node.name}}" targetFunction="angular.element($('#processEditorModule')).scope().removeConnector({{node.id}},{{task.id}},{{pool.id}},{{$index}});angular.element($('#processEditorModule')).scope().$apply();" btnClass="btn btn-danger btn-xs pull-right" icon="glyphicon glyphicon-remove"/>
                        </td>
                    </tr>
                </table>
            </div>
        </div>
        <div class="panel-body">
            <div class="form-group">
                <div class="col-md-2">
                    <span class="glyphicon glyphicon-arrow-right"></span> Ligação
                </div>
                <div class="col-md-10">
                    <select ng-change="setDirty(node)" data-nodrag class="form-control" ng-model="node.flowComponentId"
                            ng-options="f.id as f.title for f in allFlowComponents">
                    </select>
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-2">
                    <span class="glyphicon glyphicon-tag"></span> Chave
                </div>
                <div class="col-md-10">
                    <input type="text" ng-keyup="setDirty(node)" data-nodrag class="form-control" ng-model="node.keyValue">
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-2">
                    <span class="glyphicon glyphicon-envelope"></span> Enviar Emails
                </div>
                <div class="col-md-2">
                    <select class="form-control chosenOff" ng-change="setDirty(node)" ng-model="node.sendEmail" ng-options="o.v as o.n for o in [{ n: 'Sim', v: true }, { n: 'Não', v: false }]">
                    </select>
                </div>
            </div>
            <div class="form-group" ng-show="node.sendEmail==true">
                <div class="col-md-2">
                    Mensagem
                </div>
                <div class="col-md-10">
                    <textarea ng-keyup="setDirty(node)" rows="3" class="form-control" ng-model="node.msgEmail"></textarea>
                </div>
            </div>
        </div>
    </div>



</script>



<!--Estilos CSS do Exemplo do Overview Nem olhei para eles copy paste e pronto-->
<style>

    .panel-block .panel-heading, .panel-block .panel-footer
    {
        padding:5px;
    }

    /* remove */
    .gutter-0.row {
        margin-right: -0px !important;
        margin-left: -0px !important;
    }
    .gutter-0 > [class*="col-"]{
        padding-right: 0px !important;
        padding-left: 0px !important;
    }

    /* customize */
    .gutter-6.row {
        margin-right: -3px !important;
        margin-left: -3px !important;
    }
    .gutter-6 > [class*="col-"] {
        padding-right: 3px !important;
        padding-left: 3px !important;
    }




    .panel-info.bpmnActorTask > .panel-heading, .bpmnActorTask{ background-color: #fff2c3 !important;border-color: #c69763 !important }
    .bpmnTask { background-color: #fff2c3 !important;border-color: #c69763 !important }
    .bpmnStartEvent { background-color: #EEF1CA !important; border-color: #A5CF84 !important }
    .bpmnMiddleEvent { background-color: #A7BBCF !important ;border-color: #4F87B0 !important}
    .bpmnEndEvent { background-color: #FDE6E2 !important; border-color: #8C121D; !important }
    .bpmnGateway { background-color: #ffcf53 !important; border-color: #ffa42a !important}
    .bpmnFase { background-color: #ECECF4 !important; border-color: #276E9F !important}
    .panel-info.bpmnConnector > .panel-heading , .bpmnConnector { background-color: white !important; ;border-color: #b7bdbb !important }



    .panel-info.bpmnActorTask.selected > .panel-heading,.bpmnActorTask.selected { background-color: #e7daac !important;border-color: #c69763 !important }
    .bpmnTask { background-color: #fff2c3 !important;border-color: #c69763 !important }
    .bpmnStartEvent { background-color: #EEF1CA !important; border-color: #A5CF84 !important }
    .bpmnMiddleEvent { background-color: #A7BBCF !important ;border-color: #4F87B0 !important}
    .bpmnEndEvent { background-color: #FDE6E2 !important; border-color: #8C121D; !important }
    .bpmnGateway { background-color: #ffcf53 !important; border-color: #ffa42a !important}
    .bpmnFase { background-color: #ECECF4 !important; border-color: #276E9F !important}
    .panel-info.bpmnConnector.selected > .panel-heading , .bpmnConnector.selected { background-color: #dadada !important; ;border-color: #b7bdbb !important }

    .btn {
        margin-right: 8px;
    }


    .angular-ui-tree-handle {
        background: #f8faff;
        border: 1px solid #dae2ea;
        color: #7c9eb2;
        padding: 0;
    }

    .angular-ui-tree-handle:hover {
        color: #438eb9;
        background: #f4f6f7;
        border-color: #dce2e8;
    }

    .angular-ui-tree-placeholder {
        background: #f0f9ff;
        border: 2px dashed #bed2db;
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
    }

    tr.angular-ui-tree-empty {
        height:100px
    }

    .group-title {
        background-color: #687074 !important;
        color: #FFF !important;
    }


    /* --- Tree --- */
    .tree-node {
        border: 1px solid #dae2ea;
        background: #f8faff;
        color: #7c9eb2;
    }

    .nodrop {
        background-color: #f2dede;
    }


    .nodrag {
        background-color: #f2eec1;
    }

    .tree-node-content {
        margin: 10px;
    }
    .tree-handle {
        /*padding: 10px;*/
        background: #428bca;
        color: #FFF;
        margin-right: 15px;
    }

    .angular-ui-tree-handle:hover {
    }

    .angular-ui-tree-placeholder {
        background: #f0f9ff;
        border: 2px dashed #bed2db;
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
    }

    /*Estilo adicionado por mim para os movidos*/
    .moved
    {
        border: 2px solid blue !important;
    }
</style>
</div>

<%
    AbstractDao.getCurrentSession().getTransaction().commit();
%>