/*****************************************************************************
  FILE           : bn_basics.c
  SHORTNAME      : bn_basics
  SNNS VERSION   : 3.2

  PURPOSE        : Provides general procedures for the BigNet Tool
  NOTES          :

  AUTHOR         : Kai-Uwe Herrmann
  DATE           : 15.1.1993

  CHANGED BY     : Ralf Huebner
  IDENTIFICATION : @(#)bn_basics.c	1.18 3/2/94
  SCCS VERSION   : 1.18
  LAST CHANGE    : 3/2/94

             Copyright (c) 1990-1994  SNNS Group, IPVR, Univ. Stuttgart, FRG

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



#include <stdlib.h>
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/cursorfont.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/Simple.h>
#include <X11/Xaw/Grip.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/SmeBSB.h>
#include <X11/Xaw/SmeLine.h>
#include <X11/Xaw/Viewport.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/Toggle.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Cardinals.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Scrollbar.h>

#include "ui.h"
#include "glob_typ.h"
#include "kr_ui.h"
#include "ui_mainP.h"
#include "ui_confirmer.h"
#include "ui_textP.h"
#include "ui_utilP.h"
#include "ui_netUpdate.h"
#include "ui_status.h"
#include "ui_xWidgets.h"
#include "ui_fileP.h"
#include "ui_display.h"
#include "ui_event.h"
#include "ui_selection.h"

#include "bn_basics.ph"

#include "enter.xbm"
#include "delete.xbm"
#include "insert.xbm"
#include "plane_to_edit.xbm"
#include "type.xbm"
#include "pos.xbm"
#include "overwrite.xbm"
#include "link_to_edit.xbm"
#include "create_net.xbm"
#include "full_connection.xbm"
#include "shortcut_connection.xbm"
#include "cancel.xbm"
#include "next.xbm"
#include "prev.xbm"
#include "first.xbm"
#include "last.xbm"
#include "done.xbm"
#include "feed_forward.xbm"
#include "time_delay.xbm"
#include "create_td_net.xbm"
#include "art1.xbm"
#include "art2.xbm"
#include "artmap.xbm"
#include "kohonen.xbm"
#include "cancel2.xbm"
#include "jordan.xbm"
#include "elman.xbm"
#include "hopfield.xbm"
#include "assoz.xbm"







/*****************************************************************************
  FUNCTION : bn_basics_xCreateButtonItem

  PURPOSE  : create a command widget
  NOTES    :
  RETURNS  : the widget number of the widget
  UPDATE   : 19.1.1993
******************************************************************************/

Widget bn_basics_xCreateButtonItem (char *name,Widget parent,Widget left,Widget top)

{
    uint n;
    Widget   w;
    Arg	     arg[15];
    
    n = 0;
    if (strcmp (name, "enter") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   enter_bits, enter_width, enter_height)); n++;
      } 
    if (strcmp (name, "prev") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   prev_bits, prev_width, prev_height)); n++;
      } 
    if (strcmp (name, "next") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   next_bits, next_width, next_height)); n++;
      } 
    if (strcmp (name, "first") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   first_bits,first_width,first_height)); n++;
      } 
    if (strcmp (name, "last") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   last_bits,last_width,last_height)); n++;
      } 
    if (strcmp (name, "delete") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   delete_bits,delete_width,delete_height)); n++;
      } 
    if (strcmp (name, "insert") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   insert_bits,insert_width,insert_height)); n++;
      } 
    if (strcmp (name, "overwrite") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   overwrite_bits,overwrite_width,overwrite_height)); n++;
      } 
    if (strcmp (name, "plane_to_edit") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   plane_to_edit_bits,plane_to_edit_width,plane_to_edit_height)); n++;
      } 
    if (strcmp (name, "type") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   type_bits,type_width,type_height)); n++;
      } 
    if (strcmp (name, "pos") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   pos_bits,pos_width,pos_height)); n++;
      } 
    if (strcmp (name, "link_to_edit") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   link_to_edit_bits,link_to_edit_width,link_to_edit_height)); n++;
      } 
    if (strcmp (name, "full_connection") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   full_connection_bits,full_connection_width,full_connection_height)); n++;
      } 
    if (strcmp (name, "shortcut_connection") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   shortcut_connection_bits,shortcut_connection_width,
		   shortcut_connection_height)); n++;
      } 
    if (strcmp (name, "create_td_net") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display),create_td_net_bits,
		   create_td_net_width,create_td_net_height)); 
        n++;
      } 
    if (strcmp (name, "done") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   done_bits,done_width,done_height)); n++;
      } 
    if (strcmp (name, "cancel") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   cancel_bits,cancel_width,cancel_height)); n++;
      } 
    if (strcmp (name, "create_net") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   create_net_bits,create_net_width,create_net_height)); n++;
      } 
    if (strcmp (name, "feed_forward") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   feed_forward_bits,feed_forward_width, feed_forward_height)); 
        n++;
      } 
    if (strcmp (name, "time_delay") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   time_delay_bits,time_delay_width,time_delay_height)); 
        n++;
      } 
    if (strcmp (name, "art1") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   art1_bits, art1_width, art1_height)); n++;
      } 
    if (strcmp (name, "art2") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   art2_bits, art2_width, art2_height)); n++;
      } 
    if (strcmp (name, "artmap") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   artmap_bits,artmap_width,artmap_height)); n++;
      } 

    if (strcmp (name, "kohonen") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   kohonen_bits,kohonen_width,kohonen_height)); n++;
      } 
    if (strcmp (name, "hopfield") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   hopfield_bits,hopfield_width,hopfield_height)); n++;
      } 

    if (strcmp (name, "assoz") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   assoz_bits,assoz_width,assoz_height)); n++;
      } 

    if (strcmp (name, "cancel2") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   cancel2_bits,cancel2_width,cancel2_height)); n++;
      } 
 
    if (strcmp (name, "jordan") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   jordan_bits,jordan_width,jordan_height)) ; n++ ;
      } 

    if (strcmp (name, "elman") == 0)
      {  
        XtSetArg(arg[n], XtNbitmap, 
                  (Pixmap) XCreateBitmapFromData (ui_display,
                   XDefaultRootWindow (ui_display), 
                   elman_bits,elman_width,elman_height)) ; n++ ;
      } 

    XtSetArg(arg[n], XtNborderWidth, 0); n++;
    XtSetArg(arg[n], XtNinternalHeight, 1); n++;
    XtSetArg(arg[n], XtNinternalWidth , 1); n++;

    XtSetArg(arg[n], XtNfromVert , top);  n++;
    XtSetArg(arg[n], XtNfromHoriz, left);  n++;
    XtSetArg(arg[n], XtNleft  , XtChainLeft); n++;
    XtSetArg(arg[n], XtNright , XtChainLeft); n++;
    XtSetArg(arg[n], XtNtop   , XtChainTop); n++;
    XtSetArg(arg[n], XtNbottom, XtChainTop); n++;
    w = XtCreateManagedWidget(name, commandWidgetClass, parent, arg, n);
    return(w);

}



/*****************************************************************************
  FUNCTION : bn_basics_createART

  PURPOSE  : create ART1 panel
  NOTES    : calling function has to allocate memory for unitWidget and
             rowWidget arrays.

  UPDATE   : 20.1.1993
******************************************************************************/

void bn_basics_createART(int model, Widget *baseWidget,int *already_open,
                         Widget unitWidget[], Widget rowWidget[],
                         XtCallbackProc   CreateCallbackProc,
                         XtCallbackProc   DoneCallbackProc
                        )

{
    Widget      artpanel, artform, button, dummy1x, dummy1y;
    Widget      dummy2x, dummy3, dummy4, dummy5;
    Arg		args[10];
    Cardinal	n = 0;
    char        buf[40];
    int         colwidth = 12;
    int         Width, Height;
    int         NoOfDialogRows;
    int         i;
    char        Name[4][20];
    char        ModelName[20];
    
    switch (model) {
    case ART1_MODEL:
       sprintf(ModelName,"ART 1");
       Width = 314;
       Height = 103;
       NoOfDialogRows = 2;
       strcpy(Name[0],"F1 layer: ");
       strcpy(Name[1],"F2 layer: ");
       break;
    case ART2_MODEL:
       sprintf(ModelName,"ART 2");
       Width = 314;
       Height = 124;
       NoOfDialogRows = 2;
       strcpy(Name[0],"F1 layer: ");
       strcpy(Name[1],"F2 layer: ");
       break;
    case ARTMAP_MODEL:
       sprintf(ModelName,"ARTMAP");
       Width = 314;
       Height = 149;
       NoOfDialogRows = 4;
       strcpy(Name[0],"F1a layer: ");
       strcpy(Name[1],"F2a layer: ");
       strcpy(Name[2],"F1b layer: ");
       strcpy(Name[3],"F2b layer: ");
       break;
    default:
       *baseWidget = NULL;
       *already_open = 0;
       return;
    } /*switch*/

    if ( ! *already_open) {

       sprintf(buf,"BigNet (%s)", ModelName);
       
/*
       XtSetArg(args[n],XtNminHeight,Height); n++;
       XtSetArg(args[n],XtNminWidth,Width); n++;  
       XtSetArg(args[n],XtNmaxHeight,Height); n++;
       XtSetArg(args[n],XtNmaxWidth,Width); n++;
*/       

       *baseWidget = 
	    XtCreatePopupShell(buf, topLevelShellWidgetClass, ui_toplevel,
	                       args, n);

       artform = XtCreateManagedWidget ("box", boxWidgetClass, *baseWidget, args,n);

       artpanel = XtCreateManagedWidget ("form", formWidgetClass, artform,
					  NULL, 0);

       
       /* Headings */
       dummy1y = dummy1x =
             ui_xCreateLabelItem (" ",artpanel, colwidth*8, NULL, NULL);
       dummy2x = 
             ui_xCreateLabelItem ("No. of units", artpanel, colwidth*8, dummy1x, NULL);
       dummy3 = 
             ui_xCreateLabelItem ("No. of rows", artpanel, colwidth*8, dummy2x, NULL);

       /* dialog rows */
       for (i=0; i<NoOfDialogRows; i++) {

          dummy3 = 
            ui_xCreateLabelItem (Name[i], artpanel, colwidth*8, NULL, dummy1y);
          dummy4 = 
            ui_xCreateLabelItem (" ", artpanel, 2*8, dummy1x,dummy1y);
          unitWidget[i] = 
            ui_xCreateDialogItem (" ", artpanel, "",  6*8, dummy4, dummy1y);
          dummy5 = 
            ui_xCreateLabelItem (" ", artpanel, 2*8, dummy2x, dummy1y);
          rowWidget[i]  = dummy1y = 
            ui_xCreateDialogItem (" ", artpanel, "",  6*8, dummy5, dummy1y);
         
       } /*for*/
       
       /* blank line */
/*       dummy3 = ui_xCreateLabelItem (" ", artpanel, colwidth*8, NULL, dummy1y); */

       dummy3 = dummy5;

       /* buttons have to be defined by calling procedure */
       button = bn_basics_xCreateButtonItem ("create_net", artform, NULL, dummy3);
         XtAddCallback (button, XtNcallback, CreateCallbackProc, NULL); 
       button = bn_basics_xCreateButtonItem ("done", artform, button, dummy3);
         XtAddCallback (button, XtNcallback,DoneCallbackProc, NULL); 

       ui_checkWindowPosition(*baseWidget);
       XtPopup (*baseWidget, XtGrabNone); 
       ui_xDontResizeWidget (*baseWidget);

       *already_open = 1;

   } else {
       
       sprintf (buf,"BigNet (%s) already loaded!", ModelName);
       ui_confirmOk (buf);

   } /*if*/

}




/*****************************************************************************
  FUNCTION : bn_basics_refresh();

  PURPOSE  : refresh Dispaly
  NOTES    :

  UPDATE   : 20.1.1993
******************************************************************************/

void bn_basics_refresh (void)

{

   ui_sel_resetList();
   ui_net_completeRefresh(ui_currentDisplay,2);
   ui_stat_displayStatus(ui_gridPosMouse);
   strcpy(ui_filenameNET,"SNNS_NET");
   strcpy(ui_filenameSLNET,"SNNS_NET");
   ui_file_updateShellLabels();

}



/*****************************************************************************
  FUNCTION : bn_basics_check_existingNetwork();

  PURPOSE  : check if network exists and if so, as user if he wants to erase
             it by creating the new one
  NOTES    : returns TRUE, if no current network exists or user pressed YES.
             returns FALSE, if current network exists and user pressed NO.

  UPDATE   : 20.1.1993
******************************************************************************/

int bn_basics_check_existingNetwork (void)

{

  if (krui_getNoOfUnits()) { /* There is an existing network */

     if ( ! ui_confirmYes ("Create will erase current network. Create?")) {
        return 0;
     } else {
        krui_deleteNet();
        return 1;
     } /*if*/

  } else { /* There is no existing network */

      return 1;

  } /*if*/

} 





/*****************************************************************************
  FUNCTION : bn_basics_getValues();

  PURPOSE  : read out user values from dialog widgets
  NOTES    : calling function has to allocate memory for unit and row array

  UPDATE   : 20.1.1993
******************************************************************************/

void bn_basics_getValues (int NoOfLayers, int units[], int rows[],
                          Widget unitWidget[], Widget rowWidget[])

{
   int i;

   for (i=0; i<NoOfLayers; i++) {
      units[i] = ui_xIntFromAsciiWidget(unitWidget[i]);
      rows[i]  = ui_xIntFromAsciiWidget(rowWidget[i]);
   } /*for*/

   return;

}


/*****************************************************************************
  FUNCTION : bn_basics_checkValues();

  PURPOSE  : check the values, the user entered
  NOTES    : returns TRUE, if values OK
             returns FALSE, if illegal values have been entered.
             calling function has to allocate memory for unit and row array

  UPDATE   : 20.1.1993
******************************************************************************/

int bn_basics_checkValues (int NoOfLayers, int units[], int rows[])

{
   int  i;
   char buf[80];

   for (i=0; i<NoOfLayers; i++) {

     if (units[i] < 1) {
        sprintf (buf,"Number of units has to be greater than 0 in line %d!",i+1);
        ui_confirmOk (buf);
        return 0;
     } /*if*/

     if (rows[i] < 1) {
        sprintf (buf,"Number of rows has to be greater than 0 in line %d!",i+1);
        ui_confirmOk (buf);
        return 0;
     } /*if*/

     if (units[i] < rows[i]) {
        sprintf(buf,
                "Number of rows must not be greater\nthan number of units in line %d!",
                i+1);
        ui_confirmOk (buf);
        return 0;
     } /*if*/

   } /*for*/

   return 1;

} 
