/**
 * Created by rockyl on 2020-02-02.
 *
 * 转盘
 */

import {props} from '../props'
import {Stick} from "./Stick";
import ObjectPool = engine.ObjectPool;
import {PoolName} from "./object-pool-init";
import {BreakUpPart} from "./BreakUpPart";

export class Turntable extends engine.Container {
	private _wrapper: engine.Container;
	private _stickContainer: engine.Container;
	private _body: engine.Image;
	private _breakUpContainer: engine.Container;
	private _dir;
	private _radius;
	private _items = [];

	private rotationRange;

	constructor() {
		super();

		let wrapper = this._wrapper = new engine.Container();
		this.addChild(wrapper);

		let stickContainer = this._stickContainer = new engine.Container();
		wrapper.addChild(stickContainer);

		let body = this._body = new engine.Image();
		wrapper.addChild(body);

		let breakUpContainer = this._breakUpContainer = new engine.Container();
		for (let i = 0, li = props.breakUpRatios.length - 1; i < li; i++) {
			let part = new BreakUpPart(this, props.breakUpRatios[i], props.breakUpRatios[i + 1]);
			breakUpContainer.addChild(part);
		}
		breakUpContainer.visible = false;
		this.addChild(breakUpContainer);

		/*let dot = new engine.Rect();
		dot.x = 150;
		dot.y = -5;
		dot.width = 10;
		dot.height = 10;
		dot.fillColor = 'red';
		wrapper.addChild(dot);*/
	}

	private resetAsset(body, asset) {
		body.source = asset;//'asset://' +
		body.x = -body.width / 2;
		body.y = -body.height / 2;
		body.anchorX = -body.x;
		body.anchorY = -body.y;
	}

	reset(options) {
		const {turntableAssetName} = options;
		this.rotationRange = props.rotationRange;

		let body = this._body;
		body.visible = true;
		this.resetAsset(body, turntableAssetName);
		this._radius = body.width / 2;

		this.hideSticks();

		for (let part of this._breakUpContainer.children) {
			this.resetAsset(part.body, turntableAssetName);
			part.updateMask();
		}
		this._breakUpContainer.visible = false;
	}

	get radius() {
		return this._radius;
	}

	start() {
		this._dir = 1;
		this._items.splice(0);
		this.rotateOnce();
	}

	pause() {
		engine.Tween.pauseTweens(this._wrapper);
	}

	resume() {
		engine.Tween.resumeTweens(this._wrapper);
	}

	addStick(stick: Stick) {
		let angle = this.parseAngle(this._wrapper.rotation);

		let minDis = props.stickAngle * 2;
		let hitOn = false;
		for (let item of this._items) {
			if (Math.abs(item - angle) < minDis) {
				hitOn = true;
				break;
			}
		}
		if (hitOn) {
			this.pause();
		} else {
			this._items.push(angle);

			stick.anchorOffsetY = stick.y;
			stick.y = 0;
			stick.rotation = -this._wrapper.rotation;
			this._stickContainer.addChild(stick);
			this.shake();
		}

		return hitOn;
	}

	parseAngle(r) {
		let round = r % 360;
		if (round < 0) {
			round += 360;
		}
		return round;
	}

	hideSticks() {
		for (let stick of this._stickContainer.children) {
			ObjectPool.recycleObject(PoolName, stick);
		}
		this._stickContainer.removeChildren();
	}

	async playBreakUp() {
		this.pause();
		this._body.visible = false;
		this._breakUpContainer.visible = true;

		let p;
		for (let part of this._breakUpContainer.children) {
			p = part.playFall(this._wrapper.rotation);
		}

		await p;
	}

	private shake() {
		engine.Tween.get(this, null, null, true)
			.to({y: this.y - 5}, 50)
			.to({y: this.y}, 50)
	}

	private rotateOnce() {
		let [min, max] = this.rotationRange;
		let dealtRotation = Math.random() * max + min;
		let duration = dealtRotation * (Math.random() * props.rotationDurationMultipleRandom + props.rotationDurationMultipleBase);
		let rotation = this._wrapper.rotation + this._dir * dealtRotation;
		this._dir *= -1;
		engine.Tween.get(this._wrapper, null, null, true)
			.to({rotation}, duration)
			.call(this.rotateOnce, this);
	}
}
