#!/usr/bin/python
# -*- coding: utf-8 -*-

# Basic pygame demo. Based on pygame intro tutorial
# (http://www.pygame.org/docs/tut/intro/intro.html). Uses some code from
# AdaFruit to detect and use the framebuffer. Requires Python 2.7.
#
# Author: Nick Apperley.

import pygame
import os
from button import Button
from pygame import locals


class Test():

    def __init__(self, size=(800, 600)):
        self.size = size
        self.speed = [2, 2]
        self.btn = None
        self.screen = None

        # Check if a framebuffer driver has been loaded.
        if self._load_video_driver():
            self.size = ()

    def _load_video_driver(self):
        """
         Loads a single video driver via auto detection.
        """
        framebuffer = True
        found = False
        drivers = ['fbcon', 'directfb', 'svgalib']
        display_num = os.getenv("DISPLAY")

        if display_num:
            print "I'm running under X display = %s" % display_num
            # Load all Pygame modules.
            pygame.init()
            framebuffer = False
        else:
            # Check which frame buffer drivers are available. Start with fbcon
            # since DirectFB hangs with composite output.
            for item in drivers:
                # Make sure that SDL_VIDEODRIVER is set.
                if not os.getenv('SDL_VIDEODRIVER'):
                    os.putenv('SDL_VIDEODRIVER', item)
                try:
                    # Load the display module.
                    pygame.display.init()
                except pygame.error:
                    print 'Driver: %s failed.' % item
                    continue
                found = True
                break
            if not found:
                raise Exception('No suitable video driver found!')
        return framebuffer

    def _display_button(self):
        """
         Displays a button on the screen.
        """
        height_pos = 1
        bg_colour = (243, 207, 141)
        txt_colour = (0, 0, 0)
        text = 'Exit'
        width = 0
        height = 100
        x = 15
        y = self.size[height_pos] - (height + 30)
        length = 180
        self.btn = Button()

        self.btn.create_button(x=x, y=y, length=length, width=width,
            height=height, text=text, surface=self.screen, color=bg_colour,
            text_color=txt_colour)

    def _setup_screen(self):
        """
         Initialises the screen so it is ready to be rendered on as a surface.
        """
        width_pos = 0
        height_pos = 1

        if len(self.size) == 0:
            # Get the width and height of the display from the framebuffer.
            self.size = (pygame.display.Info().current_w,
                pygame.display.Info().current_h)
            print 'Framebuffer size: %d x %d' % (self.size[width_pos],
                self.size[height_pos])
            self.screen = pygame.display.set_mode(self.size, pygame.FULLSCREEN)
            # Load the font module.
            pygame.font.init()
        else:
            self.screen = pygame.display.set_mode(self.size)

        pygame.display.set_caption('Pygame Test')

    def _handle_events(self):
        """
         Handles all registered events.
        """
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                print 'Exiting...'
                exit(0)
            elif event.type == locals.MOUSEBUTTONDOWN:
                if self.btn.pressed(pygame.mouse.get_pos()):
                    print 'Exiting...'
                    exit(0)

    def _display_loop(self, ball):
        """
         Executes a GUI loop indefinitely until the program is terminated.
        """
        ball_rect = ball.get_rect()
        width_pos = 0
        height_pos = 1

        while 1:
            self._handle_events()
            ball_rect = ball_rect.move(self.speed)

            if ball_rect.bottom > self.btn.rect.topleft[1]:
                self.speed[1] = -self.speed[1]
            if ball_rect.left < 0 or ball_rect.right > self.size[width_pos]:
                self.speed[0] = -self.speed[0]
            if ball_rect.top < 0 or ball_rect.bottom > self.size[height_pos]:
                self.speed[1] = -self.speed[1]

            # Draw one image on top of another.
            self.screen.blit(ball, ball_rect)
            # Update parts of the screen.
            pygame.display.flip()

    def run_demo(self):
        """
         Starts the demo.
        """
        light_blue = (134, 200, 206)

        print 'Starting demo...'
        self._setup_screen()
        print 'Loading ball image...'
        ball = pygame.image.load('ball.gif')
        print 'Ball image loaded.'
        self.screen.fill(light_blue)
        self._display_button()
        # Update parts of the screen.
        pygame.display.flip()
        self._display_loop(ball)

if __name__ == '__main__':
    try:
        Test().run_demo()
    except KeyboardInterrupt:
        print '\nExiting...'
        exit(0)
