use strict;
use warnings;
use Carp;
use SDL ;
use SDL::Video ;
use SDL::Surface;
use SDL::Rect;
use SDL::Event;
use SDL::Events ;
use Data::Dumper;
use Math::Trig;

use lib 'lib';
use SDLx::Widget::Controller;

my $app = init();

my $paddle = {
    x     => 0,
    y     => 0,
    w     => 20,
    h     => 80,
    vel   => 250,
    x_vel => 0,
    y_vel => 0,

};


my $paddle2 = {
    x     => $app->w - 20,
    y     => 0,
    w     => 20,
    h     => 80,
    vel   => 250,
    x_vel => 0,
    y_vel => 0,

};

my $r_ball = {
    x     => $app->w /2,
    y     => $app->w /2,
    w     => 20,
    h     => 20,
    vel_x => ( 150 ),
    vel_y => ( 150 ),
    
    
    
};

sub ball_confine {
    my ($w,$h,$x,$y, $ws, $hs) = @_;
    
    my ($m_x,$m_y) = (1,1);
    $m_x = -1 if $x + $ws >= $w || $x <= 0;
    $m_y = -1 if $y + $hs >= $h || $y <= 0;
    
      
    return [$m_x,$m_y];  
      }
      
sub paddle_confine {
       #return if $_[0]->{y_vel} == 0;
       my ($p, $dt, $h) = @_;
       if ($p->{y} < 0 )
       {
           $p->{y} = 2;
           return;
       }
       elsif ( $p->{y} + $p->{h} + 2 > $h)
       {
           $p->{y} = $h - $p->{h} -2;
           return;
       }
       
       $p->{y} += $p->{y_vel} * $dt;
}      

sub init {

    # Initing video
    # Die here if we cannot make video init
    croak 'Cannot init  ' . SDL::get_error()
      if ( SDL::init(SDL_INIT_VIDEO) == -1 );

    # Create our display window
    # This is our actual SDL application window
    my $a = SDL::Video::set_video_mode( 800, 600, 32,
        SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_HWACCEL );

    croak 'Cannot init video mode 800x600x32: ' . SDL::get_error()
      unless $a;

    return $a;
}

my $game = SDLx::Widget::Controller->new( dt=> 0.1);

sub on_move {
    my $dt = shift;
    $dt = $dt / 1000;
    paddle_confine($paddle, $dt, $app->h);
    paddle_confine($paddle2, $dt, $app->h);
    # Period = $r_ball->{vel}
    
    # cc_speed = 2 * pi * r / T 
    
    my $transform = ball_confine( $app->w, $app->h, $r_ball->{x} , $r_ball->{y},  $r_ball->{w}, $r_ball->{h} );
    $r_ball->{vel_x } *= $transform->[0];
    $r_ball->{vel_y } *= $transform->[1];
    
    $r_ball->{x} += $r_ball->{vel_x } * $dt; 
    $r_ball->{y} += $r_ball->{vel_y } * $dt;
    
    
    
    

    return 1;
}

sub on_event {
    my $event = shift;

    if ( $event->type == SDL_KEYDOWN ) {
        my $key = $event->key_sym;
		if($key == SDLK_PRINT)
		{
			my $screen_shot_index = 1;
			map{$screen_shot_index = $1 + 1 if $_ =~ /Shot(\d+)\.bmp/ && $1 >= $screen_shot_index} <Shot*\.bmp>;
			SDL::Video::save_BMP($app, sprintf("Shot%04d.bmp", $screen_shot_index ));
		}
        $paddle->{y_vel} -= $paddle->{vel} if $key == SDLK_UP;
        $paddle->{y_vel} += $paddle->{vel} if $key == SDLK_DOWN;
        $paddle->{x_vel} -= $paddle->{vel} if $key == SDLK_LEFT;
        $paddle->{x_vel} += $paddle->{vel} if $key == SDLK_RIGHT;
        $r_ball->{rot_vel} += 50 if $key == SDLK_SPACE;
     
    }
    elsif ( $event->type == SDL_KEYUP ) {
        my $key = $event->key_sym;
        $paddle->{y_vel} += $paddle->{vel} if $key == SDLK_UP;
        $paddle->{y_vel} -= $paddle->{vel} if $key == SDLK_DOWN;
        $paddle->{x_vel} += $paddle->{vel} if $key == SDLK_LEFT;
        $paddle->{x_vel} -= $paddle->{vel} if $key == SDLK_RIGHT;
        
    }
    elsif ( $event->type == SDL_QUIT ) {
        return 0;
    }

    return 1;
}

#
# New subroutine "show_paddle" extracted - Thu Mar 18 15:28:02 2010.
#
sub show_paddle {
    my $app = shift;
    my $paddle = shift;



    SDL::Video::fill_rect(
        $app,
        SDL::Rect->new( $paddle->{x}, $paddle->{y}, $paddle->{w}, $paddle->{h} ),
        SDL::Video::map_RGB( $app->format, 0, 0, 255 )
    );

    return ();
} 

sub on_show {
    SDL::Video::fill_rect(
        $app,
        SDL::Rect->new( 0, 0, $app->w, $app->h ),
        SDL::Video::map_RGB( $app->format, 0, 0, 0 )
    );
    
    
   show_paddle ($app, $paddle);
    
    show_paddle ($app, $paddle2);
    
    SDL::Video::fill_rect(
        $app,
        SDL::Rect->new( $r_ball->{x}, $r_ball->{y}, $r_ball->{w}, $r_ball->{h} ),
        SDL::Video::map_RGB( $app->format, 255, 0, 0 )
    );
    
    

    SDL::Video::flip($app);

    return 0;
}

my $move_id  = $game->add_move_handler( \&on_move );
my $event_id = $game->add_event_handler( \&on_event );
my $show_id  = $game->add_show_handler( \&on_show );

$game->run();
