<html>
<head>
<script src="../../http/tests/inspector/resources/protocol-test.js"></script>
<script>

function addCompositedLayer()
{
    var element = document.createElement("div");
    element.className = "composited";
    element.id = "last-element";
    document.body.appendChild(element);
};

function test()
{
    var documentNode;
    var initialLayers;
    var eventsCount = 0;

    InspectorProtocol.eventHandler["LayerTree.layerTreeDidChange"] = function (messageObject) {
        eventsCount++;
    };

    enableLayerTreeAgent();

    function enableLayerTreeAgent(result)
    {
        step({
            name: "Enable the LayerTree agent",
            command: "LayerTree.enable",
            parameters: {},
            callback: getDocument
        });
    };
    
    function getDocument(result)
    {
        step({
            name: "Get the Document",
            command: "DOM.getDocument",
            parameters: {},
            callback: getInitialLayerTree
        });
    };
    
    function getInitialLayerTree(result)
    {
        documentNode = result.root;
        step({
            name: "Get the initial layer tree",
            command: "LayerTree.layersForNode",
            parameters: {"nodeId": documentNode.nodeId},
            callback: gotInitialLayerTree
        });
    };

    function gotInitialLayerTree(result)
    {
        initialLayers = result.layers;

        dumpLayers(initialLayers);

        step({
            name: "Message the page to add a new composited layer",
            command: "Runtime.evaluate",
            parameters: {"expression": "addCompositedLayer()"},
            callback: getModifiedLayerTree
        });
    };

    function getModifiedLayerTree(result)
    {
        step({
            name: "Get the modified layer tree",
            command: "LayerTree.layersForNode",
            parameters: {"nodeId": documentNode.nodeId},
            callback: gotModifiedLayerTree
        });
    };

    var layerCount = 0;

    function gotModifiedLayerTree(result)
    {
        dumpLayers(result.layers);

        var mutations = layerMutations(initialLayers, result.layers);
        var newLayer = mutations.additions[0];

        step({
            name: "Get attributes for the newly inserted node",
            command: "DOM.getAttributes",
            parameters: {"nodeId": newLayer.nodeId},
            callback: gotNodeAttributes
        });
    };

    function gotNodeAttributes(result)
    {
        var attributes = attributesDictionaryFromArray(result.attributes);
        if (attributes.id !== "last-element")
            ProtocolTest.log("FAIL: Did not obtain the expected element for the last inserted layer.");

        finishTest();
    };

    function finishTest()
    {
        if (!eventsCount)
            ProtocolTest.log("FAIL: Did not receive layerTreeDidChange events.");
        else
            ProtocolTest.log("\n=== Test complete, all expected conditions met ===");

        ProtocolTest.completeTest();
    };

    function layerMutations(oldLayers, newLayers)
    {
        function layerIdMap(layer) {
            return layer.layerId;
        }

        var oldLayerIds = oldLayers.map(layerIdMap);
        var newLayerIds = newLayers.map(layerIdMap);

        return {
            additions: newLayers.filter(function (layer) {
                return (oldLayerIds.indexOf(layer.layerId) === -1);
            }),
            removals: oldLayers.filter(function (layer) {
                return (newLayerIds.indexOf(layer.layerId) === -1);
            })
        };
    };

    function attributesDictionaryFromArray(attributes)
    {
        var dictionary = {}
        for (var i = 0, count = attributes.length; i < count; i += 2) {
            dictionary[attributes[i]] = attributes[i + 1];
        }
        return dictionary;
    };

    function dumpLayers(layers)
    {
        function replacer(key, value)
        {
            if (key === "layerId" || key === "nodeId" || key === "memory" || key === "paintCount")
                return typeof(value);

            // some values differ based on port, but the ones we most
            // care about will always be less or equal 100.
            if ((key === "width" || key === "height") && value > 100) 
                return typeof(value);
            
            return value;
        };
        
        ProtocolTest.log("\n" + JSON.stringify(layers, replacer, "    "));
    };

    function step(test)
    {
        ProtocolTest.log("\n=== " + test.name + " ===\n")
        InspectorProtocol.sendCommand(test.command, test.parameters, function(messageObject) {
            if (messageObject.hasOwnProperty("error")) {
                ProtocolTest.log("FAIL: " + messageObject.error.message + " (" + messageObject.error.code + ")");
                ProtocolTest.completeTest();
                return;
            }

            ProtocolTest.log("PASS");
            test.callback(messageObject.result);
        });
    };

    function assert(name, actual, expected)
    {
        if (expected === actual)
            ProtocolTest.log("PASS: " + name + ".");
        else
            ProtocolTest.log("FAIL: " + name + ". Expected " + expected + " but got " + actual);
    };

};

window.addEventListener("DOMContentLoaded", function () {
    runTest();
}, false);

</script>
<style type="text/css">
      
    div {
        position: absolute;
        top: 0;
        left: 0;
    }
      
    .regular {
        width: 100px;
        height: 100px;
        background-color: black;
    }

    .composited {
        top: 25px;
        left: 25px;
        width: 50px;
        height: 50px;
        background-color: blue;
        -webkit-transform: translateZ(0);
    }
      
    .offset {
        left: 200px;
        -webkit-transform: translateZ(0);
    }

</style>
</head>
<body>

    <div class="regular"></div>

    <div class="composited">
        <div class="composited"></div>
    </div>

    <div class="regular offset">
        <div class="composited"></div>
    </div>

</body>
</html>
