import * as THREE from 'three'
import { GLTFLoader, EXRLoader, RGBELoader, OrbitControls } from 'three/examples/jsm/Addons.js'
import { init, update, onClick, onKeyPress } from './game.js'
import gsap from 'gsap'
import { MotionPathPlugin } from 'gsap/MotionPathPlugin.js'
import Howler from 'howler'

gsap.registerPlugin(MotionPathPlugin)
Howler.autoUnlock = true
    
const game = {}
game.entities = []
game.loadingManager = new THREE.LoadingManager()
game.gltfLoader = new GLTFLoader(game.loadingManager)
game.textureLoader = new THREE.TextureLoader(game.loadingManager)
game.exrLoader = new EXRLoader(game.loadingManager)
game.rgbeLoader = new RGBELoader(game.loadingManager)
game.clock = new THREE.Clock()
game.camera = new THREE.PerspectiveCamera(60, 1, 0.1, 256)
game.scene = new THREE.Scene()
game.mousePosition = new THREE.Vector2(0, 0)
game.keyboard = {}
game.lookAtFocus = new THREE.Vector3(0, 0, 0)


function loaded() {
    game.renderer = new THREE.WebGLRenderer({
        canvas:game.canvas,
        antialias: true,

    })
    game.renderer.setSize(game.canvas.offsetWidth, game.canvas.offsetHeight)
    game.renderer.shadowMap.enabled = true
    game.renderer.shadowMap.type = THREE.PCFSoftShadowMap

    game.orbitControls = new OrbitControls(game.camera, game.renderer.domElement)
    game.orbitControls.enabled = false
    onResize()
    init(game).then(() => {
        document.getElementById("loading").style.display = "none"
        game.clock.start()
        attachAnimationFrame()
    })   
}

function onResize() {
    game.renderer.setSize(window.innerWidth, window.innerHeight, true)
    game.renderer.setPixelRatio(Math.min(2, window.devicePixelRatio))

    game.camera.aspect = game.canvas.offsetWidth / game.canvas.offsetHeight
    game.camera.updateProjectionMatrix()
}

function renderOneFrame() {
    
    update(game)
    game.orbitControls.update()
    if(!game.orbitControls.enabled) {
        game.camera.lookAt(game.lookAtFocus)
    }
    game.renderer.render(game.scene, game.camera)
}

function attachAnimationFrame() {
    renderOneFrame()
    window.requestAnimationFrame(attachAnimationFrame)
}

export default async function main(canvasElement) {
    game.canvas = canvasElement
    document.addEventListener("DOMContentLoaded", loaded)
    window.addEventListener('resize', onResize)
    game.canvas.addEventListener('mousemove', event => {
        game.mousePosition.x = 2 * (event.clientX / game.canvas.offsetWidth - 0.5)
        game.mousePosition.y = -2 * (event.clientY / game.canvas.offsetHeight - 0.5)
    })
    game.canvas.addEventListener('touchmove', event => {
        if(event.touches.length == 1) {
            game.mousePosition.x = 2 * ( event.touches[0].clientX / game.canvas.offsetWidth - 0.5)
            game.mousePosition.y = -2 * ( event.touches[0].clientY / game.canvas.offsetHeight - 0.5)  
        }
    })

    game.canvas.addEventListener('touchstart', event => {
        if(event.touches.length == 1) {
            game.mousePosition.x = 2 * ( event.touches[0].clientX / game.canvas.offsetWidth - 0.5)
            game.mousePosition.y = -2 * ( event.touches[0].clientY / game.canvas.offsetHeight - 0.5)  
        }
    })
    game.canvas.addEventListener('mousedown', event => {
        game.mousePosition.x = 2 * (event.clientX / game.canvas.offsetWidth - 0.5)
        game.mousePosition.y = -2 * (event.clientY / game.canvas.offsetHeight - 0.5)
    })

    game.canvas.addEventListener('click', event => {
        onClick()
    })

    window.addEventListener('keydown', event => {
        const lastKeyState = game.keyboard[event.code]
        game.keyboard[event.code] = true
        if (!lastKeyState) {
            onKeyPress()
        }
    })

    window.addEventListener('keyup', event => {
        game.keyboard[event.code] = false
    })
}