% joel Stephens

function RunGame


    hMainWindow = figure(...
        'Color', [0 0 0],...
        'Name', 'Game Window',...
        'Units', 'pixels',...
        'Position',[100 100 700 500]);

    
    
    img = imread('ball.bmp','bmp');
    [m,n,c] = size(img);
    hBall = axes(...
        'parent', hMainWindow,...
        'color', 'none',...
        'visible', 'off',...
        'units', 'pixels',...
        'position', [345, 245, n, m] );
    hBallImage = imshow( img );
    set(hBallImage, 'parent', hBall, 'visible', 'off' );
    ballSpeed = 0;
    ballDirection = 0;
    hTempBall = axes( ...
        'parent', hMainWindow,...
        'units', 'pixels',...
        'color', 'none',...
        'visible', 'off',...
        'position', get(hBall, 'position' ) );
    
    
    img = imread('paddle.bmp','bmp');
    [m,n,c] = size(img);
    
    hRightPaddle = axes(...
        'parent', hMainWindow,...
        'color', 'none',...
        'visible', 'off',...
        'units', 'pixels',...
        'position', [650 - 10, 250 - 50, n, m] );
    hRightPaddleImage = imshow( img );
    set(hRightPaddleImage, 'parent', hRightPaddle, 'visible', 'off' );
    targetY = 200;
    t = timer(  'TimerFcn', @UpdateRightPaddleAI,...
                'StartDelay', 2 );
            start(t)
    
    

    hLeftPaddle = axes(...
        'parent', hMainWindow,...
        'color', 'none',...
        'visible', 'off',...
        'units', 'pixels',...
        'position', [50, 250 - 50, n, m] );
    hLeftPaddleImage = imshow( img );
    set(hLeftPaddleImage, 'parent', hLeftPaddle, 'visible', 'off' );

    hBottomWall = axes(...
        'parent', hMainWindow,...
        'color', [1 1 1],...
        'units', 'pixels',...
        'visible', 'off',...
        'position', [0 40 700 10] );
    patch( [0 700 700 0], [0 0 10 10], 'b' );    
    
    hTopWall = axes(...
        'parent', hMainWindow,...
        'color', [1 1 1],...
        'units', 'pixels',...
        'visible', 'off',...
        'position', [0 450 700 10] );
    patch( [0 700 700 0], [0 0 10 10], 'b' );
    
    rightScore = 0;
    leftScore = 0;
    hRightScore = axes(...
        'parent', hMainWindow,...
        'color', 'none',...
        'visible', 'off',...
        'units', 'pixels',...
        'position', [650 485 50 10] );
    hLeftScore = axes(...
        'parent', hMainWindow,...
        'color', 'none',...
        'visible', 'off',...
        'units', 'pixels',...
        'position', [30 485 50 10] );
    hRightScoreText = text( 0, 0, '0', 'parent', hRightScore,...
        'visible', 'on', 'color', [1 1 1] );
    hLeftScoreText = text( 0, 0, '0', 'parent', hLeftScore,...
        'visible', 'on', 'color', [1 1 1] );
    
    
    
    hQuitButton = uicontrol(...
        'string', 'Quit',...
        'position', [325 475 50 20],...
        'Callback', @QuitButton_CallBack );
    
    hStartButton = uicontrol(...
        'string', 'Start',...
        'position', [325 240 50 20],...
        'Callback',@StartButton_CallBack );


    
    
    


    playing = true; 
    

    while playing == true
        

        UpdateBall()
        UpdateLeftPaddle()
        UpdateRightPaddle()

        CheckForScore()

        pause( 0.01 )
    end
    stop(t)
    close( hMainWindow )
    
    
    
    
    
    
    
    






    
    
    function UpdateBall
        
       pos = get( hBall, 'position' );
       ballX = pos(1,1);
       ballY = pos(1,2);
       
       ballDirection = NormalizeAngle( ballDirection );
      
       
       % check for collisions with the walls
       if ( ballY > 450 - 10 ) && ( ballDirection > 0 ) && ( ballDirection < 180 )
            if ( ballDirection > 90 )
                ballDirection = ballDirection + 2 * ( 180 - ballDirection );
            else
                ballDirection = ballDirection - 2 * ballDirection;
            end
       elseif ( ballY < 50 ) && ( ballDirection > 180 ) && ( ballDirection < 360 )
            if ( ballDirection > 270 )
                ballDirection = ballDirection + 2 * ( 360 - ballDirection );
            else
                ballDirection = ballDirection - 2 * ( ballDirection - 180 );
            end
       end
       
       % check for collisions with the paddles
       
       if ( ballDirection > 90 && ballDirection < 270 )
           
            leftPaddlePos = get( hLeftPaddle, 'position' );
            leftX = leftPaddlePos(1,1);
            leftY = leftPaddlePos(1,2);
          
            if(     (ballX < leftX + 10)...
                &&  (ballX > leftX + 5)...
                &&  (ballY + 10 > leftY)...
                &&  (ballY < leftY + 100)     )
                
                if ( ballDirection < 180 )
                    ballDirection = 180 - ballDirection;
                elseif( ballDirection > 180 )
                    ballDirection = 180 - ballDirection;
                end
            end
       else
            rightPaddlePos = get( hRightPaddle, 'position' );
            rightX = rightPaddlePos(1,1);
            rightY = rightPaddlePos(1,2);
            
            if(     (ballX + 10 > rightX)...
                &&  (ballX + 10 < rightX + 5)...
                &&  (ballY > rightY)...
                &&  (ballY < rightY + 100)  )
                
                if ( ballDirection < 90 )
                    ballDirection = 180 - ballDirection;
                elseif( ballDirection > 270 )
                    ballDirection = 180 - ballDirection;
                end
            end
       end
           
       MoveObject( hBall, ballSpeed, ballDirection );
        
    end


    
    function UpdateRightPaddle()

         
         speed = 5;
         pos = get( hRightPaddle, 'position' );
         rightY = pos(1,2);
         
         
         
         if( rightY + 5 < targetY - 50 && rightY < 400 - 50 )
             MoveObject( hRightPaddle, speed, 90 )
         elseif( rightY - 5 > targetY - 50 && rightY > 50 )
             MoveObject( hRightPaddle, speed, 270 )
         end
      
         pos = get( hRightPaddle, 'position' );
         rightY = pos( 1,2);
         if( rightY > 400 - 50 )
             rightY = 350;
         elseif( rightY < 50 )
             rightY = 50;
         end
         
         
        if( strcmp( get( t, 'Running' ), 'off' ) )
            start(t)
        end
    
    end

    function UpdateRightPaddleAI( ob, data )
        
        % calculate where the ball will colide.
        tempBallDirection = NormalizeAngle( ballDirection ); 
        if( tempBallDirection < 90 || tempBallDirection > 270 && ballSpeed > 0 )
           
            ballPos = get( hBall, 'position' );
            set( hTempBall, 'position', ballPos );
            ballX = ballPos(1,1);            
            while( ballX < 650 - 10  )
                
                ballPos = get( hTempBall, 'position' );
                ballX = ballPos(1,1); 
                ballY = ballPos(1,2);
                MoveObject( hTempBall, 20, tempBallDirection )

               % check for temp ball collision with walls.
               if ( ballY > 450 - 10 ) 
                   if ( tempBallDirection > 0 ) 
                       if ( tempBallDirection < 180 )    
                            tempBallDirection = 360 - tempBallDirection;
                       end
                   end
               elseif ( ballY < 60 ) 
                   if( tempBallDirection > 180 ) 
                       if( tempBallDirection < 360 )
                            tempBallDirection = 360 - tempBallDirection;
                       end
                   end
               end

%                     line( 0, 0, 'marker', '*', 'parent', hTempBall )
%                     pause( 0.0005 )
            end

            pos = get( hTempBall, 'position' );
            ballY = pos(1,2);
            targetY = ballY + ( rand * 150 ) - 75;
            
        end
    end

    function UpdateLeftPaddle()    
        scr = get( hMainWindow, 'position' );
        screenX = scr(1,1);
        screenY = scr(1,2);
        screenH = scr(1,4);
        
        mouse = get(0, 'PointerLocation' );
        y = mouse(1,2) - screenY;
        
        if( y > 100 && y < 400 )
            paddlePos = get( hLeftPaddle, 'position' ); 
            paddlePos(1,2) = y - 50; 
            set( hLeftPaddle, 'position', paddlePos );
        elseif( y > 400 )
            paddlePos = get( hLeftPaddle, 'position' ); 
            paddlePos(1,2) = 400 - 50; 
            set( hLeftPaddle, 'position', paddlePos ); 
        elseif( y < 100 )
            paddlePos = get( hLeftPaddle, 'position' ); 
            paddlePos(1,2) = 100 - 50; 
            set( hLeftPaddle, 'position', paddlePos );
        end
        
    end

    function CheckForScore()
        
       pos = get( hBall, 'position' );
       xpos = pos(1,1);
       ypos = pos(1,2);
       
       if ( xpos < 5 )
           set( hBallImage, 'visible', 'off' )
           rightScore = rightScore + 1;
           set ( hRightScoreText, 'string', num2str( rightScore ) )
           pause( .5 )
           ResetBall()
       elseif ( xpos + 10 > 695 )
           set( hBallImage, 'visible', 'off' )
           leftScore = leftScore + 1;
           set ( hLeftScoreText, 'string', num2str( leftScore ) )
           pause( .5 )
           ResetBall()
       end
       
    end
        
    function ResetBall
        
        pos = get( hBall, 'position' );
        pos(1,1) = 345;
        pos(1,2) = 255 + floor( rand*100 ) - 50;
        set( hBall, 'position', pos )
        ballSpeed = 4;
        ballDirection =  ( (rand(1) < 0.5) * 180 ) ...          % 0 or 180
                       + ( 45 + (rand(1) < 0.5) * -90 ) ...     % + 45 or - 45
                       + ( floor( rand * 40 ) - 20 );           % + -20 to 20
        set( hBallImage, 'visible', 'on' )
        pause(1)
        
    end
    



    function MoveObject( hInstance, speed, direction )

        p = get( hInstance, 'position' );

        x = p( 1, 1 );
        y = p( 1, 2 );
        
        x = x + cosd( direction ) * speed;
        y = y + sind( direction ) * speed;

        p( 1, 1 ) = x;
        p( 1, 2 ) = y;

        set( hInstance, 'position', p )

    end

    function SetObjectPosition( hObject, x, y )
       
       pos = get( hObject, 'position' );
       pos(1,1) = x;
       pos(1,2) = y;
       set( hObject, 'position', pos )
        
    end

    function a = NormalizeAngle( angle )
        
        while angle > 360
            angle = angle - 360;
        end
        
        while angle < 0
            angle = angle + 360;
        end
        a = angle;

    end

    function QuitButton_CallBack( hObject, eventData )
        playing = false;
    end

    function StartButton_CallBack( hObject, eventData )
        set( hObject, 'visible', 'off' );
        set( hLeftPaddleImage, 'visible', 'on' )
        set( hRightPaddleImage, 'visible', 'on' )
        ResetBall();
    end

end