/* w5gl.c    inputting data from graphics window  */

#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include "text_in.h"

/* menu item numbers */
#define NUMBER   1
#define VIEW     2
#define NAME     3
#define APPLY    4
#define QUIT     5

/* data declarations for popup window */
static char entered_text[100];
static char popup_msg[100];
static int popup_win;
static int main_win;
static int in_popup = 0;
static int popup_created = 0;
static int  debug = 0; /* set to  1  for debug */

/* standard application data declarations go here */
static int  winWidth, winHeight;

/* function prototypes */
/* standard application */
static void display(void);
static void mouseButton(int button, int state, int x, int y);
static void myReshape(int w, int h);
static void keyboard(unsigned char key, int x, int y);
static void menu_item(int item);

/* functions for popup window to get user text */
static void popup(char title[], void (*callback)(char user_text[]));
static void display_popup(void);
static void keyboard_popup(unsigned char key, int x, int y);
static void end_popup(char user_text[]);
static void (*popup_return)(char user_text[]);

/* callback functions, responding to user actions */
static void DoNumber(char user_text[]);
static void DoView(char user_text[]);
static void DoName(char user_text[]);
static void DoApply();
static void DoQuit();


static void display(void)
{
  int len, i;
  char msg[] = "right click for menu";

  glutSetWindow(main_win);
  glClearColor(1.0, 1.0, 1.0, 1.0);
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  /* view transform */
  glLoadIdentity();

  /* for your application */


  glPushMatrix();
    glLoadIdentity();
    glColor3f(1.0, 0.0, 0.0);
    glRasterPos2f(0.0, 0.0);
    len = strlen(msg);
    for (i = 0; i<len; i++)
      glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, msg[i]);
  glPopMatrix();

  glFlush();
  glutSwapBuffers();
}

static void mouseButton(int button, int state, int x, int y)
{
  /* for your application, except right button is for menu */
  glutPostRedisplay();
} /* end mouseButton */

static void myReshape(int w, int h)
{
  glViewport(0, 0, w, h);
  winWidth = w;
  winHeight = h;
  /* for your application, other than default perspective */
} /* end myReshape */

static void keyboard(unsigned char key, int x, int y)
{
  if(in_popup) return; /* be safe when using popup */
  switch(key)
  {
    case 'a':    /* for your application  */
      break;
    default:
      break;
  }
  glutPostRedisplay();
} /* end keyboard */

static void popup(char title[], void (*callback)(char user_text[]))
{
  if(debug) printf("popup, entered\n");
  popup_return = callback; /* save for 'end_popup' */
  if(popup_created) /* destroy and re-create did not work */
  {
    glutSetWindow(popup_win);
    glutShowWindow();
  }
  else
  {
    glutInitWindowSize(180, 60);
    glutInitWindowPosition(150,150);
    popup_win = glutCreateWindow("Data entry");
    glutDisplayFunc(display_popup);
    glutKeyboardFunc(keyboard_popup);
  }
  strcpy(popup_msg, title);
  in_popup = 1;
  clear_text(entered_text);
  get_text(entered_text, end_popup);
  if(debug) printf("popup, about to call glutPostRedisplay\n"); 
  glutPostRedisplay();
  if(debug) printf("popup, exiting\n");
}

static void end_popup(char user_text[])
{
  if(!in_popup) return; /* be parinoid safe */
  in_popup = 0;
  if(debug) printf("end_popup, user text=%s\n", user_text);
  
  /* glutDestroyWindow(popup_win); did not work! */
  glutSetWindow(popup_win);
  glutHideWindow(); /* created once, then show and hide */
  if(debug) printf("end_popup, about to call glutPostRedisplay\n");
  glutPostRedisplay();
  popup_return(user_text); /* call application callback function */
  if(debug) printf("end_popup, exiting\n");
}

static void display_popup(void)
{
  int len, i;
  GLfloat x=-0.8;
  GLfloat y=-0.1;
  GLfloat w=1.6;
  GLfloat h=0.6;

  if(debug) printf("display_popup, entering\n");
  if(!in_popup) return;
  
  glutSetWindow(popup_win);
  glClearColor(1.0, 1.0, 1.0, 1.0);
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();
  glColor3f(0.0, 0.0, 0.0);
  glPushMatrix();
    glLoadIdentity();
    glBegin(GL_LINE_LOOP);
      glVertex2f(x,   y);
      glVertex2f(x+w, y);
      glVertex2f(x+w, y+h);
      glVertex2f(x,   y+h);
    glEnd();
    glLoadIdentity();
    show_text(x+0.1, y+0.15, entered_text);
    
    glRasterPos2f(-0.7, -0.6);
    len = strlen(popup_msg);
    for (i = 0; i<len; i++)
      glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, popup_msg[i]);
  glPopMatrix();
  

  glFlush();
  glutSwapBuffers();
}

static void keyboard_popup(unsigned char key, int x, int y)
{
  if(debug) printf("keyboard_popup, entering\n");
  if(!in_popup) return;
  if(add_text(key)) return; /* activated by call to get_text() */
                            /* this is getting the text */
  glutPostRedisplay();
} /* end keyboard */

static void menu_item(int item)
{
  if(debug) printf("menu item item=%d\n", item);
  switch(item)
  {
    case NUMBER:
      if(debug) printf("Number\n"); 
      popup("Enter an integer", DoNumber);
      break;
    case VIEW:
      if(debug) printf("View Angle\n");
      popup("Enter roll, pitch and yaw", DoView);
      break;
    case NAME:
      if(debug) printf("Name\n");
      popup("Enter a file name", DoName);
      break;
    case APPLY:
      if(debug) printf("Apply\n");
      DoApply();
      break;
    case QUIT:
      if(debug) printf("Quit\n");
      DoQuit();
      break;
    default:
      break;
  }
  glutPostRedisplay();
} /* end menu_item */

int main(int argc, char *argv[])
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(300, 300);
  glutInitWindowPosition(100,100);
  main_win = glutCreateWindow(argv[0]);
  glutReshapeFunc(myReshape);
  glutDisplayFunc(display);
  glutMouseFunc(mouseButton);
  glutKeyboardFunc(keyboard);
  glutCreateMenu(menu_item);
    glutAddMenuEntry("Number", NUMBER);
    glutAddMenuEntry("View Angle", VIEW);
    glutAddMenuEntry("Name", NAME);
    glutAddMenuEntry("Apply", APPLY);
    glutAddMenuEntry("Quit", QUIT);
  glutAttachMenu(GLUT_RIGHT_BUTTON);
  glutMainLoop();
  return 0;
} /* end main of  w5gl.c */

/* callback functions, in response to user action */

static void DoNumber(char user_text[])
{
  int n;

  printf("user entered=%s \n", user_text);
  sscanf(user_text,"%d", &n);
         /* error check and tell to enter again */
  printf("converted to number %d \n", n);
} /* end DoNumber */

static void DoView(char user_text[])
{
  float view_pitch, view_roll, view_yaw;
  
  printf("user view angles=%s \n", user_text);
  sscanf(user_text,"%f %f %f", &view_pitch, &view_roll, &view_yaw );
          /* error check and tell to enter again */
  printf("view roll, pitch, yaw %f %f %f \n",
          view_pitch, view_roll, view_yaw );
} /* end DoView */

static void DoName(char user_text[])
{
  printf("user entered name =%s \n", user_text);
  /* do something here or save the name somewhere */
} /* end DoName */

static void DoApply()
{
  printf("DoApply \n");
  /* really do something with inputs */
}

static void  DoQuit()
{
  exit(0);
}

