class Stars 
{
    constructor (config)
    {
        this.scene = config.scene;

        this.x = config.x;
        this.y = config.y;


        this.vDelta = config.vDelta;
        this.ease = 'Power1';
        this.blitter = this.scene.add.blitter(0, 0, config.key);

        this.circles = [];
        this.bobs = [];

        for(let i = 0; i < 5; ++i)
        {
            this.circles.push(new Phaser.Geom.Circle(this.x, this.y + this.vDelta, 200 + i * 20));
        }

        this.isPlaying_ = false;
    }
    
    start()
    {
        this.createEndPoints();
        this.bobs.length = 0;

        for(let i = 0; i < this.endPoints.length; ++i)
        {
            this.bobs[i] = this.blitter.create(this.x, this.y + this.vDelta, Phaser.Math.Between(0, 7));

            this.addTween(i, i);
        }

        this.scene.time.addEvent({ delay: 500, callback: this.launch, callbackScope: this, repeat: -1 });

        this.isPlaying_ = true;
    }

    stop()
    {
        for(let i = 0; i < this.bobs.length; ++i)
        {
            this.scene.tweens.killTweensOf(this.bobs[i]);
            this.bobs[i].destroy();
        }

        this.bobs.length = 0;
        
        this.scene.time.removeAllEvents();

        this.isPlaying_ = false;

        for(let i = 0; i < this.circles.length; ++i)//reset circles to default positions
        {
            this.circles[i].setPosition(this.x, this.y + this.vDelta);
        }
    }
    
    launch ()
    {
        if(!this.isPlaying_)
        {
            return;
        }

        this.createEndPoints();

        for(let i = 0; i < this.endPoints.length; ++i)
        {
            let index = this.getBobIndex();

            if(index >= 0)
            {
                this.bobs[index].reset(this.x, this.y + this.vDelta, Phaser.Math.Between(0, 7));
                this.bobs[index].setVisible(true);
            }
            else
            {
                this.bobs.push(this.blitter.create(this.x, this.y + this.vDelta, Phaser.Math.Between(0, 7)));
                index = this.bobs.length - 1;
            }                

            this.addTween(index, i);
        }
    }

    createEndPoints()
    {
        this.endPoints = [];
        
        for(let i = 0; i < this.circles.length; ++i)
        {
            let pts = this.circles[i].getPoints(Phaser.Math.Between(20, 30));

            this.endPoints.splice(this.endPoints.length, 0, ...pts);
        }
    }

    addTween(index, i)
    {
        this.scene.tweens.add({
            targets: this.bobs[index],
            x: this.endPoints[i].x,
            y: this.endPoints[i].y,
            duration: Phaser.Math.Between(500, 1000),
            ease: this.ease,
            yoyo: false,
            onCompleteParams: [index],
            onCompleteScope: this,
            onComplete: function ()
            {
                if(this.bobs[index] != null && this.bobs[index].parent != null) // rare race condition check, where bob is destroyed, tween is scheduled to be destroyed on next update step but finishes before it
                {
                    this.bobs[index].setVisible(false);
                }
            }
        });
    }

    getBobIndex()
    {
        for(let i = 0; i < this.bobs.length; ++i)
        {
            if(this.bobs[i].visible == false)
            {
                return i;
            }
        }

        return -1;
    }

    onOrientationChange(v)
    {
        this.vDelta = v;

        for(let i = 0; i < this.circles.length; ++i)
        {
            this.circles[i].setPosition(this.x, this.y + this.vDelta);
        }
    }

    setPosition(x, y)
    {
        this.x = x;
        this.y = y;
        
        for(let i = 0; i < this.circles.length; ++i)
        {
            this.circles[i].setPosition(x, y);
        }
    }

    isPlaying()
    {
        return this.isPlaying_;
    }
}
