
import * as THREE from 'three';
import { OrbitControls } from '../../node_modules/three/examples/jsm/controls/OrbitControls'
import Stats from '../../node_modules/three/examples/jsm/libs/stats.module'
import { EffectComposer } from '../../node_modules/three/examples/jsm/postprocessing/EffectComposer'
import { RenderPass } from '../../node_modules/three/examples/jsm/postprocessing/RenderPass'
import { Pass } from 'three/examples/jsm/postprocessing/Pass';
import { TestPass } from './posts';

class Viewer {

    private clock: THREE.Clock;
    private viewSize: THREE.Vector2;
    private container: HTMLDivElement | null;

      renderer: THREE.WebGLRenderer;
    private composer: EffectComposer

    private scene: THREE.Scene
    private camera: THREE.PerspectiveCamera
    private controls: OrbitControls;
    private stats: Stats

    constructor() {

        this.clock = new THREE.Clock(false);
        this.container = null;
        this.viewSize = new THREE.Vector2();

        this.renderer = new THREE.WebGLRenderer({ antialias: true });
        this.composer = new EffectComposer(this.renderer);
        
        this.scene = new THREE.Scene();
        this.camera = new THREE.PerspectiveCamera();
        this.controls = new OrbitControls(this.camera, this.renderer.domElement);
        
        this.stats = Stats();
        
    }

    init() {

        this.clock.start();

        this.renderer.setPixelRatio(window.devicePixelRatio);
        this.renderer.domElement.style.width = '100%';
        this.renderer.domElement.style.height = '100%';
        
        this.composer.addPass(new RenderPass(this.scene, this.camera));
        //this.composer.addPass(new TestPass())

        this.camera.aspect = window.innerWidth / window.innerHeight;
        this.camera.position.set(0, 20.51227126407633, 50.3253462213248);
        this.camera.updateProjectionMatrix();

        this.scene.add(new THREE.GridHelper(1000, 50));
        this.scene.add(new THREE.AxesHelper(30));
    
        
        let pointLight = new THREE.PointLight(0xffffff, 20, 300)
        pointLight.position.set(0, 15, 0);
        pointLight.updateMatrixWorld()
        this.scene.add(pointLight);
        this.scene.add(new THREE.PointLightHelper(pointLight))

        let directionLight = new THREE.DirectionalLight(0xffffff, 1)
        directionLight.position.set(10,10,10)
        this.scene.add(directionLight)
        this.scene.add(new THREE.DirectionalLightHelper(directionLight))

        this.scene.add(new THREE.AmbientLight(0xffffff, 1))

        this.renderer.physicallyCorrectLights = true
        

        this.controls.enableDamping = true;
        this.controls.dampingFactor = 0.5;
        this.controls.update()
        this.update(0.016)
        this.render();
    }

    add(object: THREE.Object3D) {
        this.scene.add(object);
    }

    remove(object: THREE.Object3D) {
        this.scene.remove(object)
    }

    addPostEffectPass( pass: Pass) {

        this.composer.addPass(pass);

    }

    start( container : HTMLDivElement) {

        this.container = container;
        (this.container || document.body).appendChild(this.renderer.domElement);
        this.init();
        this.animate();

    }

    private animate() {

        this.update(this.clock.getDelta());
        this.render();
        this.stats.update()
        window.requestAnimationFrame(this.animate.bind(this));
    }

    private update(deltaTime: number) {

        this.updateSize();
    }

    private updateSize() {

        let width = this.container && this.container.clientWidth || window.innerWidth;
        let height = this.container && this.container.clientHeight || window.innerHeight;

        this.renderer.setSize(width, height, false);
        this.camera.aspect = width / height;
        this.camera.updateProjectionMatrix();

        // let width = Math.floor(this.renderer.domElement.clientWidth);
        // let height = Math.floor(this.renderer.domElement.clientHeight);

        
        // if( width != this.renderer.domElement.width || height != this.renderer.domElement.height ) {

        //     this.renderer.setSize(width, height, false);
        //     this.renderer.getSize(this.viewSize);

        //     this.camera.aspect = width / height;
        //     this.camera.updateProjectionMatrix();

        // }


        
    }

    private render() {
        
        this.composer.render();

    }


    bakeTexture( width: number, height: number, ) {

        let renderTarget = new THREE.WebGLRenderTarget(width, height);

        let geometry = new THREE.BufferGeometry();
            geometry.setAttribute("", new THREE.Float32BufferAttribute([], 4))
            geometry.setIndex([0,1,2])

        
        //this.renderer.renderBufferDirect();

    }

}

const RTUtil = {

    camera: new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 1),
    scene: new THREE.Scene(),

}

export default Viewer;