/****************************************************************
 ***                                                          ***
 ***     draw.c                                               ***
 ***          simple gl drawing program                       ***
 ***                                                          ***
 ***************************************************************/
#include "EZ.h"

extern void exit();
static void canvas_event_handle();
static void  InitializeCanvas();
static void clean_exit();

/*************************************************************************/
static char *colors[] = {
  "white",
  "dark red",
  "red",
  "green",
  "blue",
  "yellow",
  "magenta",
  "cyan",
};

static char *objects[] =
{
  "polygon",
  "line",
  "text",
};
#define POLYGON  0
#define LINE     1
#define TEXT     2

static char *fonts[] = {
  "fixed",
  "9x15",
 "-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*",
 "-*-Courier-Medium-R-Normal--*-120-*-*-*-*-*-*",
 "-Adobe-Helvetica-Bold-R-Normal--*-120-*-*-*-*-*-*",
 "-Adobe-Times-Bold-I-Normal--*-120-*-*-*-*-*-*",
 "-Adobe-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*",
 "-*-Courier-Medium-R-Normal--*-180-*-*-*-*-*-*",
 "-Adobe-Helvetica-Bold-R-Normal--*-180-*-*-*-*-*-*",
 "-Adobe-Times-Bold-I-Normal--*-180-*-*-*-*-*-*",
 "-Adobe-Helvetica-Medium-R-Normal--*-240-*-*-*-*-*-*",
 "-*-Courier-Medium-R-Normal--*-240-*-*-*-*-*-*",
 "-Adobe-Helvetica-Bold-R-Normal--*-240-*-*-*-*-*-*",
 "-Adobe-Times-Bold-I-Normal--*-240-*-*-*-*-*-*",
};
#define NFONTS 14

/*******************************************************************/

#define CLEAR   1
#define SAVEPPM 2
#define SAVEPS  3

/*******************************************************************/

static EZ_Widget *canvas;
static EZ_Widget *entry_frame = NULL;
static EZ_Widget *entry_framePS = NULL;
static int  current_color = EZ_RED, current_object = LINE, current_font = 3;
/*******************************************************************/

static void colorMCallback(menu, d)   /* set current color index */
     EZ_Widget *menu; void *d;
{
  current_color  = EZ_GetWidgetReturnData(menu);
}
/**************************************************************************/

static void objMCallback(menu, d)    /* set current object       */
     EZ_Widget *menu; void *d;
{
  current_object  = EZ_GetWidgetReturnData(menu);
}
/**************************************************************************/     

static void fontMCallback(menu,d)   /* set current font         */
     EZ_Widget *menu; void *d;
{
  current_font = EZ_GetWidgetReturnData(menu);
}
/**************************************************************************/

static void entryCallback(widget,d)
     EZ_Widget *widget; void *d;
{
  char *fname = EZ_GetEntryString(widget);
  EZ_HideWidget(entry_frame);
  EZ_Save3DCanvas2PPMImage(canvas,fname);
}

static void entryCallbackPS(widget,d)
     EZ_Widget *widget; void *d;
{
  char *fname = EZ_GetEntryString(widget);
  EZ_HideWidget(entry_framePS);
/*  EZ_Save3DCanvas2PS(canvas,fname);*/
  EZ_Save3DCanvas2PSA(canvas,
		      EZ_LANDSCAPE,     /* LANDSCAPE or PORTRAIT */
		      300,             /* printer resolution    */
		      1.0,             /* control scrn pixel <-> printer pixel conversion */
		      fname);
}

/**************************************************************************/

static void miscMCallback(menu,d)
     EZ_Widget *menu; void *d;
{
  int i = EZ_GetWidgetReturnData(menu);

  if(i == CLEAR)
    {
      EZ_Index(EZ_GRAY);
      EZ_Clear(EZ_COLOR_BUFFER_BIT);
    }
  else if(i == SAVEPPM)
    {
      if(entry_frame == (EZ_Widget *)NULL)
	{
	  EZ_Widget *label, *entry;
	  entry_frame = EZ_CreateFrame(NULL, NULL);
	  EZ_ConfigureWidget(entry_frame, EZ_STACKING, EZ_VERTICAL, 0);
	  label = EZ_CreateLabel(entry_frame, "Please Enter a file name");
	  entry = EZ_CreateEntry(entry_frame, "test.ppm");
	  EZ_SetWidgetCallBack(entry, entryCallback, NULL);
	}
      EZ_DisplayWidget(entry_frame);
    }
  else if(i == SAVEPS)
    {
      if(entry_framePS == (EZ_Widget *)NULL)
	{
	  EZ_Widget *label, *entry;
	  entry_framePS = EZ_CreateFrame(NULL, NULL);
	  EZ_ConfigureWidget(entry_framePS, EZ_STACKING, EZ_VERTICAL, 0);
	  label = EZ_CreateLabel(entry_framePS, "Please Enter a file name");
	  entry = EZ_CreateEntry(entry_framePS, "test.ps");
	  EZ_SetWidgetCallBack(entry, entryCallbackPS, NULL);
	}
      EZ_DisplayWidget(entry_framePS);
    }
}
/**************************************************************************/
int cont = 1;

main(ac, av)
     int ac; char **av;
{
  EZ_Widget *frame1, *frame2, *tmp;
  EZ_Widget *colorM, *objM, *fontM, *miscM;
  int       i;
  char      str[160];

  /*plumber_init(av[0]);*/
  EZ_Initialize(ac,av,0);

  /* Create menus.  */
  colorM = EZ_CreatePopupMenu("Colors");
  EZ_SetWidgetCallBack(colorM, colorMCallback, NULL);
  for(i = 0; i < 8; i++)
    {
      tmp = EZ_CreateMenuRadioButton(colorM, colors[i], -1, 0, i + EZ_WHITE, i + EZ_WHITE);
      sprintf(str, "Ctrl-%c", *colors[i]);
      EZ_ConfigureWidget(tmp, EZ_SHORTCUT_KEY, str,0);
    }
  EZ_SetRadioButtonGroupVariableValue(tmp, current_color);
  
  objM = EZ_CreatePopupMenu("Objects");
  EZ_SetWidgetCallBack(objM, objMCallback, NULL);
  for(i = 0; i < 3; i++)
    {
      tmp = EZ_CreateMenuRadioButton(objM, objects[i], 0, 1, i, i);
      sprintf(str, "Meta-%c", *objects[i]);
      EZ_ConfigureWidget(tmp, EZ_SHORTCUT_KEY, str,0);
    }
  EZ_SetRadioButtonGroupVariableValue(tmp, current_object);

  fontM = EZ_CreatePopupMenu("Font");
  EZ_SetWidgetCallBack(fontM, fontMCallback, NULL);
  for(i = 0; i < NFONTS; i++)
    {
      tmp = EZ_CreateMenuRadioButton(fontM, fonts[i], -1,  2, i, i);
      EZ_ConfigureWidget(tmp, EZ_TEXT_LINE_LENGTH, 80, 0);
    }
  EZ_SetRadioButtonGroupVariableValue(tmp, current_font);

  miscM = EZ_CreatePopupMenu("Misc");
  EZ_SetWidgetCallBack(miscM, miscMCallback, NULL);
  (void) EZ_CreateMenuNormalButton(miscM, "clear", 0,  CLEAR);
  (void) EZ_CreateMenuNormalButton(miscM, "save to ppm", 0, SAVEPPM);
  (void) EZ_CreateMenuNormalButton(miscM, "save to ps",  1, SAVEPS);
  tmp = EZ_CreateMenuNormalButton(miscM, "Exit", 0, 10);
  EZ_SetWidgetCallBack(tmp, clean_exit, NULL);
  
  /*
   *  make colorM a popup menu.
   */
  EZ_TiePopupMenu(colorM, Button3, 0);

  /*
   * the toplevel frame
   */
  frame1 = EZ_CreateFrame(NULL, NULL);
  EZ_ConfigureWidget(frame1, EZ_STACKING,EZ_VERTICAL_TOP, 
		     EZ_FILL_MODE, EZ_FILL_BOTH,
		     EZ_HEIGHT, 300, EZ_WIDTH, 300,
		     EZ_PADY, 0, EZ_PADX, 0, 0);

  /*
   * create a frame and 5 menubuttons.
   */
  frame2 = EZ_CreateFrame(frame1, NULL);
  EZ_ConfigureWidget(frame2, EZ_EXPAND, True,
		     EZ_PADX, 0, EZ_PADY,0,
		     EZ_IPADY, 0, EZ_HEIGHT, 0, /* so it will not be stretched vertically */
		     EZ_BORDER_TYPE, EZ_BORDER_UP,
		     EZ_BORDER_WIDTH, 2,
		     EZ_STACKING, EZ_HORIZONTAL_LEFT,
		     0);
  tmp = EZ_CreateMenuButton(frame2, "Colors", 0);
  EZ_SetMenuButtonMenu(tmp, colorM);
  tmp = EZ_CreateMenuButton(frame2, "Objects", 0);
  EZ_SetMenuButtonMenu(tmp, objM);
  tmp = EZ_CreateMenuButton(frame2, "Fonts", 0);
  EZ_SetMenuButtonMenu(tmp, fontM);
  tmp = EZ_CreateMenuButton(frame2, "Misc", 0);
  EZ_SetMenuButtonMenu(tmp, miscM);

  /*
   * finally  the canvas
   */
  frame2 = EZ_CreateFrame(frame1, NULL);
  EZ_ConfigureWidget(frame2, EZ_FILL_MODE, EZ_FILL_BOTH, 0);
  canvas = EZ_Create3DCanvas(frame2);
  EZ_ConfigureWidget(canvas, 
		     EZ_BACKING_STORE, True,
		     EZ_RESERVE_MENU_BUTTON, False,
		     EZ_EVENT_HANDLE, canvas_event_handle, NULL, 0);
  
  EZ_DisplayWidget(frame1);
  InitializeCanvas(0);

  while(cont == 1) EZ_WaitAndServiceNextEvent();  
  EZ_DestroyWidget(frame1);
  EZ_DestroyWidget(colorM);
  EZ_DestroyWidget(objM); 
  EZ_DestroyWidget(fontM);
  EZ_DestroyWidget(miscM);
  EZ_Shutdown();
  /*plumber_shutdown();  */
}
/************************************************************************/
static void  InitializeCanvas(cnt)
     int cnt;
{
  int w, h;
  EZ_Get3DCanvasSize(canvas, &w, &h);
  EZ_LoadIdentity();
  EZ_Ortho2(0.0, (float)w, 0.0, (float)h);
  if(cnt == 0)
    {
      EZ_ColorMapMode();
      EZ_ClearIndex(EZ_GRAY);
      EZ_Clear(EZ_COLOR_BUFFER_BIT);
    }
}
/************************************************************************/
static short xbuffer[4096], ybuffer[4096];
static int count;

static void canvas_event_handle(widget, d, event, xev)
     EZ_Widget *widget; void *d;
     int       event;
     XEvent    *xev;
{
  int w, h;
  XEvent xevent;

  switch(event)
    {
    case EZ_REDRAW:
      InitializeCanvas(1);
      break;
    case EZ_RESIZE:
      InitializeCanvas(1);
      EZ_Index(EZ_GRAY);
      EZ_Clear(EZ_COLOR_BUFFER_BIT); 
      break;
    case EZ_LEFT_BUTTON_PRESS:
      {
	int    x1,y1,x2,y2;

	count = 0;
	EZ_Index(current_color);                 /* color */
	switch(current_object)
	  {
	  case LINE:
	  case POLYGON:
	    x1 = EZ_MouseX;
	    y1 = EZ_MouseY;
	    if(current_object == POLYGON) 
	      {
		xbuffer[count] = x1;
		ybuffer[count++] = y1;
	      }
	    EZ_Begin(EZ_LINE_STRIP);
	    EZ_Vertex2f((float)x1, (float)y1);
	    while(1)
	      {
		int device = EZ_GLNextEvent(canvas, &xevent);
		if(device == EZ_POINTER_MOTION)
		  {
		    x2 = EZ_MouseX;
		    y2 = EZ_MouseY;
		    EZ_Vertex2f((float)x2, (float)y2);
		    EZ_End();
		    EZ_Begin(EZ_LINE_STRIP);
		    EZ_Vertex2f((float)x2, (float)y2);
		    if(current_object == POLYGON && count < 1024) 
		      {
			xbuffer[count] = x2;
			ybuffer[count++] = y2;
		      }
		  }
		else if(device == EZ_LEFT_BUTTON_RELEASE)
		  {
		    x2 = EZ_MouseX;
		    y2 = EZ_MouseY;
		    EZ_Vertex2f((float)x2, (float)y2);
		    EZ_End();
		    if(current_object == POLYGON)
		      {
			int i;
			EZ_Begin(EZ_POLYGON);
			for(i = 0; i < count; i++)
			  EZ_Vertex2f( (float)xbuffer[i], (float)ybuffer[i]);
			EZ_End();
		      }
		    break;
		  }
	      }
	    break;
	  case TEXT:
	    {
	      char str[512];
	      
	      x1 = EZ_MouseX;
	      y1 = EZ_MouseY;
	      EZ_CMove2f((float)x1, (float)y1);
	      EZ_SetBitmapFont(fonts[current_font]);   /* font  */
	      while(1)
		{
		  int device = EZ_GLNextEvent(canvas, &xevent); 
		  if(device == EZ_LEFT_BUTTON_PRESS)
		    {
		      x1 = EZ_MouseX;
		      y1 = EZ_MouseY;
		      EZ_SetBitmapFont(fonts[current_font]);   /* font  */
		      EZ_CMove2f((float)x1, (float)y1);	    
		      count = 0;
		    }
		  else if(device == EZ_MIDDLE_BUTTON_PRESS ||
			  device == EZ_RIGHT_BUTTON_PRESS)
		    break;
		  
		  if(device == EZ_KEY_PRESS)
		    {
		      if(EZ_PressedKey == EZ_BACKSPACE_KEY && count > 0) 
			{
			  EZ_Index(EZ_GRAY);
			  EZ_DrawString(EZ_BITMAP_FONT, str);
			  EZ_Index(current_color);
			  str[(--count)] = '\0';
			  EZ_DrawString(EZ_BITMAP_FONT, str);
			}
		      else if(EZ_PressedKey == EZ_RETURN_KEY) 
			break;
		      else
			{
			  str[count++] = EZ_PressedKey;
			  str[count] = '\0';
			  EZ_DrawString(EZ_BITMAP_FONT, str);
			}
		    }
		}
	    }
	    break;
	  default:
	    break;
	  }
      }
      break;
    default:
      break;
    }
}
static void clean_exit(w,d) EZ_Widget *w, *d;
{
  cont = 0;
}

