#!/usr/bin/env python
#
###
# Application: Pycadia
# File:        pyg_keys.py
# Description: pygame keys class module
# Copyright (c) 2002-2003   Andy Balcombe <http://www.anti-particle.com>
###
#
# 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 Library 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 ConfigParser
import pygame
from pygame.locals import *

class Msg:
    """simple class to display a message"""
    def __init__(self, msg, size, y, screen):
        font = pygame.font.Font(None, size)
        text = font.render(msg, 1, (255, 255, 255))
        textpos = text.get_rect()
        textpos.centerx = screen.get_rect().centerx
        textpos.centery = y #screen.get_rect().centery
        screen.blit(text, textpos)

def get_key_press():
    """get a key event"""
    #init pygame & setup screen
    pygame.init()
    screen = pygame.display.set_mode((200, 90))
    
    #display messages & update display
    Msg('Press a key', 20, 10, screen)
    #Msg('or move a controller axis.', 20, 25, screen)
    Msg('Press ESC to cancel.', 20, 70, screen)
    pygame.display.flip()
    
    #loop until a key is pressed
    key_pressed = 0
    old_event = 0
    while not key_pressed:
        for event in pygame.event.get():
            if event.type is QUIT or (event.type is KEYDOWN and event.key is K_ESCAPE):
                sKey = ''
                key_pressed = 1
            elif event.type is KEYDOWN and old_event != KEYDOWN:
                key_pressed = 1
                sKey = pygame.key.name(event.key)
                Msg(sKey, 30, 47, screen)
                pygame.display.flip()
            old_event = event.type
    #done
    pygame.time.delay(250)
    pygame.quit()
    return sKey, event.key

def get_joystick_list():
    """get dictionary of joysticks"""
    #init pygame & setup screen
    pygame.init()
    pygame.joystick.init()
    num_joys = pygame.joystick.get_count()
    dJoysticks = {-1:'None'}
    #for each joystick
    for i in range(num_joys):
        j = pygame.joystick.Joystick(i)
        dJoysticks.update({i: j.get_name()})
    #done    
    pygame.quit()
    return dJoysticks
    
def get_joystick_action(joystick):
    """get a joystick event"""
    #init pygame & setup screen
    pygame.init()
    screen = pygame.display.set_mode((200, 90))
    
    #display messages & update display
    Msg('Press a button', 20, 10, screen)
    Msg('or move a controller axis.', 20, 25, screen)
    Msg('Press ESC to cancel.', 20, 70, screen)
    pygame.display.flip()
    
    #init joystick
    pygame.joystick.init()
    joy = pygame.joystick.Joystick(joystick)
    joy.init()
    num_buttons = joy.get_numbuttons()
    num_axes = joy.get_numaxes()
    if num_axes > 2:
        num_axes = 2
    #defaults
    done = 0
    button = -1
    axis = -1
    axis_dir = ''
    axis_val = 0
    dAxis={0:'x', 1:'y', 2:'z'}
    #loop until a joystick is moved / pressed
    while not done:
        #cancel?
        for event in pygame.event.get():
            if event.type is QUIT or (event.type is KEYDOWN and event.key is K_ESCAPE):
                done=1
        #button pressed
        for i in range(num_buttons):
            pygame.event.pump()
            joy_pressed = joy.get_button(i)
            if joy_pressed:
                button = i 
                Msg("Button %s pressed" % (i) , 30, 47, screen)
                pygame.display.flip()
                done=1
        #axis moved
        for i in range(num_axes):
            pygame.event.pump()
            joy_axis = joy.get_axis(i)
            if joy_axis > 0.2 or joy_axis < -0.2:
                if joy_axis > 0.2:
                    axis_dir = 'axis +%s' % (dAxis.get(i))
                    axis_val = 1
                if joy_axis < -0.2:
                    axis_dir = 'axis -%s' % (dAxis.get(i))
                    axis_val = -1
                axis = i
                Msg(axis_dir , 30, 47, screen)
                pygame.display.flip()
                #print 'axis_dir=',axis_dir,i
                done=1
    #done
    pygame.time.delay(400)
    pygame.quit()
    return button, axis, axis_dir, axis_val
    
    
class GameKeys:
    """Pycadia keyboard & joystick class"""
    def __init__(self):
        dAxis={0:'x', 1:'y', 2:'z'}
        #read config file
        self.config = ConfigParser.ConfigParser()
        self.config.read('pycadia.conf')
        #set player control variables
        lKeyControls = ['key_left', 'key_right', 'key_thrust', 'key_fire', 'key_hyper']
        lKeyVars = ['p~k_left', 'p~k_right', 'p~k_thrust', 'p~k_fire', 'p~k_hyper']
        lJoyControls = ['joy_left', 'joy_right', 'joy_thrust', 'joy_fire', 'joy_hyper']
        lJoyVars = ['p~j_left', 'p~j_right', 'p~j_thrust', 'p~j_fire', 'p~j_hyper']
        #for each player
        for iPlayer in [1,2]:
            #for each control
            for i in range(5):
                #get key char & set player property (eg. player1.key_left)
                iKey = self.config.getint('player%s' % (iPlayer), lKeyControls[i])
                sVarName = lKeyVars[i].replace('~', str(iPlayer))
                exec('self.%s = iKey' % (sVarName)) 
                #get joy axis / button and compile necessary code into player property 
                l = eval(self.config.get('player%s' % (iPlayer), lJoyControls[i]))
                s = 'player%s.joy.' % (iPlayer)
                #joystick axis
                if l[0] == 'axis':
                    s = s + 'get_axis(%s) ' % (l[1])
                    if l[2] > 0:
                        #axis +
                        lJoy = (l[1], 0.2)
                        s = s + ' > 0.2'
                    elif l[2] < 0:
                        #axis -
                        lJoy = (l[1], -0.2)
                        s = s + ' < -0.2'
                else:
                    #joystick button
                    lJoy = (l[1])
                    s = s + 'get_button(%s) ' % (l[1])
                sVarName = lJoyVars[i].replace('~', str(iPlayer))
                c = compile(s, '', 'eval')
                exec('self.%s = c' % (sVarName))

