var RackPortOption = {
    port_width: 30,
    port_height: 26,
    port_x_gap: 3,
    port_y_gap: 3,
    port_group_padding: 3,
    port_group_count: 12,

    light_width: 10,
    light_height: 10,
    light_y_gap: 10,
    light_group_padding: 6,
    light_group_width: 90,

    card_padding: 3,
    card_gap: 10,
    group_gap: 8,

    rack_padding: 2,

    port_count: 48
};
var RackUtil = {
    parse: function (json_data) {
        var dataIDMap = {};
        var rackArr = [];
        json_data.forEach(function (rackItem) {
            var rack = new z.gv.Node(rackItem);
            if (rackItem.id) {
                dataIDMap[rackItem.id] = rack;
            }
            rackArr.push(rack);
        });

        //set rack parent;
        rackArr.forEach(function (deviceNode) {
            var pid = deviceNode.get("pid");
            if (pid) {
                var pNode = dataIDMap[pid];
                if (pNode) {
                    deviceNode.set("parent", pNode);
                    deviceNode.set("host", pNode);
                }
            }
        });
        return rackArr;
    },

    createPort: function (props) {
        return new z.gv.Node(z.util.mergeObject({
            _type: "port",
            shape: "rect", fill: "green", stroke: "#FFFFFF",
            width: RackPortOption.port_width, height: RackPortOption.port_height,
            label_position: "center", label_fill: "#FFFFFF"
        }, props));
    },
    createLight: function (props) {
        return new z.gv.Node(z.util.mergeObject({
            _type: "light",

            shape: "circle",
            fill: "linear_gradient", fill_gradient_direction: "lt_to_rb", fill_gradient_colors: {0: "#fff", 1: "green"},
            width: RackPortOption.light_width, height: RackPortOption.light_height,
            label_fill: "#FFFFFF", label_position: "right"
        }, props));
    },
    createGroup: function (props) {
        return new z.gv.Node(z.util.mergeObject({_type: "group", shape: "rect", fill: null, stroke: "silver"}, props));
    },

    createLightGroup: function (card) {
        var lights = ["SYST", "SPEED", "XPS"];

        var lightCount = lights.length;
        var arr = [];
        var group = RackUtil.createGroup({
            host: card, parent: card,
            width: RackPortOption.light_group_width,
            height: RackPortOption.light_group_padding * 2 + lightCount * RackPortOption.light_height + (lightCount - 1) * RackPortOption.light_y_gap
        });
        arr.push(group);
        lights.forEach(function (item, index) {
            arr.push(RackUtil.createLight({
                host: group, parent: group,
                name: item,
                x: RackPortOption.light_group_padding,
                y: RackPortOption.light_group_padding + index * (RackPortOption.light_height + RackPortOption.light_y_gap)
            }))
        });
        return arr;
    },
    createPortGroup: function (card, start, end) {
        var arr = [];
        var col_count = RackPortOption.port_group_count / 2;
        var group = RackUtil.createGroup({
            host: card, parent: card,
            width: RackPortOption.port_group_padding * 2 + RackPortOption.port_width * col_count + (col_count - 1) * RackPortOption.port_x_gap,
            height: RackPortOption.port_group_padding * 2 + 2 * RackPortOption.port_height + RackPortOption.port_y_gap
        });
        arr.push(group);
        var count = end - start;
        for (var i = 0; i <= count; i++) {
            var row = i % 2;
            var col = i / 2 | 0;
            arr.push(RackUtil.createPort({
                host: group, parent: group,
                // card: card,
                name: start + i,
                x: RackPortOption.port_group_padding + col * (RackPortOption.port_width + RackPortOption.port_x_gap),
                y: RackPortOption.port_group_padding + row * (RackPortOption.port_height + RackPortOption.port_y_gap)
            }));
        }
        return arr;
    },
    createCard: function (rack, props) {
        var arr = [];
        var card = new z.gv.Node(z.util.mergeObject({
            _type: "card",
            host: rack,
            parent: rack,
            shape: "rect", fill: "#3b5a69",
            label_position: "right", label_offset_x: 8
        }, props));

        arr.push(card);
        var lightGroupArr = RackUtil.createLightGroup(card);
        arr.push.apply(arr, lightGroupArr);
        var lightGroup = lightGroupArr[0];
        lightGroup.set({x: RackPortOption.card_padding, y: RackPortOption.card_padding});
        var lightGroupHeight = lightGroup.get("height");
        var x = lightGroup.get("x") + lightGroup.get("width") + RackPortOption.group_gap;
        var y = RackPortOption.card_padding;
        var portGroup;
        var group_count = RackPortOption.port_count / RackPortOption.port_group_count;
        var cardHeight = lightGroupHeight;
        var cardWidth = 0;
        for (var i = 0; i < group_count; i++) {
            var start = i * RackPortOption.port_group_count + 1;
            var end = start + RackPortOption.port_group_count - 1;
            var portGroupList = RackUtil.createPortGroup(card, start, end);//1 12\13 24\25 36\37  48
            arr.push.apply(arr, portGroupList);
            portGroup = portGroupList[0];

            if (i === 0) {
                var portGroupHeight = portGroup.get("height");
                if (lightGroupHeight < portGroupHeight) {
                    lightGroup.set("height", portGroupHeight);
                } else {
                    y += (lightGroupHeight - portGroupHeight) / 2
                }
                cardHeight = Math.max(lightGroupHeight, portGroupHeight);
            }

            portGroup.set({x: x, y: y});
            x += portGroup.get("width") + RackPortOption.group_gap;
        }
        cardWidth = x - RackPortOption.group_gap + RackPortOption.card_padding;
        card.set({width: cardWidth, height: cardHeight + RackPortOption.card_padding * 2});

        return arr;
    }
};