/**
 * This script handles all the background "Easter egg" action.
 *
 * The great rogue-like game engine ROT.js was taken (stolen) from:
 *  Ondrej Zara, http://ondras.zarovi.cz/
 *
 * -- Dejvino, 2013
 */

function initBackground()
{
    $(document).ready(function() {
        enableDungeon($("#glow-holder"));

        $("#activators").show();
        $("#stop").hide();

        $("#play").click(function() {
            $("#play").hide();
            $("#stop").show();

            $("#main-content").hide();
            $("#overlay-one").hide();
        });
        $("#stop").click(function() {
            $("#stop").hide();
            $("#play").show();

            $("#main-content").show();
            $("#overlay-one").show();
        });
    });
}

function enableDungeon(holder)
{
    window._reloadLock = 0;
    $(window).resize(function () {
        makeFullscreen('#rogue-canvas');
        makeFullscreen('#overlay-one');
        makeFullscreen('#overlay-two');
        window._reloadLock += 1;
        setTimeout("deferedInit(" + window._reloadLock + ")", 500);
    }).resize();
}

function deferedInit(lock)
{
    if (window._reloadLock != lock || lock == 1) {
        return;
    }
    if (Math.abs(Game.width * Game.cellWidth - $(window).width()
                + Game.height * Game.cellHeight - $(window).height()) < 60) {
        return;
    }
    Game.init();
    makeFullscreen('#rogue-canvas');
}

function makeFullscreen(elem)
{
    $(elem).css({
        'width': $(window).width(),
        'height': $(window).height(),
        'left': '0px',
        'top':'0px'
       });
}

/******************************************************************************
 *
 *  Game
 *
 *****************************************************************************/
var Game = {
    width: null,
    height: null,
    cellWidth: 15,
    cellHeight: 24,
    display: null,
    map: {},
    mapColor: {},
    freeCells: [],
    engine: null,
    player: null,
    goblins: {},

    imgFloor: '.',
    colorWall: "#530",
    colorFloor: "#444",
    
    inited: false,
    scheduler: null,

    init: function() {
        this.map = {};
        this.freeCells = [];
        this.goblins = {};
        this.width = $(window).width() / Game.cellWidth;
        this.height = $(window).height() / Game.cellHeight;
        var fontSize = 64;

        // (re)create canvas
        $("canvas").remove();
        this.display = new ROT.Display({width:this.width, height:this.height, spacing:1.0, fontSize:fontSize});
        document.body.appendChild(this.display.getContainer());
        $("canvas").attr("id", "rogue-canvas");
        $("#rogue-canvas").appendTo("#glow-holder").show();

        if (this.inited) {
            this.scheduler.clear();
        }

        this._generateMap();

        this.scheduler = new ROT.Scheduler.Simple();
        this.engine = new ROT.Engine(this.scheduler);

        this.scheduler.add(this.player, true);
        for (var i in this.goblins) {
            this.scheduler.add(this.goblins[i], true);
        }

        if (!this.inited) {
            this.engine.start();
        }
        this.inited = true;
    },

    makeKey: function(x,y) {
        return x+","+y;
    },

    parseKey: function(key) {
        var parts = key.split(",");
        var x = parseInt(parts[0]);
        var y = parseInt(parts[1]);
        return {x: x, y: y};
    },

    getRandomFreeCell: function() {
        var dests = this.freeCells;
        return dests[Math.floor(dests.length * Math.random())];
    },

    _generateMap: function() {
        var digger = new ROT.Map.Digger();
        var tryMakeWall = function(x,y, img) {
                var key = x+","+y;
                if (Game.map[key]) {
                    if (img != '-' && img != '|') {
                        return;
                    } else if (Game.map[key] == Game.imgFloor) {
                        return;
                    }
                }

                Game.map[key] = img;
                Game.mapColor[key] = Game.colorWall;
            };
        var digCallback = function(x, y, value) {
            if (value) { return; }
            
            var key = x+","+y;
            Game.map[key] = Game.imgFloor;
            Game.mapColor[key] = Game.colorFloor;
            Game.freeCells.push(key);

            tryMakeWall(x-1, y-1, "+");
            tryMakeWall(x+1, y-1, "+");
            tryMakeWall(x-1, y+1, "+");
            tryMakeWall(x+1, y+1, "+");

            tryMakeWall(x-1, y, "|");
            tryMakeWall(x+1, y, "|");
            tryMakeWall(x, y-1, "-");
            tryMakeWall(x, y+1, "-");
        }
        digger.create(digCallback.bind(this));

        this._generateBoxes(Game.freeCells);
        this._drawWholeMap();
        
        this.player = this._createBeing(Player, Game.freeCells);
        for (var i = 0; i < 10; i++) {
            this.goblins[i] = this._createBeing(Goblin, Game.freeCells);
        }
    },
    
    _createBeing: function(what, freeCells) {
        var index = Math.floor(ROT.RNG.getUniform() * freeCells.length);
        var key = freeCells.splice(index, 1)[0];
        var parts = key.split(",");
        var x = parseInt(parts[0]);
        var y = parseInt(parts[1]);
        return new what(x, y);
    },
    
    _generateBoxes: function(freeCells) {
        for (var i=0;i<10;i++) {
            var index = Math.floor(ROT.RNG.getUniform() * freeCells.length);
            var key = freeCells.splice(index, 1)[0];
        }
    },
    
    _drawMapCell: function(x,y) {
        var key = x+","+y;
        if (key in this.map) {
            this.display.draw(x, y, this.map[key], this.mapColor[key]);
        }
    },

    _drawWholeMap: function() {
        this.display.clear();
        for (var key in this.map) {
            var parts = key.split(",");
            var x = parseInt(parts[0]);
            var y = parseInt(parts[1]);
            this._drawMapCell(x,y);
        }
    },

    passableCallback: function(x, y) {
        var key = x+","+y;
        return (key in Game.map && Game.map[key] == Game.imgFloor);
    }

};

/******************************************************************************
 *
 *  Player
 *
 *****************************************************************************/
var Player = function(x, y) {
    this._dest = null;
    this._x = x;
    this._y = y;
    this._draw();
}
    
Player.prototype.getSpeed = function() { return 100; }
Player.prototype.getX = function() { return this._x; }
Player.prototype.getY = function() { return this._y; }

Player.prototype.act = function() {
    Game.engine.lock();

    this._move();

    setTimeout("Game.engine.unlock();", 1000);
}

Player.prototype._draw = function() {
    Game.display.draw(this._x, this._y, "@", "#ff0");
}
    
Player.prototype._move = function() {
    // generate a new quest if needed
    if (!this._dest) {
        this._dest = Game.getRandomFreeCell();
    }

    var destPos = Game.parseKey(this._dest);

    var astar = new ROT.Path.AStar(destPos.x, destPos.y, Game.passableCallback, {topology:4});

    var path = [];
    var pathCallback = function(x, y) {
        path.push([x, y]);
    }
    astar.compute(this._x, this._y, pathCallback);

    path.shift();
    if (!path || path.length <= 1) {
        // new quest!
        this._dest = null;
    } else {
        x = path[0][0];
        y = path[0][1];
        Game._drawMapCell(this._x, this._y);
        this._x = x;
        this._y = y;
        this._draw();
    }
}

/******************************************************************************
 *
 *  Goblins
 *
 *****************************************************************************/
var Goblin = function(x, y) {
    this._x = x;
    this._y = y;
    this._draw();
    this._dead = 0;
    var icons = ['g', 'z', 'k', 'd', 's'];
    this._icon = icons[Math.floor(icons.length * Math.random())];
}
    
Goblin.prototype.getSpeed = function() { return 100; }
    
Goblin.prototype.act = function() {
    if (this._dead > 0) {
        this._dead -= 1;
        if (this._dead <= 0) {
            // teleport!
            Game._drawMapCell(this._x, this._y);
            var tel = Game.parseKey(Game.getRandomFreeCell());
            this._x = tel.x;
            this._y = tel.y;
            this._draw();
        }
        this._draw();
        return;
    }

    var x = Game.player.getX();
    var y = Game.player.getY();

    var astar = new ROT.Path.AStar(x, y, Game.passableCallback, {topology:4});

    var path = [];
    var pathCallback = function(x, y) {
        path.push([x, y]);
    }
    astar.compute(this._x, this._y, pathCallback);

    path.shift();
    if (!path || path.length <= 1) {
        this._dead = 10;
    } else if (path.length > 7) {
        // screw this
        if (Math.random() <= 0.5) {
            var x = this._x + Math.round(Math.random()*2 - 1);
            var y = this._y + Math.round(Math.random()*2 - 1);
            Game._drawMapCell(this._x, this._y);
            if (Game.passableCallback(x,y)) {
                this._x = x;
                this._y = y;
            }
        }
    } else {
        x = path[0][0];
        y = path[0][1];
        Game._drawMapCell(this._x, this._y);
        this._x = x;
        this._y = y;
    }
    this._draw();
}
    
Goblin.prototype._draw = function() {
    var icon = this._icon;
    var colFg = "red";
    var colBg = "black";
    if (this._dead > 0) {
        colFg = "white";
        colBg = "red";
    }
    Game.display.draw(this._x, this._y, icon, colFg, colBg);
}    

// ====================

Game.init();

