//全局Ajax事件
$.ajaxSetup({
    dataType: 'JSON',
    cache: false,       //禁止IE9缓存
    dataFilter: function (data, type) {
        var result = JSON.parse(data);
        if (!result.isSuccess) alert(result.message);
        return data;
    }
});
$(document).ajaxError(function (event, xhr, settings, error) {
    alert('请求失败，请重试。');
});
$(document).ajaxStart(function () {
    layer.load(2, {shade: [0.3, '#3333333']});
});
$(document).ajaxStop(function () {
    layer.closeAll('loading');
});

//-----------------------------------------------------------------------------

var getUrlParams = function (name) {
    var url = window.location.search.substring(1);
    var variables = url.split('&');
    for (var i = 0; i < variables.length; i++) {
        var params = variables[i].split('=');
        if (params[0] == name) {
            return params[1];
        }
    }
    return '';
};

var runtimeProcessId = getUrlParams('runtimeProcessId');    //运行时流程Id
var deploySid = getUrlParams('deploySid');                  //部署标识符
var sub = getUrlParams('sub');                              //子流程活动
/*console.log(runtimeProcessId);
console.log(deploySid);
console.log(sub);*/

if (runtimeProcessId == '' && deploySid == '') {
    alert('必须指定运行时流程或部署标识符才能查看流程图。');
    throw new Error('必须指定运行时流程或部署标识符才能查看流程图。');
}

jsPlumb.ready(function () {
    //画布
    var canvas = document.getElementById('canvas_view');
    //jsPlumb实例
    var instance = jsPlumb.getInstance({
        //Endpoint: 'Blank',
        Endpoint: ['Dot', {radius: 7}],
        //Endpoint: ['Rectangle', { width: 15, height: 15 }],
        EndpointStyle: {'fill': '#cccccc', outlineStroke: 'black', outlineWidth: 1},
        Connector: ['Flowchart', {cornerRadius: 5}],
        PaintStyle: {stroke: 'gray', strokeWidth: 2},
        HoverPaintStyle: {stroke: '#ff0000', strokeWidth: 2},
        ConnectionOverlays: [['Arrow', {location: 1, id: 'arrow', width: 10, length: 10, foldback: 0.8}]],
        Container: 'canvas_view'
    });

    //切换连线类型
    $('#lineType').change(function () {
        var lineType = $('#lineType').val();
        console.log(lineType);
        var connector = undefined;
        if (lineType == '1') {
            connector = ['Flowchart', {cornerRadius: 5}];
        } else if (lineType == '2') {
            connector = ['StateMachine'];
        } else if (lineType == '3') {
            connector = ['Straight'];
        }
        if (connector == undefined)
            return;
        instance.importDefaults({Connector: connector});
        //重绘所有连线
        var connections = instance.getAllConnections();
        $.each(connections, function (index, conn) {
            //console.log(conn);
            conn.setConnector(connector);
            conn.addOverlay(['Arrow', {location: 1, id: 'arrow', width: 10, length: 10, foldback: 0.8}]);
        });
    });

    //-------------------------------------------------------------------------

    //设置元素，添加拖动/缩放支持、设置连线source/target属性
    var setElement = function (el, activityType, id, sourceMaxConnections, targetMaxConnections, allowLoopback,
                               resizable, left, top, width, height) {
        el.id = id;
        el.style.left = left + 'px';
        el.style.top = top + 'px';
        if (width != undefined && width != '') el.style.width = parseInt(width) + 'px';
        if (height != undefined && height != '') el.style.height = parseInt(height) + 'px';
        el.className = 'element activity_' + activityType;
        el.setAttribute('activityType', activityType);
        instance.getContainer().appendChild(el);
        //设置元素可以连线，maxConnections=-1表示无限制，0表示不接收拉出连线/接收连线
        if (sourceMaxConnections != 0) {
            instance.makeSource(el, {
                filter: '.ctl_ep',
                //anchor: 'AutoDefault',
                anchor: 'Continuous',
                maxConnections: sourceMaxConnections,
                onMaxConnections: function (info, e) {
                    alert('最多只能有(' + info.maxConnections + ') 个后续流程活动。');
                }
            });
        }
        if (targetMaxConnections != 0) {
            instance.makeTarget(el, {
                //anchor: 'AutoDefault',        //只会显示在四个边中间位置
                anchor: 'Continuous',
                allowLoopback: allowLoopback,   //是否允许连接到自已
                maxConnections: targetMaxConnections,
                onMaxConnections: function (info, e) {
                    alert('最多只能有 (' + info.maxConnections + ') 个前置流程活动。');
                }
            });
        }
        //拖动支持
        instance.draggable(el, {
            //containment: 'parent',            //此配置会使超出画布显示区域（位于滚动条中）的元素一旦移动就跳回画布显示区域中
            grid: [10, 5],
            filter: '.ui-resizable-handle',     //拖动时过滤调整大小控制元素
            stop: function (event, ui) {
            }
        });
        //缩放支持
        if (resizable) {
            $(el).resizable({
                grid: [20, 10],
                autoHide: true,
                containment: 'parent',      //缩放时不超出父元素
                resize: function (event, ui) {
                    //printLayer(el);
                    $(el).children('.position_info').show();
                    var minWidth = parseInt($(el).css('min-width'));
                    var minHeight = parseInt($(el).css('min-height'));
                    var width = $(el).width();
                    var height = $(el).height();
                    if (width < minWidth) width = minWidth; else width = width + 4;
                    if (height < minHeight) height = minHeight; else height = height + 4;
                    $(el).children('.position_info').text(width + ' * ' + height);
                    instance.repaintEverything();
                    //instance.repaint(el.id);
                    instance.revalidate(el.id); //resize后重新计算endpoints位置
                },
                stop: function (event, ui) {
                    //printLayer(el);
                    $(el).children('.position_info').hide();
                    //resize后长宽会少2像素
                    //console.log(ui.size);   //当有min-*设置时，此信息为释放鼠标的位置，与元素尺寸不一致
                    var minWidth = parseInt($(el).css('min-width'));
                    var minHeight = parseInt($(el).css('min-height'));
                    var width = $(el).width();
                    var height = $(el).height();
                    if (width > minWidth) $(el).css('width', (width + 4) + 'px');
                    if (height > minHeight) $(el).css('height', (height + 4) + 'px');
                }
            });
        }
    };
    var appendElementStart = function (id, left, top) {
        var el = document.createElement('div');
        el.innerHTML = '<div class="title">开始</div>'
            + '<div class="control_container"><div class="ctl_sel fa fa-check"></div></div>';
        setElement(el, 'start', id, 1, 0, false,
            false, left, top);
        return el;
    };
    var appendElementTask = function (id, name, left, top, width, height) {
        var el = document.createElement('div');
        el.innerHTML = '<div class="position_info"></div><div class="title">处理</div><div class="name">' + name + '</div>'
            + '<div class="control_container"><div class="ctl_edit fa fa-cog"></div>'
            + '<div class="ctl_sel fa fa-check"></div></div>';
        setElement(el, 'task', id, -1, -1, true,
            true, left, top, width, height);
        return el;
    };
    var appendElementDecision = function (id, name, left, top, width, height) {
        var el = document.createElement('div');
        el.innerHTML = '<div class="position_info"></div><div class="title">判定</div><div class="name">' + name + '</div>'
            + '<div class="control_container">'
            + '<div class="ctl_sel fa fa-check"></div></div>';
        setElement(el, 'decision', id, -1, -1, false,
            true, left, top, width, height);
        return el;
    };
    var appendElementConcurrency = function (id, name, left, top, width, height) {
        var el = document.createElement('div');
        el.innerHTML = '<div class="position_info"></div><div class="title">并行</div><div class="name">' + name + '</div>'
            + '<div class="control_container"><div class="ctl_edit fa fa-cog"></div>'
            + '<div class="ctl_sel fa fa-check"></div></div>'
            + '<div class="concurrency_subprocesses"></div>';
        setElement(el, 'concurrency', id, 1, -1, false,
            true, left, top, width, height);
        return el;
    };
    var appendElementReplication = function (id, name, left, top, width, height) {
        var el = document.createElement('div');
        el.innerHTML = '<div class="position_info"></div><div class="title">重复</div><div class="name">' + name + '</div>'
            + '<div class="control_container"><div class="ctl_edit fa fa-cog"></div>'
            + '<div class="ctl_sel fa fa-check"></div></div>'
            + '<div class="replication_subprocess">'
            + '<a href="diagram.html?runtimeProcessId=' + runtimeProcessId + '&deploySid=' + deploySid + '&sub=' + id + '" target="_blank" title="子流程">'
            + '<i class="fa fa-edit"></i></a></div>';
        setElement(el, 'replication', id, 1, -1, false,
            true, left, top, width, height);
        return el;
    };
    var appendElementEnd = function (id, left, top/*, hasCc*/) {
        var el = document.createElement('div');
        el.innerHTML = //'<div class="title' + (hasCc ? ' highlight' : '') + '">结束</div>'
            '<div class="title">结束</div>'
            //+ '<div class="control_container">' + (sub == undefined ? '<div class="ctl_edit fa fa-cog"></div>' : '') //只能根流程可以配置抄送
            + '<div class="control_container">'
            + '<div class="ctl_sel fa fa-check"></div></div>';
        setElement(el, 'end', id, 0, -1, false,
            false, left, top);
        return el;
    };
    //打印布局信息，调试用
    var printLayer = function (el) {
        console.log(
            'element:offsetLeft=' + el.offsetLeft + ',offsetTop=' + el.offsetTop + ','
            + 'offsetWidth=' + el.offsetWidth + ',offsetHeight=' + el.offsetHeight + ';'
            + 'jquery:offset=' + JSON.stringify($(el).offset()) + ','
            + 'position=' + JSON.stringify($(el).position()) + ','
            + 'scrollLeft=' + $(el).scrollLeft() + ',scrollTop=' + $(el).scrollTop() + ','
            + 'width=' + $(el).width() + ',height=' + $(el).height() + ','
            + 'outerWidth=' + $(el).outerWidth() + ',outerHeight=' + $(el).outerHeight() + ','
            + 'innerWidth=' + $(el).innerWidth() + ',innerHeight=' + $(el).innerHeight() + ','
            + 'css(width)=' + $(el).css('width') + ',css(height)=' + $(el).css('height') + ';'
        );
    };

    //-------------------------------------------------------------------------

    //添加并行子流程元素
    var appendElementConcurrencySubprocess = function (activityId, subprocessId, subprocessName) {
        $('#' + activityId).children('.concurrency_subprocesses').append(
            '<div class="concurrency_subprocess" id="' + subprocessId + '">'
            + '<div class="concurrency_subprocess_name">'
            + '<a href="diagram.html?runtimeProcessId=' + runtimeProcessId + '&deploySid=' + deploySid + '&sub=' + subprocessId + '" title="' + subprocessName + '" target="_blank">'
            + subprocessName + '</a></div>'
            + '</div>'
        );
    };

    //-------------------------------------------------------------------------

    //全选
    $('#selectAll').click(function () {
        $('#canvas_view .element').each(function (index) {
            if (!$(this).hasClass('element_selected')) {
                $(this).addClass('element_selected');
                instance.addToDragSelection($(this));
            }
        });
    });
    //点击空白处取消选中
    $('#canvas_view').on('click', function (e) {
        if ($(e.target).closest('.element').length == 0) {
            $('#canvas_view .element').each(function (index) {
                if ($(this).hasClass('element_selected'))
                    $(this).removeClass('element_selected');
            });
            instance.clearDragSelection();
        }
    });
    //选中元素
    $('#canvas_view').on('click', '.ctl_sel', function (e) {
        var target = $(e.target).closest('.element');
        if (target.hasClass('element_selected')) {
            target.removeClass('element_selected');
            instance.removeFromDragSelection(target);
        } else {
            target.addClass('element_selected');
            instance.addToDragSelection(target);
        }
    });
    //鼠标事件，元素控制图标显示/隐藏
    $('#canvas_view').on('mouseenter', '.element', function () {
        $(this).children('.control_container').show();
    });
    $('#canvas_view').on('mouseleave', '.element', function () {
        $(this).children('.control_container').hide();
    });

    var zindex = 1;
    //点击元素使其置顶
    jsPlumb.on(canvas, "click", ".element", function (e) {
        $(this).css("z-index", ++zindex);
    });
    //点击连线使其置顶
    jsPlumb.on(canvas, "click", ".jtk-overlay", function (e) {
        $(this).css("z-index", ++zindex);
    });

    //-------------------------------------------------------------------------

    //连接元素
    instance.bind('connection', function (info) {
        //console.log(info);
        var conn = info.connection;
        if (instance.select({source: conn.sourceId, target: conn.targetId}).length > 1) {
            alert('不能重复连接。');
            instance.deleteConnection(conn);
            return;
        }
        var activityType = $(info.source).attr('activityType');
        var name = '';
        //设置判定条件连接事件
        if (activityType == 'decision') {
            name = '未命名条件';
            //info.connection.getOverlay('label').setLabel(info.connection.id);
            var count = instance.getConnections({source: info.sourceId}).length;
            conn.addOverlay([
                'Label', {
                    label: count + '.' + name,
                    id: 'label',
                    cssClass: 'connection_label',
                    events: {
                        click: function (params) {
                            //$console(params);
                            var sourceId = $(params).attr('sourceId');
                            var targetId = $(params).attr('targetId');
                            var condition = getDecisionCondition(sourceId, targetId);
                            if (condition != undefined) {
                                $('#conditionName').text(condition.name);
                                $('#conditionExpression').text(condition.conditionExpression);
                                $('#dialogDecisionCondition').dialog({
                                    modal: true,
                                    width: 500,
                                    title: '判定条件'
                                });
                            }
                        }
                    }
                }
            ]);
            //info.connection.getOverlay('label').setLabel(count + '.' + name);
            var lbl = info.connection.getOverlay('label');
            $(lbl).attr('sourceId', conn.sourceId);
            $(lbl).attr('targetId', conn.targetId);
        }
        //设置处理动作连接事件
        if (activityType == 'task') {
            name = '未命名动作';
            conn.addOverlay([
                'Label', {
                    label: name,
                    id: 'label',
                    cssClass: 'connection_label',
                    events: {
                        click: function (params) {
                            var sourceId = $(params).attr('sourceId');
                            var targetId = $(params).attr('targetId');
                            var action = getTaskAction(sourceId, targetId);
                            // console.log(action);
                            if (action != undefined) {
                                $('#actionSid').text(action.sid);
                                $('#actionName').text(action.name);
                                $('#actionDescription').text(action.description);
                                $('#actionAdditionalControl').text(action.additionalControl);
                                $('#actionAdditionalControlParam').text(action.additionalControlParam);
                                $('#actionCommentLabel').text(action.commentLabel);
                                if (action.commentRequired != null) {
                                    if (action.commentRequired)
                                        $('#actionCommentRequired').text('必填');
                                    else
                                        $('#actionCommentRequired').text('可空');
                                } else
                                    $('#actionCommentRequired').text('不显示');
                                $('#actionSwitchable').text(action.switchable ? '是' : '否');
                                $('#actionSwitchParam').text(action.switchParam);
                                $('#dialogTaskAction').dialog({
                                    modal: true,
                                    width: 500,
                                    title: '处理动作',
                                });
                            }
                        }
                    }
                }
            ]);
            var lbl = info.connection.getOverlay('label');
            $(lbl).attr('sourceId', conn.sourceId);
            $(lbl).attr('targetId', conn.targetId);
        }
    });

    //-------------------------------------------------------------------------

    //编辑活动
    jsPlumb.on(canvas, 'click', '.ctl_edit', function (e) {
        var el = $(this).closest('.element');
        var activityType = el.attr('activityType');
        var activityId = el.attr('id');
        var activity = getActivity(activityId);
        //处理活动
        if (activityType == 'task') {
            $('#taskName').text(activity.name);
            $('#taskSid').text(activity.sid);
            $('#taskActorExpression').text(activity.actorExpression);
            $('#taskAllowDeliver').text(activity.allowDeliver ? '是' : '否');
            if (activity.allowDeliver) {
                $('#trTaskDeliverControl').show();
                $('#taskDeliverControl').text(activity.deliverControl);
            } else {
                $('#trTaskDeliverControl').hide();
            }
            //初始化可退回至范围
            $('#taskAllowReturnTo').empty();
            var taskAllowReturnToNames = $.map(activity.allowReturnToActivitiesId, function (item, index) {
                if (taskActivitiesMap.hasOwnProperty(item))
                    return taskActivitiesMap[item];
            });
            $('#taskAllowReturnTo').text(taskAllowReturnToNames.join('、'));
            $('#taskAllowTakeBack').text(activity.allowTakeBack ? '是' : '否');
            $('#dialogTask').dialog({
                width: 500,
                modal: true,
                title: '处理活动'
            });
            return;
        }
        //并行活动
        if (activityType == 'concurrency') {
            $('#concurrencyName').text(activity.name);
            $('#concurrencySid').text(activity.sid);
            if (activity.endWay == 'All')
                $('#concurrencyEndWay').text('子流程需全部结束');
            else if (activity.endWay == 'Any')
                $('#concurrencyEndWay').text('任意子流程结束即可（其他平行子流程继续运行）');
            else if (activity.endWay == 'AnyEndOther')
                $('#concurrencyEndWay').text('任意子流程结束即可（自动结束其他平行子流程，包括子流程的子流程）');
            $('#dialogConcurrency').dialog({
                width: 500,
                modal: true,
                title: '并行活动'
            });
            return;
        }
        //重复活动
        if (activityType == 'replication') {
            $('#replicationName').text(activity.name);
            $('#replicationSid').text(activity.sid);
            if (activity.endWay == 'All')
                $('#replicationEndWay').text('子流程需全部结束');
            else if (activity.endWay == 'Any')
                $('#replicationEndWay').text('任意子流程结束即可（其他平行子流程继续运行）');
            else if (activity.endWay == 'AnyEndOther')
                $('#replicationEndWay').text('任意子流程结束即可（自动结束其他平行子流程，包括子流程的子流程）');
            $('#replicationStartExpression').text(activity.startExpression);
            $('#dialogReplication').dialog({
                width: 500,
                modal: true,
                title: '重复活动'
            });
            return;
        }
        //结束活动
        /*if (activityType == 'end') {
            $('#endCcAll').text(activity.ccAll ? '是' : '否');
            $('#endCcExpression').text(activity.ccExpression);
            $('#dialogEnd').dialog({
                width: 500,
                modal: true,
                title: '结束活动'
            });
            return;
        }*/
    });

    //-------------------------------------------------------------------------

    var deployProcess = undefined;
    var activityRoot = undefined;
    var taskActivitiesMap = undefined;
    //取活动
    var getActivity = function (activityId) {
        var activity = undefined;
        $.each(activityRoot.activities, function (index, item) {
            if (item.id == activityId) {
                activity = item;
                return;
            }
        });
        return activity;
    };
    //取处理动作
    var getTaskAction = function (sourceId, targetId) {
        var action = undefined;
        $.each(activityRoot.activities, function (index, item) {
            if (item.id == sourceId) {
                $.each(item.actions, function (index, item) {
                    // console.log(item);
                    if (item.nextActivityId == targetId) {
                        action = item;
                        return;
                    }
                });
                return;
            }
        });
        return action;
    };
    //取判定条件
    var getDecisionCondition = function (sourceId, targetId) {
        var condition = undefined;
        $.each(activityRoot.activities, function (index, item) {
            if (item.id == sourceId) {
                $.each(item.conditions, function (index, item) {
                    if (item.nextActivityId == targetId) {
                        condition = item;
                        return;
                    }
                });
                return;
            }
        });
        return condition;
    };

    $.ajax({
        type: 'GET',
        url: processEngineServer + '/api/diagram',
        data: {runtimeProcessId: runtimeProcessId, deploySid: deploySid, sub: sub},
        success: function (data) {
            if (!data.isSuccess) return;
            if (data.data == null) return;
            deployProcess = data.data;
            activityRoot = data.data.activityRoot;
            taskActivitiesMap = data.data.taskActivitiesMap;

            $('#name').text(deployProcess.name);
            $('#processName').text(deployProcess.processName);

            var activities = data.data.activityRoot.activities;
            //添加元素
            $.each(activities, function (index, item) {
                if (item.type == 'StartActivity')
                    appendElementStart(item.id, item.designInfo.left, item.designInfo.top);
                else if (item.type == 'TaskActivity') {
                    appendElementTask(item.id, item.name + (item.sid == '' ? '' : '<br>[' + item.sid + ']'), item.designInfo.left, item.designInfo.top, item.designInfo.width, item.designInfo.height);
                } else if (item.type == 'DecisionActivity')
                    appendElementDecision(item.id, item.name + (item.sid == '' ? '' : '<br>[' + item.sid + ']'), item.designInfo.left, item.designInfo.top, item.designInfo.width, item.designInfo.height);
                else if (item.type == 'ConcurrencyActivity') {
                    appendElementConcurrency(item.id, item.name + (item.sid == '' ? '' : '<br>[' + item.sid + ']'), item.designInfo.left, item.designInfo.top, item.designInfo.width, item.designInfo.height);
                    $.each(item.subProcesses, function (index, subprocess) {
                        appendElementConcurrencySubprocess(item.id, subprocess.id, subprocess.name);
                    });
                } else if (item.type == 'ReplicationActivity')
                    appendElementReplication(item.id, item.name + (item.sid == '' ? '' : '<br>[' + item.sid + ']'), item.designInfo.left, item.designInfo.top, item.designInfo.width, item.designInfo.height);
                else if (item.type == 'EndActivity')
                    appendElementEnd(item.id, item.designInfo.left, item.designInfo.top/*, item.ccAll || item.ccExpression != ''*/);
            });
            //添加连线
            $.each(activities, function (index, item) {
                if (item.type == 'StartActivity' && item.nextActivityId != '')
                    instance.connect({source: item.id, target: item.nextActivityId});
                else if (item.type == 'TaskActivity') {
                    $.each(item.actions, function (index, action) {
                        var conn = instance.connect({source: item.id, target: action.nextActivityId});
                        conn.getOverlay('label').setLabel((index + 1) + '.' + action.name + (action.description ? '<br />' + action.description : ''));
                    });
                } else if (item.type == 'DecisionActivity') {
                    $.each(item.conditions, function (index, condition) {
                        var conn = instance.connect({source: item.id, target: condition.nextActivityId});
                        conn.getOverlay('label').setLabel((index + 1) + '.' + condition.name);
                    });
                } else if (item.type == 'ConcurrencyActivity' && item.nextActivityId != '')
                    instance.connect({source: item.id, target: item.nextActivityId});
                else if (item.type == 'ReplicationActivity' && item.nextActivityId != '')
                    instance.connect({source: item.id, target: item.nextActivityId});
            });
        }
    });

});
