/* This is an extensive demo application. It shows the use of
   a form in combination with a dynamic changing window of the
   application. Note that the special object EVENT is used
   to catch redraw events for the application window.
   The demo also shows the use of a subwindow.
*/

#include <stdlib.h>
#include "forms.h"

/* The cube definition */
float v0[3] = {0.0, 0.0, 0.0};
float v1[3] = {1.0, 0.0, 0.0};
float v2[3] = {1.0, 1.0, 0.0};
float v3[3] = {0.0, 1.0, 0.0};
float v4[3] = {0.0, 0.0, 1.0};
float v5[3] = {1.0, 0.0, 1.0};
float v6[3] = {1.0, 1.0, 1.0};
float v7[3] = {0.0, 1.0, 1.0};

void drawcube(int wire)
/* Draw a colored cube */
{
    if (wire) bgnclosedline(); else bgnpolygon();
      cpack(0xff0000); v3f(v0); v3f(v1); v3f(v2); v3f(v3);
    if (wire) endclosedline(); else endpolygon();
    if (wire) bgnclosedline(); else bgnpolygon();
      cpack(0xffff00); v3f(v4); v3f(v5); v3f(v6); v3f(v7);
    if (wire) endclosedline(); else endpolygon();
    if (wire) bgnclosedline(); else bgnpolygon();
      cpack(0xff00ff); v3f(v0); v3f(v1); v3f(v5); v3f(v4);
    if (wire) endclosedline(); else endpolygon();
    if (wire) bgnclosedline(); else bgnpolygon();
      cpack(0x00ffff); v3f(v2); v3f(v3); v3f(v7); v3f(v6);
    if (wire) endclosedline(); else endpolygon();
    if (wire) bgnclosedline(); else bgnpolygon();
      cpack(0x00ff00); v3f(v0); v3f(v4); v3f(v7); v3f(v3);
    if (wire) endclosedline(); else endpolygon();
    if (wire) bgnclosedline(); else bgnpolygon();
      cpack(0x0000ff); v3f(v1); v3f(v2); v3f(v6); v3f(v5);
    if (wire) endclosedline(); else endpolygon();
}

float lasttime = 0.0;

void redraw(int wire,float size,float speed)
/* redraw the window */
{
  lasttime = lasttime+speed;
  zclear();
  cpack(0);
  clear();
  pushmatrix();
  rot(lasttime*1.6,'Z'); rot(lasttime*4.2,'X'); rot(lasttime*2.3,'Y');
  translate(-1.0,1.2,-1.5);
  scale(size,size,size);
  drawcube(wire);
  popmatrix();
  swapbuffers();
}

FL_FORM *form;
FL_OBJECT *speed, *size, *button, *wire, *flat;

void openwindow()
/* Opens my own window */
{
  prefposition(form->x+24, form->x+365, form->y+24, form->y+365);
  noborder();
  winopen("Cube");
  doublebuffer();
  RGBmode();
  gconfig();
  perspective(500,1.0,1.0,40.0);
  lookat(0.0,0.0,10.0,0.0,0.0,0.0,3600);
  zbuffer(1);
  fl_qdevice(ESCKEY);
  fl_qdevice(ENDKEY);
}

void makeform()
{
  FL_OBJECT *obj;
  form = fl_bgn_form(FL_NO_BOX,510.0,390.0);
  obj = fl_add_box(FL_UP_BOX,0.0,0.0,510.0,390.0,"");
  obj = fl_add_box(FL_DOWN_BOX,20.0,20.0,350.0,350.0,"");
  speed = obj = fl_add_slider(FL_VERT_SLIDER,390.0,80.0,40.0,220.0,"Speed");
  size = obj = fl_add_slider(FL_VERT_SLIDER,450.0,80.0,40.0,220.0,"Size");
  wire = obj = fl_add_lightbutton(FL_RADIO_BUTTON,390.0,340.0,100.0,30.0,"Wire");
  flat = obj = fl_add_lightbutton(FL_RADIO_BUTTON,390.0,310.0,100.0,30.0,"Flat");
  button = obj = fl_add_button(FL_NORMAL_BUTTON,390.0,20.0,100.0,30.0,"Exit");
  fl_end_form();
}

int
main(int argc, char *argv[])
{
  FL_OBJECT *obj;
  long dev;
  short val;
  fl_initialize(argv[0], "FormDemo", 0, 0 ,&argc, argv);
  makeform();
  fl_set_slider_bounds(speed,0.0,4.0);
  fl_set_slider_value(speed,1.0);
  fl_set_slider_bounds(size,0.01,4.0);
  fl_set_slider_value(size,1.0);
  fl_set_button(flat,1);
  fl_show_form(form,FL_PLACE_CENTER,FL_NOBORDER,NULL);
  openwindow();
  while (1)
  {
    redraw(fl_get_button(wire),fl_get_slider_value(size),
		fl_get_slider_value(speed));
    obj = fl_check_forms();
    if (obj == button) exit(0);
    if (fl_qtest())
    {
      dev = fl_qread(&val);
      if (dev == ESCKEY || dev == ENDKEY) exit(0);
      else if (dev == REDRAW) reshapeviewport();
    }
  }
  return 0;
}
