/* -----------------------------------------------------------------------------
| Copyright (c) Jupyter Development Team.
| Distributed under the terms of the Modified BSD License.
|----------------------------------------------------------------------------*/
/**
 * This module contains some utility functions to operate on cells. This
 * could be shared by widgets that contain cells, like the CodeConsole or
 * Notebook widgets.
 */
import { each } from '@lumino/algorithm';
import { h, VirtualDOM } from '@lumino/virtualdom';
/**
 * Constants for drag
 */
/**
 * The threshold in pixels to start a drag event.
 */
const DRAG_THRESHOLD = 5;
/**
 * The class name added to drag images.
 */
const DRAG_IMAGE_CLASS = 'jp-dragImage';
/**
 * The class name added to singular drag images
 */
const SINGLE_DRAG_IMAGE_CLASS = 'jp-dragImage-singlePrompt';
/**
 * The class name added to the drag image cell content.
 */
const CELL_DRAG_CONTENT_CLASS = 'jp-dragImage-content';
/**
 * The class name added to the drag image cell content.
 */
const CELL_DRAG_PROMPT_CLASS = 'jp-dragImage-prompt';
/**
 * The class name added to the drag image cell content.
 */
const CELL_DRAG_MULTIPLE_BACK = 'jp-dragImage-multipleBack';
export var CellDragUtils;
(function (CellDragUtils) {
    /**
     * Find the cell index containing the target html element.
     * This function traces up the DOM hierarchy to find the root cell
     * node. Then find the corresponding child and select it.
     *
     * @param node - the cell node or a child of the cell node.
     * @param cells - an iterable of Cells
     * @param isCellNode - a function that takes in a node and checks if
     * it is a cell node.
     *
     * @returns index of the cell we're looking for. Returns -1 if
     * the cell is not founds
     */
    function findCell(node, cells, isCellNode) {
        let cellIndex = -1;
        while (node && node.parentElement) {
            if (isCellNode(node)) {
                each(cells, (cell, index) => {
                    if (cell.node === node) {
                        cellIndex = index;
                        return false;
                    }
                });
                break;
            }
            node = node.parentElement;
        }
        return cellIndex;
    }
    CellDragUtils.findCell = findCell;
    /**
     * Detect which part of the cell triggered the MouseEvent
     *
     * @param cell - The cell which contains the MouseEvent's target
     * @param target - The DOM node which triggered the MouseEvent
     */
    function detectTargetArea(cell, target) {
        let targetArea;
        if (cell) {
            if (cell.editorWidget.node.contains(target)) {
                targetArea = 'input';
            }
            else if (cell.promptNode.contains(target)) {
                targetArea = 'prompt';
            }
            else {
                targetArea = 'cell';
            }
        }
        else {
            targetArea = 'unknown';
        }
        return targetArea;
    }
    CellDragUtils.detectTargetArea = detectTargetArea;
    /**
     * Detect if a drag event should be started. This is down if the
     * mouse is moved beyond a certain distance (DRAG_THRESHOLD).
     *
     * @param prevX - X Coordinate of the mouse pointer during the mousedown event
     * @param prevY - Y Coordinate of the mouse pointer during the mousedown event
     * @param nextX - Current X Coordinate of the mouse pointer
     * @param nextY - Current Y Coordinate of the mouse pointer
     */
    function shouldStartDrag(prevX, prevY, nextX, nextY) {
        const dx = Math.abs(nextX - prevX);
        const dy = Math.abs(nextY - prevY);
        return dx >= DRAG_THRESHOLD || dy >= DRAG_THRESHOLD;
    }
    CellDragUtils.shouldStartDrag = shouldStartDrag;
    /**
     * Create an image for the cell(s) to be dragged
     *
     * @param activeCell - The cell from where the drag event is triggered
     * @param selectedCells - The cells to be dragged
     */
    function createCellDragImage(activeCell, selectedCells) {
        const count = selectedCells.length;
        let promptNumber;
        if (activeCell.model.type === 'code') {
            const executionCount = activeCell.model
                .executionCount;
            promptNumber = ' ';
            if (executionCount) {
                promptNumber = executionCount.toString();
            }
        }
        else {
            promptNumber = '';
        }
        const cellContent = activeCell.model.value.text.split('\n')[0].slice(0, 26);
        if (count > 1) {
            if (promptNumber !== '') {
                return VirtualDOM.realize(h.div(h.div({ className: DRAG_IMAGE_CLASS }, h.span({ className: CELL_DRAG_PROMPT_CLASS }, '[' + promptNumber + ']:'), h.span({ className: CELL_DRAG_CONTENT_CLASS }, cellContent)), h.div({ className: CELL_DRAG_MULTIPLE_BACK }, '')));
            }
            else {
                return VirtualDOM.realize(h.div(h.div({ className: DRAG_IMAGE_CLASS }, h.span({ className: CELL_DRAG_PROMPT_CLASS }), h.span({ className: CELL_DRAG_CONTENT_CLASS }, cellContent)), h.div({ className: CELL_DRAG_MULTIPLE_BACK }, '')));
            }
        }
        else {
            if (promptNumber !== '') {
                return VirtualDOM.realize(h.div(h.div({ className: `${DRAG_IMAGE_CLASS} ${SINGLE_DRAG_IMAGE_CLASS}` }, h.span({ className: CELL_DRAG_PROMPT_CLASS }, '[' + promptNumber + ']:'), h.span({ className: CELL_DRAG_CONTENT_CLASS }, cellContent))));
            }
            else {
                return VirtualDOM.realize(h.div(h.div({ className: `${DRAG_IMAGE_CLASS} ${SINGLE_DRAG_IMAGE_CLASS}` }, h.span({ className: CELL_DRAG_PROMPT_CLASS }), h.span({ className: CELL_DRAG_CONTENT_CLASS }, cellContent))));
            }
        }
    }
    CellDragUtils.createCellDragImage = createCellDragImage;
})(CellDragUtils || (CellDragUtils = {}));
//# sourceMappingURL=celldragutils.js.map