export default class Serialization {
    constructor(context) {
        this.context = context;
    }

    save() {
        const saveobj = {
            state: this.context.state.serialize(),
            dynamics: this.serializeDynamicItems(),
            itemLocations: this.serializeItemLocations(),
            itemStates: this.serializeItemStates(),
            player:             {
                currentRoom: this.context.player.currentRoom,
                inventory: this.context.player.inventory
            },
            volumes: {
                music: this.context.output.sound.musicVolume,
                sfx: this.context.output.sound.sfxVolume,
                ambience: this.context.output.sound.ambienceVolume
            }
        };
        localStorage.setItem("save", JSON.stringify(saveobj));
    }

    load() {
        const loadobj = JSON.parse(localStorage.getItem("save"));
        this.context.state.deserialize(loadobj.state);
        this.deserializeDynamicItems(loadobj.dynamics);
        this.deserializeItemLocations(loadobj.itemLocations);
        this.deserializeItemStates(loadobj.itemStates);
        this.deserializePlayer(loadobj.player);
        this.context.output.sound.setSFXVolume(loadobj.volumes.sfx);
        this.context.output.sound.setMusicVolume(loadobj.volumes.music);
        this.context.output.sound.setAmbienceVolume(loadobj.volumes.ambience);
    }

    serializeItemLocations() {
        return this.context.rooms.map((item) => {
            return [item.id, 
                item.objects
            ]
        });
    }

    deserializeItemLocations(items) {
        items.forEach((item) => {
            const room = this.context.getRoom(item[0]);
            room.objects = item[1];
        })
    }

    deserializeItemStates(items) {
        items.forEach((item) => {
            const obj = this.context.getItem(item[0]);
            obj.state.deserialize(item[1]);
        })
    }

    deserializePlayer(player) {
        this.context.move(player.currentRoom);
        this.context.player.inventory = player.inventory;
    }

    serializeItemStates() {
        return this.context.items.map((item) => {
            return [item.getID(), item.state.serialize()]
        });
    }

    serializeDynamicItems() {
        return this.context.items.filter((item) => item.dynamic).map((item) => [item.id, item.dynamicID]);
    }

    deserializeDynamicItems(items) {
        items.forEach((item) => {
            const base = this.context.getItem(item[0]);
            const cloned = base.clone();
            cloned.dynamicID = item[1];
            this.context.items.push(cloned);
        })
    }
}