485b032f61179e1e54a145e416c3e52be446761b
[naja.git] / naja / scenes / load_save.py
1 """
2 Load and save scenes.
3 """
4
5 import json
6 import os
7 from datetime import datetime
8
9 import pygame.locals as pgl
10
11 from naja.constants import KEYS
12 from naja.events import SceneChangeEvent, InvalidateTheWorld
13 from naja.options import options
14 from naja.scenes.scene import Scene
15 from naja.widgets.save_slot import SaveSlotWidget
16 from naja.widgets.selector import SelectorWidget
17
18
19 def save_path(path):
20     return os.path.join(options.save_location, *path.split('/'))
21
22
23 def ensure_save_path_exists():
24     location = save_path('')
25     if not os.path.isdir(location):
26         os.makedirs(location)
27
28
29 class SaveGameScene(Scene):
30     def __init__(self, state):
31         super(SaveGameScene, self).__init__(state)
32         selector = SelectorWidget()
33         self.add(selector)
34         self.slots = {}
35
36         for slot_num in range(8):
37             slot = self.make_slot_widget(slot_num)
38             self.slots[slot_num] = slot
39             selector.add(slot)
40
41     def save_path(self, slot_num):
42         return save_path('slot_%s.json' % (slot_num,))
43
44     def get_game_data(self, slot_num):
45         try:
46             with open(self.save_path(slot_num), 'r') as save_file:
47                 return json.load(save_file)
48         except IOError:
49             return None
50         except Exception as e:
51             print "Error reading savegame in slot %s: %s" % (slot_num, e)
52             return None
53
54     def make_slot_widget(self, slot_num):
55         game_data = self.get_game_data(slot_num)
56         y_offset = 74 * slot_num
57         slot = SaveSlotWidget((100, y_offset), slot_num, game_data)
58         slot.add_callback('click', lambda event: self.save_game(slot_num))
59         return slot
60
61     def save_game(self, slot_num):
62         save_data = {
63             'timestamp': datetime.now().ctime(),
64             'data': self.state.gameboard.export(),
65         }
66         try:
67             ensure_save_path_exists()
68             with open(self.save_path(slot_num), 'w') as save_file:
69                 json.dump(save_data, save_file)
70         except Exception as e:
71             print "Error saving game in slot %s: %s" % (slot_num, e)
72         self.slots[slot_num].game_data = self.get_game_data(slot_num)
73         InvalidateTheWorld.post()
74
75     def handle_scene_event(self, ev):
76         if ev.type == pgl.KEYDOWN and ev.key in KEYS.QUIT:
77             from naja.scenes.menu import MenuScene
78             SceneChangeEvent.post(MenuScene)
79             return