/**
 * MapList is a list of maps with one active index.
 * It contains some utility functions to change the map.
 *
 * @export
 * @class MapList
 */
export class MapList {
    constructor(active = null, maps = {}) {
        this._maps = maps
        this._active = active

        if (Object.keys(maps).length > 0) this.select(active)
    }

    /**
     * Selects a map from the map list.
     *
     * @public
     * @param {string} active - Name of the map to select.
     * @returns {Map} - Returns the active map. Returns null if no map was added to the MapList.
     * @memberof MapList
     */
    select(active) {
        let map = null

        if (active !== this.active) {
            let keys = Object.keys(this.maps)
            if (keys.length > 0) {
                if (this.maps[active] == null) {
                    let altActive = keys[0]
                    console.warn(
                        `The MapList does not contain the provided active key '${active}'. Used '${altActive}' as fallback.`
                    )

                    active = altActive
                }

                if (this.active !== active) {
                    this._active = active
                    map = this.maps[active]
                }
            } else {
                console.error(`Could not provide a fallback map! The map object is empty.`)
            }
        }

        return map
    }

    /**
     * Clones the entire maplist.
     *
     * @public
     * @returns {MapList} - Returns a cloned instance of this map list.
     * @memberof MapList
     */
    clone() {
        let maps = {}

        for (let name of Object.keys(this.maps)) {
            maps[name] = this.maps[name].clone()
        }

        return new MapList(this.active, maps)
    }

    /**
     * Adds a new map to the map list.
     *
     * @public
     * @param {string} key - Key to identify the map.
     * @param {GeoMap} map - The GeoMap to add.
     * @memberof MapList
     */
    add(key, map) {
        if (this.maps[key] != null) consol.warn('Key already in mapList. The existing key was overwritten.')
        if (this.active == null) this._active = key
        map.name = key
        this.maps[key] = map
    }

    /**
     * Returns the the active map.
     * If none is set, it returns null.
     *
     *@public
     * @readonly
     * @member {GeoMap}
     * @memberof MapList
     */
    get map() {
        return this.maps && this.maps[this.active] ? this.maps[this.active] : null
    }

    /**
     * Returns the list of addedd cards.
     *
     * @member {object}
     * @readonly
     * @memberof MapList
     */
    get maps() {
        return this._maps
    }

    /**
     *  Returns the active key.
     *
     * @member {string}
     * @readonly
     * @memberof MapList
     */
    get active() {
        return this._active
    }

    /**
     * Selects the next map in the map array.
     *
     * @public
     * @returns {GeoMap} - Returns the next map in the list.
     * @memberof MapList
     */
    next() {
        let keys = Object.keys(this.maps)
        let idx = keys.indexOf(this.active)

        let next = idx + 1 < keys.length ? keys[idx + 1] : keys[0]
        return next
    }

    /**
     * Removes all maps from the maplist.
     * And cleans up all maps.
     *
     * @public
     * @memberof MapList
     */
    cleanup() {
        for (let key in this.maps) {
            let map = this.maps[key]
            map.remove()
        }
    }
}