<template>
    <div class="card mt-1">
        <div class="card-header">Vializer</div>
        <div class="card-body">
            <div ref="container3d" id="container3d" class="border p-0 m-0"></div>
        </div>
    </div>
</template>

<script>
    import * as THREE from 'three';
    import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
	import { TransformControls } from 'three/addons/controls/TransformControls.js'
    import { LineBasicMaterial, DoubleSide, Group, LineSegments, Mesh } from 'three';

    let camera, scene, renderer, tool

    export default {
        props: {
            width: Number,
            height: Number,
            x: Number,
            y: Number,
            z: Number,
            a: Number,
            x_max: Number,
            x_min: Number,
            y_max: Number,
            y_min: Number,
            z_max: Number,
            z_min: Number
        },
        methods: {
            render() {
                renderer.render( scene, camera )
            },
            setSize() {
                renderer.setSize( this.width, this.height )
                this.render()
            },
            setPos() {
                let pos = {x: this.x, y: this.y, z:this.z, a:this.a}

                pos.x = (pos.x>this.x_max)?this.x_max:pos.x
                pos.x = (pos.x<this.x_min)?this.x_min:pos.x

                pos.y = (pos.y>this.y_max)?this.y_max:pos.y
                pos.y = (pos.y<this.y_min)?this.y_min:pos.y

                pos.z = (pos.z>this.z_max)?this.z_max:pos.z
                pos.z = (pos.z<this.z_min)?this.z_min:pos.z

                pos.a = 1.8 * pos.a // degrees

                let toolPos = {
                    x: (2000 * pos.x) / (this.x_max-this.x_min),
                    y: (2000 * pos.y) / (this.y_max-this.y_min),
                    z: (2000 * pos.z) / (this.z_max-this.z_min),
                    a: pos.a * (Math.PI/180)
                }

                // Set position with "start position" on 3d scene
                tool.position.z = 1000 + toolPos.x
                tool.position.x = 1000 + toolPos.y
                tool.position.y = 100 + toolPos.z
                tool.rotation.set(Math.PI, toolPos.a, 0)

				this.render()
            }
            /*
            onWindowResize() {
				camera.aspect = window.innerWidth / window.innerHeight
				camera.updateProjectionMatrix()
				renderer.setSize( window.innerWidth, window.innerHeight )
				this.render()
            }
            */
        },
        mounted() {
			//let camera, scene, renderer
			let transformControl

            let container = this.$refs['container3d']

            scene = new THREE.Scene()
            scene.background = new THREE.Color( 0xf0f0f0 )
            
            //camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 )
            camera = new THREE.PerspectiveCamera( 70, this.width / this.height, 1, 10000 )
            camera.rotation.set(-Math.PI / 2, 0, -Math.PI / 2)
            camera.position.set( -300, 1800, 0 )
            scene.add( camera )

            scene.add( new THREE.AmbientLight( 0xf0f0f0, 3 ) )
            const light = new THREE.SpotLight( 0xffffff, 4.5 )
            light.position.set( 0, 1500, 200 )
            light.angle = Math.PI * 0.2
            light.decay = 0
            light.castShadow = true
            light.shadow.camera.near = 200
            light.shadow.camera.far = 2000
            light.shadow.bias = - 0.000222
            light.shadow.mapSize.width = 1024
            light.shadow.mapSize.height = 1024
            scene.add( light )

            const planeGeometry = new THREE.PlaneGeometry( 50, 50 )
            //planeGeometry.rotateX( - Math.PI / 2 )
            const planeMaterial = new THREE.ShadowMaterial( { color: 0x000000, opacity: 0.2 } )
            const plane = new THREE.Mesh( planeGeometry, planeMaterial )
            plane.position.y = - 200
            plane.receiveShadow = true
            scene.add( plane )

            const helper = new THREE.GridHelper( 2000, 20 )
            helper.position.y = 0
            helper.material.opacity = 0.25
            helper.material.transparent = true
            scene.add( helper )

            const axesHelper = new THREE.AxesHelper( 200 )
            axesHelper.position.x = 1000
            axesHelper.position.z = 1000
            axesHelper.rotateY( Math.PI )
            scene.add( axesHelper )

            renderer = new THREE.WebGLRenderer( { antialias: true } )
            renderer.setPixelRatio( window.devicePixelRatio )
            renderer.setSize( this.width, this.height )
            renderer.shadowMap.enabled = true
            container.appendChild( renderer.domElement )

            // Controls
            const controls = new OrbitControls( camera, renderer.domElement )
            controls.damping = 0.2
            controls.addEventListener( 'change', this.render )

            transformControl = new TransformControls( camera, renderer.domElement )
            transformControl.addEventListener( 'change', this.render )
            transformControl.addEventListener( 'dragging-changed', function ( event ) {
                controls.enabled = ! event.value
            })
            scene.add(transformControl.getHelper())

            transformControl.addEventListener( 'objectChange', function () {
                updateSplineOutline()
            })

            //window.addEventListener( 'resize', this.onWindowResize )

            const geometry = new THREE.ConeGeometry( 50, 200, 4, 1 )
            const lineMaterial = new LineBasicMaterial( { color: 0xffffff, transparent: true, opacity: 0.5 } )
            const material = new THREE.MeshPhongMaterial( { color: 0x156289, emissive: 0x072534, side: DoubleSide, flatShading: true } )

            tool = new Group()
            tool.add( new LineSegments( geometry, lineMaterial ) )
            tool.add( new Mesh( geometry, material ) )
            scene.add( tool )

            // Start Position
            tool.rotateX( Math.PI )
            tool.position.y = 100
            tool.position.x = 1000
            tool.position.z = 1000

            this.setPos()

            this.render()
        },
        watch: {
            height() {
                this.setSize()
            },
            width() {
                this.setPos()
            },
            x() {
                this.setPos()
            },
            y() {
                this.setPos()
            },
            z() {
                this.setPos()
            },
            a() {
                this.setPos()
            }
        }
    }
</script>

<style>
    #container3d {
        max-width: 602px;
        max-height: 402px;
    }
</style>