import { each, isArray } from '@antv/util';
import { catmullRom2bezier, getLinePath } from '../../geometry/shape/util/path';
import { toPoints } from '../../util/bbox';
import { isPolygonsIntersect } from '@antv/path-util';
function getMaskBBox(context, tolerance) {
    var event = context.event;
    var maskShape = event.target;
    var maskBBox = maskShape.getCanvasBBox();
    // 如果 bbox 过小则不返回
    if (!(maskBBox.width >= tolerance || maskBBox.height >= tolerance)) {
        return null;
    }
    return maskBBox;
}
function getMaskPath(context, tolerance) {
    var event = context.event;
    var maskShape = event.target;
    var maskBBox = maskShape.getCanvasBBox();
    // 如果 bbox 过小则不返回
    if (!(maskBBox.width >= tolerance || maskBBox.height >= tolerance)) {
        return null;
    }
    return maskShape.attr('path');
}
/**
 * 获取当前事件相关的图表元素
 * @param context 交互的上下文
 * @ignore
 */
export function getCurrentElement(context) {
    var event = context.event;
    var element;
    var target = event.target;
    if (target) {
        element = target.get('element');
    }
    return element;
}
/**
 * 获取委托对象
 * @param context 上下文
 * @ignore
 */
export function getDelegationObject(context) {
    var event = context.event;
    var target = event.target;
    var delegateObject;
    if (target) {
        delegateObject = target.get('delegateObject');
    }
    return delegateObject;
}
export function isElementChange(context) {
    var event = context.event.gEvent;
    // 在同一个 element 内部移动，label 和 shape 之间
    if (event && event.fromShape && event.toShape && event.fromShape.get('element') === event.toShape.get('element')) {
        return false;
    }
    return true;
}
/**
 * 是否是列表组件
 * @param delegateObject 委托对象
 * @ignore
 */
export function isList(delegateObject) {
    return delegateObject && delegateObject.component && delegateObject.component.isList();
}
/**
 * 是否是滑块组件
 * @param delegateObject 委托对象
 * @ignore
 */
export function isSlider(delegateObject) {
    return delegateObject && delegateObject.component && delegateObject.component.isSlider();
}
/**
 * 是否由 mask 触发
 * @param context 上下文
 * @ignore
 */
export function isMask(context) {
    var event = context.event;
    var target = event.target;
    return target && target.get('name') === 'mask';
}
/**
 * 获取被遮挡的 elements
 * @param context 上下文
 * @ignore
 */
export function getMaskedElements(context, tolerance) {
    var target = context.event.target;
    if (target.get('type') === 'path') {
        var maskPath = getMaskPath(context, tolerance);
        if (!maskPath) {
            return;
        }
        return getElementsByPath(context.view, maskPath);
    }
    var maskBBox = getMaskBBox(context, tolerance);
    // 如果 bbox 过小则不返回
    if (!maskBBox) {
        return null;
    }
    return getIntersectElements(context.view, maskBBox);
}
/**
 * @ignore
 */
export function getSiblingMaskElements(context, sibling, tolerance) {
    var maskBBox = getMaskBBox(context, tolerance);
    // 如果 bbox 过小则不返回
    if (!maskBBox) {
        return null;
    }
    var view = context.view;
    var start = getSiblingPoint(view, sibling, { x: maskBBox.x, y: maskBBox.y });
    var end = getSiblingPoint(view, sibling, { x: maskBBox.maxX, y: maskBBox.maxY });
    var box = {
        minX: start.x,
        minY: start.y,
        maxX: end.x,
        maxY: end.y,
    };
    return getIntersectElements(sibling, box);
}
/**
 * 获取所有的图表元素
 * @param view View/Chart
 * @ignore
 */
export function getElements(view) {
    var geometries = view.geometries;
    var rst = [];
    each(geometries, function (geom) {
        var elements = geom.elements;
        rst = rst.concat(elements);
    });
    if (view.views && view.views.length) {
        each(view.views, function (subView) {
            rst = rst.concat(getElements(subView));
        });
    }
    return rst;
}
/**
 * 获取所有的图表元素
 * @param view View/Chart
 * @param field 字段名
 * @param value 字段值
 * @ignore
 */
export function getElementsByField(view, field, value) {
    var elements = getElements(view);
    return elements.filter(function (el) {
        return getElementValue(el, field) === value;
    });
}
/**
 * 根据状态名获取图表元素
 * @param view View/Chart
 * @param stateName 状态名
 * @ignore
 */
export function getElementsByState(view, stateName) {
    var geometries = view.geometries;
    var rst = [];
    each(geometries, function (geom) {
        var elements = geom.getElementsBy(function (el) { return el.hasState(stateName); });
        rst = rst.concat(elements);
    });
    return rst;
}
/**
 * 获取图表元素对应字段的值
 * @param element 图表元素
 * @param field 字段名
 * @ignore
 */
export function getElementValue(element, field) {
    var model = element.getModel();
    var record = model.data;
    var value;
    if (isArray(record)) {
        value = record[0][field];
    }
    else {
        value = record[field];
    }
    return value;
}
/**
 * 两个包围盒是否相交
 * @param box1 包围盒1
 * @param box2 包围盒2
 * @ignore
 */
export function intersectRect(box1, box2) {
    return !(box2.minX > box1.maxX || box2.maxX < box1.minX || box2.minY > box1.maxY || box2.maxY < box1.minY);
}
/**
 * 获取包围盒内的图表元素
 * @param view View/Chart
 * @param box 包围盒
 * @ignore
 */
export function getIntersectElements(view, box) {
    var elements = getElements(view);
    var rst = [];
    each(elements, function (el) {
        var shape = el.shape;
        var shapeBBox = shape.getCanvasBBox();
        if (intersectRect(box, shapeBBox)) {
            rst.push(el);
        }
    });
    return rst;
}
function pathToPoints(path) {
    var points = [];
    each(path, function (seg) {
        var command = seg[0];
        if (command !== 'A') {
            for (var i = 1; i < seg.length; i = i + 2) {
                points.push([seg[i], seg[i + 1]]);
            }
        }
        else {
            var length_1 = seg.length;
            points.push([seg[length_1 - 2], seg[length_1 - 1]]);
        }
    });
    return points;
}
/**
 * 获取包围盒内的图表元素
 * @param view View/Chart
 * @param path 路径
 * @ignore
 */
export function getElementsByPath(view, path) {
    var elements = getElements(view);
    var points = pathToPoints(path);
    var rst = elements.filter(function (el) {
        var shape = el.shape;
        var shapePoints;
        if (shape.get('type') === 'path') {
            shapePoints = pathToPoints(shape.attr('path'));
        }
        else {
            var shapeBBox = shape.getCanvasBBox();
            shapePoints = toPoints(shapeBBox);
        }
        return isPolygonsIntersect(points, shapePoints);
    });
    return rst;
}
/**
 * 获取当前 View 的所有组件
 * @param view View/Chart
 * @ignore
 */
export function getComponents(view) {
    return view.getComponents().map(function (co) { return co.component; });
}
/** @ignore */
export function distance(p1, p2) {
    var dx = p2.x - p1.x;
    var dy = p2.y - p1.y;
    return Math.sqrt(dx * dx + dy * dy);
}
/** @ignore */
export function getSpline(points, z) {
    if (points.length <= 2) {
        return getLinePath(points, false);
    }
    var first = points[0];
    var arr = [];
    each(points, function (point) {
        arr.push(point.x);
        arr.push(point.y);
    });
    var path = catmullRom2bezier(arr, z, null);
    path.unshift(['M', first.x, first.y]);
    return path;
}
/**
 * 检测点是否在包围盒内
 * @param box 包围盒
 * @param point 点
 * @ignore
 */
export function isInBox(box, point) {
    return box.x <= point.x && box.maxX >= point.x && box.y <= point.y && box.maxY > point.y;
}
/**
 * 获取同 view 同一级的 views
 * @param view 当前 view
 * @returns 同一级的 views
 * @ignore
 */
export function getSilbings(view) {
    var parent = view.parent;
    var siblings = null;
    if (parent) {
        siblings = parent.views.filter(function (sub) { return sub !== view; });
    }
    return siblings;
}
function point2Normalize(view, point) {
    var coord = view.getCoordinate();
    return coord.invert(point);
}
/**
 * 将 view 上的一点转换成另一个 view 的点
 * @param view 当前的 view
 * @param sibling 同一层级的 view
 * @param point 指定点
 * @ignore
 */
export function getSiblingPoint(view, sibling, point) {
    var normalPoint = point2Normalize(view, point);
    return sibling.getCoordinate().convert(normalPoint);
}
/**
 * 是否在记录中，临时因为所有的 view 中的数据不是引用，而使用的方法
 * 不同 view 上对数据的引用不相等，导致无法直接用 includes
 * 假设 x, y 值相等时是同一条数据，这个假设不完全正确，而改成 isEqual 则成本太高
 * 后面改成同一个引用时可以修改回来
 * @param records
 * @param record
 * @param xFiled
 * @param yField
 * @returns
 * @ignore
 */
export function isInRecords(records, record, xFiled, yField) {
    var isIn = false;
    each(records, function (r) {
        if (r[xFiled] === record[xFiled] && r[yField] === record[yField]) {
            isIn = true;
            return false;
        }
    });
    return isIn;
}
// 级联获取 field 对应的 scale，如果 view 上没有，遍历子 view
export function getScaleByField(view, field) {
    var scale = view.getScaleByField(field);
    if (!scale && view.views) {
        each(view.views, function (subView) {
            scale = getScaleByField(subView, field);
            if (scale) {
                return false; // 终止循环
            }
        });
    }
    return scale;
}
//# sourceMappingURL=util.js.map