/**
 * Created by rockyl on 2018/11/9.
 *
 * 常用工具
 */

/**
 * 属性注入方法
 * @param target 目标对象
 * @param data 被注入对象
 * @param callback 自定义注入方法
 * @param ignoreMethod 是否忽略方法
 * @param ignoreNull 是否忽略Null字段
 *
 * @return 是否有字段注入
 */
export function injectProp(target: any, data?: any, callback?: Function, ignoreMethod: boolean = true, ignoreNull: boolean = true): boolean {
	if (!target || !data) {
		return false;
	}

	let result = false;
	for (let key in data) {
		let value: any = data[key];
		if ((!ignoreMethod || typeof value != 'function') && (!ignoreNull || value != null) && key.indexOf('_') !== 0 && key.indexOf('$') !== 0) {
			if (callback) {
				callback(target, key, value);
			} else {
				try {
					target[key] = value;
				} catch (e) {

				}
			}

			result = true;
		}
	}
	return result;
}

/**
 * 属性拷贝
 * @param target
 * @param data
 * @param config
 */
export function copyProp(target, data?, config?) {
	if (config) {
		for (let key in config) {
			let valueConfig = config[key];
			if (Array.isArray(valueConfig)) {
				target[key] = {};
				for (let field of valueConfig) {
					target[key][field] = data[key][field];
				}
			} else if (typeof valueConfig === 'string') {
				target[valueConfig] = data[valueConfig];
			} else if (typeof valueConfig === 'object') {
				target[key] = {};
				copyProp(target[key], data[key], valueConfig)
			}
		}
	}
}

/**
 * 对象转搜索字符串
 * @param obj
 */
export function objectStringify(obj) {
	if (!obj) {
		return '';
	}
	let arr = [];
	for (let key in obj) {
		arr.push(key + '=' + obj[key]);
	}
	return arr.join('&');
}

/**
 * 生成一个等待Promise
 * @param duration
 */
export function waitPromise(duration): Promise<void> {
	return new Promise(resolve => {
		setTimeout(resolve, duration);
	});
}

/**
 * 可视化字符串
 * @param formatStr
 * @param params
 */
export function format(formatStr: string, ...params): string {
	return formatApply(formatStr, params);
}

/**
 * 格式化字符串(apply调用)
 * @param formatStr
 * @param params
 */
export function formatApply(formatStr: string, params: any[]): string {
	let result: string = formatStr;
	for (let i = 0, len = params.length; i < len; i++) {
		let reg = new RegExp("\\{" + i + "\\}", 'g');
		result = result.replace(reg, params[i]);
	}

	return result;
}

const zeros: Array<string> = [
	"0",
	"00",
	"000",
	"0000",
	"00000",
	"000000",
	"0000000",
	"00000000",
	"000000000",
	"0000000000"
];

/**
 * 补零
 * @param value
 * @param count
 */
export function supplement(value: number, count: number): string {
	let index = count - value.toString().length - 1;
	if (index < 0) {
		return value.toString();
	}
	return zeros[index] + value;
}

/**
 * 点eval
 * @param expression
 * @param context
 * @param strict
 * @param dotChar
 */
export function dotEval(expression: string, context = window, strict = true, dotChar = '.') {
	if (!expression || !context) {
		return context;
	}
	let result = expression
		.split(dotChar)
		.reduce(function (pre, cur, index, arr) {
			let ref;
			if (strict) {
				if (pre && pre.hasOwnProperty(cur)) {
					ref = pre[cur];
				} else {
					const e = `can not get ${cur} on ${index === 0 ? 'context' : arr.slice(0, index).join(dotChar)}`;
					console.warn(e);
					throw new Error(e);
				}
			} else {
				ref = cur && pre[cur] || pre
			}
			return ref;
		}, context);

	return result;
}
