'use strict';

const ANJUNA_DRAG_CLASS = 'anj-dragging';
class DragController {
    constructor(element, data) {
        this.element = element;
        this.data = data;
        this.dragStartListener = (e) => this.onDragStart(e);
        this.dragEndListener = (e) => this.onDragEnd(e);
    }
    connect() {
        this.element.setAttribute('draggable', 'true');
        this.element.addEventListener('dragstart', this.dragStartListener);
        this.element.addEventListener('dragend', this.dragEndListener);
        return this;
    }
    disconnect() {
        this.element.removeAttribute('draggable');
        this.element.removeEventListener('dragstart', this.dragStartListener);
        this.element.removeEventListener('dragend', this.dragEndListener);
        return undefined;
    }
    onDragStart(event) {
        this.element.classList.add(ANJUNA_DRAG_CLASS);
        if (event.dataTransfer) {
            event.dataTransfer.effectAllowed = 'move';
            if (this.data) {
                event.dataTransfer.setData('data', JSON.stringify(this.getData()));
            }
        }
    }
    onDragEnd(event) {
        event.preventDefault();
        this.element.classList.remove(ANJUNA_DRAG_CLASS);
    }
    getData() {
        return typeof this.data === 'function' ? this.data() : this.data;
    }
}

const ANJUNA_DROP_CLASS = 'anj-dragover';
class DropController {
    constructor(element) {
        this.element = element;
        this.dragEnterListener = () => this.onDragEnter();
        this.dragLeaveListener = () => this.onDragLeave();
        this.dragOverListener = e => this.onDragOver(e);
        this.dropListener = e => this.onDrop(e);
    }
    connect() {
        this.element.addEventListener('dragenter', this.dragEnterListener);
        this.element.addEventListener('dragleave', this.dragLeaveListener);
        this.element.addEventListener('dragover', this.dragOverListener);
        this.element.addEventListener('drop', this.dropListener);
        return this;
    }
    disconnect() {
        this.element.removeEventListener('dragenter', this.dragEnterListener);
        this.element.removeEventListener('dragleave', this.dragLeaveListener);
        this.element.removeEventListener('dragover', this.dragOverListener);
        this.element.removeEventListener('drop', this.dropListener);
        return undefined;
    }
    onDragEnter() {
        this.element.classList.add(ANJUNA_DROP_CLASS);
    }
    onDragLeave() {
        this.element.classList.remove(ANJUNA_DROP_CLASS);
    }
    onDragOver(event) {
        if (event.preventDefault) {
            event.preventDefault();
        }
        this.checkStyle();
        event.dataTransfer.dropEffect = 'move';
        return false;
    }
    onDrop(event) {
        if (event.stopPropagation) {
            event.stopPropagation(); // Stops some browsers from redirecting.
        }
        this.element.classList.remove(ANJUNA_DROP_CLASS);
        if (event.dataTransfer && event.dataTransfer.getData && event.dataTransfer.getData('data')) {
            const detail = JSON.parse(event.dataTransfer.getData('data'));
            const anjEvent = new CustomEvent('anjDrop', { detail, bubbles: true });
            this.element.dispatchEvent(anjEvent);
        }
        return false;
    }
    checkStyle() {
        if (!this.element.classList.contains(ANJUNA_DROP_CLASS)) {
            this.element.classList.add(ANJUNA_DROP_CLASS);
        }
    }
}

exports.ANJUNA_DRAG_CLASS = ANJUNA_DRAG_CLASS;
exports.ANJUNA_DROP_CLASS = ANJUNA_DROP_CLASS;
exports.DragController = DragController;
exports.DropController = DropController;
