
export default class prePlayScene{

    constructor(){
        // this.initScene();
    }
    static _instance: prePlayScene;
    static get instance() {
        return prePlayScene._instance || (prePlayScene._instance = new prePlayScene())
    }

    public BABYLON:any = window['BABYLON'];
    public canvasWebgl:any;
    public scene:any;
    public camera:any;
    public light:any;
    public light2:any;
    public cloudPool:any[] = []; // 云的数组
    public cloudTemplate:any; // 云的模板
    public rocketP:any;
    public rocketLine:any;
    public rocket:any;
    public realRocket:any;
    public gravity:number = -0.98;
    public glowLayer:any; // 发光层
    public planet:any; // 星球
    public touchDown:boolean; // 是否点击屏幕
    public rotateSpeed:number = 0; // 旋转速度
    public lastPosition:any; // 最后的位置
    public startTimestamp:number; // 开始的时间戳
    public stopTimestamp:number; // 
    public score:number = 0; // 分数
    public downSpeed:number = -0.025; // 下落速度
    public downAddSpeed:number = 0.04; // 下落加速度
    public createCount:number = 0; // 生成云的计数
    public cloudRange:number = 30; // 云生成的范围
    public TailSystem:any; // 尾巴粒子系统
    public bg:any;

    initScene(){
       
        let container = document.getElementById("egretContainer");
        let w = document.documentElement.clientWidth || document.body.clientWidth;
        let h = document.documentElement.clientHeight || document.body.clientHeight;
        document.querySelectorAll("canvas")[0].style.position = "absolute";
        document.querySelectorAll("canvas")[0].setAttribute("touch-action","none");
        this.canvasWebgl = document.createElement("canvas");
        this.canvasWebgl.width = w;
        this.canvasWebgl.height = h;
        container.appendChild(this.canvasWebgl);

        let engine = new this.BABYLON.Engine(this.canvasWebgl, true);
        engine.getRenderingCanvas=function(){
            return document.querySelectorAll("canvas")[0]
        };

        this.scene = new this.BABYLON.Scene(engine);
        this.scene.ambientColor = this.BABYLON.Color3.FromInts(10, 30, 10);
        this.scene.clearColor = this.BABYLON.Color3.FromInts(22, 3, 49);
        this.scene.collisionsEnabled = true;

        this.light = new this.BABYLON.HemisphericLight("dir01", new this.BABYLON.Vector3(0, -1, -0.3), this.scene);
        this.light.position = new this.BABYLON.Vector3(20, 60, 30);
        this.light2 = new this.BABYLON.HemisphericLight("dir02", new this.BABYLON.Vector3(0, 1, 0.3), this.scene);
        this.light2.position = new this.BABYLON.Vector3(20, -60, 30);

        this.camera = new this.BABYLON.FreeCamera("Camera", new this.BABYLON.Vector3(0, 0, 150), this.scene);

        this.glowLayer = new this.BABYLON.GlowLayer("glow", this.scene);
        this.glowLayer.intensity = 2;
        // 背景
        let bg = this.BABYLON.Mesh.CreatePlane('bg',400,this.scene);
        bg.position.set(0,0,-10);
        bg.rotate(new this.BABYLON.Vector3(0,0,1),Math.PI/2)
        let bgMaterial = new this.BABYLON.StandardMaterial('bgMaterial',this.scene);
        bgMaterial.diffuseTexture = new this.BABYLON.Texture('//yun.duiba.com.cn/db_games/activity/gravityBall1.0/model/bg.jpg',this.scene);
        bgMaterial.backFaceCulling = false;
        bg.material = bgMaterial;
        this.bg = bg;

        // 云
        this.BABYLON.SceneLoader.ImportMesh("", "//yun.duiba.com.cn/db_games/activity/gravityBall1.0/model/", "cloud.obj", this.scene, (newMeshes) => {
            const cloud = newMeshes[0];
            cloud.scaling.set(0.015,0.015,0.015);
            let cloudtMaterial = new this.BABYLON.StandardMaterial("cloudtMaterial", this.scene);
            cloudtMaterial.diffuseColor = new this.BABYLON.Color3(1,1,1);
            cloudtMaterial.ambientColor = new this.BABYLON.Color3(1,1,1);
            cloudtMaterial.specularColor = new this.BABYLON.Color3(1,1,1);
            cloudtMaterial.backFaceCulling = false;
            cloud.material = cloudtMaterial;
            cloud.position.y = 10;
            cloud.visibility = 0;
            this.cloudTemplate = cloud;
        })

        // 星球和用户球体
        this.BABYLON.SceneLoader.ImportMesh("", "//yun.duiba.com.cn/db_games/activity/gravityBall1.0/model/", "planet.gltf", this.scene, (newMeshes) => {
            // 星球
            this.planet = newMeshes[0]['_children'][0];
            let planetMaterial = new this.BABYLON.StandardMaterial("planetMaterial", this.scene);
            planetMaterial.diffuseTexture = new this.BABYLON.Texture('//yun.duiba.com.cn/db_games/activity/gravityBall1.0/model/texture.png', this.scene);
            planetMaterial.ambientColor = new this.BABYLON.Color3(1,1,1);
            planetMaterial.diffuseColor = new this.BABYLON.Color3(1,1,1);
            planetMaterial.backFaceCulling = false;
            this.planet.material = planetMaterial;

            // 用户球体
            this.realRocket = newMeshes[0]['_children'][0].clone();
            this.realRocket.scaling = new this.BABYLON.Vector3(1.5,1.5,1.5);
            this.rocket = this.BABYLON.Mesh.CreateBox('rocket', 2, this.scene);
            this.rocketP = this.BABYLON.Mesh.CreateBox('rocketP', 2, this.scene);
            this.rocket.parent = this.rocketP;
            this.rocket.visibility = 0;
            this.rocketP.visibility = 0;
            
            this.rocketP.ellipsoid = new this.BABYLON.Vector3(1, 1, 1);
            this.rocketP.ellipsoidOffset = new this.BABYLON.Vector3(0, 0, 0);
            let rocketMaterial = new this.BABYLON.StandardMaterial("rocketMaterial", this.scene);
            rocketMaterial.diffuseColor = new this.BABYLON.Color3(140/255,50/255,0);
            rocketMaterial.ambientColor = new this.BABYLON.Color3(140/255,50/255,0);
            rocketMaterial.specularColor = new this.BABYLON.Color3(140/255,50/255,0);
            rocketMaterial.emissiveColor = new this.BABYLON.Color3(140/255,50/255,0);
            rocketMaterial.backFaceCulling = false;
            this.realRocket.material = rocketMaterial;
            this.realRocket.parent = this.rocket;
            this.camera.parent = this.rocketP;
            this.camera.setTarget(this.realRocket.position.add(new this.BABYLON.Vector3(0,0,0)))

            this.rocketP.position.y = 40;
            this.lastPosition = this.rocketP.position.clone();
            this.realRocket.addRotation(0, 0, Math.PI);

            this.initTail()
        })

        // Fog
        this.scene.fogMode = this.BABYLON.Scene.FOGMODE_EXP;
        this.scene.fogDensity = 0.0015;
        this.scene.fogColor = this.scene.clearColor;

        let inputManager = this.camera.inputs;
        this.startTimestamp = Date.now();
    }

    // 初始化云
    initCloudPool(demo:any){
        // 生成云池
        for(let i = 0; i < 30; i++){
            let nCloud = demo.clone(`cloud_${i}`);
            let randomNum = Math.random();
            let newScale = Math.max(0.01*randomNum,0.005)
            nCloud.scaling.set(newScale, newScale, newScale);
            let newAngle = Math.random()*360;
            let newRadius = Math.max(Math.random()*this.cloudRange,10);
            nCloud.position.set(newRadius*Math.cos(newAngle),newRadius*Math.sin(newAngle),0);
            nCloud.lookAt(new this.BABYLON.Vector3(0,0,0));
            nCloud.rotate(new this.BABYLON.Vector3(1,0,0),Math.PI/2);
            nCloud.visibility = 1;
            this.cloudPool.push(nCloud);
        }
    }

    // 初始化尾巴
    initTail(){
        // debugger
        this.TailSystem = new this.BABYLON.ParticleSystem("particles", 1000, this.scene);
        this.TailSystem.particleTexture = new this.BABYLON.Texture("//yun.duiba.com.cn/db_games/activity/gravityBall1.0/model/fire.jpg", this.scene);
        this.TailSystem.blendMode = this.BABYLON.ParticleSystem.BLENDMODE_ONEONE;

        this.TailSystem.minAngularSpeed = -2;
        this.TailSystem.maxAngularSpeed = 2;
        this.TailSystem.minSize = 3;
        this.TailSystem.maxSize = 4;
        this.TailSystem.minLifeTime = 0.005;
        this.TailSystem.maxLifeTime = 0.015;
        this.TailSystem.minEmitPower = 0.5;
        this.TailSystem.maxEmitPower = 4.0;
        this.TailSystem.emitter = this.rocketP;
        this.TailSystem.emitRate = 10000;
        this.TailSystem.direction1 = new this.BABYLON.Vector3(-0.2, -0.2, -0.2);
        this.TailSystem.direction2 = new this.BABYLON.Vector3(0.2, 0.2, 0.2);
        this.TailSystem.color1 = new this.BABYLON.Color3(1, 0, 0);
        this.TailSystem.color2 = new this.BABYLON.Color3(0.95, 0.84, 0.05);
        
        // this.TailSystem.moveSource = true;
        this.TailSystem.start();
    }

    disposeAll(){
        for(let cloud of this.cloudPool){
            cloud.dispose();
            this.removeEle(cloud, this.cloudPool);
        }
    }

    /** 
     * 让物体朝传入方向移动
     * 放在onEnterFrame里或者render里
     * 该方法里重力垂直向下
    */
    public moveByVector3(mesh:any, forward:any, speed?:number, isGravity?:boolean){
        let _speed:number = 1;
        let _gravity = 0;
        let _isGravity = false;
        if(speed){
            _speed = speed;
        }
        if(isGravity){
            _isGravity = isGravity;
        }
        if(_isGravity && this.gravity){
            _gravity = this.gravity;
        }
        mesh.position.x += forward.x * _speed;
        mesh.position.y += forward.y * _speed + _gravity;
        mesh.position.z += forward.z * _speed;
    }

    /**
     *  让物体朝传入方向加速/减速移动
     * */ 
    public tempSpeed:number = 0;
    public accelerateByVector3(mesh:any, forward:any, speed?:number, addSpeed?:number, isGravity?:boolean){
        let _speed:number = 1;
        let _addSpeed:number = 0;
        let _gravity = 0;
        let _isGravity = false;

        const time = (Date.now() - this.startTimestamp)/1000;
        if(speed){
            _speed = speed;
        }
        if(addSpeed){
            _addSpeed = addSpeed;
        }
        if(isGravity){
            _isGravity  = isGravity;
        }
        if(_isGravity && this.gravity){
            _gravity = this.gravity
        }
        // v1 = v0 + a*t
        let newSpeed = _speed + _addSpeed * time;
        mesh.position.x += forward.x * newSpeed;
        mesh.position.y += forward.y * newSpeed + _gravity;
        mesh.position.z += forward.z * newSpeed;
    }

    /**
     *  移除数组里的元素
     *  @param e 要移除的元素
     *  @param arr 目标数组
     *  */
    public removeEle(e, arr) {
        var index = arr.indexOf(e);
        if (index >= 0) {
            arr.splice(index, 1)
        }
    }
}