/*
 * Copyright (C) 2018 Apple Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// 1()RenderView|2(1)RenderBlock|3(2)RenderBody|4(3)RenderBlock|5(3)AnonymousRenderBlock|
class TreeBuilder {

    createTree(document, renderTreeDump) {
        // Root.
        let initialBlockContainer = new Layout.InitialBlockContainer(document, parseInt(renderTreeDump.substring(0, renderTreeDump.indexOf("("))));
        initialBlockContainer.setRendererName("RenderView");
        renderTreeDump = renderTreeDump.substring(renderTreeDump.indexOf("|") + 1);

        while (true) {
            let endOfId = renderTreeDump.indexOf("(");
            let boxId = parseInt(renderTreeDump.substring(0, endOfId));
            let endOfParentId = renderTreeDump.indexOf(")");
            let parentId = parseInt(renderTreeDump.substring(endOfId + 1, endOfParentId));
            let endOfName = renderTreeDump.indexOf("|");
            let name = renderTreeDump.substring(endOfParentId + 1, endOfName);

            this._createAndAttachBox(initialBlockContainer, boxId, name, parentId);
            if (endOfName == renderTreeDump.length - 1)
                break;
            renderTreeDump = renderTreeDump.substring(endOfName + 1);
        }
        return initialBlockContainer;
    }

    _createAndAttachBox(initialBlockContainer, id, name, parentId) {
        let box = null;
        let text = null;
        let node = this._findNode(initialBlockContainer.node(), id, name);
        if (name == "RenderBlock" || name == "RenderBody")
            box = new Layout.BlockContainer(node, id);
        else if (name == "RenderInline") {
            box = new Layout.InlineContainer(node, id);
        } else if (name == "RenderText") {
            text = new Text(node, id);
        } else
            box = new Layout.Box(node, id);

        if (box)
            box.setRendererName(name);

        let parentBox = this._findBox(initialBlockContainer, parentId);
        // WebKit does not construct anonymous inline container for text if the text
        // is a direct child of a block container.
        if (text && !parentBox.isInlineContainer) {
            box = new Layout.InlineBox(null, -1);
            box.setIsAnonymous();
            box.setText(text);
        }
        this._appendChild(parentBox, box);
        return box;
    }

    _appendChild(parent, child) {
        child.setParent(parent);
        let firstChild = parent.firstChild();
        if (!firstChild) {
            parent.setFirstChild(child);
            parent.setLastChild(child);
            return;
        }
        let lastChild = parent.lastChild();
        lastChild.setNextSibling(child);
        child.setPreviousSibling(lastChild);
        parent.setLastChild(child);
    }

    _findBox(root, boxId) {
        if (root.id() == boxId)
            return root;
        // Super inefficient but this is all temporary anyway.
        for (let box = root.firstChild(); box; box = box.nextSibling()) {
            if (box.id() == boxId)
                return box;
            if (box.isContainer() && box.hasChild()) {
                let candidate = this._findBox(box, boxId);
                if (candidate)
                    return candidate;
            }
        }
    }

    _findNode(node, boxId) {
        // Super inefficient but this is all temporary anyway.
        for (let currentNode = node.firstChild; currentNode; currentNode = currentNode.nextSibling) {
            if (currentNode.rendererId == boxId)
                return currentNode;
            let candidate = this._findNode(currentNode, boxId);
            if (candidate)
                return candidate;
        }
    }
}
