window.onload = function () {

    var game = new Phaser.Game(1280, 800, Phaser.AUTO, '', { preload: preload, create: create, update: update, render: render });

    // Handler for mouse leaving the browser window
    function mouseLeftWindow(fn) {
        document.addEventListener('mouseout', function (e) {
            var from = e.relatedTarget || e.toElement;
            if (!from || from.nodeName === 'HTML') {
                fn.call({ x: e.x, y: e.y });
            }
        });
    }

    var modulesArray = [];
    var randomModulesArray = [];
    var music = [];
    var pMusic = 0;

    var options = {
        GRAVITY: 0,
        MAX_SPEED: 0,
        DRAG: 0,
        ACCELERATION: 0
    };

    var worldX = game.width / 3;

    var api = {
        getObjectByName: function(name) {
            for (var i = 0; i < modulesArray.length; i++) {
                if (modulesArray[i].name == name)
                    return modulesArray[i].getObject();
            }
        },
        getObjectsByName: function (name) {
            var objs = [];
            for (var i = 0; i < modulesArray.length; i++) {
                if (modulesArray[i].name == name)
                    objs.push(modulesArray[i].getObject());
            }
            return objs;
        },
        initImageCache: function () {
            //game.load.image("mureena", 'resources/images/mureena.png');
            game.load.spritesheet("mureena", 'resources/images/Moreay_attack_sprite_02.png', 340, 800, 48);
            //game.load.spritesheet(self.name, 'resources/images/Fish_swim_sprite_100.png', 150, 100, 14);
            game.load.spritesheet("player", 'resources/images/Fish_swim_sprite.png', 75, 50, 14);
            //game.load.spritesheet(self.name + "2", 'resources/images/Fish_whutnow_sprite_100.png', 150, 100, 24)
            game.load.spritesheet("player2", 'resources/images/Fish_whutnow_sprite.png', 75, 50, 24);
            //game.load.spritesheet(self.name + "3", 'resources/images/Fish_die_sprite_100.png', 150, 110, 24)
            game.load.spritesheet("player3", 'resources/images/Fish_die_sprite.png', 75, 55, 59);
            
			game.load.audio('fish_move', 'resources/sfx/fish-move.ogg');

			game.load.audio('fish_die1', 'resources/sfx/die-1.ogg');
			game.load.audio('fish_die2', 'resources/sfx/die-2.ogg');
			game.load.audio('fish_die3', 'resources/sfx/die-3.ogg');
			game.load.audio('fish_die4', 'resources/sfx/die-4.ogg');
			game.load.audio('fish_die5', 'resources/sfx/die-5.ogg');
			game.load.audio('fish_move1', 'resources/sfx/move-1.ogg');
			game.load.audio('fish_move2', 'resources/sfx/move-2.ogg');
			game.load.audio('fish_move3', 'resources/sfx/move-3.ogg');
			game.load.audio('fish_move4', 'resources/sfx/move-4.ogg');
			game.load.audio('fish_move5', 'resources/sfx/move-5.ogg');
			game.load.audio('fish_move6', 'resources/sfx/move-6.ogg');
			game.load.audio('fish_move7', 'resources/sfx/move-7.ogg');
			game.load.audio('fish_whatnow1', 'resources/sfx/what-now-1.ogg');
			game.load.audio('fish_whatnow2', 'resources/sfx/what-now-2.ogg');
			game.load.audio('fish_whatnow3', 'resources/sfx/what-now-3.ogg');
			game.load.audio('fish_whatnow4', 'resources/sfx/what-now-4.ogg');
			game.load.audio('fish_whatnow5', 'resources/sfx/what-now-5.ogg');
			game.load.audio('fish_whatnow6', 'resources/sfx/what-now-6.ogg');
			game.load.audio('fish_whatnow7', 'resources/sfx/what-now-7.ogg');
			game.load.audio('fish_whatnow8', 'resources/sfx/what-now-8.ogg');
			game.load.audio('fish_whatnow9', 'resources/sfx/what-now-9.ogg');
			game.load.audio('fish_whatnow10', 'resources/sfx/what-now-10.ogg');
			game.load.audio('fish_whatnow11', 'resources/sfx/what-now-11.ogg');
			game.load.audio('mureena_laugh', 'resources/sfx/muraena-laugh-1.ogg');
			game.load.audio('mureena_snap1', 'resources/sfx/muraena-snap-1.ogg');
			game.load.audio('mureena_snap2', 'resources/sfx/muraena-snap-2.ogg');





            game.load.spritesheet("exclamation", 'resources/images/ExclamationSheet.png', 44, 67, 6);
            //game.load.atlasXML(self.name, 'resources/images/kalatesti.png', 'assets/sprites/kalatesti.xml');
            game.load.image('GOMenuTitle', 'resources/images/GameOver/gameover.png');
        },
        stopCurrentMusic: function () {
            return music[pMusic].obj.stop();
        },
        playCurrentMusic: function () {
            return music[pMusic].obj.play();
        }
    }

     // Menu stuff

    var inMenu = goStartMenu(game, options, api);

    ////////////////////////////////
    // Modules Related Functions  //
    ////////////////////////////////

    function loadModules() {
        modulesArray.push(goPlayer(game, options, api));
        modulesArray.push(goPlayer(game, options, api));
        modulesArray.push(goPlayer(game, options, api));
        modulesArray.push(goPlayer(game, options, api));
        modulesArray.push(goGround(game, options, api));
		modulesArray.push(goMureena(game, options, api));
		modulesArray.push(goStartMenu(game, options, api));
    }

    function executeModulesFunction(name, param1, param2) {
        for (var i = 0; i < modulesArray.length; i++) {
            if (typeof modulesArray[i][name] == "function") {
                modulesArray[i][name](param1, param2);
            }
        }
    }

    function setupGravity() {
        options.GRAVITY = 100; // pixels/second/second
        options.MAX_SPEED = 200; // pixels/second
        options.DRAG = 100; // pixels/second
        options.ACCELERATION = 200; // pixels/second/second

        //game.physics.arcade.gravity.y = options.GRAVITY;
    }

    /////////////////////////////////
    // Game Engine State Functions //
    /////////////////////////////////

    function preload() {
        mouseLeftWindow(function () {
            executeModulesFunction("onInputUp", null, this);
        }, this);

        //loadModules();
        loadLevel();
        executeModulesFunction("preload");
        api.initImageCache();
        inMenu.preload();
    }

    var loopTimer = null;

    function create() {
        if (inMenu) {
            music[pMusic].obj = game.add.audio(music[pMusic].name);
            music[pMusic].obj.play();
            inMenu.create();
            return;
        }

        setupGravity();
        executeModulesFunction("create");
        game.stage.backgroundColor = 0x154dca;

        // Init the random object lottery
        loopTimer = game.time.events.loop(Phaser.Timer.SECOND, randomObjectLottery, this);

        // Start music
        pMusic = 0;
        music[pMusic].obj = game.add.audio(music[pMusic].name);
        music[pMusic].obj.play();

        game.input.keyboard.addKeyCapture([
            Phaser.Keyboard.K
        ]);
    }

    var lastSpawnPos = worldX;

    function randomObjectLottery() {
        // Check if we have moved at all
        /*
        if(lastSpawnPos <= worldX - 100) {
            return;
        }
        */
        

        // While loading the level we generated a random lottery coupon numbers for all random objects
        // Tässä funktiossa arvotaan oikeat numerot, jos jollakin satunnaisella objektilla on edes yksi oikein
        // niin kyseinen objekti pääsee leveliin.

        var lotteryNumber = game.rnd.between(0, 99);
        for (var i = 0; i < randomModulesArray.length; i++) {
            console.log("Lottery correct number: " + lotteryNumber);
            if (randomModulesArray[i][randomModulesArray[i].length - 1].indexOf(lotteryNumber) > 0) {
                console.log("Won in lottery!");
                var gameObject = randomModulesArray[i][0](game, options, api);
                gameObject.setInitialPosition(new Phaser.Point(game.rnd.between(200, game.width), randomModulesArray[i][3]));
                if (gameObject.create)
                    gameObject.create();
                modulesArray.push(gameObject);
                lastSpawnPos = worldX;
            }
        }
    }

    var d = new Date();
    var framesLastSecond = 0;
    var frames = 0;
    var secondTimer = 0;

    var theEnd = false;

    function update() {
        if (inMenu) {
            var startGame = inMenu.update();
            if (startGame === true) {
                inMenu = null;
                music[pMusic].obj.stop();
                create();
                d = new Date();
            }
            return;
        }

        if (theEnd === true) {
            return;
        }

        // Calculate time
        var timeDelta = (new Date()).getTime() - d.getTime();
        d = new Date();
        frames++;
        secondTimer += timeDelta;
        if (secondTimer >= 1000) {
            framesLastSecond = frames;
            frames = 0;
            secondTimer = 0;
        }

        executeModulesFunction("update", timeDelta);
        updateCamera();

        for (var i = modulesArray.length - 1; i >= 0; i--) {
            if (modulesArray[i].getObject) {
                var obj = modulesArray[i].getObject();
                if (obj.alive == false) {
                    var mdl = modulesArray.pop();
                    delete mdl;
                }
            }
        }
    }

    function updateCamera() {
        var players = api.getObjectsByName("player");

        // Calculate fishling average x position
        var totalX = 0;
        var alivePlayers = 0;

        for (var i = 0; i < players.length; i++) {
            if (players[i].getCustomState() != 3) {
                totalX += players[i].x;
                alivePlayers += 1;
            }
        }

        //game.debug.text("alivePlayers: " + alivePlayers, 10, 10);

        if (alivePlayers < 4) {
            game.time.events.removeAll();
            for (var i = 0; i < modulesArray.length; i++) {
                var obj = modulesArray[i].getObject();
                if (obj.animations) {
                    if (obj.animations.name == "die") {

                    } else {
                        obj.animations.stop();
                    }
                    

                }
            }

            theEnd = true;
            game.add.sprite(game.width / 6, 0, 'GOMenuTitle');
            //game.world.destroy(true, true);
            //modulesArray = [];
            setTimeout(function () {
                window.location.reload();
            }, 5000)
            return;
        }

        if (alivePlayers <= 0)
            return;


        var medianX = totalX / alivePlayers;

        // If average x position is below third of the screen width don't do anything
        if (medianX <= game.width / 3)
            return;

        // Calculate the difference of average x and old world x with minimum step of -5
        var difX = Math.max((game.width / 3) - medianX, -5);

        // Update the world x
        worldX += Math.abs(difX);

        // Update everything to by the difX amount.
        //TODO: Add time/fps correction
        executeModulesFunction("moveObject", difX, worldX);
    }

    function render() {
        if (inMenu) {
            return;
        }
        executeModulesFunction("render");

        //game.debug.pointer(game.input.pointer1);
        /*
        game.debug.text("worldX: " + worldX, 10, 30);
        var totals = 0;
        var layerGroups = api.getObjectByName("bg02");
        for (var i = 0; i < layerGroups.length; i++) {
            totals += layerGroups[i].countLiving();
        }
        game.debug.text("FPS: " + framesLastSecond + ", bgobjs: " + totals, 10, 10);
        */
    }

    /////////////////////////////
    // Level Related Functions //
    /////////////////////////////

    function loadLevel() {
        // Sample level for testing
        var level = {
            id: "level1",
            startObjects: [
                [goPlayer, 100, 100],
                [goPlayer, 200, 100],
                [goPlayer, 300, 100],
                [goPlayer, 100, 200],
                [goPlayer, 200, 200],
                [goPlayer, 300, 200],
                [goPlayer, 100, 300],
                [goPlayer, 200, 400],
                [goPlayer, 300, 300],
                [goPlayer, 100, 400]
            ],
            randomObjects: [
                [goMureena, 20, 0, game.height] //Object, Chance of appearance (0=never, 1=once, 100=always), spawn position (WorldX offset), spawn position (height), [lottery numbers]
            ],
            ground: [
                ["ground", game.height - 50], //url, y, x
                ["ground", game.height - 50],
                ["ground", game.height - 50],
                ["ground", game.height - 50],
                ["ground", game.height - 50],
                ["ground", game.height - 50],
                ["ground", game.height - 50],
                ["ground", game.height - 50],
                ["ground", game.height - 50],
                ["ground", game.height - 50],
                ["ground", game.height - 50]
            ],
            background: [
                {
                    name: "bg01",
                    layers: [
                        ["resources/images/background1.png", 0.25] //Url, speed
                    ]
                },
                {
                    name: "bg02",
                    layers: [
                        ["resources/images/Parallax/t1_parallax1.png", 1],
                        ["resources/images/Parallax/t1_parallax2.png", 0.5],
                        ["resources/images/Parallax/tausta1_parallax_special2.png", 0.25],
                        ["resources/images/Parallax/t1_parallax3.png", 0.125]
                    ]
                },
                {
                    name: "bg03",
                    layers: [
                        ["resources/images/tausta_sini.png", 0.25] //Url, speed
                    ]
                }
            ],
            music: [
                {
                    name: "bgm01",
                    file: "resources/music/music-a.ogg"
                },
                {
                    name: "bgm02",
                    file: "resources/music/music-b.ogg"
                },
                {
                    name: "bgm_intro02",
                    file: "resources/music/music-intro-b.ogg"
                }
            ]
        }

        //for (var i = 0; i < level.background.length; i++) {
            // Load background
            var bg = goBackground(game, options, api);
            bg.SetConfig(level.background[1]);
            modulesArray.push(bg);
        //}

        // Load ground
        //var ground = goGround(game, options, api);
        //modulesArray.push(ground);

        // Add the ground objects
        //ground.SetConfig(level.ground);

        // Load startup objects
        for (var i = 0; i < level.startObjects.length; i++) {
            var gameObject = level.startObjects[i][0](game, options, api);
            gameObject.setInitialPosition(new Phaser.Point(level.startObjects[i][1], level.startObjects[i][2]));
            modulesArray.push(gameObject);
        }

        // Generate random numbers for random objects
        for (var i = 0; i < level.randomObjects.length; i++) {
            var randomObjDef = level.randomObjects[i];
            var randomPool = [];
            // Generate Array of random numbers, for chance lottery later
            for (var x = 0; x < randomObjDef[1]; x++) {
                var randomNumber = 0;
                do {
                    randomNumber = game.rnd.between(0, 99);
                } while (randomPool.indexOf(randomNumber) > 0);
                randomPool.push(randomNumber);
            }
            level.randomObjects[i].push(randomPool);
            console.log("Lottery row:");
            console.log(randomPool);
        }
        randomModulesArray = level.randomObjects;

        // Load music
        pMusic = 2;
        music = level.music;
        for (var i = 0; i < music.length; i++) {
            game.load.audio(music[i].name, music[i].file);
        }
        

    }
};