# Balazar Brothers
# Copyright (C) 2006 Jean-Baptiste LAMY
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

import os, os.path, random
import cerealizer
import soya, tofu, soya.tofu4soya as tofu4soya, soya.sdlconst as sdlconst

import balazar_brothers, balazar_brothers.globdef as globdef
from balazar_brothers.character import JumpAction, QuitMenuAction

class EventListener(soya.CoordSyst):
  def __init__(self, parent = None):
    soya.CoordSyst.__init__(self, parent)
    
    self.jump1_keys       = set([sdlconst.K_LSHIFT, sdlconst.K_LCTRL, sdlconst.K_SPACE, "0", "6"]) # Strings are for joystick buttons.
    self.jump2_keys       = set([sdlconst.K_RSHIFT, sdlconst.K_RCTRL, sdlconst.K_SPACE, "1", "7"])
    self.quit_keys        = set([sdlconst.K_q, sdlconst.K_ESCAPE, "2"])
    self.screenshot_keys  = set([sdlconst.K_c])
    
    self.camera_distance_speed  = 0.0
    self.camera_angle_speed     = 0.0
    self.nb_camera_keys_pressed = 0.0
    
    if globdef.SAVE_REPLAY: self.replay = Replay()
    else:                   self.replay = None
    
    self.reset()
    
  def reset(self):
    self.jump1_key_down = 0
    self.jump2_key_down = 0
    
  def begin_round(self):
    events = soya.process_event()
    
    if self.replay: self.replay.add_events(events)
    
    for event in events:
      if   event[0] == sdlconst.JOYAXISMOTION:
        
        if   event[1] == 0:
          if   event[2] < 0: event_type = sdlconst.KEYDOWN; event_key = sdlconst.K_LEFT
          elif event[2] > 0: event_type = sdlconst.KEYDOWN; event_key = sdlconst.K_RIGHT
          else:              event_type = sdlconst.KEYUP  ; event_key = sdlconst.K_LEFT # XXX or right
        elif event[1] == 1:
          if   event[2] < 0: event_type = sdlconst.KEYDOWN; event_key = sdlconst.K_UP
          elif event[2] > 0: event_type = sdlconst.KEYDOWN; event_key = sdlconst.K_DOWN
          else:              event_type = sdlconst.KEYUP  ; event_key = sdlconst.K_UP # XXX or down
          
      elif event[0] == sdlconst.JOYBUTTONDOWN:
        event_type = sdlconst.KEYDOWN
        event_key  = str(event[1])
        
      elif event[0] == sdlconst.JOYBUTTONUP:
        event_type = sdlconst.KEYUP
        event_key  = str(event[1])
        
      else:
        event_type = event[0]
        if len(event) > 1: event_key  = event[1]
        
        
      if event_type == sdlconst.KEYDOWN:
        if   event_key in self.jump1_keys: self.jump1_key_down = 1
        if   event_key in self.jump2_keys: self.jump2_key_down = 1
        
        elif event_key in self.quit_keys:
          tofu.GAME_INTERFACE.traveling.characters[0].doer.do_action(QuitMenuAction())
          
        elif event_key in self.screenshot_keys:
          import tempfile
          screenshot_file = tempfile.mktemp(".png")
          soya.screenshot(screenshot_file)
          print "* Balazar Brothers * Screenshot saved as %s" % screenshot_file
          
        elif event_key == sdlconst.K_LEFT:  self.camera_angle_speed    = -0.04; self.nb_camera_keys_pressed += 1.0
        elif event_key == sdlconst.K_RIGHT: self.camera_angle_speed    =  0.04; self.nb_camera_keys_pressed += 1.0
        elif event_key == sdlconst.K_UP:    self.camera_distance_speed = -1.20; self.nb_camera_keys_pressed += 1.0
        elif event_key == sdlconst.K_DOWN:  self.camera_distance_speed =  1.20; self.nb_camera_keys_pressed += 1.0
        
        elif event_key == sdlconst.K_d:
          print tofu.GAME_INTERFACE.traveling.characters
          print [i.uid for i in tofu.GAME_INTERFACE.traveling.characters]
          
      elif event_type == sdlconst.KEYUP:
        if   event_key in self.jump1_keys: self.jump1_key_down = 0
        if   event_key in self.jump2_keys: self.jump2_key_down = 0
        
        elif event_key == sdlconst.K_LEFT:  self.camera_angle_speed    = 0.0
        elif event_key == sdlconst.K_RIGHT: self.camera_angle_speed    = 0.0
        elif event_key == sdlconst.K_UP:    self.camera_distance_speed = 0.0
        elif event_key == sdlconst.K_DOWN:  self.camera_distance_speed = 0.0
        
    # Camera control
    if self.nb_camera_keys_pressed > 2.0:
      # Reset camera
      self.nb_camera_keys_pressed = -4.0
      tofu.GAME_INTERFACE.traveling.custom_distance = 0.0
      tofu.GAME_INTERFACE.traveling.custom_angle    = 0.0
      self.camera_distance_speed = self.camera_angle_speed = 0.0
      
    elif self.nb_camera_keys_pressed < 0.0:
      self.nb_camera_keys_pressed += 0.1
      
    else:
      if self.nb_camera_keys_pressed > 0.1: self.nb_camera_keys_pressed -= 0.1
      tofu.GAME_INTERFACE.traveling.custom_distance += self.camera_distance_speed
      tofu.GAME_INTERFACE.traveling.custom_angle    += self.camera_angle_speed
      
      
    if tofu.GAME_INTERFACE.traveling.characters:
      if self.jump1_key_down:
        if tofu.GAME_INTERFACE.left_bubble.discussion and tofu.GAME_INTERFACE.left_bubble.discussion.validable:
          self.jump1_key_down = 0
        tofu.GAME_INTERFACE.traveling.characters[ 0].start_jumping = 1
          
      if self.jump2_key_down:
        if tofu.GAME_INTERFACE.right_bubble.discussion and tofu.GAME_INTERFACE.right_bubble.discussion.validable:
          self.jump2_key_down = 0
        tofu.GAME_INTERFACE.traveling.characters[-1].start_jumping = 1
      




class Replay(object):
  def __init__(self):
    import os, os.path, shutil
    
    self.random_state = random.getstate()
    self.events       = []
    self.replay_dir   = os.path.join(globdef.SAVED_GAME_DIR, globdef.NAME) + "__replay__"
    
    src_dir = os.path.join(globdef.SAVED_GAME_DIR, globdef.NAME)
    if os.path.exists(src_dir):
      if os.path.exists(self.replay_dir): shutil.rmtree(self.replay_dir)
      shutil.copytree(src_dir, self.replay_dir)
      for i in os.listdir(os.path.join(self.replay_dir, "players")):
        shutil.move(os.path.join(self.replay_dir, "players", i), os.path.join(self.replay_dir, "players", i[:-5] + "__replay__.data"))
    else:
      if not os.path.exists(self.replay_dir): os.mkdir(self.replay_dir)
      
  def save(self):
    cerealizer.dump(self, open(os.path.join(self.replay_dir, "replay.data"), "w"))
    
  def get(klass, login):
    return cerealizer.load(open(os.path.join(globdef.SAVED_GAME_DIR, login, "replay.data")))
  get = classmethod(get)
                           
  def add_events(self, events):
    self.events.append(events)
    
  def get_events(self):
    print self.nb_events - len(self.events), "/", self.nb_events
    if self.events: return self.events.pop(0)
    soya.IDLER.stop()
    return []
  
  def replay2video(self, login, password):
    self.nb_events = len(self.events)
    soya.process_event = self.get_events
    random.setstate(self.random_state)
    globdef.FPS_LABEL = 0
    globdef.IMG_DIR   = self.replay_dir
    r = balazar_brothers.game_interface.start_single(login, password, IdlerClass = balazar_brothers.game_interface.Replay2VideoIdler)
    
    #os.system("""transcode -i %s/img_00000.png -x im,null -y xvid,null -f 30 --use_rgb -J videocore=flip -o %s/video.mpeg""" % (self.replay_dir, self.replay_dir))
    
cerealizer.register(Replay)



