/*----------------------------------------------------------------------*\
| Ball Class; August 2004; CS128 Labs                                    |
| Modified by Jim Rogers and Colin Kern from original file.              |
| Original File:                                                         |
| zBall Class; April 2004; CS256 Final Project                           |
| Colin Copeland (copelco@earlham.edu)                                   |
\------------------------------------------------------------------------/
 | 
 |           FILE: ball.h
 | CLASS PROVIDED: Ball (part of the namespace CS128)
 | 
 | ----------------------------------------------------------------/
 |
 | CONSTRUCTORS for the Ball class:
 |
 |     Ball( unsigned int size = 5,
 |           unsigned int patternType = 0,
 |           unsigned int red = 0, 
 |           unsigned int green = 0, 
 |           unsigned int blue = 255,
 |           unsigned int patternRepeat = 3, 
 |           unsigned int incRed = 128,
 |           unsigned int incGreen = 0,
 |           unsigned int incBlue = 128,
 |           double spin = 0,
 |           double aspectRatio = 1,
 |           double xPos = 0, double yPos = 0,
 |           double xVel = 0, double vVel = 0 );
 |      
 |      Parameter ranges:
 |        size - No limit, since the size of the window is unknown.
 |        patternType - Given value modulo 2.  0 is solid, 1 is striped,
 |                  and 2 is sectored.
 |        red, green, blue - No limit
 |        patternRepeat - No limit
 |        incRed, incGreen, incBlue - Given value modulo 255.
 |        spin - No limit.
 |        xStretch, yStretch - Ranges 1 to 2, with 1 being normal and 2 being
 |                             half the diameter in that dimension.  Only the
 |                             decimal of the given value is looked at (4.56
 |                             would be 1.56, -124.25 would be 1.25, etc.).
 |        xPos, yPos - No limit, since the size of the window is unknown.
 |        xVel, yVel - No limit.
 |
 |      Postcondition: A new Ball has been created.
 | 
 | ----------------------------------------------------------------/
 |
 | MODIFICATION MEMBER FUNCTIONS for the Ball class:
 |
 |    void step( double speed = 1, int gravity = 0 )
 |      Postcondition: Ball advanced based on it's velocity vector.
 |
 |    void step_back( double speed = 1, int gravity = 0 )
 |      Postcondition: Ball advanced backwards based on it's vector.
 | 
 |    void step_increment( int gravity = 0 )
 |      Postcondition: Ball advanced based on vecloicty/100. 
 |
 |    void set_velocity( Vec& v )
 |      Postcondition: velocity now equals v.
 |   
 |    void set_center( Point& c )
 |      Postcondition: center now equals c.
 |
 |    void move_y(double delta)
 |      Precondition: delta is the desired displacement in the y direction.
 |      Postcondition: The ball has been moved delta in the y direction.
 |
 |    void move_x(double delta)
 |      Precondition: delta is the desired displacement in the x direction.
 |      Postcondition: The ball has been moved delta in the x direction.
 |
 |    void bounce_y(double delta)
 |      Precondition: delta is the distance the ball has moved past the wall.
 |      Postcondition: The ball has bounced off the wall.
 |
 |    void bounce_x(double delta)
 |      Precondition: delta is the distance the ball has moved past the wall.
 |      Postcondition: The ball has bounced off the wall.
 |
 |    void scale_dx(double s)
 |      Precondition: s is a multiplier for the x velocity.
 |      Postcondition: The x velocity has been scaled by s.
 |
 |    void scale_dy(double s)
 |      Precondition: s is a multiplier for the y velocity.
 |      Postcondition: The y velocity has been scaled by s.
 |
 |
 | ----------------------------------------------------------------/
 |
 | CONSTANT MEMBER FUNCTIONS for the Ball class:
 |
 |    void erase( Window& ) const
 |    void erase( WindowWrapper& ) const
 |      Postcondition: The ball has been erased (drawn black).
 |
 |    void display( Window& ) const
 |    void display( WindowWrapper& ) const
 |      Postcondition: The ball has been drawn.
 |
 |    double x( ) const
 |      Postcondition: Return value is center's x.
 |  
 |    double y( ) const
 |      Postcondition: Return value is center's y.
 |
 |    vec get_velocity( ) const
 |      Postcondition: Return value is the current velocity.
 |
 |    point get_center( ) const
 |      Postcondition: Return value is the ball's center.
 |
 |    int get_radius( ) const
 |      Postcondition: Return value is the ball's radius.
 |
 |    double left_side( ) const
 |      Postcondition: Return value is the x value of the left side.
 |
 |    double right_side( ) const
 |      Postcondition: Return value is the x value of the right side.
 |
 |    double top( ) const
 |      Postcondition: Return value is the y value of the top.
 |
 |    double bottom( ) const
 |      Postcondition: Return value is the y value of the bottom.
 |
 |    int get_pattern( ) const
 |      Postcondition: Returns the pattern type.
 |
 |    double get_aspect_ratio( ) const
 |      Postcondition: Returns the aspect ratio.
 |
 | -----------------------------------------------------------/
 |
 | NON-MEMBER FUNCTIONS for the Ball class
 |
 | bool balls_collided( Ball&, Ball& )
 |   Postcondition: Returns true of the two balls have collided.
 |
 | void handle_collision( Ball&, Ball&, double speed )
 |   Postcondition: The balls velocities and positions have been changed.
 | 
 \*---------------------------------------------------------------------*/

#ifndef CS128_BALL
#define CS128_BALL

#include "point.h"
#include "vec.h"
#include "windowwrapper.h"
#include "CarnegieMellonGraphics.h"

namespace CS128
{
  class Ball
    {
    public:
      //TYPEDEFs
      typedef double component;
      enum {SOLID, CHORD, WEDGE};
      
      Ball( unsigned int size = 5,
            unsigned int patternType = 0,
            unsigned int red = 0, 
            unsigned int green = 0, 
            unsigned int blue = 255,
            unsigned int patternRepeat = 3, 
            unsigned int incRed = 128, 
            unsigned int incGreen = 0, 
            unsigned int incBlue = 128,
            double spin = 0,
	    double aspectRatio = 1,
            double xPos = 0, double yPos = 0,
            double xVel = 0, double vVel = 0 );
             
      
      //MODIFICATION MEMBER FUNCTIONS
      void step( double speed = 1, int gravity = 0 );
      void step_back( double speed = 1, int gravity = 0 );
      void step_increment( int gravity = 0 );
      void set_velocity( Vec& v );
      void set_center( Point& c );
      void move_y(double delta);
      void move_x(double delta);
      void bounce_y(double delta);
      void bounce_x(double delta);
      void scale_dx(double s);
      void scale_dy(double s);
     
      //CONSTANT MEMBER FUNCTIONS
      void erase( Window& ) const;
      void erase( WindowWrapper& ) const;
      void display( Window& ) const;
      void display( WindowWrapper& ) const;
      double x( ) const;
      double y( ) const;
      Vec get_velocity( ) const;
      Point get_center( ) const;
      int get_radius( ) const;
      Color get_color( ) const;
      double left_side( ) const;
      double right_side( ) const;
      double top( ) const;
      double bottom( ) const;
      int get_pattern( ) const;
      double get_aspect_ratio( ) const;
      
    private:
      int radius;           // radius of ball
      Color color;          // color of ball
      unsigned int r_shift; // Color increment of stripes/wedges
      unsigned int g_shift; // ''
      unsigned int b_shift; // ''
      Point center;         // center of ball
      Vec velocity;         // delta x and y
      Vec increment;        // small delta x and y
      double rot;           // current rotational position
      double omega;         // current rotational velocity
      int pattern;          // The pattern on the ball
      int pat_num;          // Number of stripes or wedges
      double ratio;	    // The aspect ratio of the ball
    };    

  bool balls_collided( Ball& b1, Ball& b2 );
  void handle_collision( Ball& b1, Ball& b2, double speed = 1 );
};

#endif
