;(function() {
    $.FlowDesign = function (options) {
        var defaults = {
            canvasID: '', //设计器ID
            canvas: $(), //设计器       
            connections: [], //连接线关系
            fnRepeat: function() {
                alert("步骤连接重复");
            },
            fnClick: function() {
                alert("单击");
            },
            fnDbClick: function() {
                alert("双击");
            },
            draggable: true,
            connectorPaintStyle: {
                lineWidth: 2,
                strokeStyle: "#49afcd",
                joinstyle: "round"
            }, //连接线路绘画样式            
            connectorHoverStyle: {
                lineWidth: 2,
                strokeStyle: "#da4f49"
            } //鼠标经过样式
        };

        this.opts = $.extend(defaults, options);
        var instance = this;
        if (!this.opts.canvas || this.opts.canvas.size() == 0) {
            var canvasID = this.opts.canvasID;
            if (canvasID && $.trim(canvasID).length > 0) {
                this.opts.canvas = $("#" + $.trim(canvasID));
            }
        }
        if (!this.opts.canvas || this.opts.canvas.size() == 0) {
            throw "要初始化的设计器为空";
            return false;
        }

        jsPlumb.importDefaults({
            DragOptions: {
                cursor: 'pointer'
            },
            EndpointStyle: {
                fillStyle: '#225588'
            },
            Endpoint: ["Dot", {
                radius: 1
            }],
            ConnectionOverlays: [
                ["Arrow", {
                    location: 1,
                    width: 12,
                    length: 10
                }],
                ["Label", {
                    location: 0.1,
                    id: "label",
                    cssClass: "aLabel"
                }]
            ],
            Anchor: 'Continuous',
            ConnectorZIndex: 5,
            HoverPaintStyle: {
                lineWidth: 2,
                strokeStyle: "#da4f49"
            }
        });

        this.setConnections = function (conn, remove) {
            if (!remove) {
                instance.opts.connections.push(conn);
            } else {
                var idx = -1;
                for (var i = 0; i < instance.opts.connections.length; i++) {
                    if (instance.opts.connections[i] == conn) {
                        idx = i;
                        break;
                    }
                }
                if (idx != -1) instance.opts.connections.splice(idx, 1);
            }

            if (instance.opts.connections.length > 0) {
                var s = "";
                for (var j = 0; j < instance.opts.connections.length; j++) {
                    var from = $('#' + instance.opts.connections[j].sourceId).attr('process_id');
                    var target = $('#' + instance.opts.connections[j].targetId).attr('process_id');
                    s = s + "<input type='hidden' value=\"" + from + "," + target + "\">";
                }
                $('#process_info').html(s);
            } else {
                $('#process_info').html('');
            }

            jsPlumb.repaintEverything();//重画
        };

        this.initEndPoints = function () {
            $(".process-flag").each(function (i, e) {
                var p = $(e).parent();
                var _sanchor = $(p).attr("process_sanchor");
                jsPlumb.makeSource($(e), {
                    parent: p,
                    anchor: _sanchor ? _sanchor : "Continuous",
                    endpoint: ["Dot", {
                        radius: 1
                    }],
                    connector: ["Flowchart", {
                        stub: [5, 5]
                    }],
                    connectorStyle: instance.opts.connectorPaintStyle,
                    hoverPaintStyle: instance.opts.connectorHoverStyle,
                    dragOptions: {},
                    maxConnections: -1
                });

                var _tanchor = $(p).attr("process_tanchor");
                jsPlumb.makeTarget($(p), {
                    dropOptions: {
                        hoverClass: "hover",
                        activeClass: "active"
                    },
                    anchor: _tanchor ? _tanchor : "Continuous",
                    maxConnections: -1,
                    endpoint: ["Dot", {
                        radius: 1
                    }],
                    paintStyle: {
                        fillStyle: "#ec912a",
                        radius: 1
                    },
                    hoverPaintStyle: instance.opts.connectorHoverStyle,
                    beforeDrop: function (params) {
                        var j = 0;
                        $('#process_info').find('input').each(function (i) {
                            var str = $('#' + params.sourceId).attr('process_id') + ',' + $('#' + params.targetId).attr('process_id');
                            if (str == $(this).val()) {
                                j++;
                                return;
                            }
                        })
                        if (j > 0) {
                            defaults.fnRepeat();
                            return false;
                        } else {
                            return true;
                        }
                    }
                });
            });
        };
        
        this.canvasDesign = function(processData) {
            $('.process-step').each(function(i) {
                var sourceId = $(this).attr('process_id');
                var prcsto = $(this).attr('process_to');
                var toArr = new Array();
                if (typeof prcsto != "undefined") {
                    toArr = prcsto.split(",");
                }
                $.each(toArr, function(j, targetId) {
                    if (targetId != '' && targetId != 0) {
                        //检查 source 和 target是否存在
                        var is_source = false,
                            is_target = false,
                            is_diamond = false;
                        $.each(processData, function(i, row) {
                            if (row.ACT_ID == sourceId) {
                                is_source = true;
                                if (row.ACT_TYPE == "DIAMOND") {
                                    is_diamond = true;
                                }
                            } else if (row.ACT_ID == targetId) {
                                is_target = true;
                            }
                            if (is_source && is_target)
                                return true;
                        });
                        if (is_source && is_target) {
                            var lbl = "";
                            if (is_diamond) {
                                if (j == 0)
                                    lbl = "否";
                                else if (j == 1)
                                    lbl = "是";
                                else
                                    lbl = j;
                            }
                            jsPlumb.connect({
                                source: "window" + sourceId,
                                target: "window" + targetId,
                                label: lbl
                                /* ,labelStyle : { cssClass:"component label" }
                                 ,label : id +" - "+ n*/
                            });
                            return;
                        }
                    }
                })
            });
        };

        this.getProcessInfo = function () {
            try {
                var aFromData = new Array();
                $("#process_info input[type=hidden]").each(function (i) {
                    var processVal = $(this).val().split(",");
                    if (processVal.length == 2) {
                        if (!aFromData[processVal[1]]) {
                            aFromData[processVal[1]] = new Array();
                        }
                        aFromData[processVal[1]].push(processVal[0]);
                    }
                })

                var aProcessData = {};
                $("#process_info input[type=hidden]").each(function (i) {
                    var processVal = $(this).val().split(",");
                    if (processVal.length == 2) {
                        if (!aProcessData[processVal[0]]) {
                            aProcessData[processVal[0]] = {
                                "top": 0,
                                "left": 0,
                                "process_from": [],
                                "process_to": []
                            };
                        }
                        if (typeof aFromData[processVal[0]] != "undefined") {
                            aProcessData[processVal[0]]["process_from"] = aFromData[processVal[0]];
                        }
                        aProcessData[processVal[0]]["process_to"].push(processVal[1]);
                    }
                })
                /*位置*/
                instance.opts.canvas.find("div.process-step").each(function (i) {
                    if ($(this).attr('id')) {
                        var pId = $(this).attr('process_id');
                        var pLeft = parseInt($(this).css('left'));
                        var pTop = parseInt($(this).css('top'));

                        if (!aProcessData[pId]) {
                            aProcessData[pId] = {
                                "top": 0,
                                "left": 0,
                                "process_from": [],
                                "process_to": []
                            };
                        }
                        aProcessData[pId]["top"] = pTop;
                        aProcessData[pId]["left"] = pLeft;
                        if (typeof aFromData[pId] != "undefined") {
                            aProcessData[pId]["process_from"] = aFromData[pId];
                        }
                    }
                })

                return JSON.stringify(aProcessData);
            } catch (e) {
                return '';
            }
        };

        this.addProcess = function (data) {
            var $div = $('<div class="process-step btn btn-small"></div>');
            $div.attr('id', 'window' + data.ACT_ID);
            $div.attr('style', 'top:' + data.ACT_TOP + 'px;left:' + data.ACT_LEFT + 'px');
            $div.attr('process_to', data.ACT_TO);
            $div.attr('process_id', data.ACT_ID);
            $div.attr('process_sanchor', data.ANCHOR_SOURCE == null ? '' : data.ANCHOR_SOURCE);
            $div.attr('process_tanchor', data.ANCHOR_TARGET == null ? '' : data.ANCHOR_TARGET);

            var $span = $('<span class="process-flag"></span>');
            var $font = $('<font>' + data.ACT_NAME + '</font>');
            $div.append($span);
            $div.append($font);

            instance.opts.canvas.append($div);

            //点击或双击事件,这里进行了一个单击事件延迟，因为同时绑定了双击事件
            var timeout = null;
            $div.bind('click', function () {
                var guid = $(this).attr("process_id");
                $("#active_id").val(guid);
                clearTimeout(timeout);
                var obj = this;
                timeout = setTimeout(instance.opts.fnClick, 300);
            }).bind('dblclick', function() {
                clearTimeout(timeout);
                instance.opts.fnDbClick();
            });

            //使之可拖动和连线
            if (instance.opts.draggable) {
                jsPlumb.draggable(jsPlumb.getSelector(".process-step"));
            }
            instance.initEndPoints();
        };

        this.loadProcess = function (processData) {           
            $.each(processData, function(i, row) {
                instance.addProcess(row);
            });

            instance.canvasDesign(processData);
        };

        this.delProcess = function (id) {
            $("#window" + id).remove();
        }

        this.getActiveId = function () {
            return $("#active_id").val();
        }

        this.init = function () {
            var $input = $('<input type="hidden" id="active_id" value="0"/>');
            var $div = $('<div id="process_info"></div>');
            instance.opts.canvas.html('');
            instance.opts.canvas.append($input).append($div);
            instance.opts.connections = [];

            if (!$.support.leadingWhitespace) { //ie9以下，用VML画图
                jsPlumb.setRenderMode(jsPlumb.VML);
            } else { //其他浏览器用SVG
                jsPlumb.setRenderMode(jsPlumb.SVG);
            }

            jsPlumb.reset();

            //绑定添加连接操作,画线,拒绝重复连接
            jsPlumb.bind("jsPlumbConnection", function(info) {
                instance.setConnections(info.connection)
            });
            //绑定删除connection事件
            jsPlumb.bind("jsPlumbConnectionDetached", function(info) {
                instance.setConnections(info.connection, true);
            });
            //绑定删除确认操作
            jsPlumb.bind("click", function (c) {
                if (instance.opts.draggable) {
                    if (confirm("你确定取消连接吗?")) {
                        jsPlumb.detach(c);
                    }
                }
            });
        };

        return this;
    };
})(jQuery);