'use strict';

const riotQuery = require("riot-query");
const arrayDiff = require("arraydiff");

module.exports = {
	init: function() {
		let knownTags = [];
		let listeners = {};

		function triggerEvent(action, query, item) {
			if (listeners[query] != null && listeners[query][action] != null) {
				listeners[query][action].forEach((handler) => {
					handler(item);
				});
			}
		}

		this.on("updated", () => {
			Object.keys(listeners).forEach((query) => {
				let currentTags = riotQuery(this, query);
				let diff = arrayDiff(knownTags, currentTags);

				diff.forEach((item) => {
					if (item.type === "remove") {
						for (let i = item.index; i < (item.index + item.howMany); i++) {
							triggerEvent("remove", query, knownTags[i]);
						}
					} else if (item.type === "move") {
						for (let i = item.index; i < (item.from + item.howMany); i++) {
							triggerEvent("move", query, knownTags[i]);
						}
					} else if (item.type === "insert") {
						item.values.forEach((value) => {
							triggerEvent("create", query, value);
						})
					}
				});

				knownTags = currentTags;
			});
		});

		this.onChild = function(eventName, handler) {
			let [action, query] = eventName.split(":", 2);

			if (listeners[query] == null) {
				listeners[query] = {};
			}

			if (listeners[query][action] == null) {
				listeners[query][action] = [];
			}

			listeners[query][action].push(handler);
		}
	}
}