//=======================================================================
//@V@:Note: This file generated by vgen V1.04 (10:59:00 22 Jun 1998).
//	bnccnv.cpp:	Source for bncOGLCanvasPane class
//=======================================================================
/*
 * Bouncing ball demo.
 *
 * This program is in the public domain
 *
 * Brian Paul
 */
// Conversion to V by Bruce E. Wampler

#include "bnccnv.h"
#include <math.h>
#include <stdlib.h>
#define COS(X)   cos( (X) * 3.14159/180.0 )
#define SIN(X)   sin( (X) * 3.14159/180.0 )

#define RED 1
#define WHITE 2
#define CYAN 3

GLuint Ball;
GLenum Mode;
GLfloat Zrot = 0.0, Zstep = 6.0;
GLfloat Xpos = 0.0, Ypos = 1.0;
GLfloat Xvel = 0.2, Yvel = 0.0;
GLfloat Xmin = -4.0, Xmax = 4.0;
GLfloat Ymin = -3.8, Ymax = 4.0;
GLfloat G = -0.1;

static GLuint 
make_ball(void)
{
  GLuint list;
  GLfloat a, b;
  GLfloat da = 18.0, db = 18.0;
  GLfloat radius = 1.0;
  GLuint color;
  GLfloat x, y, z;

  list = glGenLists(1);

  glNewList(list, GL_COMPILE);

  color = 0;
  for (a = -90.0; a + da <= 90.0; a += da) {

    glBegin(GL_QUAD_STRIP);
    for (b = 0.0; b <= 360.0; b += db) {

      if (color) {
	glIndexi(RED);
      } else {
	glIndexi(WHITE);
      }

      x = COS(b) * COS(a);
      y = SIN(b) * COS(a);
      z = SIN(a);
      glVertex3f(x, y, z);

      x = radius * COS(b) * COS(a + da);
      y = radius * SIN(b) * COS(a + da);
      z = radius * SIN(a + da);
      glVertex3f(x, y, z);

      color = 1 - color;
    }
    glEnd();

  }

  glEndList();

  return list;
}

static void 
reshape(int width, int height)
{
  glViewport(0, 0, (GLint) width, (GLint) height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-6.0, 6.0, -6.0, 6.0, -6.0, 6.0);
  glMatrixMode(GL_MODELVIEW);
}

static void 
draw(void)
{
  GLint i;

  glClear(GL_COLOR_BUFFER_BIT);

  glIndexi(CYAN);
  glBegin(GL_LINES);
  for (i = -5; i <= 5; i++) {
    glVertex2i(i, -5);
    glVertex2i(i, 5);
  }
  for (i = -5; i <= 5; i++) {
    glVertex2i(-5, i);
    glVertex2i(5, i);
  }
  for (i = -5; i <= 5; i++) {
    glVertex2i(i, -5);
    glVertex2f(i * 1.15, -5.9);
  }
  glVertex2f(-5.3, -5.35);
  glVertex2f(5.3, -5.35);
  glVertex2f(-5.75, -5.9);
  glVertex2f(5.75, -5.9);
  glEnd();

  glPushMatrix();
  glTranslatef(Xpos, Ypos, 0.0);
  glScalef(2.0, 2.0, 2.0);
  glRotatef(8.0, 0.0, 0.0, 1.0);
  glRotatef(90.0, 1.0, 0.0, 0.0);
  glRotatef(Zrot, 0.0, 0.0, 1.0);

  glCallList(Ball);

  glPopMatrix();

  glFlush();
}

static void 
idle(void)
{
  static float vel0 = -100.0;

  Zrot += Zstep;

  Xpos += Xvel;
  if (Xpos >= Xmax) {
    Xpos = Xmax;
    Xvel = -Xvel;
    Zstep = -Zstep;
  }
  if (Xpos <= Xmin) {
    Xpos = Xmin;
    Xvel = -Xvel;
    Zstep = -Zstep;
  }
  Ypos += Yvel;
  Yvel += G;
  if (Ypos < Ymin) {
    Ypos = Ymin;
    if (vel0 == -100.0)
      vel0 = fabs(Yvel);
    Yvel = vel0;
  }
}


//===================>>> bncOGLCanvasPane::bncOGLCanvasPane <<<====================
  bncOGLCanvasPane::bncOGLCanvasPane(unsigned int vGLmode, PaneType pt)
  {
    initDone = 0;
  }

//===================>>> bncOGLCanvasPane::~bncOGLCanvasPane <<<====================
  bncOGLCanvasPane::~bncOGLCanvasPane()
  {
  }

//======================>>> bncOGLCanvasPane::TimerAnimate <<<========================
  void bncOGLCanvasPane::TimerAnimate(void)
  {
    // **** Called by CmdWindow AuxTimer for animation.
    idle();
    vglMakeCurrent();  // Typically done here
    draw();
    vglFlush();  // After you draw, typically flush
    

  }
//======================>>> bncOGLCanvasPane::graphicsInit <<<========================
  void bncOGLCanvasPane::graphicsInit(void)
  {
    vBaseGLCanvasPane::graphicsInit();	// Always call the superclass first!

    // **** Your OpenGL initialization code goes here!
  Ball = make_ball();
  glCullFace(GL_BACK);
  glEnable(GL_CULL_FACE);
  glDisable(GL_DITHER);
  glShadeModel(GL_FLAT);
  reshape(300,300);


    initDone = 1;
  }
//======================>>> bncOGLCanvasPane::HPage <<<========================
  void bncOGLCanvasPane::HPage(int shown, int top)
  {
    vBaseGLCanvasPane::HPage(shown, top);
  }

//======================>>> bncOGLCanvasPane::VPage <<<========================
  void bncOGLCanvasPane::VPage(int shown, int top)
  {
    vBaseGLCanvasPane::VPage(shown, top);
  }

//=======================>>> bncOGLCanvasPane::HScroll <<<======================
  void bncOGLCanvasPane::HScroll(int step)
  {
    vBaseGLCanvasPane::HScroll(step);
  }

//======================>>> bncOGLCanvasPane::VScroll <<<======================
  void bncOGLCanvasPane::VScroll(int step)
  {
    vBaseGLCanvasPane::VScroll(step);
  }

//======================>>> bncOGLCanvasPane::MouseDown <<<======================
  void bncOGLCanvasPane::MouseDown(int X, int Y, int button)
  {
    vBaseGLCanvasPane::MouseDown(X,Y,button);
  }

//========================>>> bncOGLCanvasPane::MouseUp <<<======================
  void bncOGLCanvasPane::MouseUp(int X, int Y, int button)
  {
    vBaseGLCanvasPane::MouseUp(X,Y,button);
  }

//======================>>> bncCanvasPane::MouseMove <<<======================
  void bncOGLCanvasPane::MouseMove(int x, int y, int button)
  {
    vBaseGLCanvasPane::MouseMove(x,y,button);
  }

//=========================>>> bncOGLCanvasPane::Redraw <<<======================
  void bncOGLCanvasPane::Redraw(int x, int y, int w, int h)
  {
    static int inRedraw = 0;

    if (inRedraw || !initDone)  // Don't draw until initialized
        return;

    inRedraw = 1;  // Don't allow recursive redraws.

    vglMakeCurrent();  // Typically done here

    // *** Your drawing code typically goes here. You may
    // insert it here, or just call a drawing routine.
    draw();

    vglFlush();  // After you draw, typically flush

    inRedraw = 0;  // Out of Redraw

  }

//======================>>> bncOGLCanvasPane::Resize <<<======================
  void bncOGLCanvasPane::Resize(int w, int h)
  {
    vBaseGLCanvasPane::Resize(w,h);
    reshape(w,h);
  }

