/**
 * Created by rockyl on 2019-05-17.
 *
 * 物品层管理
 */

import ScillaComponent from "components/base/ScillaComponent";
import {dynamic, instantiate, math, resource, Size, Texture} from "scilla";
import Item from "./Item";
import Transform from "components/base/Transform";

export default class ItemLayer extends ScillaComponent {
	itemCount = 13;
	itemPosPadding = 50;
	itemPosRange: Size = new Size(750, 500);
	itemCellPadding = 20;
	itemPosOffsetY = 50;
	playCreditsCount = 4;
	itemPrefab: resource;
	activityBaseInfo: dynamic;
	holeRes: Texture;
	itemRes: Texture;

	private _items: Item[] = [];
	private _playCreditsCount;
	private _itemGap;
	private _itemPosOffset;
	private _freePlayCreditsCount;
	private _excludeItemQueue = [];
	private _timerCreditsAnimation;

	onAwake() {
		super.onAwake();

		this._playCreditsCount = Math.floor(this.itemCount / 3);
		this._itemGap = {
			x: (this.itemPosRange.width - this.itemPosPadding * 2) / 3,
			y: (this.itemPosRange.height - this.itemCellPadding * 2) / 3,
		};
		this._itemPosOffset = {
			x: -this.itemPosRange.width / 2,
			y: this.itemPosOffsetY,
		};

		for (let i = 0; i < this.itemCount; i++) {
			let itemEntity = instantiate(this.itemPrefab);
			this.entity.addChild(itemEntity);
			itemEntity.enabled = false;

			this._items.push(itemEntity.getComponent(Item));
		}
	}

	prepareItems() {
		this._freePlayCreditsCount = this.playCreditsCount;
		this._excludeItemQueue.splice(0);

		const {_itemGap, _itemPosOffset, itemPosPadding, itemCellPadding, itemPosRange} = this;

		let i, j;
		for (i = 0; i < 4; i++) {
			this.addItem(i, {
				x: i * _itemGap.x + _itemPosOffset.x + itemPosPadding,
				y: _itemPosOffset.y + Math.random() * itemPosRange.height + itemPosPadding,
			})
		}
		for (j = 0; j < this.itemCount - 4; j++) {
			const gx = j % 3;
			const gy = Math.floor(j / 3);

			this.addItem(i + j, {
				x: gx * _itemGap.x + _itemPosOffset.x + itemPosPadding + Math.random() * (_itemGap.x - itemCellPadding * 2) + itemCellPadding,
				y: gy * _itemGap.y + _itemPosOffset.y + itemPosPadding + Math.random() * (_itemGap.y - itemCellPadding * 2) + itemCellPadding,
			})
		}

		this.entity.children.sort((a, b) => {
			return a.getComponent(Transform).position.y - b.getComponent(Transform).position.y
		});

		this.stopCreditsAnimation();
		this.playCreditsAnimation();
	}

	private addItem(i, pos) {
		const item = this._items[i];
		item.reset(pos);
	}

	playCreditsAnimation() {
		this._timerCreditsAnimation = setInterval(this.playACredits, 200)
	}

	stopCreditsAnimation() {
		if (this._timerCreditsAnimation) {
			clearInterval(this._timerCreditsAnimation);
			this._timerCreditsAnimation = null;
		}

		for (let item of this._items) {
			item.stopCredits();
		}
	}

	private playACredits = async () => {
		if (this._freePlayCreditsCount > 0) {
			const {_excludeItemQueue, _items} = this;

			let targetItem: Item, index;
			while (true) {
				index = Math.floor(Math.random() * _items.length);
				if (_excludeItemQueue.indexOf(index) < 0) {
					targetItem = _items[index];
					if (!targetItem.playing) {
						break;
					}
				}
			}
			this._freePlayCreditsCount--;
			_excludeItemQueue.push(index);
			if (_excludeItemQueue.length > this._playCreditsCount * 2) {
				_excludeItemQueue.shift();
			}
			const cost = math.makeRandomInt(this.activityBaseInfo.miningExpend * 2, 1);
			await targetItem.playCredits(cost);
			this._freePlayCreditsCount++;
		}
	};

	digDelegate = (x, y) => {
		let items = [];
		let hitWidth = this.holeRes.width + this.itemRes.width - 40;
		for (let item of this._items) {
			if (!item.exclude && item.hit(x, y, hitWidth, 5)) {
				items.push(item);
			}
		}
		return items;
	}
}
