"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const letters_1 = require("../letters");
const collisionLayer_1 = require("./collisionLayer");
class GameData {
    constructor(source, title, metadata, objects, legends, sounds, collisionLayers, rules, winConditions, levels) {
        this.title = title;
        this.metadata = metadata;
        this.objects = objects;
        this.legends = legends;
        this.sounds = sounds;
        this.collisionLayers = collisionLayers;
        this.winConditions = winConditions;
        this.levels = levels;
        // assign an index to each GameSprite
        this.objects.forEach((sprite, index) => {
            sprite.allSpritesBitSetIndex = index;
        });
        let spriteIndexCounter = this.objects.length; // 1 more than all the game sprites
        const ruleCache = new Map();
        const bracketCache = new Map();
        const neighborCache = new Map();
        const tileCache = new Map();
        this.rules = rules.map((rule) => rule.simplify(ruleCache, bracketCache, neighborCache, tileCache));
        const firstSpriteWithPixels = this.objects.filter((sprite) => sprite.hasPixels())[0];
        if (firstSpriteWithPixels) {
            const firstSpritePixels = firstSpriteWithPixels.getPixels(1, 1); // We don't care about these args
            this.cacheSpriteSize = {
                spriteHeight: firstSpritePixels.length,
                spriteWidth: firstSpritePixels[0].length
            };
        }
        else {
            // All the sprites are just a single color, so set the size to be 5x5
            this.cacheSpriteSize = {
                spriteHeight: 1,
                spriteWidth: 1
            };
        }
        // Create a collisionlayer for the letter sprites
        this.letterSprites = letters_1.getLetterSprites(source);
        for (const letterSprite of this.letterSprites.values()) {
            letterSprite.allSpritesBitSetIndex = spriteIndexCounter++;
        }
        const letterCollisionLayer = new collisionLayer_1.CollisionLayer(source, [...this.letterSprites.values()], () => {
            throw new Error(`BUG: Letter collision layers should not have a problem`);
        });
        this.collisionLayers.push(letterCollisionLayer);
    }
    _getSpriteByName(name) {
        return this.objects.find((sprite) => sprite.getName().toLowerCase() === name.toLowerCase());
    }
    _getTileByName(name) {
        return this.legends.find((tile) => tile.getName().toLowerCase() === name.toLowerCase());
    }
    getMagicBackgroundSprite() {
        if (this.cachedBackgroundSprite) {
            return this.cachedBackgroundSprite;
        }
        else {
            const background = this._getSpriteByName('background');
            if (!background) {
                const legendBackground = this.legends.find((tile) => tile.spriteNameOrLevelChar.toLocaleLowerCase() === 'background');
                if (legendBackground) {
                    if (legendBackground.isOr()) {
                        return null;
                    }
                    else {
                        return legendBackground.getSprites()[0];
                    }
                }
            }
            if (!background) {
                throw new Error(`ERROR: Game does not have a Background Sprite or Tile`);
            }
            this.cachedBackgroundSprite = background;
            return background;
        }
    }
    getPlayer() {
        const player = this._getSpriteByName('player') || this.legends.find((tile) => tile.spriteNameOrLevelChar.toLocaleLowerCase() === 'player');
        if (!player) {
            throw new Error(`BUG: Could not find the Player sprite or tile in the game`);
        }
        return player;
    }
    clearCaches() {
        for (const rule of this.rules) {
            rule.clearCaches();
        }
        for (const sprite of this.objects) {
            sprite.clearCaches();
        }
    }
    getSpriteSize() {
        return this.cacheSpriteSize;
    }
    getLetterSprite(char) {
        const sprite = this.letterSprites.get(char);
        if (!sprite) {
            throw new Error(`BUG: Cannot find sprite for letter "${char}"`);
        }
        return sprite;
    }
}
exports.GameData = GameData;
//# sourceMappingURL=game.js.map