#include <X11/Xlib.h>
#include <Xm/XmAll.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <signal.h>
#include <gl.h>
#include <device.h>
#include "globals.h"
#include "states.h"
#include "util.h"
#include "link.h"
#include "render.h"
#include "event.h"
#include "lights.h"
#include "init.h"
#include "menu.h"
#include "geom.h"
#include "output.h"
#include "render_menu.h"
#include "geom_menu.h"

/* scherk variables */
int scherk_branches, scherk_storeys, scherk_mesh_tiles, scherk_tex_tiles, scherk_detail; 
int scherk_red, scherk_green, scherk_blue, scherk_select, scherk_save_mode;
float scherk_height, scherk_flange, scherk_azimuth, scherk_twist, scherk_warp, scherk_thickness, scherk_rim_bulge, scherk_scale;
char scherk_select_str[SCHERK_SELECT_SIZE+1][4] = {"f1", "f2", "r1", "r2", "r3", "r4", "all"};
char scherk_save_str[SCHERK_SAVE_SIZE+1][13] = {"Specs only", "PS boards", "UG slices", "3D UG file", ".STL B_rep", "PPHIGS_UNC", "abcdefghijkl", "PS slices", "SIF 4 SFF", "L-SIF_2D"};

/* scherk widgets */
Widget scherk_dialog_save, scherk_dialog_load_texture, ScherkTextureW, saveW;
Widget scherk_scroll_detail, scherk_scroll_storeys, scherk_scroll_height, scherk_scroll_flange;
Widget scherk_scroll_azimuth, scherk_scroll_twist, scherk_scroll_warp;
Widget scherk_scroll_thickness, scherk_scroll_scale;
Widget scherk_scroll_tex_tiles, scherk_scroll_rim_bulge, scherk_scroll_branches;
Widget scherk_scroll_mesh_tiles, scherk_scroll_save_mode;
Widget scherk_label_detail, scherk_label_storeys, scherk_label_height, scherk_label_flange;
Widget scherk_label_azimuth, scherk_label_twist, scherk_label_warp;
Widget scherk_label_thickness, scherk_label_scale;
Widget scherk_label_tex_tiles, scherk_label_rim_bulge, scherk_label_branches;
Widget scherk_label_mesh_tiles, scherk_label_save_mode;
Widget scherk_red_scroll, scherk_green_scroll, scherk_blue_scroll;
Widget scherk_red_label, scherk_green_label, scherk_blue_label;
Widget scherk_select_scroll, scherk_select_label;

/* call back function prototypes */
void SaveCB(Widget w, char *client_data, int call_data);
void SaveScherkCB(Widget w, char *client_data, int call_data);
void LoadScherkTextureCB(Widget w, char *client_data, int call_data);
void ScherkTextureCB(Widget w, char *client_data, int call_data);
void ScherkDetailCB(Widget w, char *client_data, int call_data);
void ScherkStoreysCB(Widget w, char *client_data, int call_data);
void ScherkHeightCB(Widget w, char *client_data, int call_data);
void ScherkFlangeCB(Widget w, char *client_data, int call_data);
void ScherkScaleCB(Widget w, char *client_data, int call_data);
void ScherkAzimuthCB(Widget w, char *client_data, int call_data);
void ScherkTwistCB(Widget w, char *client_data, int call_data);
void ScherkWarpCB(Widget w, char *client_data, int call_data);
void ScherkThicknessCB(Widget w, char *client_data, int call_data);
void ScherkNtexCB(Widget w, char *client_data, int call_data);
void ScherkRimBulgeCB(Widget w, char *client_data, int call_data);
void ScherkBranchesCB(Widget w, char *client_data, int call_data);
void ScherkMeshTilesCB(Widget w, char *client_data, int call_data);
void ScherkSaveModeCB(Widget w, char *client_data, int call_data);
void ScherkRedCB(Widget w, char *client_data, int call_data);
void ScherkGreenCB(Widget w, char *client_data, int call_data);
void ScherkBlueCB(Widget w, char *client_data, int call_data);
void ScherkSelectCB(Widget w, char *client_data, int call_data);

static void scherk_material(int material, unsigned char r, unsigned char g, unsigned char b)
{
  make_material(material, (float)r/255.0, (float)g/255.0, (float)b/255.0,
		0.2, 0.8, 0.8, 10.0, 0.2, 1.0);
}

void init_geom_data()
{
  int i;

  /* scherk surface globals */
  scherk_branches = 2;
  scherk_storeys = 3;
  scherk_height = 1.0;
  scherk_scale = 1.0;
  scherk_flange = 1.0;
  scherk_thickness = 0.04;
  scherk_rim_bulge = 0.0;
  scherk_twist = 0.0;
  scherk_warp = 0.0;
  scherk_azimuth = 0.0;
  scherk_mesh_tiles = 13;
  scherk_tex_tiles = 1;
  scherk_detail = 6;
  scherk_red = scherk_green = scherk_blue = 255;
  scherk_select = SCHERK_SELECT_SIZE;
  scherk_save_mode = 0;

  for (i=SCHERK_FIRST_TEXTURE; i<SCHERK_FIRST_TEXTURE+SCHERK_SELECT_SIZE; i++)
    {
      load_texture(i, image_file);
    }

  /* scherk material */
  scherk_material(SCHERK_FACE1_MATERIAL, scherk_red, scherk_green, scherk_blue);
  scherk_material(SCHERK_FACE2_MATERIAL, scherk_red, scherk_green, scherk_blue);
  scherk_material(SCHERK_RIM1_MATERIAL, scherk_red, scherk_green, scherk_blue);
  scherk_material(SCHERK_RIM2_MATERIAL, scherk_red, scherk_green, scherk_blue);
  scherk_material(SCHERK_RIM3_MATERIAL, scherk_red, scherk_green, scherk_blue);
  scherk_material(SCHERK_RIM4_MATERIAL, scherk_red, scherk_green, scherk_blue);
}

void make_geom_widgets()
{
  char s[MAX_STR];

  scherk_dialog_save = MakeFileSelectionDialog("file name:", SaveScherkCB, "1", SaveScherkCB, "0");
  scherk_dialog_load_texture = MakeFileSelectionDialog("file name:", LoadScherkTextureCB, "1", LoadScherkTextureCB, "0");

  /* create  a push button to load a texture */
  ScherkTextureW = MakeButton("texture", ScherkTextureCB, NULL);
  /* create  a push button to save a scherk surface */
  saveW = MakeButton("save", SaveCB, NULL);

  /* set up the scherk surface's scroll bars */
  /* Widget MakeScrollbar(int horizontal, CallbackFunc func, char *func_param, int min, int max, int curr_value) */
  scherk_scroll_detail = MakeScrollbar(1, ScherkDetailCB, "scherk_detail", 1, 20, scherk_detail);
  sprintf(s, "detail = %d", scherk_detail);
  scherk_label_detail = MakeLabel(s);

  scherk_scroll_storeys = MakeScrollbar(1, ScherkStoreysCB, "scherk_storeys", 1, 20, scherk_storeys);
  sprintf(s, "storeys = %d", scherk_storeys);
  scherk_label_storeys = MakeLabel(s);

  scherk_scroll_height = MakeScrollbar(1, ScherkHeightCB, "scherk_height", 0, 400, (int)(80.0*scherk_height));
  sprintf(s, "height = %.2f", scherk_height);
  scherk_label_height = MakeLabel(s);

  scherk_scroll_flange = MakeScrollbar(1, ScherkFlangeCB, "scherk_flange", 0, 100, (int)(20.0*scherk_flange));
  sprintf(s, "flange = %.2f", scherk_flange);
  scherk_label_flange = MakeLabel(s);

  scherk_scroll_scale = MakeScrollbar(1, ScherkScaleCB, "scherk_scale", 0, 100, (int)(20.0*scherk_scale));
  sprintf(s, "scale = %.2f", scherk_scale);
  scherk_label_scale = MakeLabel(s);

  scherk_scroll_azimuth = MakeScrollbar(1, ScherkAzimuthCB, "scherk_azimuth", 0, 288, (int)(1.25*scherk_azimuth+144));
  sprintf(s, "azimuth = %.2f", scherk_azimuth);
  scherk_label_azimuth = MakeLabel(s);

  scherk_scroll_twist = MakeScrollbar(1, ScherkTwistCB, "scherk_twist", 0, 266, (int)(7.5*scherk_twist+120));
  sprintf(s, "twist = %.2f", scherk_twist);
  scherk_label_twist = MakeLabel(s);

  scherk_scroll_warp = MakeScrollbar(1, ScherkWarpCB, "scherk_warp", 0, 1800, scherk_warp);
  sprintf(s, "warp = %.2f", scherk_warp);
  scherk_label_warp = MakeLabel(s);

  scherk_scroll_thickness = MakeScrollbar(1, ScherkThicknessCB, "scherk_thickness", 0, 100, (int)(100.0*scherk_thickness));
  sprintf(s, "thickness = %.2f", scherk_thickness);
  scherk_label_thickness = MakeLabel(s);

  scherk_scroll_tex_tiles = MakeScrollbar(1, ScherkNtexCB, "scherk_tex_tiles", 0, 20, scherk_tex_tiles);
  sprintf(s, "textr tiles = %d", scherk_tex_tiles);
  scherk_label_tex_tiles = MakeLabel(s);

  scherk_scroll_rim_bulge = MakeScrollbar(1, ScherkRimBulgeCB, "scherk_rim_bulge", -100, 400, (int)(100.0*scherk_rim_bulge));
  sprintf(s, "rim bulge = %.2f", scherk_rim_bulge);
  scherk_label_rim_bulge = MakeLabel(s);

  scherk_scroll_branches = MakeScrollbar(1, ScherkBranchesCB, "scherk_branches", 1, 10, scherk_branches);
  sprintf(s, "branches = %d", scherk_branches);
  scherk_label_branches = MakeLabel(s);

  scherk_scroll_mesh_tiles = MakeScrollbar(1, ScherkMeshTilesCB, "mesh tiles", 0, 20, scherk_mesh_tiles);
  sprintf(s, "board stack = %d", scherk_mesh_tiles);
  scherk_label_mesh_tiles = MakeLabel(s);
  
  /* scherk rgb */
  scherk_red_scroll = MakeScrollbar(1, ScherkRedCB, "scherk_red", 0, 255, scherk_red);
  sprintf(s, "red = %d", scherk_red);
  scherk_red_label = MakeLabel(s);

  scherk_green_scroll = MakeScrollbar(1, ScherkGreenCB, "scherk_green", 0, 255, scherk_green);
  sprintf(s, "green = %d", scherk_green);
  scherk_green_label = MakeLabel(s);

  scherk_blue_scroll = MakeScrollbar(1, ScherkBlueCB, "scherk_blue", 0, 255, scherk_blue);
  sprintf(s, "blue = %d", scherk_blue);
  scherk_blue_label = MakeLabel(s);


  scherk_select_scroll = MakeScrollbar(1, ScherkSelectCB, "scherk_select", 0, SCHERK_SELECT_SIZE+1, scherk_select);
  sprintf(s, "select = %s", scherk_select_str[scherk_select]);
  scherk_select_label = MakeLabel(s);

  scherk_scroll_save_mode = MakeScrollbar(1, ScherkSaveModeCB, "save", 0, SCHERK_SAVE_SIZE+1, scherk_save_mode);
  sprintf(s, "save: %s", scherk_save_str[scherk_save_mode]);  /* which defines format ? << THIS ONE */
  scherk_label_save_mode = MakeLabel(s);
}
  

/* === POSITION THE SCHERK SLIDERS AND LABELS ON THE FORM === */
void place_geom_widgets()
{
  int scherk_left, scherk_middle, scherk_right;

  WidgetPosition(&saveW,     25, 20, 40, 12);

  scherk_left = 2;
  scherk_middle = 40;
  scherk_right = 75;
  
  /* scherk red */
  /* scroll bar */
  WidgetLeftPosition(&scherk_red_scroll, scherk_left);
  WidgetBottomAttachment(&scherk_red_scroll, NULL);
  WidgetRightPosition(&scherk_red_scroll, scherk_middle - scherk_left);
  WidgetTopAttachment(&scherk_red_scroll, &sepi);
  /* label */
  WidgetLeftPosition(&scherk_red_label, scherk_left);
  WidgetBottomAttachment(&scherk_red_label, NULL);
  WidgetRightPosition(&scherk_red_label, scherk_middle - scherk_left);
  WidgetTopAttachment(&scherk_red_label, &scherk_red_scroll);

  /* scherk green */
  /* scroll bar */
  WidgetLeftPosition(&scherk_green_scroll, scherk_left);
  WidgetBottomAttachment(&scherk_green_scroll, NULL);
  WidgetRightPosition(&scherk_green_scroll, scherk_middle - scherk_left);
  WidgetTopAttachment(&scherk_green_scroll, &scherk_red_label);
  /* label */
  WidgetLeftPosition(&scherk_green_label, scherk_left);
  WidgetBottomAttachment(&scherk_green_label, NULL);
  WidgetRightPosition(&scherk_green_label, scherk_middle - scherk_left);
  WidgetTopAttachment(&scherk_green_label, &scherk_green_scroll);

  /* scherk blue */
  /* scroll bar */
  WidgetLeftPosition(&scherk_blue_scroll, scherk_left);
  WidgetBottomAttachment(&scherk_blue_scroll, NULL);
  WidgetRightPosition(&scherk_blue_scroll, scherk_middle - scherk_left);
  WidgetTopAttachment(&scherk_blue_scroll, &scherk_green_label);
  /* label */
  WidgetLeftPosition(&scherk_blue_label, scherk_left);
  WidgetBottomAttachment(&scherk_blue_label, NULL);
  WidgetRightPosition(&scherk_blue_label, scherk_middle - scherk_left);
  WidgetTopAttachment(&scherk_blue_label, &scherk_blue_scroll);

  /* scherk select */
  /* scroll bar */
  WidgetLeftPosition(&scherk_select_scroll, scherk_left + 8);
  WidgetBottomAttachment(&scherk_select_scroll, NULL);
  WidgetRightPosition(&scherk_select_scroll, scherk_middle - scherk_left - 8);
  WidgetTopAttachment(&scherk_select_scroll, &scherk_blue_label);
  /* label */
  WidgetLeftPosition(&scherk_select_label, scherk_left + 8);
  WidgetBottomAttachment(&scherk_select_label, NULL);
  WidgetRightPosition(&scherk_select_label, scherk_middle - scherk_left - 8);
  WidgetTopAttachment(&scherk_select_label, &scherk_select_scroll);

  /* scherk save mode */
  /* scroll bar */
  WidgetLeftPosition(&scherk_scroll_save_mode, scherk_left + 8);
  WidgetBottomAttachment(&scherk_scroll_save_mode, NULL);
  WidgetRightPosition(&scherk_scroll_save_mode, scherk_middle - scherk_left - 8);
  WidgetTopAttachment(&scherk_scroll_save_mode, &scherk_select_label);
  /* label */
  WidgetLeftPosition(&scherk_label_save_mode, scherk_left + 6);       /* was 8 */
  WidgetBottomAttachment(&scherk_label_save_mode, NULL);
  WidgetRightPosition(&scherk_label_save_mode, scherk_middle - scherk_left - 6);
  WidgetTopAttachment(&scherk_label_save_mode, &scherk_scroll_save_mode);

  /* scherk texture button */
  WidgetLeftPosition(&ScherkTextureW, scherk_left + 8);
  WidgetBottomAttachment(&ScherkTextureW, NULL);
  WidgetRightPosition(&ScherkTextureW, scherk_middle - scherk_left - 8);
  WidgetTopAttachment(&ScherkTextureW, &scherk_label_save_mode);

  /* scherk branches */
  /* scroll bar */
  WidgetLeftPosition(&scherk_scroll_branches, scherk_middle);
  WidgetBottomAttachment(&scherk_scroll_branches, NULL);
  WidgetRightPosition(&scherk_scroll_branches, scherk_right);
  WidgetTopAttachment(&scherk_scroll_branches, &sepi);
  /* label */
  WidgetLeftAttachment(&scherk_label_branches, &scherk_scroll_branches);
  WidgetBottomAttachment(&scherk_label_branches, NULL);
  WidgetRightAttachedToForm(&scherk_label_branches);
  WidgetTopAttachment(&scherk_label_branches, &sepi);

  /* scherk storeys */
  /* scroll bar */
  WidgetLeftPosition(&scherk_scroll_storeys, scherk_middle);
  WidgetBottomAttachment(&scherk_scroll_storeys, NULL);
  WidgetRightPosition(&scherk_scroll_storeys, scherk_right);
  WidgetTopAttachment(&scherk_scroll_storeys, &scherk_scroll_branches);
  /* label */
  WidgetLeftAttachment(&scherk_label_storeys, &scherk_scroll_storeys);
  WidgetBottomAttachment(&scherk_label_storeys, NULL);
  WidgetRightAttachedToForm(&scherk_label_storeys);
  WidgetTopAttachment(&scherk_label_storeys, &scherk_scroll_branches);

  /* scherk height */
  /* scroll bar */
  WidgetLeftPosition(&scherk_scroll_height, scherk_middle);
  WidgetBottomAttachment(&scherk_scroll_height, NULL);
  WidgetRightPosition(&scherk_scroll_height, scherk_right);
  WidgetTopAttachment(&scherk_scroll_height, &scherk_scroll_storeys);
  /* label */
  WidgetLeftAttachment(&scherk_label_height, &scherk_scroll_height);
  WidgetBottomAttachment(&scherk_label_height, NULL);
  WidgetRightAttachedToForm(&scherk_label_height);
  WidgetTopAttachment(&scherk_label_height, &scherk_scroll_storeys);

  /* scherk flange */
  /* scroll bar */
  WidgetLeftPosition(&scherk_scroll_flange, scherk_middle);
  WidgetBottomAttachment(&scherk_scroll_flange, NULL);
  WidgetRightPosition(&scherk_scroll_flange, scherk_right);
  WidgetTopAttachment(&scherk_scroll_flange, &scherk_scroll_height);
  /* label */
  WidgetLeftAttachment(&scherk_label_flange, &scherk_scroll_flange);
  WidgetBottomAttachment(&scherk_label_flange, NULL);
  WidgetRightAttachedToForm(&scherk_label_flange);
  WidgetTopAttachment(&scherk_label_flange, &scherk_scroll_height);

  /* scherk thickness */
  /* scroll bar */
  WidgetLeftPosition(&scherk_scroll_thickness, scherk_middle);
  WidgetBottomAttachment(&scherk_scroll_thickness, NULL);
  WidgetRightPosition(&scherk_scroll_thickness, scherk_right);
  WidgetTopAttachment(&scherk_scroll_thickness, &scherk_scroll_flange);
  /* label */
  WidgetLeftAttachment(&scherk_label_thickness, &scherk_scroll_thickness);
  WidgetBottomAttachment(&scherk_label_thickness, NULL);
  WidgetRightAttachedToForm(&scherk_label_thickness);
  WidgetTopAttachment(&scherk_label_thickness, &scherk_scroll_flange);

  /* scherk rim bulge */
  /* scroll bar */
  WidgetLeftPosition(&scherk_scroll_rim_bulge, scherk_middle);
  WidgetBottomAttachment(&scherk_scroll_rim_bulge, NULL);
  WidgetRightPosition(&scherk_scroll_rim_bulge, scherk_right);
  WidgetTopAttachment(&scherk_scroll_rim_bulge, &scherk_scroll_thickness);
  /* label */
  WidgetLeftAttachment(&scherk_label_rim_bulge, &scherk_scroll_rim_bulge);
  WidgetBottomAttachment(&scherk_label_rim_bulge, NULL);
  WidgetRightAttachedToForm(&scherk_label_rim_bulge);
  WidgetTopAttachment(&scherk_label_rim_bulge, &scherk_scroll_thickness);

  /* scherk twist */
  /* scroll bar */
  WidgetLeftPosition(&scherk_scroll_twist, scherk_middle);
  WidgetBottomAttachment(&scherk_scroll_twist, NULL);
  WidgetRightPosition(&scherk_scroll_twist, scherk_right);
  WidgetTopAttachment(&scherk_scroll_twist, &scherk_scroll_rim_bulge);
  /* label */
  WidgetLeftAttachment(&scherk_label_twist, &scherk_scroll_twist);
  WidgetBottomAttachment(&scherk_label_twist, NULL);
  WidgetRightAttachedToForm(&scherk_label_twist);
  WidgetTopAttachment(&scherk_label_twist, &scherk_scroll_rim_bulge);

  /* scherk warp */
  /* scroll bar */
  WidgetLeftPosition(&scherk_scroll_warp, scherk_middle);
  WidgetBottomAttachment(&scherk_scroll_warp, NULL);
  WidgetRightPosition(&scherk_scroll_warp, scherk_right);
  WidgetTopAttachment(&scherk_scroll_warp, &scherk_scroll_twist);
  /* label */
  WidgetLeftAttachment(&scherk_label_warp, &scherk_scroll_warp);
  WidgetBottomAttachment(&scherk_label_warp, NULL);
  WidgetRightAttachedToForm(&scherk_label_warp);
  WidgetTopAttachment(&scherk_label_warp, &scherk_scroll_twist);

  /* scherk azimuth */
  /* scroll bar */
  WidgetLeftPosition(&scherk_scroll_azimuth, scherk_middle);
  WidgetBottomAttachment(&scherk_scroll_azimuth, NULL);
  WidgetRightPosition(&scherk_scroll_azimuth, scherk_right);
  WidgetTopAttachment(&scherk_scroll_azimuth, &scherk_scroll_warp);
  /* label */
  WidgetLeftAttachment(&scherk_label_azimuth, &scherk_scroll_azimuth);
  WidgetBottomAttachment(&scherk_label_azimuth, NULL);
  WidgetRightAttachedToForm(&scherk_label_azimuth);
  WidgetTopAttachment(&scherk_label_azimuth, &scherk_scroll_warp);

  /* scherk mesh_tiles */
  /* scroll bar */
  WidgetLeftPosition(&scherk_scroll_mesh_tiles, scherk_middle);
  WidgetBottomAttachment(&scherk_scroll_mesh_tiles, NULL);
  WidgetRightPosition(&scherk_scroll_mesh_tiles, scherk_right);
  WidgetTopAttachment(&scherk_scroll_mesh_tiles, &scherk_scroll_azimuth);
  /* label */
  WidgetLeftAttachment(&scherk_label_mesh_tiles, &scherk_scroll_mesh_tiles);
  WidgetBottomAttachment(&scherk_label_mesh_tiles, NULL);
  WidgetRightAttachedToForm(&scherk_label_mesh_tiles);
  WidgetTopAttachment(&scherk_label_mesh_tiles, &scherk_scroll_azimuth);

  /* scherk tex_tiles */
  /* scroll bar */
  WidgetLeftPosition(&scherk_scroll_tex_tiles, scherk_middle);
  WidgetBottomAttachment(&scherk_scroll_tex_tiles, NULL);
  WidgetRightPosition(&scherk_scroll_tex_tiles, scherk_right);
  WidgetTopAttachment(&scherk_scroll_tex_tiles, &scherk_scroll_mesh_tiles);
  /* label */
  WidgetLeftAttachment(&scherk_label_tex_tiles, &scherk_scroll_tex_tiles);
  WidgetBottomAttachment(&scherk_label_tex_tiles, NULL);
  WidgetRightAttachedToForm(&scherk_label_tex_tiles);
  WidgetTopAttachment(&scherk_label_tex_tiles, &scherk_scroll_mesh_tiles);

  /* scherk detail */
  /* scroll bar */
  WidgetLeftPosition(&scherk_scroll_detail, scherk_middle);
  WidgetBottomAttachment(&scherk_scroll_detail, NULL);
  WidgetRightPosition(&scherk_scroll_detail, scherk_right);
  WidgetTopAttachment(&scherk_scroll_detail, &scherk_scroll_tex_tiles);
  /* label */
  WidgetLeftAttachment(&scherk_label_detail, &scherk_scroll_detail);
  WidgetBottomAttachment(&scherk_label_detail, NULL);
  WidgetRightAttachedToForm(&scherk_label_detail);
  WidgetTopAttachment(&scherk_label_detail, &scherk_scroll_tex_tiles);

  /* scherk scale */
  /* scroll bar */
  WidgetLeftPosition(&scherk_scroll_scale, scherk_middle);
  WidgetBottomAttachment(&scherk_scroll_scale, NULL);
  WidgetRightPosition(&scherk_scroll_scale, scherk_right);
  WidgetTopAttachment(&scherk_scroll_scale, &scherk_scroll_detail);
  /* label */
  WidgetLeftAttachment(&scherk_label_scale, &scherk_scroll_scale);
  WidgetBottomAttachment(&scherk_label_scale, NULL);
  WidgetRightAttachedToForm(&scherk_label_scale);
  WidgetTopAttachment(&scherk_label_scale, &scherk_scroll_detail);

}

/* === ALL CALL BACK FUNCTIONS GO HERE === */
void SaveCB(Widget w, char *client_data, int call_data)
{
  /* make the save dialog box visible */
  MANAGE(scherk_dialog_save);
  gstate.timeout = SHORT_TIMEOUT_DELAY;
}

void SaveScherkCB(Widget w, char *client_data, int call_data)
{
  char *s;
  XmSelectionBoxCallbackStruct *callback;
  FILE *fp;

  callback = (XmSelectionBoxCallbackStruct *)call_data;

  if (client_data[0] == '1')
    {
      XmStringGetLtoR(callback->value, *GetCharSet(), &s);

      /* save scherk data to the specified file */
      fp = fopen(s, "w");
      output_newscherk_data(fp);
      fclose(fp);
    }

  /* make the dialog box invisible */
  UNMANAGE(w);
  gstate.timeout = SHORT_TIMEOUT_DELAY;
}

void LoadScherkTextureCB(Widget w, char *client_data, int call_data)
{
  int i;
  char *s;
  XmSelectionBoxCallbackStruct *callback;

  callback = (XmSelectionBoxCallbackStruct *)call_data;

  if (client_data[0] == '1')
    {
      XmStringGetLtoR(callback->value, *GetCharSet(), &s);

      if (scherk_select == SCHERK_SELECT_SIZE) /* select all */
	{
	  for (i=0; i<SCHERK_SELECT_SIZE; i++)
	    load_texture(SCHERK_FIRST_TEXTURE+i, s);
	}
      else
	{
	  load_texture(SCHERK_FIRST_TEXTURE+scherk_select, s);
	}
      XtFree(s);
    }

  /* make the dialog box invisible */
  UNMANAGE(w);
  gstate.timeout = SHORT_TIMEOUT_DELAY;
}

void ScherkTextureCB(Widget w, char *client_data, int call_data)
{
  Widget list;
  XmString xs;
  link_handle l;
  char buf[1024];

  link_open(&l, "ls", "-F");

  list = (Widget)XmSelectionBoxGetChild(dialog2, XmDIALOG_LIST);
  XmListDeleteAllItems(list);

  while(!link_read(&l, buf))
    {
      xs = XmStringCreateLtoR(buf, *GetCharSet());
      if (strcmp(&buf[strlen(buf)-4], ".rgb") == 0)
	XmListAddItem(list, xs, 0);
      XmStringFree(xs);
    }
  link_close(&l);

  /* make the dialog box for scherk texture loading visible */
  MANAGE(scherk_dialog_load_texture);

  gstate.timeout = SHORT_TIMEOUT_DELAY;
}

void ScherkDetailCB(Widget w, char *client_data, int call_data)
{
  char s[256];
  Arg args[1];

  scherk_detail = ((XmScrollBarCallbackStruct *)call_data)->value;
  sprintf(s, "%9s = %d   ", "detail", scherk_detail);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_label_detail, args, 1);
  gstate.timeout = TIMEOUT_DELAY;;
}

void ScherkStoreysCB(Widget w, char *client_data, int call_data)
{
  char s[256];
  Arg args[1];

  scherk_storeys = ((XmScrollBarCallbackStruct *)call_data)->value;
  sprintf(s, "%9s = %d   ", "storeys", scherk_storeys);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_label_storeys, args, 1);
  gstate.timeout = TIMEOUT_DELAY;
}

void ScherkHeightCB(Widget w, char *client_data, int call_data)
{
  char s[256];
  Arg args[1];

  scherk_height = 0.05*(float)((XmScrollBarCallbackStruct *)call_data)->value;
  sprintf(s, "%9s = %.2f   ", "height", scherk_height);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_label_height, args, 1);
  gstate.timeout = TIMEOUT_DELAY;;
}

void ScherkScaleCB(Widget w, char *client_data, int call_data)
{
  char s[256];
  Arg args[1];

  scherk_scale = 0.05*(float)((XmScrollBarCallbackStruct *)call_data)->value;
  sprintf(s, "%9s = %.2f   ", "scale", scherk_scale);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_label_scale, args, 1);
  gstate.timeout = TIMEOUT_DELAY;;
}

void ScherkFlangeCB(Widget w, char *client_data, int call_data)
{
  char s[256];
  Arg args[1];

  scherk_flange = 0.05*(float)((XmScrollBarCallbackStruct *)call_data)->value;
  sprintf(s, "%9s = %.2f   ", "flange", scherk_flange);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_label_flange, args, 1);
  gstate.timeout = TIMEOUT_DELAY;;
}

void ScherkAzimuthCB(Widget w, char *client_data, int call_data)
{
  char s[256];
  Arg args[1];

  scherk_azimuth = 1.25*(float)(((XmScrollBarCallbackStruct *)call_data)->value - 144);
  sprintf(s, "%9s = %.2f   ", "azimuth", scherk_azimuth);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_label_azimuth, args, 1);
  gstate.timeout = TIMEOUT_DELAY;;
}

void ScherkTwistCB(Widget w, char *client_data, int call_data)
{
  char s[256];
  Arg args[1];

  scherk_twist = 7.5*(float)(((XmScrollBarCallbackStruct *)call_data)->value - 120);
  sprintf(s, "%9s = %.2f   ", "twist", scherk_twist);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_label_twist, args, 1);
  gstate.timeout = TIMEOUT_DELAY;;
}

void ScherkWarpCB(Widget w, char *client_data, int call_data)
{
  char s[256];
  Arg args[1];

  scherk_warp = ((XmScrollBarCallbackStruct *)call_data)->value;
  sprintf(s, "%9s = %.2f   ", "warp", scherk_warp);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_label_warp, args, 1);
  gstate.timeout = TIMEOUT_DELAY;;
}

void ScherkThicknessCB(Widget w, char *client_data, int call_data)
{
  char s[256];
  Arg args[1];

  scherk_thickness = 0.01*(float)((XmScrollBarCallbackStruct *)call_data)->value;
  sprintf(s, "%9s = %.2f   ", "thickness", scherk_thickness);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_label_thickness, args, 1);
  gstate.timeout = TIMEOUT_DELAY;;
}

void ScherkNtexCB(Widget w, char *client_data, int call_data)
{
  char s[256];
  Arg args[1];

  scherk_tex_tiles = ((XmScrollBarCallbackStruct *)call_data)->value;
  sprintf(s, "%9s = %d   ", "textr tiles", scherk_tex_tiles);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_label_tex_tiles, args, 1);
  gstate.timeout = TIMEOUT_DELAY;;
}

void ScherkRimBulgeCB(Widget w, char *client_data, int call_data)
{
  char s[256];
  Arg args[1];

  scherk_rim_bulge = 0.01*(float)((XmScrollBarCallbackStruct *)call_data)->value;
  sprintf(s, "%9s = %.2f   ", "rim bulge", scherk_rim_bulge);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_label_rim_bulge, args, 1);
  gstate.timeout = TIMEOUT_DELAY;;
}

void ScherkBranchesCB(Widget w, char *client_data, int call_data)
{
  char s[256];
  Arg args[1];

  scherk_branches = ((XmScrollBarCallbackStruct *)call_data)->value;
  sprintf(s, "%9s = %d   ", "branches", scherk_branches);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_label_branches, args, 1);
  gstate.timeout = TIMEOUT_DELAY;;
}

void ScherkMeshTilesCB(Widget w, char *client_data, int call_data)
{
  char s[256];
  Arg args[1];

  scherk_mesh_tiles = ((XmScrollBarCallbackStruct *)call_data)->value;
  sprintf(s, "%9s = %d   ", "board stack", scherk_mesh_tiles);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_label_mesh_tiles, args, 1);
  gstate.timeout = TIMEOUT_DELAY;
}

void ScherkRedCB(Widget w, char *client_data, int call_data)
{
  int i;
  char s[256];
  Arg args[1];

  scherk_red = ((XmScrollBarCallbackStruct *)call_data)->value;
  sprintf(s, "%9s = %d   ", "red", scherk_red);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_red_label, args, 1);
  if (scherk_select == SCHERK_SELECT_SIZE)
    {
      for (i=0; i<SCHERK_SELECT_SIZE; i++)
	scherk_material(SCHERK_FIRST_MATERIAL+i, scherk_red, scherk_green, scherk_blue);
    }
  else
    {
      scherk_material(SCHERK_FIRST_MATERIAL+scherk_select, scherk_red, scherk_green, scherk_blue);
    }
  gstate.timeout = TIMEOUT_DELAY;
}

void ScherkGreenCB(Widget w, char *client_data, int call_data)
{
  int i;
  char s[256];
  Arg args[1];

  scherk_green = ((XmScrollBarCallbackStruct *)call_data)->value;
  sprintf(s, "%9s = %d   ", "green", scherk_green);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_green_label, args, 1);
  if (scherk_select == SCHERK_SELECT_SIZE)
    {
      for (i=0; i<SCHERK_SELECT_SIZE; i++)
	scherk_material(SCHERK_FIRST_MATERIAL+i, scherk_red, scherk_green, scherk_blue);
    }
  else
    {
      scherk_material(SCHERK_FIRST_MATERIAL+scherk_select, scherk_red, scherk_green, scherk_blue);
    }
  gstate.timeout = TIMEOUT_DELAY;
}

void ScherkBlueCB(Widget w, char *client_data, int call_data)
{
  int i;
  char s[256];
  Arg args[1];

  scherk_blue = ((XmScrollBarCallbackStruct *)call_data)->value;
  sprintf(s, "%9s = %d   ", "blue", scherk_blue);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_blue_label, args, 1);
  if (scherk_select == SCHERK_SELECT_SIZE)
    {
      for (i=0; i<SCHERK_SELECT_SIZE; i++)
	scherk_material(SCHERK_FIRST_MATERIAL+i, scherk_red, scherk_green, scherk_blue);
    }
  else
    {
      scherk_material(SCHERK_FIRST_MATERIAL+scherk_select, scherk_red, scherk_green, scherk_blue);
    }
  gstate.timeout = TIMEOUT_DELAY;
}

void ScherkSelectCB(Widget w, char *client_data, int call_data)
{
  char s[256];
  Arg args[1];

  scherk_select = ((XmScrollBarCallbackStruct *)call_data)->value;
  /* sprintf(s, "%9s = %s     ", "select", scherk_select_str[scherk_select]);  bad original */
  sprintf(s, "select = %s", scherk_select_str[scherk_select]);
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_select_label, args, 1);
  gstate.timeout = TIMEOUT_DELAY;
}

void ScherkSaveModeCB(Widget w, char *client_data, int call_data)
{
  char s[256];
  Arg args[1];

  scherk_save_mode = ((XmScrollBarCallbackStruct *)call_data)->value;
  /*sprintf(s, "%20s: %s   ", "save", scherk_save_str[scherk_save_mode]);   original - which defines format ? */
  sprintf(s, "save: %s", scherk_save_str[scherk_save_mode]);  /*  new try: works!  */
  XtSetArg(args[0], XmNlabelString, XmStringCreate(s, *GetCharSet()));
  XtSetValues(scherk_label_save_mode, args, 1);
  gstate.timeout = TIMEOUT_DELAY;
}