var game = new Phaser.Game(1280, 720, Phaser.AUTO, 'phaser-example'); //{ preload: preload, create: create, update: update, render: render }

var loadingText;

var loadingState = {
    preload: function () {
        game.load.image('bullet', 'assets/bullet.png', 9, 9);
        game.load.spritesheet('spider', 'assets/spider.png', 31, 31);
        game.load.image('bee', 'assets/bee.png');
        game.load.image('live', 'assets/lives.png');
        game.load.spritesheet('kaboom', 'assets/explode.png', 128, 128);
        game.load.image('background', 'assets/background.png');
        game.load.image('start_screen', 'assets/start_screen.png');
        game.load.image('SideBar', 'assets/SideBar.png');
        game.load.image('ring', 'assets/ring.png');
        game.load.image('score', 'assets/score.png');
        game.load.image('game_over', 'assets/GameOver.png');

        game.load.spritesheet('startButton', 'assets/startButton.png', 383, 135);
        game.load.spritesheet('restartButton', 'assets/try_again.png', 383, 135);
        game.load.spritesheet('sound', 'assets/sound.png', 55, 50);
        game.load.image('gameLogo', 'assets/gameLogo.png');
        game.load.image('placeholder', 'assets/tiles/16.png');
        game.load.atlas('tiles', 'assets/tiles/tiles.png', 'assets/tiles/tiles.json');
        loadingText = game.add.text(game.world.centerX, game.world.centerY, 'Loading 0/100', {
            font: "30px Arial",
            fill: "#ffffff",
            align: "center"
        });
        loadingText.anchor.set(0.5, 0.5);

        this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
        game.scale.setShowAll();
        game.scale.refresh();
        this.scale.forceLandscape = true;
        //this.scale.pageAlignHorizontally = true;
        //this.scale.pageAlignVertically = true;
        game.scale.refresh();

        game.load.audio('bg_music', ['assets/bg_music.mp3']);
        game.load.audio('enemy_hit', ['assets/enemy_hit.wav']);
        game.load.audio('tile_set', ['assets/tile_set.wav']);
        game.load.audio('player_hit', ['assets/player_hit.wav']);
    },

    loadUpdate: function () {
        loadingText.text = 'Loading ' + game.load.progress + '/100';
    },

    create: function () {

        bgMusic = game.add.audio('bg_music');
        //bgMusic.volume = 0.2;
        enemyHitSound = game.add.audio('enemy_hit');
        tileSetSound = game.add.audio('tile_set');
        playerHitSound = game.add.audio('player_hit');

        console.log('loading finished');
        game.time.advancedTiming = true;
        game.state.start('mainMenu');
        game.scale.fullScreenScaleMode = Phaser.ScaleManager.SHOW_ALL;
        game.stage.disableVisibilityChange = true;
    },

    update: function () {
        console.log('loading:', arguments);
        loadingText = 'Loading ' + game.load.progress + '/100';
    }
};

var mainMenuState = {
    create: function () {
        console.log('main menu created');
        //game.add.image(game.world.centerX - game.cache.getImage("gameLogo").width / 2, 100, 'gameLogo');
        var background = game.add.tileSprite(0, 0, 1280, 720, 'start_screen');
        startButton = game.add.button(game.world.centerX, 400, 'startButton', mainMenuState.startButtonClicked, this, 2, 1, 0);
        startButton.anchor.set(0.5, 0);
        mainMenuState.playMusic();
    },

    update: function () {
        //console.log('game updates')
    },

    startButtonClicked: function () {
        game.state.start('game');
        game.scale.startFullScreen();
    },

    playMusic: function () {
        bgMusic.loop=true;
        bgMusic.volume = 0.01;
        bgMusic.play();
    },

    stopMusic: function () {
        bgMusic.stop();
    }
};

var gameState = {
    create: function () {
        currentWave = 0;
        score = 0;
        waves = [];
        for (var i = 0; i < WAVE_LIMIT; i++) {
            waves.push((i + 1) * ENEMY_WAVE_INCREMENT);
        }

        console.log('game created');
        create();
    },

    update: function () {
        //console.log('game updates')
        update();
    },
    render: render
};

var tilesX = 17;
var tilesY = 9;
var tileWidth = 66;
var realTileWidth = 90;
var tileHeight = 74;
var hiveMaxWidth = tilesX * tileWidth;
var hiveMaxHeight = (tilesY + 0.5) * tileHeight;
var EMPTY_TILE = 'empty';
var START_TILE = 'start';
var tileTypes = {};

var bgMusic;
var enemyHitSound;
var tileSetSound;
var playerHitSound;

var ENEMY_SPAWN_DELAY = 1000;
var ONHIT_IMMORTALITY_TIME = 3000;
var ENEMY_WAVE_INCREMENT = 10;
var ENEMY_FLY_SPEED = 150;
var ENEMY_CRAWL_SPEED = 60;
var WAVE_LIMIT = 999;
var LIVE_COUNT = 3;

addTileType('0', [], EMPTY_TILE);
addTileType('1', [[0, 3], [1, 5], [2, 4]]);
addTileType('2', [[0, 2], [1, 5], [3, 4]]);
addTileType('3', [[0, 3], [1, 4], [2, 5]]);
addTileType('4', [[0, 5], [1, 2], [3, 4]]);
addTileType('5', [[0, 3], [1, 2], [4, 5]]);
addTileType('6', [[0, 4], [1, 3], [2, 5]]);
addTileType('7', [[0, 2], [1, 4], [3, 5]]);
addTileType('8', [[0, 4], [1, 5], [2, 3]]);
addTileType('9', [[0, 1], [2, 4], [3, 5]]);
addTileType('10', [[0, 5], [1, 3], [2, 4]]);
addTileType('11', [[0, 2], [1, 3], [5, 4]]);
addTileType('12', [[0, 4], [1, 2], [3, 5]]);
addTileType('13', [[0, 1], [2, 5], [3, 4]]);
addTileType('14', [[0, 5], [1, 4], [2, 3]]);
addTileType('15', [], START_TILE);

function addTileType(type, routes, name) {
    tileTypes[name || type] = {
        name: name || type,
        routes: routes,
        spriteFrame: type
    }
}

var routeTiles = [];
for (var i = 1; i < 14; i++) {
    routeTiles.push(tileTypes[i.toString()]);
}


function createTile(type) {

    var tile =
    {
        setRoutes: function (routes) {
            this.routes = {};
            this.threeRoutes = routes;
            for (var i = 0; i < routes.length; i++) {
                var route = routes[i];
                this.routes[route[0]] = route[1];
                this.routes[route[1]] = route[0];
            }
        },
        type: type,
        routes: {},
        threeRoutes: [],
        getExitForEntry: function (entry) {
            return this.routes[entry];
        },
        pos: {x: 0, y: 0},
        setCoordinate: function (x, y) {
            this.pos.x = x;
            this.pos.y = y;

            var gameCenterX = (game.world.width) / 2;
            var gameCenterY = (game.world.height) / 2;
            var offsetX = (centerX * tileWidth + realTileWidth / 2);
            var offsetY = (centerY * tileHeight + (centerX % 2 * tileHeight / 2) + tileHeight / 2);
            offsetX -= gameCenterX;
            offsetY -= gameCenterY;

            this.sprite.position.x = x * tileWidth - offsetX;
            this.sprite.position.y = y * tileHeight + x % 2 * tileHeight / 2 - offsetY;
        },
        setTileType: function (type) {
            this.type = type;
            this.sprite.frameName = type.spriteFrame;
            this.setRoutes(type.routes);
        },
        sprite: game.add.sprite(0, 0, 'tiles', '0'),
        getEntryIndexFromNeighbourExistIndex: function (index) {
            return (index + 3) % 6;
        },

        getCoordinateAtIndex: function (index) {
            var center = this.getCenterCoordinate();
            center.x += 45 * Math.sin(index * Math.PI / 3);
            center.y -= 45 * Math.cos(index * Math.PI / 3);
            return center;
        },

        getCenterCoordinate: function () {
            return {
                x: this.sprite.position.x + realTileWidth / 2,
                y: this.sprite.position.y + tileHeight / 2
            };
        }
    };

    tile.setTileType(type);
    bindFunctions(tile);
    return tile;
}


function bindFunctions(object) {
    for (var property in object) {
        if (object.hasOwnProperty(property)) {
            if (typeof object[property] == 'function') {
                object[property] = object[property].bind(object);
            }
        }
    }
}


var endState = {
    create: function () {
        console.log('end created');
        game.add.tileSprite(0, 0, 1280, 720, 'game_over');
        restartButton = game.add.button(game.world.width / 2, game.world.height / 2, 'restartButton', endState.restartButtonClicked, this, 2, 1, 0);
        restartButton.anchor.x = 0.5;
        restartButton.anchor.y = 0.5;
    },

    update: function () {

    },

    restartButtonClicked: function () {
        restart();
        game.state.start('game');
        waveInProgress = true;
    }
};

game.state.add('loading', loadingState);
game.state.add('mainMenu', mainMenuState);
game.state.add('game', gameState);
game.state.add('end', endState);
game.state.start('loading');


var player;
var aliens;
var bullets;
var cursors;
var explosions;
var background;
var score = 0;
var scoreString = '';
var scoreText;
var lives;
var stateText;
var livingEnemies = [];
var turret;
var spawnTime = 0;
var waves = [];
var currentWave = 0;
var waveEnemies;
var waveInProgress = false;
var waveString;
var waveText;
var enemiesLeftString;
var enemiesLeftText;
var enemiesNextText;
var startButton;
var restartButton;
var invulTime = 0;

var tileMap;
function createTileMap() {
    tileMap = {
        tiles: [[]],
        setSize: function (width, height) {
            for (var i = 0; i < width; i++) {
                this.tiles[i] = [];
                for (var j = 0; j < height; j++) {
                    var tile = createTile(tileTypes[EMPTY_TILE]);
                    this.tiles[i][j] = tile;
                    tile.setCoordinate(i, j);
                }
            }
        },
        setTile: function (tile, x, y) {
            this.tiles[x][y] = tile;
        },

        getTile: function (x, y) {
            var column = this.tiles[x];
            if (column) {
                return column[y];
            }
            return undefined;
        },

        getBorderEmptyTiles: function () {
            var res = [];
            for (var i = 0; i < this.tiles.length; i++) {
                var tilesRow = this.tiles[i];
                for (var j = 0; j < tilesRow.length; j++) {
                    var tile = tilesRow[j];
                    if (tile.type.name == EMPTY_TILE && this.hasNonEmptyNeighbours(tile)) {
                        res.push(tile);
                    }
                }
            }
            return res;
        },

        getPath: function (inTile, index) {
            var tile = inTile;
            var entryIndex = index;
            var path = {};
            path.result = '';
            path.points = [];

            var exitIndex = tile.getExitForEntry(entryIndex);
            var tileAtExit = this.getNeighbourAtIndex(tile, exitIndex);

            addPoints(tile, entryIndex, exitIndex)

            function addPoints(tile, entryIndex, exitIndex) {
                var start = tile.getCoordinateAtIndex(entryIndex);
                var end = tile.getCoordinateAtIndex(exitIndex);
                var center = tile.getCenterCoordinate();

                var cx = (start.x + end.x) / 2;
                var cy = (start.y + end.y) / 2;
                cx = (cx + center.x) / 2;
                cy = (cy + center.y) / 2;

                path.points.push(start);
                path.points.push({x: cx, y: cy});
            }

            //path.points.push(tile.getCoordinateAtIndex(entryIndex));
            //path.points.push(tile.getCenterCoordinate());

            while (tileAtExit && tileAtExit.type.name != EMPTY_TILE && tileAtExit.type.name != START_TILE) {
                tile = tileAtExit;

                entryIndex = tile.getEntryIndexFromNeighbourExistIndex(exitIndex);
                var exitIndex = tile.getExitForEntry(entryIndex);
                console.log(entryIndex, exitIndex);
                tileAtExit = this.getNeighbourAtIndex(tile, exitIndex);

                addPoints(tile, entryIndex, exitIndex)

            }

            path.points.push(tile.getCoordinateAtIndex(exitIndex));

            if (!tileAtExit || tileAtExit.type.name == EMPTY_TILE) {
                path.result = "exit";
            } else {
                path.result = "center";
            }

            var lastPoint = path.points[path.points.length - 1];
            var center = tileMap.getTile(centerX, centerY);
            lastPoint = findFurtherPoint(center.getCenterCoordinate(), lastPoint);
            path.points.push(lastPoint);
            if (path.result == 'exit' && path.points.length == 2) {
                console.log('error');
            }
            return path;
        },

        getRandomPath: function () {
            var tiles = this.getBorderTiles();

            var tile = tiles[getRandomInt(0, tiles.length)];
            var entries = this.getEmptyEntries(tile);
            var entryIndex = entries[getRandomInt(0, entries.length)];
            return this.getPath(tile, entryIndex);
        },

        getNeighbourAtIndex: function (tile, index) {
            var neighbours = this.getTileNeighbours(tile);
            return neighbours[index];
        },

        getEmptyEntries: function (tile) {
            var indexes = [];
            var neighbours = this.getTileNeighbours(tile);
            for (var i = 0; i < neighbours.length; i++) {
                var neighbour = neighbours[i];
                if (neighbour.type.name == EMPTY_TILE) {
                    indexes.push(i);
                }
            }
            return indexes;
        },

        getBorderTiles: function () {
            var res = [];
            for (var i = 0; i < this.tiles.length; i++) {
                var tilesRow = this.tiles[i];
                for (var j = 0; j < tilesRow.length; j++) {
                    var tile = tilesRow[j];
                    if (tile.type.name != EMPTY_TILE) {
                        var neighbours = this.hasEmptyNeighbours(tile);
                        if (neighbours) {
                            res.push(tile);
                        }
                    }
                }
            }
            return res;
        },

        hasEmptyNeighbours: function (tile) {
            var neighbours = this.getTileNeighbours(tile);
            for (var i = 0; i < neighbours.length; i++) {
                var tile = neighbours[i];
                if (tile.type.name == EMPTY_TILE) {
                    return true;
                }
            }
            return false;
        },

        hasNonEmptyNeighbours: function (tile) {
            var neighbours = this.getTileNeighbours(tile);
            for (var i = 0; i < neighbours.length; i++) {
                var tile = neighbours[i];
                if (tile.type.name != EMPTY_TILE) {
                    return true;
                }
            }
            return false;
        },

        getTileNeighbours: function (tile) {
            var x = tile.pos.x;
            var y = tile.pos.y;
            var shift = x % 2;
            var neighbours = [
                this.getTile(x, y - 1),
                this.getTile(x + 1, y - 1 + shift),
                this.getTile(x + 1, y + shift),
                this.getTile(x, y + 1),
                this.getTile(x - 1, y + shift),
                this.getTile(x - 1, y - 1 + shift),
            ];
            return neighbours.filter(function (item) {
                return item != undefined;
            });
        }
    };
    bindFunctions(tileMap);
    tileMap.setSize(tilesX, tilesY);
}
var centerX = Math.floor(tilesX / 2);
var centerY = Math.floor(tilesY / 2);
function setMapStartState() {
    centerX = Math.floor(tilesX / 2);
    centerY = Math.floor(tilesY / 2);
    console.log('center', centerX, centerY);
    tileMap.getTile(centerX, centerY).setTileType(tileTypes[START_TILE]);
    tileMap.getTile(centerX, centerY - 1).setTileType(tileTypes['5']);
    tileMap.getTile(centerX, centerY + 1).setTileType(tileTypes['5']);
    tileMap.getTile(centerX + 1, centerY - 1).setTileType(tileTypes['14']);
    tileMap.getTile(centerX - 1, centerY - 1).setTileType(tileTypes['13']);
    tileMap.getTile(centerX - 1, centerY).setTileType(tileTypes['14']);
    tileMap.getTile(centerX + 1, centerY).setTileType(tileTypes['13']);

    /*var empty = tileMap.getBorderEmptyTiles();
     for (var i = 0; i < empty.length; i++) {
     var tile = empty[i];
     tile.setTileType(routeTiles[getRandomInt(0, routeTiles.length)]);
     }*/
}

function create() {

    game.physics.startSystem(Phaser.Physics.ARCADE);

    //  The scrolling background background
    background = game.add.tileSprite(0, 0, 1280, 720, 'background');

    createTileMap();
    setMapStartState();

    //  Our bullet group
    bullets = game.add.group();
    bullets.enableBody = true;
    bullets.physicsBodyType = Phaser.Physics.ARCADE;
    bullets.createMultiple(30, 'bullet');
    bullets.setAll('anchor.x', 0.5);
    bullets.setAll('anchor.y', 1);
    bullets.setAll('outOfBoundsKill', true);
    bullets.setAll('checkWorldBounds', true);

    //  The hero!
    player = game.add.sprite(game.width / 2, game.height / 2, 'bee');
    player.anchor.setTo(0.4, 0.6);
    game.physics.enable(player, Phaser.Physics.ARCADE);
    player.body.setSize(50, 50, 0, 0);
    turret = new Turret(game, player);

    //  The baddies!
    aliens = game.add.group();
    aliens.enableBody = true;
    aliens.physicsBodyType = Phaser.Physics.ARCADE;

    //  The score


    //  The score

    //  The enemies left
    var sidebar = game.add.sprite(game.world.width - 112, 0, 'SideBar');
    var ring = game.add.sprite(game.world.centerX, 0, 'ring');
    ring.anchor.set(0.5, 0);
    var scoreImage = game.add.sprite(game.world.width - 330, 120, 'score');
    var sound = game.add.sprite(10, 10, 'sound', 0);
    sound.inputEnabled = true;
    sound.input.useHandCursor = true;
    sound.events.onInputDown.add(function () {
        if (sound.frame == 0) {
            mainMenuState.stopMusic();
            sound.frame = 1;
        } else {
            mainMenuState.playMusic();
            sound.frame = 0;
        }
    }, this);

    var enemiesLeftHeight = game.world.height - 40;
    enemiesLeftText = game.add.text(game.world.centerX, 70, 'x' + waves[0].length, {
        font: '34px Arial',
        fill: '#ff0000'
    });
    enemiesLeftText.anchor.set(0.5, 0);
    enemiesNextText = game.add.text(game.world.width - 80, 110, 'x' + waves[0].length, {
        font: '34px Arial',
        fill: '#ffff00'
    });
    scoreText = game.add.text(game.world.width - 200, 120, score, {font: '34px Arial', fill: '#ffff88'});

    //  Lives
    lives = game.add.group();
    //game.add.text(game.world.width - 100, 10, 'Lives : ', {font: '34px Arial', fill: '#fff'});

    waveEnemies = game.add.group();

    //  Text
    stateText = game.add.text(game.world.centerX, game.world.centerY, ' ', {font: '84px Arial', fill: '#fff'});
    stateText.anchor.setTo(0.5, 0.5);
    stateText.visible = false;

    for (var i = 0; i < LIVE_COUNT; i++) {
        var bee = lives.create(game.world.width - 300 + (60 * i), 80, 'live');
        bee.anchor.setTo(0.5, 0.5);
        bee.angle = 0;
        //bee.alpha = 0.8;
    }

    //  And some controls to play the game with
    cursors = game.input.keyboard.createCursorKeys();
    //fireButton = game.pointe+------
    var path = tileMap.getRandomPath();


}

function update() {
    if (player.alive) {

        player.alpha = 1;
        if (invulTime > game.time.now) {
            if ((invulTime - game.time.now) % 200 > 100)
                player.alpha = 0.4;
            else
                player.alpha = 1;
        }

        turret.alignToCursor();
        //  Firing?
        if (game.input.activePointer.isDown && waveInProgress) {
            turret.fireBullet(bullets);
        }

        //  Run collision
        game.physics.arcade.overlap(bullets, waveEnemies, collisionHandler, null, this);
        game.physics.arcade.overlap(player, waveEnemies, playerHitHandler, null, this);

        spawnEnemies();
        moveEnemies();
    }
}


function moveEnemies() {

}

function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min)) + min;
}

var waveInProgress = true;

function findFurtherPoint(center, point) {
    var dx = point.x - center.x;
    var dy = point.y - center.y;
    var l = Math.sqrt(dx * dx + dy * dy);

    dx = center.x + 640 * dx / l;
    dy = center.y + 640 * dy / l;
    return {x: dx, y: dy};
}

function spawnEnemies() {
    if (waveInProgress) {
        var totalWaveEnemies = waves[currentWave];
        if (game.time.now > spawnTime && waveEnemies.length < totalWaveEnemies) {
            var entryData = tileMap.getRandomPath();

            var center = tileMap.getTile(centerX, centerY).getCenterCoordinate();
            var firstPoint = entryData.points[0];
            var startPoint = findFurtherPoint(center, firstPoint);

            var enemy = new Enemy(game, startPoint.x, startPoint.y);
            enemy.sprite.events.onKilled.add(function () {
                //  Increase the score
                score += 20;
                scoreText.text = scoreString + score;

                if (waveEnemies.countLiving() == 0) {
                    if (currentWave == waves.length - 1) {
                        allWavesEnded();
                    } else {
                        waveEnded();
                    }
                }

                updateEnemiesLeftText();
            }, enemy);
            waveEnemies.add(enemy.sprite);

            spawnTime = game.time.now + ENEMY_SPAWN_DELAY * 5 / (5 + currentWave);

            var enemyEntryTween = game.add.tween(enemy.sprite);
            var tweenTime = 640 / ENEMY_FLY_SPEED * 1000;
            var dx = entryData.points[0].x - startPoint.x;
            var dy = entryData.points[0].y - startPoint.y;
            var rotation = -(Math.atan2(dx, dy) + 60 * Math.PI / 180);
            enemyEntryTween.to({rotation: rotation}, 1, Phaser.Easing.Linear.None, false, 0, 0, false);
            enemyEntryTween.to(entryData.points[0], tweenTime, Phaser.Easing.Linear.None, false, 0, 0, false);
            //enemyEntryTween.onComplete.add(function(){alert(tweenTime)}, enemy);

            var prevPoint = new Phaser.Point(entryData.points[0].x, entryData.points[0].y);
            var path = entryData.points;
            for (var i = 1; i < path.length; i++) {
                dx = entryData.points[i].x - prevPoint.x;
                dy = entryData.points[i].y - prevPoint.y;
                rotation = -(Math.atan2(dx, dy) + 60 * Math.PI / 180);

                tweenTime = prevPoint.distance(path[i]) / ENEMY_CRAWL_SPEED * 1000;
                enemyEntryTween.to({rotation: rotation}, 1, Phaser.Easing.Linear.None, false, 0, 0, false);
                enemyEntryTween.to(path[i], tweenTime, Phaser.Easing.Linear.None, false, 0, 0, false);
                prevPoint = new Phaser.Point(entryData.points[i].x, entryData.points[i].y);
            }
            enemyEntryTween.interpolation(Phaser.Math.bezierInterpolation);
            enemyEntryTween.onComplete.add(function () {
                if (this.sprite.alive) {
                    waves[currentWave + 1]++;
                    this.sprite.kill();
                }
            }, enemy);
            enemyEntryTween.onChildComplete.add(function () {

            }, enemy);
            enemyEntryTween.start();
            updateEnemiesLeftText();
        }
    }
}

function render() {
    game.debug.text(game.time.fps || '--', 2, 14, "#00ff00");
    // for (var i = 0; i < aliens.length; i++)
    // {
    //     game.debug.body(aliens.children[i]);
    // }

}

function collisionHandler(bullet, enemy) {
    //  When a bullet hits an alien we kill them both
    bullet.kill();
    enemy.kill();

    enemyHitSound.play('', 0, 0.4, false);
}

function allWavesEnded() {
    score += 1000;
    scoreText.text = scoreString + score;

    stateText.text = " You Won, \n Click to restart";
    stateText.visible = true;

    //the "click to restart" handler
    game.input.onTap.addOnce(restart, this);
}

function waveEnded() {
    currentWave++;
    waveEnemies.removeAll();
    waveInProgress = false;
    showTileOptions();
}
var tilesChoice = [];
function showTileOptions() {
    tilesChoice = [];
    for (var i = 0; i < 5; i++) {
        var tile = createTile(
            routeTiles[getRandomInt(0, routeTiles.length)]
        );
        tilesChoice.push(tile);
        tile.sprite.position.x = game.world.width - 11 - realTileWidth;
        tile.sprite.position.y = 187 + (tileHeight + 34) * i;
        tile.sprite.inputEnabled = true;
        tile.sprite.input.useHandCursor = true;
        tile.sprite.alpha = 0.8;
        tile.sprite.events.onInputDown.add(pickTile.bind(this, tile), this);
    }
}

function pickTile(selectedTile, sprite, pointer) {
    for (var i = 0; i < placeholders.length; i++) {
        var placeholder = placeholders[i];
        placeholder.destroy();
    }
    for (var i = 0; i < tilesChoice.length; i++) {
        var tile = tilesChoice[i];
        tile.sprite.alpha = 0.8;
    }
    sprite.alpha = 1;
    showPlaceholders(selectedTile);
}

var placeholders = [];
function showPlaceholders(selectedTile) {
    var tiles = tileMap.getBorderEmptyTiles();
    placeholders = [];
    for (var i = 0; i < tiles.length; i++) {

        var tile = tiles[i];
        var neighbours = tileMap.getTileNeighbours(tile);
        neighbours = neighbours.filter(function (tile) {
            return tile.type.name != EMPTY_TILE;
        });
        if (neighbours.length > 1) {

            var count = 0;
            for (var j = 0; j < selectedTile.threeRoutes.length; j++) {
                var route = selectedTile.threeRoutes[j];
                if (routeNotAllowed(tile, route[0], route[1])) {
                    count++;
                }
            }
            console.log(count);
            if (count==0) {
                var pos = tile.getCenterCoordinate();
                var placeHolder = game.add.sprite(pos.x - realTileWidth / 2, pos.y - tileHeight / 2, 'placeholder');
                placeHolder.inputEnabled = true;
                placeHolder.input.useHandCursor = true;
                placeHolder.events.onInputDown.add(placeTile.bind(this, selectedTile, tile), this);
                placeholders.push(placeHolder);
            }
        }
    }
}

function routeNotAllowed(tile, index1, index2) {
    var exitIndex = tile.getEntryIndexFromNeighbourExistIndex(index1);
    var tileAtExit = tileMap.getNeighbourAtIndex(tile, index1);

    var path1 = tileMap.getPath(tileAtExit, exitIndex)

    exitIndex = tile.getEntryIndexFromNeighbourExistIndex(index2);
    tileAtExit = tileMap.getNeighbourAtIndex(tile, index2);

    var path2 = tileMap.getPath(tileAtExit, exitIndex)

    console.log(path1, path2);
    return path1.result == path2.result && path1.result == "center";
}


function placeTile(selectedTile, targetTile) {
    for (var i = 0; i < placeholders.length; i++) {
        var holder = placeholders[i];
        holder.destroy();
    }
    targetTile.setTileType(selectedTile.type);
    selectedTile.sprite.destroy();
    tilesChoice.splice(tilesChoice.indexOf(selectedTile), 1);
    if (tilesChoice.length == 3) {
        finishTilePlacement();
    }

    console.log("play tile sound");
    tileSetSound.play('', 0, 0.4, false);
}

function finishTilePlacement() {
    for (var i = 0; i < tilesChoice.length; i++) {
        var tile = tilesChoice[i];
        tile.sprite.destroy();
    }
    waveInProgress = true;
}

function restart() {

    //  A new level starts

    //resets the life count
    lives.callAll('revive');
    //  And brings the aliens back from the dead :)
    waveEnemies.removeAll();

    //revives the player
    player.revive();
    //hides the text
    stateText.visible = false;


}

function playerHitHandler(player, enemy) {
    enemy.kill();

    playerHitSound.play('', 0, 0.4, false);

    var live = lives.getFirstAlive();

    if (live && game.time.now > invulTime) {
        live.kill();
        invulTime = game.time.now + ONHIT_IMMORTALITY_TIME;
    }

    // When the player dies
    if (lives.countLiving() < 1) {
        player.kill();
        waveEnemies.callAll('kill');

        game.state.start('end');
    }
}

function updateEnemiesLeftText() {
    enemiesLeftText.text = 'x' + (waves[currentWave] - waveEnemies.countDead());

    var nextWave = waves[currentWave + 1];
    if (currentWave + 1 == waves.length)
        nextWave = 0;
    enemiesNextText.text = 'x' + (nextWave);
}