/*
C----------------------------------------------------------------------
C /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\
C   \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/
C----------------------------------------------------------------------
C	                  		             
C     +---------------------------------------+     .          	  
C     |                                       |    / \ 	              
C     |     Author:                           |    | |		 
C     |                           	      |    |.|		 
C     |     Marten Levenstam                  |    |.|
C     |     Dep. of Mathematics               |    |:|      __
C     |     Chalmers University of Technology |  ,_|:|_,   /  )
C     |     S-412 96 Goteborg                 |	   (Oo    / _I_
C     |     SWEDEN                            |	    +\ \  || __|
C     |     martenl@math.chalmers.se          |	       \ \||___|
C     |                       	       	      |         \ /.:.\-\
C     |        	      \|/              	      |           |.:. /-----\
C     +---------------( )---------------------+           |___|::oOo::|
C                    (@ @)     	       	                  /   |:<_T_>:|
C     +------o00------(	)------00o---------+             |_____\ ::: /
C     |	               o       	       	   |              | |  \ \:/
C     |	               	       	       	   |              | |   | |  	     
C     |	         what comes free       	   |              \ /   | \___
C     |      comes without a guarantee     |              / |   \_____\
C     +------------------------------------+	      	  `-'
C     +----------------------------------------------------------------+
C     |                                                                |
C     |    THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS |
C     |    OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE   |
C     |    IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A     |
C     |    PARTICULAR PURPOSE.                                         |
C     |                                                                |
C     +----------------------------------------------------------------+
C======================================================================
C   4 6  10        20        30        40        50        60        70
C   ]|{   |    |    |    |    |    |    |    |    |    |    |    |    |}
C======================================================================
*/
/* $Log: kraftwerk.c,v $
 * Revision 1.16  1995/03/20  14:55:07  martenl
 * *** empty log message ***
 *
 * Revision 1.15  1995/03/12  16:08:23  martenl
 * Added setCursor
 *
 * Revision 1.14  1995/03/12  14:30:56  martenl
 * Added new types of boundaries
 *
 * Revision 1.13  1995/03/11  13:53:00  martenl
 * fixed new state stuff for multiple modules
 *
 * Revision 1.12  1995/03/10  12:06:03  martenl
 * *** empty log message ***
 *
 * Revision 1.11  1995/03/10  11:50:24  martenl
 * *** empty log message ***
 *
 * Revision 1.10  1995/03/09  16:52:59  martenl
 * *** empty log message ***
 *
 * Revision 1.9  1995/03/04  11:39:47  martenl
 * init_flags:
 * 	Changed the default arrowscale
 *
 * Revision 1.8  1995/03/04  11:25:59  martenl
 * *** empty log message ***
 *
 * Revision 1.7  1995/03/04  11:21:24  martenl
 * *** empty log message ***
 *
 * Revision 1.6  1995/03/02  10:59:46  martenl
 * *** empty log message ***
 *
 * Revision 1.5  1995/03/01  16:24:51  martenl
 * fixed dynamic loading of solver modules
 *
 * Revision 1.4  1995/02/24  12:24:03  martenl
 * init_flags:
 * 	Puts cdbc.n = 0 at startup time
 *
 * Revision 1.3  1995/02/22  15:44:09  martenl
 * Small typographical changes
 *
 * Revision 1.2  1995/02/22  15:28:34  martenl
 * Changed input of boundary conditions and equation data to two separate
 * windows
 *
 * Revision 1.1  1995/02/21  07:53:52  martenl
 * Initial revision
 *
 * */




#include "libsx.h"             /* gets us in the door with libsx          */
#include <X11/cursorfont.h>
#include <X11/Shell.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "globals.h"
#include "geodata.h"
#include "kraftwerk.h"
#include "boundary.h"
#include "solve.h"
#include "post.h"
#include "graph.h"
#include "grid.h"
#include "naca.h"
#include "module.h"
#include "icon.bm"

void getDrawBox();
void sbarfcn(Widget w, float new_val, void *data);
void sbarfcn1(Widget w, float new_val, void *data);
void sbarfcn2(Widget w, float new_val, void *data);
void equationDataWindow(Widget widget, void *data);
void check(Widget w, void *d);
void animate(Widget widget, void *data);
void  KeyPressFunc(Widget w, char *input, int up_or_down, void *data);

int ctr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};

static Pixmap   iconP;

void setIcon()
{
   Display        *dpy;
   Arg             wargs[1];
   Widget top;
   top = (Widget) XtParent(XtParent(drawWindow));
   dpy = (Display *) XtDisplay(drawWindow);
   iconP = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy),
                                 icon_bits, icon_width, icon_height);
   XtSetArg(wargs[0], XtNiconPixmap, iconP);
   XtSetValues(top, wargs, 1);
}


void setCursor(unsigned int shape)
{
  Display *display;
  display = (Display *) XtDisplay(drawWindow);
  XDefineCursor(display, XtWindow(drawWindow),
		XCreateFontCursor(display, shape));

}


void getServerInfo()
{
  int depth;
  Display *display;

  display = (Display *) XtDisplay(drawWindow);
  depth = DefaultDepth(display, DefaultScreen(display));
  if(depth == 1){
    printf("%s\n", "Server is black and white");
    have_colors = FALSE;
  }
  else{
    printf("%s\n", "Server has colors");
    have_colors = TRUE;
  }

}

void setAction(int doThis)
{
  action = doThis;

  switch(doThis)
    {
    case NORMAL:
      setCursor(XC_arrow);
      break;
    case DRAWING:
      setCursor(XC_pencil);
      break;
    case MOVING:
      setCursor(XC_hand1);
      break;
    case PICKING:
      setCursor(XC_hand1);
      break;
    case DELETING:
      setCursor(XC_pirate);
      break;
    case WAITING:
      setCursor(XC_watch);
      break;
    case ZOOMING:
      setCursor(XC_sizing);
      break;
    }
}
void rmSolutionMenus()
{
  int k, i;

  if(state >= HAVE_SOLUTION){
    k = plotMenu.noItems;
    for(i = k-1; i > 5; i--){
      XtDestroyWidget(plotMenu.item[i]);
      plotMenu.noItems--;
    }
  }
}


void addSolutionMenus()
{
  int i, k;
  k = plotMenu.noItems;
  for(i = 0; i < mySol[currentSolution].n; i++){
    plotMenu.item[k] = MakeMenuItem(plotMenu.name, mySol[currentSolution].name[i], draw, &ctr[k]); 
    plotMenu.needs[k] = HAVE_NOTHING; k++;
    plotMenu.noItems++ ;
  }
}


void updateMenuItems(menu thisMenu)
{
 int i;

  for(i = 0; i < thisMenu.noItems; i++){
    if( thisMenu.needs[i] <= state)
      SetWidgetState(thisMenu.item[i], TRUE);
    else
      SetWidgetState(thisMenu.item[i], FALSE);
  }

}

void set_menu_state()
{
  updateMenuItems(fileMenu);
  updateMenuItems(geomMenu);
  updateMenuItems(meshMenu);
  updateMenuItems(solverMenu);
  updateMenuItems(plotMenu);
  updateLevelButtons();
  SetDrawArea(infoWindow);
  ClearDrawArea();
  SetDrawArea(drawWindow);
}    

void infoHandler(char *info)
{
/*
  SetTextWidgetText(infoWindow, info, FALSE);
*/

  SetDrawArea(infoWindow);
  DrawText(info, 15, 20);
  SetDrawArea(drawWindow);

}
void errorHandler(char *msg)
{
  Beep();
  GetYesNo( msg); /* Should really be an alert box, not a yes/no box */
}

void init_flags()
{
  int i;
  for(i = 0; i < 5; i++)
    cdbc[i].n = 0;
  nlev = 10;
  ncolor = 128;
  arrwscl = 2.0;
  nwinx = 1;
  nwiny = 1;
  state = HAVE_NOTHING;
  zoomActive = FALSE;
  flags.zoom = 0;
  maxscalarX = 1.0;
  minscalarX = 0.0;
}

int init_display(int argc, char **argv)
{

  int i, j;
  int *ptr;
  int *num[20];

  ptr = (int *) malloc(sizeof(int));
  for(i = 0; i < 20; ++i)
    {
      num[i] = (int *) malloc(sizeof(int));
      *num[i] = i;
    }
  argc = OpenDisplay(argc, argv);
  if (argc == FALSE)
    return argc;

  init_flags();
  readModules();

/*
 *   Here are the toplevel widgets
 */

  fileMenu.name   = MakeMenu("File");
  geomMenu.name   = MakeMenu("Geometry");
  meshMenu.name   = MakeMenu("Mesh");
  solverMenu.name = MakeMenu("Equations");
  plotMenu.name   = MakeMenu("View Result");
  sbar = MakeHorizScrollbar(200, sbarfcn, NULL);
  SetScrollbar(sbar, 50., 100., 2.);

  sbar1 = MakeHorizScrollbar(200, sbarfcn1, NULL);
  SetScrollbar(sbar1, 0., 100., 2.);
  sbar2 = MakeHorizScrollbar(200, sbarfcn2, NULL);
  SetScrollbar(sbar2, 100., 100., 2.);

  drawWindow = MakeDrawArea(X_SIZE, Y_SIZE, redisplay, NULL);

  logoWindow = MakeDrawArea(LOGO_SIZE, INFO_Y_SIZE, inforedisplay, NULL);

  infoWindow = MakeDrawArea(X_SIZE-LOGO_SIZE-6-200-6, INFO_Y_SIZE, redisplay, NULL);
/*
  infoWindow = MakeTextWidget(NULL, FALSE, FALSE, X_SIZE-LOGO_SIZE-6, INFO_Y_SIZE);
 */
/*
 *  Now place the widgets
 */

  SetWidgetPos(geomMenu.name,   PLACE_RIGHT, fileMenu.name,    NO_CARE, NULL);
  SetWidgetPos(meshMenu.name,   PLACE_RIGHT, geomMenu.name,    NO_CARE, NULL);
  SetWidgetPos(solverMenu.name, PLACE_RIGHT, meshMenu.name,    NO_CARE, NULL);
  SetWidgetPos(plotMenu.name,   PLACE_RIGHT, solverMenu.name,  NO_CARE, NULL);
  SetWidgetPos(drawWindow, PLACE_UNDER, fileMenu.name,    NO_CARE, NULL);
  SetWidgetPos(logoWindow, PLACE_UNDER, drawWindow,  NO_CARE, NULL);
  SetWidgetPos(infoWindow, PLACE_RIGHT, logoWindow,PLACE_UNDER, drawWindow);  
  SetWidgetPos(sbar, PLACE_RIGHT, infoWindow, PLACE_UNDER, drawWindow);
  SetWidgetPos(sbar1, PLACE_UNDER, sbar, PLACE_RIGHT, infoWindow);
  SetWidgetPos(sbar2, PLACE_UNDER, sbar1,PLACE_RIGHT, infoWindow);

/*
 *  Fix all the different menu items
 */
  i = 0;
  fileMenu.item[i] = MakeMenuItem(fileMenu.name, "Load..."  , file, num[i]); 
  fileMenu.needs[i] = HAVE_NOTHING; i++;
  fileMenu.item[i] = MakeMenuItem(fileMenu.name, "Save..." , save, num[i]); 
  fileMenu.needs[i] = HAVE_BOUNDARY; i++;
  fileMenu.item[i] = MakeMenuItem(fileMenu.name, "Print..." , print, num[i]);
  fileMenu.needs[i] = HAVE_BOUNDARY; i++;
  fileMenu.item[i] = MakeMenuItem(fileMenu.name, "Print to file..." , print2file, num[i]);
  fileMenu.needs[i] = HAVE_BOUNDARY; i++;
  fileMenu.item[i] = MakeMenuItem(fileMenu.name, "Quit"     , quit, num[i]);
  fileMenu.needs[i] = HAVE_NOTHING; i++;
  fileMenu.noItems = i ;
  i = 0;
  geomMenu.item[i] = MakeMenuItem(geomMenu.name, "Define scale..." , getBoundaryScale, num[i]); 
  geomMenu.needs[i] = HAVE_NOTHING; i++;
  geomMenu.item[i] = MakeMenuItem(geomMenu.name, "Define boundaries..." , naca, num[i]); 
  geomMenu.needs[i] = HAVE_SCALE; i++;
  geomMenu.noItems = i ;
  i = 0;
  meshMenu.item[i] = MakeMenuItem(meshMenu.name, "Define Mesh Size..." , mesh, num[i]); 
  meshMenu.needs[i] = HAVE_BOUNDARY; i++;
  meshMenu.item[i] = MakeMenuItem(meshMenu.name, "Make Mesh"  , mesh, num[i]); 
  meshMenu.needs[i] = HAVE_MESHSIZE; i++;
  meshMenu.noItems = i ;
  i = 0;
  for(j = 0; j < numberOfModules; j++){
    solverMenu.item[i] = MakeMenuItem(solverMenu.name, module[j].name  , check, num[i]); 
    solverMenu.needs[i] = HAVE_MESH; i++;
  }
  solverMenu.item[i] = MakeMenuItem(solverMenu.name, "Equation data..." ,equationDataWindow, num[i]); 
  solverMenu.needs[i] = HAVE_MESH; i++;
  solverMenu.item[i] = MakeMenuItem(solverMenu.name, "Solve..." , solve, num[i]); 
  solverMenu.needs[i] = HAVE_EQDATA; i++;
  solverMenu.noItems = i ;
  i = 0;
  plotMenu.item[i] = MakeMenuItem(plotMenu.name, "Zoom" , zoom,num[i] ); 
  plotMenu.needs[i] = HAVE_BOUNDARY; i++;
  plotMenu.item[i] = MakeMenuItem(plotMenu.name, "Restore Zoom" , unzoom,num[i] ); 
  plotMenu.needs[i] = HAVE_BOUNDARY; i++;
  plotMenu.item[i] = MakeMenuItem(plotMenu.name, "Setup..."     , plotprefs, num[i]); 
  plotMenu.needs[i] = HAVE_NOTHING; i++;
  plotMenu.item[i] = MakeMenuItem(plotMenu.name, "animate..."     , NULL, num[i]); 
  plotMenu.needs[i] = HAVE_MORE; i++;
  plotMenu.item[i] = MakeMenuItem(plotMenu.name, " "     , NULL, NULL); 
  plotMenu.needs[i] = HAVE_NOTHING; i++;
  plotMenu.item[i] = MakeMenuItem(plotMenu.name, "Mesh"  , draw, num[i]); 
  plotMenu.needs[i] = HAVE_SOLUTION; i++;
  plotMenu.noItems = i ;

  putUpLevelButtons();
/*
 * Get some colors for drawing with.
 */

/*
 * Now actually put the display on the screen.
 */
  ShowDisplay();

  SetMenuItemChecked(solverMenu.item[0], TRUE);
  SetMenuItemChecked(plotMenu.item[0], FALSE);
  SetMenuItemChecked(plotMenu.item[5], TRUE);
  getServerInfo();
  GetStandardColors();
/*
  white1 = GetPrivateColor();
  white2 = GetPrivateColor();
  SetPrivateColor(white2, 0, 0, 0);
*/
  SetBgColor(drawWindow, BLACK);
  curcol = 1;
  SetDrawArea(drawWindow);
  ClearDrawArea();

  SetFgColor(logoWindow  , GetNamedColor("red"));

  inforedisplay(logoWindow, i, i, NULL);
  set_menu_state();

  return argc;
}

void main(int argc, char **argv)
{
  int width, height;
  argc = init_display(argc, argv);  /* setup the display */
  if (argc == 0)
    exit(0);
  winid = 1;
  substate = 0;
  init_geodata();
  getDrawBox();
  getDrawingScale();
  SetDrawArea(drawWindow);
  mySetColor(WHITE); 
  GetDrawAreaSize(&width, &height);
  setAction(NORMAL);
  setIcon();
/*  SetKeypressCB(drawWindow, KeyPressFunc); */
  GREY = GetPrivateColor();
  if(GREY != -1)
    SetPrivateColor(GREY, 100, 100, 100);
  else
    GREY = WHITE;

  color_ps = FALSE;



 

  MainLoop();                                /* go right into the main loop */
}
  


syntax highlighted by Code2HTML, v. 0.9.1