from gfxutils import V2


class GamePad:

    gamepads = {}

    def __init__(self, index):
        ''' Creates a gamepad object and indicates to the engine that
            you would like it to try to connect a gamepad to this object
            when someone plugs in an actual gamepad.

            This class is intended to be subclassed and have these methods:
                on_button_pressed(self, button)
                on_button_released(self, button)
                on_dpad_changed(self, x, y)
        '''
        if index in GamePad.gamepads:
            raise IndexError('Cannot have 2 GamePads mapped to the same index')
        self.index = index
        self.gamepad = None
        GamePad.gamepads[index] = self

    @property
    def connected(self):
        ''' Returns True if there is an actual gamepad mapped to this object.
                if not connected:
                    polling for state will return default 0 values
                    you will not receive events
                The engine framework is responsible for detecting and connecting gamepads.
        '''
        if self.gamepad is None:
            return False
        else:
            return True

    def on_button_pressed(self, button):
        ''' called when a button is pressed
            Possible Buttons: 'A', 'B', 'X', 'Y',
                   Shoulders: 'LB', 'RB',
                      Sticks: 'LS', 'RS',
                      Others: 'SELECT', 'START'
        '''

    def on_button_released(self, button):
        ''' called when a button is released
            Possible Buttons: 'A', 'B', 'X', 'Y',
                   Shoulders: 'LB', 'RB',
                      Sticks: 'LS', 'RS',
                      Others: 'SELECT', 'START'
        '''

    def on_dpad_changed(self, x, y):
        ''' called when the dpad is changed
                x is -1 , 0, or 1 for left, center, or right
                y is -1 , 0, or 1 for down, center, or up
        '''

    @property
    def left_stick(self):
        ''' Vector of max-length 1.0 (rounded corners)
                for direction and magnitude of left stick
        '''
        if self.connected:
            return self.gamepad.left_stick()
        else:
            return V2(0, 0)

    @property
    def right_stick(self):
        ''' Vector of max-length 1.0 (rounded corners)
                for direction and magnitude of right stick
        '''
        if self.connected:
            return self.gamepad.right_stick()
        else:
            return V2(0, 0)

    @property
    def left_trigger(self):
        ''' Value of left trigger between 0 and 1 (inclusive)
                0 = not depressed
                1 = fully depressed
        '''
        if self.connected:
            return self.gamepad.left_trigger()
        else:
            return 0

    @property
    def right_trigger(self):
        ''' Value of right trigger between 0 and 1 (inclusive)
                0 = not depressed
                1 = fully depressed
        '''
        if self.connected:
            return self.gamepad.right_trigger()
        else:
            return 0

    @property
    def a_button(self):
        ''' Boolean for whether `a_button` is pressed '''
        if self.connected:
            return self.gamepad.a_button() == 1
        else:
            return False

    @property
    def b_button(self):
        ''' Boolean for whether `b_button` is pressed '''
        if self.connected:
            return self.gamepad.b_button() == 1
        else:
            return False

    @property
    def x_button(self):
        ''' Boolean for whether `x_button` is pressed '''
        if self.connected:
            return self.gamepad.x_button() == 1
        else:
            return False

    @property
    def y_button(self):
        ''' Boolean for whether `y_button` is pressed '''
        if self.connected:
            return self.gamepad.y_button() == 1
        else:
            return False

    @property
    def back_button(self):
        ''' Boolean for whether `back_button` is pressed '''
        if self.connected:
            return self.gamepad.back_button() == 1
        else:
            return False

    @property
    def start_button(self):
        ''' Boolean for whether `start_button` is pressed '''
        if self.connected:
            return self.gamepad.start_button() == 1
        else:
            return False

    @property
    def left_stick_button(self):
        ''' Boolean for whether `left_stick_button` is pressed '''
        if self.connected:
            return self.gamepad.left_stick_button() == 1
        else:
            return False

    @property
    def right_stick_button(self):
        ''' Boolean for whether `right_stick_button` is pressed '''
        if self.connected:
            return self.gamepad.right_stick_button() == 1
        else:
            return False

    @property
    def left_shoulder_button(self):
        ''' Boolean for whether `left_shoulder_button` is pressed '''
        if self.connected:
            return self.gamepad.left_shoulder_button() == 1
        else:
            return False

    @property
    def right_shoulder_button(self):
        ''' Boolean for whether `right_shoulder_button` is pressed '''
        if self.connected:
            return self.gamepad.right_shoulder_button() == 1
        else:
            return False
