//-----------------------------------------------------------------------------
// ImageManager
//
// The static class that loads images, creates bitmap objects and retains them.
/**
 * The static class that loads images, creates bitmap objects and retains them.
 *
 * @namespace
 */
function ImageManager() {
    throw new Error("This is a static class");
}
/**
 * The standard width of an icon
 *
 * @type number
 * @static
 * @since 1.9.0
 * @name ImageManager.standardIconWidth
 */
ImageManager.standardIconWidth = 32;
/**
 * The standard height of an icon
 *
 * @type number
 * @static
 * @since 1.9.0
 * @name ImageManager.standardIconHeight
 */
ImageManager.standardIconHeight = 32;
/**
 * The standard width of a face image
 *
 * @type number
 * @static
 * @since 1.9.0
 * @name ImageManager.standardFaceWidth
 */
ImageManager.standardFaceWidth = 144;
/**
 * The standard height of a face image
 *
 * @type number
 * @static
 * @since 1.9.0
 * @name ImageManager.standardFaceHeight
 */
ImageManager.standardFaceHeight = 144;
ImageManager._cache = {};
ImageManager._system = {};
ImageManager._emptyBitmap = new Bitmap(1, 1);
/**
 * The width of an icon
 *
 * @type number
 * @static
 * @name ImageManager.iconWidth
 */
Object.defineProperty(ImageManager, "iconWidth", {
    get: function() {
        return this.getIconSize();
    },
    configurable: true
});
/**
 * The height of an icon
 *
 * @type number
 * @static
 * @name ImageManager.iconHeight
 */
Object.defineProperty(ImageManager, "iconHeight", {
    get: function() {
        return this.getIconSize();
    },
    configurable: true
});
/**
 * The width of a face image
 *
 * @type number
 * @static
 * @name ImageManager.faceWidth
 */
Object.defineProperty(ImageManager, "faceWidth", {
    get: function() {
        return this.getFaceSize();
    },
    configurable: true
});
/**
 * The height of a face image
 *
 * @type number
 * @static
 * @name ImageManager.faceHeight
 */
Object.defineProperty(ImageManager, "faceHeight", {
    get: function() {
        return this.getFaceSize();
    },
    configurable: true
});
/**
 * Gets the icon size from database if possible, otherwise a default icon size
 *
 * @static
 * @since 1.9.0
 * @return {number} The icon width
 */
ImageManager.getIconSize = function() {
    if ("iconSize" in $dataSystem) {
        return $dataSystem.iconSize;
    } else {
        return this.defaultIconWidth;
    }
};
/**
 * Gets the face image size from database if possible, otherwise a default face size
 *
 * @static
 * @since 1.9.0
 * @return {number} The face image width
 */
ImageManager.getFaceSize = function() {
    if ("faceSize" in $dataSystem) {
        return $dataSystem.faceSize;
    } else {
        return this.defaultFaceWidth;
    }
};
/**
 * Loads an animation with given filename, from the animations folder
 *
 * @static
 * @param {string} filename - Filename of the animation to load (no file extension)
 * @return {Bitmap} The image file as a bitmap
 */
ImageManager.loadAnimation = function(filename) {
    return this.loadBitmap("img/animations/", filename);
};
/**
 * Loads a battleback1 with given filename, from the battlebacks1 folder
 *
 * @static
 * @param {string} filename - Filename of the battleback1 to load (no file extension)
 * @return {Bitmap} The image file as a bitmap
 */
ImageManager.loadBattleback1 = function(filename) {
    return this.loadBitmap("img/battlebacks1/", filename);
};
/**
 * Loads a battleback2 with given filename, from the battlebacks2 folder
 *
 * @static
 * @param {string} filename - Filename of the battleback2 to load (no file extension)
 * @return {Bitmap} The image file as a bitmap
 */
ImageManager.loadBattleback2 = function(filename) {
    return this.loadBitmap("img/battlebacks2/", filename);
};
/**
 * Loads an enemy with given filename, from the enemies folder
 *
 * @static
 * @param {string} filename - Filename of the enemy to load (no file extension)
 * @return {Bitmap} The image file as a bitmap
 */
ImageManager.loadEnemy = function(filename) {
    return this.loadBitmap("img/enemies/", filename);
};
/**
 * Loads a character with given filename, from the characters folder
 *
 * @static
 * @param {string} filename - Filename of the character sheet to load (no file extension)
 * @return {Bitmap} The image file as a bitmap
 */
ImageManager.loadCharacter = function(filename) {
    return this.loadBitmap("img/characters/", filename);
};
/**
 * Loads a face with given filename, from the faces folder
 *
 * @static
 * @param {string} filename - Filename of the face sheet to load (no file extension)
 * @return {Bitmap} The image file as a bitmap
 */
ImageManager.loadFace = function(filename) {
    return this.loadBitmap("img/faces/", filename);
};
/**
 * Loads a parallax with given filename, from the parallaxes folder
 *
 * @static
 * @param {string} filename - Filename of the parallax to load (no file extension)
 * @return {Bitmap} The image file as a bitmap
 */
ImageManager.loadParallax = function(filename) {
    return this.loadBitmap("img/parallaxes/", filename);
};
/**
 * Loads a picture with given filename, from the pictures folder
 *
 * @static
 * @param {string} filename - Filename of the picture to load (no file extension)
 * @return {Bitmap} The image file as a bitmap
 */
ImageManager.loadPicture = function(filename) {
    return this.loadBitmap("img/pictures/", filename);
};
/**
 * Loads a side view actor sheet with given filename, from the sv_actors folder
 *
 * @static
 * @param {string} filename - Filename of the side view actor sheet to load (no file extension)
 * @return {Bitmap} The image file as a bitmap
 */
ImageManager.loadSvActor = function(filename) {
    return this.loadBitmap("img/sv_actors/", filename);
};
/**
 * Loads a side view enemy with given filename, from the sv_enemies folder
 *
 * @static
 * @param {string} filename - Filename of the side view enemy to load (no file extension)
 * @return {Bitmap} The image file as a bitmap
 */
ImageManager.loadSvEnemy = function(filename) {
    return this.loadBitmap("img/sv_enemies/", filename);
};
/**
 * Loads a system graphic with given filename, from the system folder
 *
 * @static
 * @param {string} filename - Filename of the system graphic to load (no file extension)
 * @return {Bitmap} The image file as a bitmap
 */
ImageManager.loadSystem = function(filename) {
    return this.loadBitmap("img/system/", filename);
};
/**
 * Loads a tileset with given filename, from the tilesets folder
 *
 * @static
 * @param {string} filename - Filename of the tileset to load (no file extension)
 * @return {Bitmap} The image file as a bitmap
 */
ImageManager.loadTileset = function(filename) {
    return this.loadBitmap("img/tilesets/", filename);
};
/**
 * Loads a title1 with given filename, from the titles1 folder
 *
 * @static
 * @param {string} filename - Filename of the title1 to load (no file extension)
 * @return {Bitmap} The image file as a bitmap
 */
ImageManager.loadTitle1 = function(filename) {
    return this.loadBitmap("img/titles1/", filename);
};
/**
 * Loads a title2 with given filename, from the titles2 folder
 *
 * @static
 * @param {string} filename - Filename of the title2 to load (no file extension)
 * @return {Bitmap} The image file as a bitmap
 */
ImageManager.loadTitle2 = function(filename) {
    return this.loadBitmap("img/titles2/", filename);
};
/**
 * Loads a bitmap from the given folder with given filename
 *
 * @static
 * @param {string} folder - Folder part of the path to the file, for example "img/titles2/"
 * @param {string} filename - Filename of the image to load (no file extension)
 * @return {Bitmap} The image file as a bitmap. If no filename, returns empty bitmap
 */
ImageManager.loadBitmap = function(folder, filename) {
    if (filename) {
        const url = folder + Utils.encodeURI(filename) + ".png";
        return this.loadBitmapFromUrl(url);
    } else {
        return this._emptyBitmap;
    }
};
/**
 * Loads a bitmap from the given url
 *
 * @static
 * @param {string} url - The full folder + filename + extension path to the file
 * @return {Bitmap} The image file as a bitmap
 */
ImageManager.loadBitmapFromUrl = function(url) {
    const cache = url.includes("/system/") ? this._system : this._cache;
    if (!cache[url]) {
        cache[url] = Bitmap.load(url);
    }
    return cache[url];
};
/**
 * Destroys all bitmap objects in the image cache
 *
 * @static
 */
ImageManager.clear = function() {
    const cache = this._cache;
    for (const url in cache) {
        cache[url].destroy();
    }
    this._cache = {};
};
/**
 * Check if there are any bitmaps loading
 *
 * @static
 * @return {boolean} True if there are no bitmaps loading, false if any bitmap is still loading
 */
ImageManager.isReady = function() {
    for (const cache of [this._cache, this._system]) {
        for (const url in cache) {
            const bitmap = cache[url];
            if (bitmap.isError()) {
                this.throwLoadError(bitmap);
            }
            if (!bitmap.isReady()) {
                return false;
            }
        }
    }
    return true;
};
/**
 * Throw a retry screen error when bitmap could not be loaded
 *
 * @static
 * @throws Retry screen error
 */
ImageManager.throwLoadError = function(bitmap) {
    const retry = bitmap.retry.bind(bitmap);
    throw ["LoadError", bitmap.url, retry];
};
/**
 * Check if the filename begins with a ! character
 *
 * @static
 * @param {string} filename - The filename to check
 * @return {boolean} True if the filename begins with !
 */
ImageManager.isObjectCharacter = function(filename) {
    const sign = Utils.extractFileName(filename).match(/^[!$]+/);
    return sign && sign[0].includes("!");
};
/**
 * Check if the filename begins with a $ character
 *
 * @static
 * @param {string} filename - The filename to check
 * @return {boolean} True if the filename begins with $
 */
ImageManager.isBigCharacter = function(filename) {
    const sign = Utils.extractFileName(filename).match(/^[!$]+/);
    return sign && sign[0].includes("$");
};
/**
 * Check if the filename begins with a ! character
 *
 * @static
 * @param {string} filename - The filename to check
 * @return {boolean} True if the filename begins with !
 */
ImageManager.isZeroParallax = function(filename) {
    return Utils.extractFileName(filename).charAt(0) === "!";
};