<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Airavata Workflow Composer</title>
    <script type="text/javascript">
        mxBasePath = 'src';
    </script>
    <script type="text/javascript" src="src/js/mxClient.js"></script>
    <script type="text/javascript" src="src/js/components.js"></script>
    <script type="text/javascript">
        function main(container, tbContainer)
        {
            if (!mxClient.isBrowserSupported())
            {
                // Displays an error message if the browser is not supported.
                mxUtils.error('Browser is not supported!', 200, false);
            }
            else
            {
                var toolbar = new mxToolbar(tbContainer);
                toolbar.enabled = false

                // Workaround for Internet Explorer ignoring certain styles
                if (mxClient.IS_QUIRKS)
                {
                    document.body.style.overflow = 'hidden';
                    new mxDivResizer(tbContainer);
                    new mxDivResizer(container);
                }

                var doc = mxUtils.createXmlDocument();

                var relation = doc.createElement('Edge');

                var graph = new mxGraph(container);

                graph.dropEnabled = true;

                mxDragSource.prototype.getDropTarget = function(graph, x, y)
                {
                    var cell = graph.getCellAt(x, y);

                    if (!graph.isValidDropTarget(cell))
                    {
                        cell = null;
                    }

                    return cell;
                };

                // Enables new connections in the graph
                graph.setConnectable(true);
                graph.setMultigraph(false);

                var addVertex = function(icon, w, h, componentName)
                {
                    addToolbarItem(graph, toolbar, fetchComponent(componentName, doc), icon);
                };

                addVertex('src/icons/start.png', 40, 40, 'START');
                addVertex('src/icons/stop.png', 40, 40, 'STOP');
                addVertex('src/icons/parallel.png', 40, 40, 'PARALLEL');
                addVertex('src/icons/ssh.png', 40, 60, 'SSH');
                addVertex('src/icons/copy.png', 40, 60, 'CP');
                addVertex('src/icons/s3.png', 40, 60, 'S3');
                toolbar.addLine();

                graph.setCellsResizable(false);
                graph.setResizeContainer(true);
                graph.minimumContainerSize = new mxRectangle(0, 0, 500, 380);
                graph.setBorder(60);

                new mxKeyHandler(graph);

                // Overrides method to disallow edge label editing
                graph.isCellEditable = function(cell)
                {
                    return !this.getModel().isEdge(cell);
                };

                // Overrides method to provide a cell label in the display
                graph.convertValueToString = function(cell)
                {
                    if (mxUtils.isNode(cell.value))
                    {
                        if (cell.value.nodeName.toLowerCase() == 'processingelement')
                        {
                            var name = cell.getAttribute('name', '');

                            return name;
                        }
                        else if (cell.value.nodeName.toLowerCase() == 'edge')
                        {
                            return '';
                        }

                    }

                    return '';
                };

                // Overrides method to store a cell label in the model
                var cellLabelChanged = graph.cellLabelChanged;
                graph.cellLabelChanged = function(cell, newValue, autoSize)
                {
                    if (mxUtils.isNode(cell.value) &&
                        cell.value.nodeName.toLowerCase() == 'processingelement')
                    {
                        // Clones the value for correct undo/redo
                        var elt = cell.value.cloneNode(true);

                        elt.setAttribute('name', newValue);
                        newValue = elt;
                        autoSize = true;
                    }

                    cellLabelChanged.apply(this, arguments);
                };

                // Overrides method to create the editing value
                var getEditingValue = graph.getEditingValue;
                graph.getEditingValue = function(cell)
                {
                    if (mxUtils.isNode(cell.value) &&
                        cell.value.nodeName.toLowerCase() == 'processingelement')
                    {
                        var name = cell.getAttribute('name', '');

                        return name;
                    }
                };

                new mxRubberband(graph);

                document.body.appendChild(mxUtils.button('View XML', function()
                {
                    var encoder = new mxCodec();
                    var node = encoder.encode(graph.getModel());
                    mxUtils.popup(mxUtils.getPrettyXml(node), true);
                }));

                // Changes the style for match the markup
                // Creates the default style for vertices
                var style = graph.getStylesheet().getDefaultVertexStyle();
                style[mxConstants.STYLE_STROKECOLOR] = 'gray';
                style[mxConstants.STYLE_ROUNDED] = true;
                style[mxConstants.STYLE_SHADOW] = true;
                style[mxConstants.STYLE_FILLCOLOR] = '#DFDFDF';
                style[mxConstants.STYLE_GRADIENTCOLOR] = 'white';
                style[mxConstants.STYLE_FONTCOLOR] = 'black';
                style[mxConstants.STYLE_FONTSIZE] = '12';
                style[mxConstants.STYLE_SPACING] = 4;

                // Creates the default style for edges
                style = graph.getStylesheet().getDefaultEdgeStyle();
                style[mxConstants.STYLE_STROKECOLOR] = '#0C0C0C';
                style[mxConstants.STYLE_LABEL_BACKGROUNDCOLOR] = 'white';
                style[mxConstants.STYLE_EDGE] = mxEdgeStyle.ElbowConnector;
                style[mxConstants.STYLE_ROUNDED] = true;
                style[mxConstants.STYLE_FONTCOLOR] = 'black';
                style[mxConstants.STYLE_FONTSIZE] = '10';

                var parent = graph.getDefaultParent();
                graph.getModel().beginUpdate();
                try
                {
                    //var v1 = graph.insertVertex(parent, null, pe1, 40, 40, 80, 30);
                    //var v2 = graph.insertVertex(parent, null, pe2, 200, 150, 80, 30);
                    //var e1 = graph.insertEdge(parent, null, relation, v1, v2);
                }
                finally
                {
                    // Updates the display
                    graph.getModel().endUpdate();
                }

                // Implements a properties panel that uses
                // mxCellAttributeChange to change properties
                graph.getSelectionModel().addListener(mxEvent.CHANGE, function(sender, evt)
                {
                    selectionChanged(graph);
                });

                selectionChanged(graph);

            }

            /**
             * Updates the properties panel
             */
            function selectionChanged(graph)
            {
                var div = document.getElementById('properties');

                // Forces focusout in IE
                graph.container.focus();

                // Clears the DIV the non-DOM way
                div.innerHTML = '';

                // Gets the selection cell
                var cell = graph.getSelectionCell();

                if (cell == null)
                {
                    mxUtils.writeln(div, 'Nothing selected.');
                }
                else if (cell.value)
                {
                    // Writes the title
                    var center = document.createElement('center');
                    mxUtils.writeln(center, cell.value.nodeName + ' (' + cell.id + ')');
                    div.appendChild(center);
                    mxUtils.br(div);

                    // Creates the form from the attributes of the user object
                    var form = new mxForm();

                    var attrs = cell.value.attributes;

                    for (var i = 0; i < attrs.length; i++)
                    {
                        if (!attrs[i].nodeName.startsWith("in-") && !attrs[i].nodeName.startsWith("out-")) {
                            createTextField(graph, form, cell, attrs[i]);
                        }
                    }

                    div.appendChild(form.getTable());
                    mxUtils.br(div);
                }
            }

            function createTextField(graph, form, cell, attribute)
            {
                var input = form.addText(attribute.nodeName + ':', attribute.nodeValue);

                var applyHandler = function()
                {
                    var newValue = input.value || '';
                    var oldValue = cell.getAttribute(attribute.nodeName, '');

                    if (newValue != oldValue)
                    {
                        graph.getModel().beginUpdate();

                        try
                        {
                            var edit = new mxCellAttributeChange(
                                cell, attribute.nodeName,
                                newValue);
                            graph.getModel().execute(edit);
                            graph.updateCellSize(cell);
                        }
                        finally
                        {
                            graph.getModel().endUpdate();
                        }
                    }
                };

                mxEvent.addListener(input, 'keypress', function (evt)
                {
                    // Needs to take shift into account for textareas
                    if (evt.keyCode == /*enter*/13 &&
                        !mxEvent.isShiftDown(evt))
                    {
                        input.blur();
                    }
                });

                if (mxClient.IS_IE)
                {
                    mxEvent.addListener(input, 'focusout', applyHandler);
                }
                else
                {
                    // Note: Known problem is the blurring of fields in
                    // Firefox by changing the selection, in which case
                    // no event is fired in FF and the change is lost.
                    // As a workaround you should use a local variable
                    // that stores the focused field and invoke blur
                    // explicitely where we do the graph.focus above.
                    mxEvent.addListener(input, 'blur', applyHandler);
                }
            }

            function addToolbarItem(graph, toolbar, prototype, image)
            {
                // Function that is executed when the image is dropped on
                // the graph. The cell argument points to the cell under
                // the mousepointer if there is one.
                var funct = function(graph, evt, cell, x, y)
                {

                    var parent = graph.getDefaultParent();
                    var model = graph.getModel();

                    var v1 = null;

                    model.beginUpdate();

                    try
                    {
                        v1 = graph.insertVertex(parent, null, prototype.cloneNode(true), x, y, 80, 60);
                        v1.setConnectable(false);

                        var inputs = [];
                        var outputs = [];
                        for (var i = 0; i < prototype.attributes.length; i++)
                        {
                            attr = prototype.attributes[i];
                            if (attr.nodeName.startsWith("in-")) {
                                inputs.push(attr.nodeValue);
                            }
                            if (attr.nodeName.startsWith("out-")) {
                                outputs.push(attr.nodeValue);
                            }
                        }

                        var inputDivision = 1/(inputs.length + 1);
                        var outputDivision = 1/(outputs.length + 1);

                        inputs.forEach(function(input, index) {
                            var v11 = graph.insertVertex(v1, null, input, 0, (index*inputDivision + inputDivision), 10, 10);
                            v11.geometry.offset = new mxPoint(-5, -5);
                            v11.geometry.relative = true;
                        });

                        outputs.forEach(function(output, index) {
                            var v11 = graph.insertVertex(v1, null, output, 1, (index*outputDivision + outputDivision), 10, 10);
                            v11.geometry.offset = new mxPoint(-5, -5);
                            v11.geometry.relative = true;
                        });
                    }
                    finally
                    {
                        // Updates the display
                        graph.getModel().endUpdate();
                    }

                    graph.updateCellSize(v1);
                    graph.setSelectionCell(v1);
                };

                // Creates the image which is used as the drag icon (preview)
                var img = toolbar.addMode(null, image, funct);
                mxUtils.makeDraggable(img, graph, funct);
            }
        };
    </script>
</head>
<body onload="main(document.getElementById('graphContainer'), document.getElementById('toolContainer'))">
<table style="position:relative;">
    <tr>
        <td>
            <div id="toolContainer" style="border: solid 1px black; width: 80px; cursor: default">

            </div>
        </td>
        <td>
            <div id="graphContainer"
                 style="border: solid 1px black;overflow:hidden;width:321px; cursor:default;">
            </div>
        </td>
        <td valign="top">
            <div id="properties"
                 style="border: solid 1px black; padding: 10px;">
            </div>
        </td>
    </tr>
</table>
</body>
</html>