/*****************************************************************
  launcher.cpp
  by Dave Pape
  4 March 2003

 This program demonstrates using random numbers for motion.
 It continually launches a set of balls from the center of the
 window.  The velocity vector for each ball is chosen randomly,
 giving them both a random speed and random direction.

*****************************************************************/
#include <unistd.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <dms/dms.h>

void drawEverything(void);
void key(unsigned char k, int x, int y);
void idle(void);
void launchBall(void);


#define NUM_BALLS 10
dms::Vector3 position[NUM_BALLS];
dms::Vector3 velocity[NUM_BALLS];

dms::OrthoCamera camera(-20, 20, -20, 20);
dms::QuadricObject ball;


int main(int argc, char *argv[])
    {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(512,512);
    glutCreateWindow(argv[0]);
    glutDisplayFunc(drawEverything);
    glutKeyboardFunc(key);
    glutIdleFunc(idle);
    glLineWidth(2);
    launchBall();
    glutMainLoop();
    return 0;
    }


void drawEverything(void)
    {
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    
    camera.apply();
    
    glColor3f(1.0, 0.9, 0.0);
    for (int i=0; i < NUM_BALLS; i++)
        {
        glPushMatrix();
        glTranslatef(position[i][0], position[i][1], position[i][2]);
        ball.draw();
        glPopMatrix();
        }

    glutSwapBuffers();
    }


/*************** CODE OF INTEREST ******************************/
/* Fire a ball.  This picks a random X & Y value for the ball's*/
/* velocity vector, in the range (-10,-10,0) to (10,10,0).     */
/* The static variable 'nextBall' keeps track of which ball to */
/* fire next; it is incremented modulo NUM_BALLS, so that we   */
/* will continue to cycle through all the balls in the array.  */
/*                                                             */
void launchBall(void)
    {
    static int nextBall = 0;
    position[nextBall].set(0,0,0);
    velocity[nextBall][0] = drand48()*20.0 - 10.0;
    velocity[nextBall][1] = drand48()*20.0 - 10.0;
    velocity[nextBall][2] = 0;
    nextBall = (nextBall+1) % NUM_BALLS;
    }


void key(unsigned char k, int x, int y)
    {
    if (k == 27)
        exit(0);
    }


void idle(void)
    {
    static float lastLaunch = 0;
    dms::beginFrame();
/*************** CODE OF INTEREST ******************************/
/* Fire a ball once every tenth of a second.  The function     */
/* keeps track of when it last fired a ball with the variable  */
/* 'lastLaunch' - the time value last time launchBall() was    */
/* called.  If the current time is more than .1 seconds since  */
/* the last launch, we fire another ball.                      */
/*                                                             */
    if (dms::currentTime() - lastLaunch > 0.1)
        {
        launchBall();
        lastLaunch = dms::currentTime();
        }
    for (int i=0; i < NUM_BALLS; i++)
        position[i] += velocity[i] * dms::deltaTime();
    glutPostRedisplay();
    }

