'use strict';

var VirtualDOM = require('./../../virtual-dom');

var MESSAGES_ATTR_KEY = 'data-messages';

function updateVirtualDOM(elements, payload) {
    for (var i = 0; i < elements.length; i++) {
        var element = elements[i];
        var parent = element.parentNode;
        parent.removeChild(element);
        for (var j = 0; j < payload.length; j++) {
            var messages = JSON.stringify(payload[j]);
            var clone = VirtualDOM.clone(element);
            clone.setAttribute(MESSAGES_ATTR_KEY, messages);
            parent.appendChild(clone);
        }
    }
}

function initialization(info) {
    if (info.payload instanceof Array) {
        var elements = VirtualDOM.query(info.domStore.childrenRoot, info.selector);
        updateVirtualDOM(elements, info.payload);
    }
    else {
        throw new Error('Unsupported payload type for $repeat');
    }
}

module.exports = {
    initialization: initialization,
    runTime: initialization
};

'use strict';

var VirtualDOM = require('./../../virtual-dom');
var ArrayUtils = require('framework-utilities/array');

var MESSAGES_ATTR_KEY = 'data-messages';
var TREE_SIG_ATTR_KEY = 'tree_sig';

function initializeRepeat(info) {
    var data = info.controlFlowData.repeat;
    data[info.selector] = {};
    data[info.selector].payload = info.payload;

    var elements = VirtualDOM.query(info.domStore.childrenRoot, info.selector);
    for (var i = 0; i < elements.length; i++) {
        var element = elements[i];
        var parent = element.parentNode;
        parent.removeChild(element);
        for (var j = 0; j < info.payload.length; j++) {
            var clone = VirtualDOM.clone(element);
            attachMessage(clone, info.payload[j]);
            parent.appendChild(clone);
        }
    }
}

function attachMessage(node, message) {
    var messages = JSON.stringify(message);
    node.setAttribute(MESSAGES_ATTR_KEY, messages);
}

function verifyPayload(payload) {
    if (!(payload instanceof Array)) {
        throw new Error('Unsupported payload type for $repeat');
    }
}

function initialization(info) {
    verifyPayload(info.payload);
    initializeRepeat(info);
}

function runTime(info) {
    verifyPayload(info.payload);

    // Bucket elemets by parent UID
    var repeatedElements = info.domStore.treeSignature.querySelectorAll(info.selector);
    var parentData = {};
    var uids = [];
    var parent;
    var parentUID;
    var i;
    for (i = 0; i < repeatedElements.length; i++) {
        parentUID = VirtualDOM.getUID(repeatedElements[i].parentNode);
        if (!parentData[parentUID]) {
            uids.push(parentUID);
            parentData[parentUID] = {};
            parentData[parentUID].nodes = [];
        }
        parentData[parentUID].nodes.push(repeatedElements[i]);
    }

    // Attach 'blueprint' to parent
    var blueprints = info.domStore.childrenSnapShot.querySelectorAll(info.selector);
    for (i = 0; i < blueprints.length; i++) {
         parentData[uids[i]].blueprint = blueprints[i];
    }

    // Diff. payloads
    var data = info.controlFlowData.repeat[info.selector];
    var payloadEquality = ArrayUtils.checkElementEquality(data.payload, info.payload);
    data.payload = info.payload;

    // Add nodes to add/remove stack based on payload diff.
    var result = {
        'add'    : [],
        'remove' : []
    };
    var clone;
    for (i = 0; i < payloadEquality.length; i++) {
        if (!payloadEquality[i]) {
            for (parentUID in parentData) {
                if (parentData[parentUID].nodes[i]) {
                    result.remove.push(parentData[parentUID].nodes[i])
                }
                else {
                    if (info.payload[i] === undefined) debugger;
                    clone = VirtualDOM.clone(parentData[parentUID].blueprint);
                    attachMessage(clone, info.payload[i]);
                    clone.setAttribute(TREE_SIG_ATTR_KEY, VirtualDOM.getUID(info.domStore.treeSignature));
                    result.add.push({
                        parentUID: parentUID,
                        blueprintDOMNode: clone
                    });
                }
            }
        }
    }

    return result;
}

module.exports = {
    initialization: initialization,
    runTime: runTime
};

Implement runTime behavior for RepeatController