import { Utils } from '../common/Utils';
import { MathUtils } from '../math/MathUtils';
import { BaseLine } from './BaseLine';

/**
 * RouteLine - 道路线
 * 
 * 用于创建道路线物体,支持宽度、拐角和样式。
 * 
 * @class RouteLine
 * @memberof THING
 * @extends THING.BaseLine
 * @public
 * 
 * @example
 * const road = new THING.RouteLine({
 *   points: [[0, 0, 0], [10, 0, 0]],
 *   width: 3,
 *   style: { color: '#888888' },
 * });
 */
class RouteLine extends BaseLine {

	static defaultTagArray = ['Line'];

	/**
	 * 道路线
	 * @param {object} param 初始参数.
	 * @param {Array<number[]>} param.points 路径坐标的数组
	 * @param {number} [param.width=1] 线宽度(单位米)
	 * @param {number} [param.cornerRadius=0.3] 拐角半径
	 * @param {number} [param.cornerSplit=10] 拐角分割面数,数值越大拐角越平滑
	 * @param {boolean} [param.frenet=true] 是否开启Frenet模式
	 * @param {object} [param.style] 线样式
	 * @constructor
	 * @public
	 */
	constructor(param = {}) {
		super(param);
	}

	// #region Overrides

	onSetupResource(param) {
		this._width = Utils.parseNumber(param['width'], 1);
		this._cornerRadius = Utils.parseNumber(param['cornerRadius'], 0.3);
		this._cornerSplit = Utils.parseNumber(param['cornerSplit'], 10);
		this._frenet = Utils.parseBoolean(param['frenet'], true);
		this._arrow = Utils.parseBoolean(param['arrow'], false);

		super.onSetupResource(param);
	}

	onCreateBodyNode(param) {
		const node = Utils.createObject('RouteLine', { app: this.app });
		return node;
	}

	onSetupBodyNode(node) {
		super.onSetupBodyNode(node);

		node.setWidth(this._width);
		node.setCornerRadius(this._cornerRadius);
		node.setCornerSplit(this._cornerSplit);
		node.setFrenet(this._frenet);
		node.setArrow(this._arrow);
	}

	onRefreshAttributes() {
		let bodyNode = this.bodyNode;
		bodyNode.setWidth(this._width);
		bodyNode.setCornerRadius(this._cornerRadius);
		bodyNode.setCornerSplit(this._cornerSplit);
		bodyNode.setFrenet(this._frenet);
		bodyNode.setArrow(this._arrow);
	}

	onExportExternalData() {
		let external = Object.assign({}, super.onExportExternalData());
		Utils.setAttributeIfExist(external, 'width', this);
		Utils.setAttributeIfExist(external, 'cornerRadius', this);
		Utils.setAttributeIfExist(external, 'cornerSplit', this);
		Utils.setAttributeIfExist(external, 'frenet', this);
		Utils.setAttributeIfExist(external, 'arrow', this);
		return external;
	}

	setUv(uv) {
		Utils.warn('RouteLine.setUv is not supported.');
	}

	getUv() {
		Utils.warn('RouteLine.getUv is not supported.');
		return [];
	}

	// #endregion

	// #region Accessor

	/**
	 * 获取/设置本地坐标系下线路面的朝向
	 * @type {Array<number>}
	 * @example
	 * // 获取朝向
	 * const facingDirection = this.facingDirection;
	 * // 设置朝向
	 * this.facingDirection = [0, 0, 1];
	 * @public
	 */
	get facingDirection() {
		let target = [0, 0, 0];
		return this.bodyNode.getUpDirection(target);
	}
	set facingDirection(value) {
		this.bodyNode.setUpDirection(value);
	}

	/**
	 * 线宽度(米)
	 * @type {number}
	 * @default 1.0
	 * @example
	 * // 获取宽度
	 * const width = this.width;
	 * // 设置宽度
	 * this.width = 2.0;
	 * @public
	 */
	get width() {
		return this._width;
	}
	set width(value) {
		this._width = value;

		this.bodyNode.setWidth(this._width);
	}

	/**
	 * 道路线转弯半径(一般大于宽度的一半)
	 * @type {number}
	 * @default 0.3
	 * @example
	 * // 获取转弯半径
	 * const cornerRadius = this.cornerRadius;
	 * // 设置转弯半径
	 * this.cornerRadius = 0.5;
	 * @public
	 */
	get cornerRadius() {
		return this._cornerRadius;
	}
	set cornerRadius(value) {
		this._cornerRadius = value;

		this.bodyNode.setCornerRadius(this._cornerRadius);
	}

	/**
	 * 获取/设置拐角分割面数,数值越大拐角越平滑(必须是整数)
	 * @type {number}
	 * @default 10
	 * @example
	 * // 获取拐角分割面数
	 * const cornerSplit = this.cornerSplit;
	 * // 设置拐角分割面数
	 * this.cornerSplit = 20;
	 * @public
	 */
	get cornerSplit() {
		return this._cornerSplit;
	}
	set cornerSplit(value) {
		this._cornerSplit = MathUtils.toInteger(value);

		this.bodyNode.setCornerSplit(this._cornerSplit);
	}

	/**
	 * 开启/关闭 Frenet 模式
	 * @type {boolean}
	 * @default true
	 * @public
	 */
	get frenet() {
		return this._frenet;
	}
	set frenet(value) {
		this._frenet = value;

		this.bodyNode.setFrenet(this._frenet);
	}

	/**
	 * 开启/关闭 箭头模式
	 * @type {boolean}
	 * @example
	 * // 获取箭头模式
	 * const arrow = this.arrow;
	 * // 设置箭头模式
	 * this.arrow = true;
	 * @public
	 */
	get arrow() {
		return this._arrow;
	}
	set arrow(value) {
		this._arrow = value;

		this.bodyNode.setArrow(this._arrow);
	}

	// #endregion

	get isRouteLine() {
		return true;
	}

}

export { RouteLine }