/** 
 * 工具函数,包括zrender所有util方法 {@link https://ecomfe.github.io/zrender-doc/public/api.html#zrenderutil}
 * 
 * @module util/index 
 */

import { isObject, isArray, each, merge } from 'zrender/src/core/util'
import { Path } from './graphic';

export * from 'zrender/src/core/util'; // 输出zrender中的util的所有方法

/**
 * 类管理扩展
 * 
 * @param {Object} entity 
 * @returns {Object} entity
 */
export function enableClassManagement(entity) {
    let storage = {};

    // 注册Class
    entity.registerClass = function (Clazz, componentType) {
        storage[componentType] = Clazz;
        return Clazz;
    }

    // 获取Class
    entity.getClass = function (componentType) {
        return storage[componentType];
    }

    entity.hasClass = function (componentType) {
        return !!storage[componentType];
    }

    entity.getAllClass = function () {
        return storage;
    }

    return entity;
}

function _trim(str) {
    return str.replace(/^\s+/, '').replace(/\s+$/, '');
}

/**
 * 解析百分比
 * 
 * @param {string|number} percent 若为字符则进行解析,若为数字直接返回
 * @param {number} [num=1] 获取num与percent相乘结果
 * @returns {number}
 */
export function parsePercent(percent, num = 1) {
    if (percent === undefined) return;
    switch (percent) {
        case 'center':
        case 'middle':
            percent = '50%';
            break;
        case 'left':
        case 'top':
            percent = '0%';
            break;
        case 'right':
        case 'bottom':
            percent = '100%';
            break;
    }
    if (typeof percent === 'string') {
        if (_trim(percent).match(/%$/)) {
            return parseFloat(percent) / 100 * num;
        }

        return parseFloat(percent);
    } else if (typeof percent === 'number') {
        return percent;
    }

    return percent == null ? NaN : +percent;
}


/**
 * 获取数组中所有符合条件的
 * 
 * @param {Array} array 数组
 * @param {Function} func 寻找函数
 * @param {any} context 
 * @returns {Array.<any>} 寻找结果
 */
export function findAll(array, func, context) {
    if (!(array && func)) {
        return;
    }

    let result = [];

    for (var i = 0, len = array.length; i < len; i++) {
        if (func.call(context, array[i], i, array)) {
            result.push(array[i]);
        }
    }

    return result;
}

/**
 * 获取数组中第一个符合条件的index
 * 
 * @param {Array} array 数组
 * @param {Function} func 寻找函数
 * @param {any} context 
 * @returns {any} 寻找结果
 */
export function findIndex(array, func, context) {
    if (!(array && func)) {
        return;
    }
    for (var i = 0, len = array.length; i < len; i++) {
        if (func.call(context, array[i], i, array)) {
            return i;
        }
    }
}

/**
 * 获取数组中所有符合条件的index
 * 
 * @param {Array} array 数组
 * @param {Function} func 寻找函数
 * @param {any} context 
 * @returns {number[]}
 */
export function findAllIndex(array, func, context) {
    if (!(array && func)) {
        return;
    }

    let result = [];

    for (var i = 0, len = array.length; i < len; i++) {
        if (func.call(context, array[i], i, array)) {
            result.push(i);
        }
    }

    return result;
}

/**
 * 解析size
 * 
 * @param {number|number[]} size 
 * @param {number} [num] 获取与size相乘结果
 * @returns {Object} size {width: xxx, height: xxx}
 */
export function parseSize(size, num) {
    if (isArray(size)) {
        return {
            width: parsePercent(size[0], num),
            height: parsePercent(size[1], num)
        }
    } else {
        return {
            width: parsePercent(size, num),
            height: parsePercent(size, num)
        }
    }
}

export function typeOf(v) {
    return Object.prototype.toString.call(v).slice(8, -1);
}

export function setObjectKV(
    obj = {},
    key,
    value,
    mergeObject = false,
    overwrite = true
) {
    let i = 0;
    let cur = obj;

    key = key.split('.');

    for (; i < key.length - 1; i++) {
        cur[key[i]] = cur[key[i]] || {};
        cur = cur[key[i]];
    }

    if (typeOf(value) === 'Object' && mergeObject) {
        cur[key[i]] = merge(cur[key[i]] || {}, value, overwrite);
    } else {
        cur[key[i]] = value;
    }

    return obj;
}

export function getObjectKV(obj, key) {
    let cur = obj;
    let i = 0;

    key = key.split('.');

    for (; i < key.length - 1; i++) {
        if (cur[key[i]]) {
            cur = cur[key[i]];
        } else {
            return undefined;
        }
    }

    return cur[key[i]];
}