import { localWave } from './../localWave';
import ObjectPool = engine.ObjectPool;
import {getStage} from "./utils";
import {getTextureByName} from "./utils";
import {props} from "../props";
import { Block } from "./Block";

export class Road extends engine.Container{
    container: engine.Container;
    dustEffect:[];
    dustNode:engine.Container;
    dustSprite:engine.Sprite;
    dustIndex:number = 0;
	flag: engine.Sprite;
    reward;

    index = 0;
	minDistance = parseInt(props.blockMinDistance) || 100;
	maxDistance = parseInt(props.blockMaxDistance) || 300;

	basePos = getStage().width / 2 - 100;
	padding = 500;
	lastPos;

	rewardIndex;
	aniReward:any;
	tweenReward;
    lastBlockType;
    
    preSetup() {
        this.addChild(this.container = new engine.Container());
        const flag = this.flag = new engine.Sprite(getTextureByName('flag_record'));
        this.anchorRate(flag, 0.5, 1);
        flag.y = -230;
		flag.x = this.transScoreToFlagPos();
		flag.visible = flag.x > 0;
        this.addChild(flag);
    }
    

    setup(){
        this.dustNode = new engine.Container();
        this.dustSprite = new engine.Sprite();
        this.dustSprite.visible = false;
        this.dustNode.y = -1000;
        this.dustNode.x = -450;
        this.dustNode.addChild(this.dustSprite);
        this.addChild(this.dustNode)



        const reward = this.reward = new engine.Sprite();
		reward.visible = false;
		reward.y = -500;
        this.addChild(reward);
        this.aniReward = new localWave();
        this.aniReward.init(reward, 2000, localWave.sin.bind(null, 10));
    }
	start(revive = false) {
		if(revive){

		}else{
			this.rewardIndex = 0;
			this.showReward();
		}
	}
	reset(revive = false) {
		if (!revive) 
		{
			this.index = 0;
			this.lastPos = 0;

			this.clear();
			this.fill();
			this.flag.x = this.transScoreToFlagPos();
			this.flag.visible = this.flag.x > 0;
		}
	}


    anchorRate(target: any, rx: number, ry: number, width: number = 0, height: number = 0, resetPos = true): void {
        if (width == 0) {
            width = target.width;
        }
        if (height == 0) {
            height = target.height;
        }
        if (resetPos) {
            if (rx == 0) {
                target.x -= target.anchorOffsetX;
            }
            if (ry == 0) {
                target.y -= target.anchorOffsetY;
            }
        }

        target.anchorOffsetX = width * rx;
        target.anchorOffsetY = height * ry;

        if (resetPos) {
            if (rx > 0) {
                target.x += target.anchorOffsetX;
            }
            if (ry > 0) {
                target.y += target.anchorOffsetY;
            }
        }
    }
    transScoreToFlagPos(){
        //const maxScore = props.maxScore;
        //maxScore * 100
		return -1;
    }
	clear() {
		while (this.container.children.length > 0) {
			this.removeBlockAt(0);
		}
    }
    //添加障碍
    addBlock() {
		let type = 0, v;

		if (this.index > 10) {
			do {
				const rv = Math.random();
				v = 0;
				for (let i = 0; i < 5; i++) {
					v += Block.configs[i].ratio;
					if (rv < v) {
						type = i;
						break;
					}
				}
			} while (this.lastBlockType == type);
			this.lastBlockType = type;
        }
        const block: Block = ObjectPool.getObject('block', {type});

		const {width} = Block.configs[type];

		const distance = this.index == 0 ?
			this.maxDistance :
			this.makeRandomFloat(this.maxDistance, this.minDistance);
		const pos = this.lastPos + distance;
		block.x = pos;

		this.container.addChild(block);

		this.lastPos = pos + width;

		this.index++;
	}
    removeBlockAt(index){
        const block = this.container.removeChildAt(index);
		ObjectPool.recycleObject('block', block);
    }
    removeBlock(block) {
		this.container.removeChild(block);
		ObjectPool.recycleObject('block', block);
	}
    fill() {
		if (isNaN(this.lastPos)) {
			return;
		}

		while (true) {
			if (this.lastPos + this.x > getStage().width + this.padding) {
				break;
			}
			this.addBlock();
		}
    }
    makeRandomFloat(max: number, min: number = 0): number {
        return Math.random() * (max - min) + min;
    }

	setViewport(pos) {
		this.x = this.basePos - pos;

		while (this.container.children.length > 0) {
			if (this.container.getChildAt(0).x >= pos - this.padding) {
				break;
			}

			this.removeBlockAt(0);
		}

		this.fill();
    }
    showReward(type = 10) {
		this.rewardIndex++;

		const pos = this.rewardIndex * getStage().width * 3;

		const reward = this.reward;
		reward.visible = true;
        reward.alpha = 1;
		reward.texture = getTextureByName('menu_block_10');
		reward.x = pos;
		this.aniReward.updateRegisterPos();
    }
    
    hideReward() {
		const reward = this.reward;
		this.tweenReward = engine.Tween.get(reward)
			.to({alpha: 0}, 200)
			.call(() => {
				this.tweenReward = null;
				this.showReward();
			})
	}
    hitReward(pos) {
		if (this.reward.visible && pos >= this.reward.x && !this.tweenReward) {
			this.hideReward();
			return true;
		}
    }
    playDust(pos) {
        this.dustSprite.x = pos;
        //播放序列帧
        this.dustSprite.visible = true;
        this.addEventListener(engine.Event.ENTER_FRAME,this.onEnterFrame,this);
    }
    onEnterFrame(){
        if(this.dustIndex < 12){
            this.dustSprite.texture = getTextureByName('dust_'+this.dustIndex);
            this.dustIndex ++;
        }else{
            this.dustIndex = 0;
            this.dustSprite.visible = false;
            this.removeEventListener(engine.Event.ENTER_FRAME,this.onEnterFrame,this);
        }
    }
    hitBlock(pos) {
		let target, lastTarget;

		//console.log('*******************');
		let foot = {a: pos - 84 / 2, b: pos + 84 / 2};
		//console.log(foot);
		this.container.children.some((block: Block, i) => {
			const {width} = Block.configs[block.type];
			const line = {a: block.x - width / 2, b: block.x + width / 2};
			//console.log(i, line);
			if (this.lineHitTest(foot, line)) {
				target = block;
				return true;
			}
		});

		//console.log(target ? 'hit on' : 'safe');

		if (!target) {
			for (let i = this.container.children.length; i > 0; i--) {
				const block = this.container.getChildAt(i - 1);
				if (block.x < pos) {
					lastTarget = block;
					break;
				}
			}
		}

		return {
			target,
			lastTarget,
		};
    }
    lineHitTest(l0, l1) {
        return l0.a < l1.b && l0.b > l1.a;
    }
}