class Bookmark extends THREE.Object3D {
    constructor(position, target, scale = 500.0) {
        super();

        position = new THREE.Vector3().copy(position);
        target = new THREE.Vector3().copy(target);

        this.position.copy(position);
        this.target = new THREE.Vector3().copy(target);

        this.t = 0;

        let material = new THREE.LineBasicMaterial({
            color: 0xffffff,
            linewidth: 3,
        });
        let geometry = new THREE.Geometry();

        let direction = this.target.clone().sub(position).normalize().multiplyScalar(this.length());

        geometry.vertices.push(new THREE.Vector3(0.0, -1000000.0, 0.0));
        geometry.vertices.push(new THREE.Vector3(0.0, 0.0, 0.0));

        this.line = new THREE.Line(geometry, material);
        this.add(this.line);

        this.numberOfPoints = 20;
        this.createCircle();
        this._shining = false;

        this.t = 0;
    }

    createCircle() {
        let map = new THREE.TextureLoader().load("assets/eye.png");
        let material = new THREE.SpriteMaterial({
            map: map,
            color: 0xfffffff,
            transparent: true,
        });
        let geometry = new THREE.Geometry();
        this.circle = new THREE.Sprite(material);
        this.add(this.circle);
    }

    length() {
        return 25 * (Math.cos(this.t) + 5);
    }

    get shining() {
        return this._shining;
    }

    set shining(other) {
        this._shining = other;
        if (!other) {
            this.circle.material.color = new THREE.Color(1, 1, 1);
            this.line.material.color = new THREE.Color(1, 1, 1);
        }
    }

    update(camera) {
        // super.update(camera);

        /// assert(camera instanceof THREE.Camera);
        let distance = this.localToWorld(this.position.clone()).distanceTo(camera.position);
        this.t += 0.05;
        let l = this.length();
        this.circle.scale.x = l * Math.log(1 + distance);
        this.circle.scale.y = l * Math.log(1 + distance);
        this.circle.scale.z = l * Math.log(1 + distance);
        this.line.geometry.vertices[1].y = -this.circle.scale.x / 2;
        this.line.geometry.verticesNeedUpdate = true;

        if (this.shining) {
            let value = (1 + Math.cos(Math.PI / 2 + this.t * 2)) / 2;
            this.circle.material.color = new THREE.Color(1 - value, value, 0);
            this.line.material.color = new THREE.Color(1 - value, value, 0);
        }
    }

}

