(function(){
    // Switches
    function saveSwitches(){
        return $gameSwitches._data;
    }
    function loadSwitches(cont){
        $gameSwitches = new Game_Switches();
        $gameSwitches._data = cont.switches;
        return $gameSwitches;
    }

    // Variables
    function saveVariables(){
        return [1].map(function(n){ return $gameVariables.value(n);});
    }
    function loadVariables(cont){
        $gameVariables = new Game_Variables();
        $gameVariables.setValue(1, cont.variables[0])
    }

    // SelfSwitches
    function saveSelfSwitches(){
        const keys = Object.keys($gameSelfSwitches._data);
        return keys.filter(function(key){ return !!$gameSelfSwitches._data[key]; });
    }
    function loadSelfSwitches(cont){
        $gameSelfSwitches  = new Game_SelfSwitches();
        cont.selfSwitches.forEach(function(key){ $gameSelfSwitches._data[key] = true; });
    }

    // position
    function loadPos(cont){
        $gameMap    = new Game_Map();
        $gamePlayer = new Game_Player();
        const pos = cont.position;
        const x = (pos>>4) % 16, y = pos % 16, mapId = pos >> 8;
        $gamePlayer._needsMapReload = true;
        $gamePlayer.reserveTransfer(mapId,x,y,2,2);
    }

    // Actor
    const actorSaveFmt = [
        "_hp","_mp","_name","_equips","_paramPlus","_states","_stateTurns","_stateSteps"];
    function saveActors(){
        const save = {};
        const party = $gameParty._actors;
        const wait = $gameSystem.waitingMembers();
        $gameActors._data.forEach(function(actor){
            if (actor){
                const id = actor.actorId();
                if (party.contains(id) || wait.contains(id)){
                    const li = {};
                    actorSaveFmt.forEach(function(name){ li[name] = actor[name]; });
                    li._exp = actor.currentExp();
                    save[id] = li;
                }
            }
        });
        return save;
    }

    function loadActors(contents){
        $gameActors = new Game_Actors();
        Object.keys(contents.actors).forEach(function(id){
            const cont = contents.actors[id];
            const actor = $gameActors.actor(Math.floor(id));
            actorSaveFmt.forEach(function(param){ actor[param] = cont[param]; });
            actor.changeExp(cont._exp,false);
        });
        const actor = $gameActors.actor(1);
        actor.setKanjiPCLock(true);
        actor._characterName = "People2";
        actor._faceName = "face"
        if ($gameSwitches.value(1)){
            actor._characterIndex = actor._faceIndex = 0;
        }else{
            actor._characterIndex = actor._faceIndex = 1;
        };
    }


    DataManager.makeSaveContents = function() {
        const contents = {};
        contents.system       = $gameSystem;
        contents.party        = $gameParty;
        contents.actors       = saveActors();
        contents.switches     = saveSwitches();
        contents.variables    = saveVariables();
        contents.selfSwitches = saveSelfSwitches();
        contents.position = 
        Math.floor(($gameMap.mapId()<<8) + ($gamePlayer.x<<4) + $gamePlayer.y);
        return contents;
    };


    DataManager.extractSaveContents = function(contents) {
        $gameTimer  = new Game_Timer();
        $gameScreen = new Game_Screen();
        $gameScreen.showPicture(2,"light",0,0,0,200,200,100,0);
        $gameParty  = contents.party;
        $gameSystem = contents.system;
        loadSwitches(contents);
        loadVariables(contents);
        loadSelfSwitches(contents);
        loadPos(contents);
        loadActors(contents);
    };
})();