var engine = null;
var game = null;
var ui = null;
var water = null;
var shadowMap = null;

var music = new Audio( "sounds/music.ogg" );
music.loop = true;
var b_playMusic = true;
music.volume = 0.7;
var sound_build = new Audio( "sounds/build.ogg" );
var sound_upgrade = new Audio( "sounds/upgrade.ogg" );
var sound_demolish = new Audio( "sounds/demolish.ogg" );
var sound_gameover_water = new Audio( "sounds/gameover_water.ogg" );
var sound_gameover_food = new Audio( "sounds/gameover_food.ogg" );
var sound_gameover_crime = new Audio( "sounds/gameover_crime.ogg" );
var sound_raft = new Audio( "sounds/survivors.ogg" );

function init()
{
    engine = new Sparrow.Engine( "canvas" );
    engine.canvas.fillBrowserWindow( true );
    engine.setClearColor( 0 , 0.5 , 1 , 1 );
    engine.setFogOptions( 0.04 , Color3f.WHITE );
    engine.enableSky();
    engine.b_drawDebugInfo = false;

    var camera = new Sparrow.ArcBallCamera( engine );
    camera.lookAt = new vec3( 5.5 , 0.5 , 1.5 );
    camera.zoom = 8;
    camera.yaw = -0.2;
    camera.maxZoom = 12;
    camera.minPos = new vec3( 0 , 0.5 , 0 );
    camera.maxPos = new vec3( 11 , 0.5 , 3 );
    camera.minPitch = 0;
    camera.speed = 0.2;
    camera.sensitivity = 0.5;
    camera.zoomSpeed = 0.5;
    // camera.enableTrackPadControls();
    engine.activeCamera = camera;
    camera.update();

    // var shader3DLighting = Sparrow.Shader.createDefaultShader3DLighting( engine );
    // var shader3DLightingShadowMap = Sparrow.Shader.createDefaultShader3DLightingShadowMap( engine );

    // var testFloor = new Sparrow.Plane( engine , new vec3( 5.5 , 0.5 , 1.5 ) , 5.5 , 1.5 );
    // testCube = new Sparrow.Cube( engine , 0 , 0 , 0 , 1 , 1 , 1 );
    // testCube.translation = new vec3( 0 , 2 , -4 );
    // testCube.addOnClickHandler( () => { console.log( "testCube clicked" ); } );
    // var testSphere = new Sparrow.Sphere( engine , 0 , 0 , 0 , 1 );
    // testSphere.translation = new vec3( 1 , 4 , 3 );
    // testSphere.scale = new vec3( 0.5 , 0.5 , 0.5 );
    // var testModel = Sparrow.ModelLoader.loadGLTF( engine , "cup.gltf" );
    // var testModel = Sparrow.ModelLoader.loadGLTF( engine , "saloon.gltf" );
    // var testModel = Sparrow.ModelLoader.loadGLTF( engine , "flat_shading_test.gltf" );
    // testModel.translation = new vec3( 2 , 1 , -2 );
    // testModel.scale = new vec3( 0.5 , 0.5 , 0.5 );

    // var gltfTestModel = Sparrow.GLTF.load( engine , "bat_with_cube.gltf" );
    // gltfTestModel.translation = new vec3( 0 , 2 , 0 );
    // gltfTestModel.addOnClickHandler( () => { console.log( "animated gltf model clicked" ); } );
    
    // var gltfTest2 = Sparrow.GLTF2.load( engine , "bat_with_cube.gltf" );
    // var gltfTest2 = Sparrow.GLTF2.load( engine , "gltf_test_0.gltf" );
    // var gltfTest2 = Sparrow.GLTF2.load( engine , "bat_with_cube_animated_armature.gltf" , ( gltf ) => {
    //     for ( let i = 0 ; i < gltf.objects.length ; ++i )
    //     {
    //         if ( gltf.objects[i].name === "Cube.001" )
    //         {
    //             gltf.objects[i].addOnClickHandler( () => {
    //                 console.log( "gltf cube clicked" );
    //             } );
    //         }
    //     }
    // } );
    // var gltfTest2 = Sparrow.GLTF2.load( engine , "bat_0_3_test_with_cube_for_gltf_1.gltf" );
    // var gltfTest2 = Sparrow.GLTF2.load( engine , "water_test_0.gltf" );
    // gltfTest2.translation = new vec3( 3 , 1 , 2 );
    // gltfTest2.scale = new vec3( 0.2 , 0.2 , 0.2 );

    // var animatedModelTest = Sparrow.AnimatedModel.load( engine , "bat_with_cube.gltf" );
    // animatedModelTest.translation = new vec3( 0 , 1 , 0 );
    // animatedModelTest.addOnClickHandler( () => { console.log( "animatedModelTest clicked" ); } );
    // console.log( animatedModelTest );

    shadowMap = new Sparrow.ShadowMap( engine , engine.globalLightDirection , 4096 , 4096 );
    engine.activeShadowMap = shadowMap;

    water = new Sparrow.Water( engine , { size: 150 , scalingFactor: 30 , murkiness: 3 } );
    // waterTest.addObject( gltfTest2 );
    // waterTest.addObject( animatedModelTest );
    // var waterDebugMenu = new Sparrow.WaterDebugMenu( engine , waterTest );

    game = new Game();
    

    ui = new UI( engine );

    engine.onMouseMove = ( event ) => {
        var rayDirection = Sparrow.Util.getMouseRayDirection( engine , engine.M_projection , camera.M_view , event.clientX , event.clientY , camera.position );

        var ray = new Ray( camera.position , rayDirection );

        game.log.mouseMove( ray );
    };

    engine.onMouseClick = ( event ) => {
        if ( event.button === 0 )
        {
            var rayDirection = Sparrow.Util.getMouseRayDirection( engine , engine.M_projection , camera.M_view , event.clientX , event.clientY , camera.position );

            var ray = new Ray( camera.position , rayDirection );

            game.log.mouseClick( ray );
        }
    };

    engine.onKeyUp = ( event ) => {
        if ( event.type == "keyup" )
        {
            if ( event.code == "KeyM" )
            {
                if ( b_playMusic )
                {
                    b_playMusic = false;
                    music.pause();
                }
                else
                {
                    b_playMusic = true;
                    music.play();
                }
            }
        }
    };

    engine.update = ( dt ) => 
    {
        game.update( dt );
        water.update( dt );
        // animatedModelTest.update( dt );
    }

    engine.draw = () =>
    {
        engine.gl.enable( engine.gl.DEPTH_TEST );
        engine.useDefaultShader3D();

        // testFloor.draw();

        game.draw();

        water.draw();

        engine.gl.disable( engine.gl.DEPTH_TEST );
        engine.defaultShader2D.use();
        engine.restoreDefaultUniforms();
        ui.draw();
        // engine.colorPicker.debugQuad.draw();
        // waterTest.drawDebugQuads();
    }

    engine.start();
}