/**
 * Created by rockyl on 2018-12-26.
 *
 * 进度条
 */

import {Entity, ScillaComponent, decorators, createTween, ease} from "scilla";
import RectRenderer from "../renderer/RectRenderer";
import Transform from "../base/Transform";
import TextRenderer from "../renderer/TextRenderer";

const {dirtyFieldTrigger} = decorators;

function renderLabelFuncSample(value, maximum, minimum){
	return Math.floor(value / (maximum - minimum) * 100) + '%';
}

export default class ProgressBar extends ScillaComponent {
	viewport: Entity;
	thumb: Entity;
	widget: Entity;
	label: Entity;

	@dirtyFieldTrigger
	value: number = 0;
	@dirtyFieldTrigger
	minimum: number = 0;
	@dirtyFieldTrigger
	maximum: number = 0;
	@dirtyFieldTrigger
	snapInterval: number = 1;
	@dirtyFieldTrigger
	renderLabelFunc: Function;
	@dirtyFieldTrigger
	fixWithRange: boolean = true;

	private _mask: RectRenderer;
	private _widgetTransform: Transform;
	private _label: TextRenderer;
	private _thumbSize: any;

	onCreate() {
		super.onCreate();

		this.renderLabelFunc = renderLabelFuncSample;
	}

	onAwake() {
		super.onAwake();

		this._mask = this.viewport.getComponent(RectRenderer);
		this._mask.width = 0;
		if(this.widget){
			this._widgetTransform = this.widget.getComponent(Transform);
		}

		this._label = this.label.getComponent(TextRenderer);

		this.callOnNextTick(this.updateThumbSize);
	}

	private updateThumbSize=()=>{
		const {width, height} = this.thumb.getComponent(Transform);
		this._thumbSize = {width, height};

		this.update();
	};

	onModify(value, key, oldValue) {
		super.onModify(value, key, oldValue);

		if(oldValue === undefined){
			return;
		}
		this.callOnNextTick(this.update);
	}

	private update(){
		const {minimum, maximum, _thumbSize} = this;

		if(!_thumbSize){
			return ;
		}

		const range = maximum - minimum;

		let value = Math.max(minimum, Math.min(maximum, this.value));

		const percentage = (value - minimum) / range;
		const width = percentage * _thumbSize.width;

		//this._mask.width = width;
		createTween(this._mask, true)
			.to({width}, 300, ease.cubicOut);

		if(this._widgetTransform){
			this._widgetTransform.position.x = width;
		}

		let renderValue = this.fixWithRange ? Math.max(minimum, Math.min(maximum, this.value)) : this.value;
		this.value = value;
		if(this._label){
			let text = this.renderLabelFunc(renderValue, this.maximum, this.minimum);
			if(typeof text == 'string'){
				this._label.text = text;
				this._label.textFlow = null;
			}else{
				this._label.textFlow = text;
				this._label.updateTextFlow();
			}
		}
	}
}
