Save game.
[naja.git] / naja / scenes / load_save.py
diff --git a/naja/scenes/load_save.py b/naja/scenes/load_save.py
new file mode 100644 (file)
index 0000000..485b032
--- /dev/null
@@ -0,0 +1,79 @@
+"""
+Load and save scenes.
+"""
+
+import json
+import os
+from datetime import datetime
+
+import pygame.locals as pgl
+
+from naja.constants import KEYS
+from naja.events import SceneChangeEvent, InvalidateTheWorld
+from naja.options import options
+from naja.scenes.scene import Scene
+from naja.widgets.save_slot import SaveSlotWidget
+from naja.widgets.selector import SelectorWidget
+
+
+def save_path(path):
+    return os.path.join(options.save_location, *path.split('/'))
+
+
+def ensure_save_path_exists():
+    location = save_path('')
+    if not os.path.isdir(location):
+        os.makedirs(location)
+
+
+class SaveGameScene(Scene):
+    def __init__(self, state):
+        super(SaveGameScene, self).__init__(state)
+        selector = SelectorWidget()
+        self.add(selector)
+        self.slots = {}
+
+        for slot_num in range(8):
+            slot = self.make_slot_widget(slot_num)
+            self.slots[slot_num] = slot
+            selector.add(slot)
+
+    def save_path(self, slot_num):
+        return save_path('slot_%s.json' % (slot_num,))
+
+    def get_game_data(self, slot_num):
+        try:
+            with open(self.save_path(slot_num), 'r') as save_file:
+                return json.load(save_file)
+        except IOError:
+            return None
+        except Exception as e:
+            print "Error reading savegame in slot %s: %s" % (slot_num, e)
+            return None
+
+    def make_slot_widget(self, slot_num):
+        game_data = self.get_game_data(slot_num)
+        y_offset = 74 * slot_num
+        slot = SaveSlotWidget((100, y_offset), slot_num, game_data)
+        slot.add_callback('click', lambda event: self.save_game(slot_num))
+        return slot
+
+    def save_game(self, slot_num):
+        save_data = {
+            'timestamp': datetime.now().ctime(),
+            'data': self.state.gameboard.export(),
+        }
+        try:
+            ensure_save_path_exists()
+            with open(self.save_path(slot_num), 'w') as save_file:
+                json.dump(save_data, save_file)
+        except Exception as e:
+            print "Error saving game in slot %s: %s" % (slot_num, e)
+        self.slots[slot_num].game_data = self.get_game_data(slot_num)
+        InvalidateTheWorld.post()
+
+    def handle_scene_event(self, ev):
+        if ev.type == pgl.KEYDOWN and ev.key in KEYS.QUIT:
+            from naja.scenes.menu import MenuScene
+            SceneChangeEvent.post(MenuScene)
+            return