import Renderables from '../Renderables';
import EventStream from "../../event/EventStream";
import { EventType } from "../../event/EventType";
import { MessageType } from "../../support/MessageType";
/**
 * Implementation of the 'selection' markup element.
 * A HTML div element is used to create a selection containing multiple 'selectionItem' elements.
 * Only one 'selectionItem' is visible.
 * The user can either click on the left or right side of the visible 'selectionItem' to select one of the two options.
 * If the click happened, the next 'selectionItem' will be showed.
 * For CSS manipulations the following classes are added:
 *  lto-selection: the container
 *  lto-selection-left: click to choose the left option
 *  lto-selection-right: click to choose the right option
 *  lto-animation-left: is set when clicking lto-selection-left
 *  lto-animation-right: is set when clicking lto-selection-right
 *
 * @see {@link IRenderable}
 * @see {@link IStackeable}
 */
var Selection = /** @class */ (function () {
    function Selection(message) {
        this.values = [];
        this.isPublished = false;
        this.animationDuration = 300;
        this.spec = message;
        this.numOfBlocks = this.spec.elements.length;
        this.selection = document.createElement('div');
    }
    /**
     * @inheritDoc
     */
    Selection.prototype.render = function (renderer, isNested) {
        var _this = this;
        var position = this.spec.position || 'left';
        this.selection.setAttribute("name", this.spec.name || "");
        this.selection.classList.add('lto-selection', "lto-" + position);
        if (this.spec.id !== undefined) {
            this.selection.id = this.spec.id;
        }
        if (this.spec.class !== undefined)
            this.spec.class.split(" ").forEach(function (e) { return _this.selection.classList.add(e); });
        var publishedBlocks = 0;
        var elements = (this.spec.elements || []).map(function (e) { return renderer.render(e, _this); });
        elements.forEach(function (e) { return e.forEach(function (items) {
            var left = document.createElement("div");
            var right = document.createElement("div");
            items.style.userSelect = "none";
            left.className = "lto-selection-left";
            right.className = "lto-selection-right";
            items.appendChild(left);
            items.appendChild(right);
            _this.selection.appendChild(items);
        }); });
        this.selection.querySelectorAll(".lto-selection-item").forEach(function (items) {
            items.addEventListener("click", function (ev) {
                var _a, _b;
                //@ts-ignore
                if (ev.target.getAttribute("class") === "lto-selection-left") {
                    items.classList.add("lto-animate-left");
                    _this.values.push((_a = {}, _a[items.getAttribute("name") || ""] = "left", _a));
                }
                else {
                    items.classList.add("lto-animate-right");
                    _this.values.push((_b = {}, _b[items.getAttribute("name") || ""] = "right", _b));
                }
                setTimeout(function () { return items.style.display = "none"; }, _this.animationDuration);
                if (++publishedBlocks === _this.numOfBlocks) {
                    // wait till animation is finished
                    setTimeout(function () {
                        _this.setFinished();
                        _this.publish();
                    }, _this.animationDuration);
                }
            });
        });
        if (isNested) {
            this.selection.classList.add('lto-nested');
        }
        if (this.spec.countdownInSec !== 0) {
            setTimeout(function () {
                _this.setFinished();
                _this.publish();
            }, this.spec.countdownInSec * 1000);
        }
        return this.selection;
    };
    Selection.prototype.publish = function () {
        if (!this.isPublished) {
            this.selection.style.pointerEvents = "none";
            var evType = EventType.withChannelId(EventType.PUBLISH, this.spec.channelId);
            // Workaround since a map with contains a map which contains an array of maps (this.values)
            // cannot be serialized. (Failed to deserialize message from [akka://HeimdallActorSystem@127.0.0.1:25520]
            // with serializer id [6] and manifest []. java.io.NotSerializableException: cannot handle datatype
            // dynabuffers.ast.datatype.MapType@712d5ed4
            // This also removes the need to reduceToMap in the onComplete of the prompt
            // Take the array of maps (selection items and choice) and convert it to single map
            // Contained in a map that has as key the selection form name
            var selectionMap = {};
            selectionMap[this.spec.name] = {};
            for (var _i = 0, _a = this.values; _i < _a.length; _i++) {
                var selectionItemAndChoice = _a[_i];
                selectionMap[this.spec.name][Object.keys(selectionItemAndChoice)[0]] =
                    selectionItemAndChoice[Object.keys(selectionItemAndChoice)[0]];
            }
            var payload = {
                type: MessageType.SUBMIT,
                attributes: {
                    name: this.spec.name,
                    value: JSON.stringify(selectionMap)
                },
                payload: {
                    text: this.spec.name,
                    value: JSON.stringify(selectionMap)
                }
            };
            EventStream.emit(evType, payload);
            this.isPublished = true;
        }
    };
    Selection.prototype.setFinished = function () {
        this.selection.classList.add("lto-selection-finished");
    };
    return Selection;
}());
export { Selection };
Renderables.register("selection", Selection);
//# sourceMappingURL=index.js.map