
 
/***************************************************************************
 *                                                                         *
 * Alberi:  Graphical Language Interface for POSTGRES                      *
 *                                                                         *
 * Copyright (c) 1992, 1993 The University of Georgia Research             *
 *                          Foundation, Inc.                               *
 *                                                                         *
 ***************************************************************************
 *                                                                         *
 * Designer and Programmer:  Ruben Robles                                  *
 * Email:  ruben@pollux.cs.uga.edu or rubenr3@aol.com or                   *
 *         rubenr3@psi.com@aol.com                                         *
 *                                                                         *
 * Modified by:		K.J. Kochut                                        *
 *			Department of Computer Science                     *
 *			University of Georgia                              *
 *			Athens, GA 30602                                   *
 *                                                                         *
 * Send comments/fixes/improvements/modifications to:                      *
 *                                                                         *
 *                     kochut@cs.uga.edu                                   *
 *                                                                         *
 ***************************************************************************/


#include <xview/xview.h>
#include <xview/panel.h>
#include <xview/textsw.h>
#include <xview/xv_xrect.h>

#include <sspkg/canshell.h>
#include <sspkg/rectobj.h>
#include <sspkg/drawobj.h>
#include <sspkg/tree.h>
#include <sspkg/array.h>
#include <sspkg/list.h>

#include <tmp/c.h>
#include <tmp/libpq-fe.h>

#include "delete_instances_ui.h"
#include "constants.h"


extern int PQtracep;

/*
 * Notify callback function for `class_list'.
 */
int
delete_class_selection(item, string, client_data, op, event)
     Panel_item	item;
     char		*string;
     Xv_opaque		client_data;
     Panel_list_op	op;
     Event		*event;
{
  delete_instances_pop_objects	*ip = 
    (delete_instances_pop_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  Rectobj_list *the_classes, *the_instances, *the_array;
  Array_tile class_list, instances_list;
  Rectobj class, temp, instance;
  char *classname, *the_parent_name, *current_name;
	
  switch (op) {
  case PANEL_LIST_OP_DESELECT:
    while((int) xv_get(ip->instances_list, PANEL_LIST_NROWS))  
      xv_set(ip->instances_list, 
	     PANEL_LIST_DELETE, 0,
	     NULL);
    xv_set(ip->instances_list, PANEL_LABEL_STRING, "Nothing", NULL);
    xv_set(ip->instance_field, PANEL_VALUE, "", NULL);
		
    break;

  case PANEL_LIST_OP_SELECT:
    class_list = (Array_tile) xv_get(ip->pop, XV_KEY_DATA, FUNC);
    the_classes = (Rectobj_list *) xv_get(class_list, RECTOBJ_CHILDREN);
    list_for(the_classes) {
      temp = RECTOBJ_LIST_HANDLE(the_classes);
      classname = strdup((char *) xv_get(temp, DRAWTEXT_STRING));
      if (!strcmp(classname, string))
	class = temp;
    }
    the_array = (Rectobj_list *) xv_get(class, RECTOBJ_CHILDREN);
    xv_set(ip->instances_list, XV_KEY_DATA, OPER, class, NULL);
    if ( (Array_tile) xv_get(class,
			     XV_KEY_DATA, INSTANCES) == 0) {  /* Do nothing */
      while ((int) xv_get(ip->instances_list, PANEL_LIST_NROWS))  
	xv_set(ip->instances_list, 
	       PANEL_LIST_DELETE, 0,
	       NULL);
      xv_set(ip->instances_list, PANEL_LABEL_STRING, "Nothing", NULL);
      xv_set(ip->instance_field, PANEL_VALUE, "", NULL);
                  
    }
    else {
      instances_list = (Array_tile) xv_get(class, XV_KEY_DATA, INSTANCES);
  
      current_name = (char *) malloc(15*sizeof(char) + strlen(classname));
      sprintf(current_name, "%s's instances", classname);
      xv_set(ip->instances_list, PANEL_LABEL_STRING, current_name, NULL);
      the_instances = (Rectobj_list *) xv_get(instances_list, RECTOBJ_CHILDREN);
      while((int) xv_get(ip->instances_list, PANEL_LIST_NROWS))  
	xv_set(ip->instances_list, 
	       PANEL_LIST_DELETE, 0,
	       NULL);
      
      if ((Rectobj_list *) the_instances != NULL) {
	list_for(the_instances) {
	  temp = RECTOBJ_LIST_HANDLE(the_instances);
       
	  the_parent_name = strdup((char *) xv_get(temp, DRAWTEXT_STRING));
	  xv_set(ip->instances_list, 
		 PANEL_LIST_INSERT, 
		   (int) xv_get(ip->instances_list, PANEL_LIST_NROWS),
		 PANEL_LIST_STRING, 
		   (int) xv_get(ip->instances_list, PANEL_LIST_NROWS) , 
		   the_parent_name,
		 PANEL_LIST_CLIENT_DATA, 
		   (int) xv_get(ip->instances_list, PANEL_LIST_NROWS), 
		   (Rectobj) instance,
		 NULL);
	}
      }
    }
		
    break;

  case PANEL_LIST_OP_VALIDATE:
		
    break;

  case PANEL_LIST_OP_DELETE:
		
    break;
  }
  return XV_OK;

}

/*
 * Notify callback function for `instances_list'.
 */
int
delete_instance_select(item, string, client_data, op, event)
	Panel_item	item;
	char		*string;
	Xv_opaque	client_data;
	Panel_list_op	op;
	Event		*event;
{
	delete_instances_pop_objects	*ip = (delete_instances_pop_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
	
        char *the_field;
	
	switch(op) {
	case PANEL_LIST_OP_DESELECT:
                xv_set(ip->instance_field, PANEL_VALUE, "", NULL);
	
		break;

	case PANEL_LIST_OP_SELECT:
                the_field = strdup(string);
                xv_set(ip->instance_field, PANEL_VALUE, the_field, NULL);
		
		break;

	case PANEL_LIST_OP_VALIDATE:
		
		break;

	case PANEL_LIST_OP_DELETE:
		
		break;
	}
	return XV_OK;
}

/*
 * Notify callback function for `assign_button'.
 */
void
assign_the_delete_command(item, event)
	Panel_item	item;
	Event		*event;
{
	delete_instances_pop_objects	*ip = (delete_instances_pop_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
	Canvas_shell the_shell;
        Frame the_frame;
        Array_tile attrib_array;
        char *classname, *footer, temp2[36];
        int ROWS, row;

        the_shell = (Canvas_shell) xv_get(ip->pop, XV_KEY_DATA, OPER);
        the_frame = (Frame) xv_get(the_shell, XV_OWNER);
        classname = "";
        ROWS = (int) xv_get(ip->class_list, PANEL_LIST_NROWS);
        for(row = 0 ; row < ROWS ; row++) {
            if((Bool) xv_get(ip->class_list, PANEL_LIST_SELECTED, row)) 
              classname = strdup((char *) xv_get(ip->class_list, PANEL_LIST_STRING, row)); 
        }
        
        xv_set(the_shell, RECTOBJ_ACCEPTS_DROP, FALSE, NULL);
        attrib_array = (Array_tile) xv_get(the_shell, XV_KEY_DATA, THE_ARRAY);
        xv_set(the_frame, FRAME_BUSY, TRUE, NULL);
	while (xv_get(attrib_array, ARRAY_TILE_POSITION, 0, 0)) {
            xv_set(attrib_array, ARRAY_TILE_AUTO_LAYOUT, FALSE, NULL);
            xv_destroy((Drawicon) xv_get(attrib_array, ARRAY_TILE_POSITION, 0, 0));
            xv_set(attrib_array, ARRAY_TILE_AUTO_LAYOUT, TRUE, NULL);
	}

        xv_set(the_frame, FRAME_BUSY, FALSE, NULL);

        ROWS = (int) xv_get(ip->instances_list, PANEL_LIST_NROWS); 
        for(row = 0 ; row < ROWS ; row++) {
            if((Bool) xv_get(ip->instances_list, PANEL_LIST_SELECTED, row)) 
              classname = strdup((char *) xv_get(ip->instances_list, PANEL_LIST_STRING, row)); 
        } 
        if(classname) {
            sprintf(temp2, "delete %s ", classname);
            footer = strdup(temp2);
          xv_set(the_frame, FRAME_LEFT_FOOTER, footer, NULL);
          xv_set(ip->pop, XV_SHOW, FALSE, NULL);
        } else xv_set(ip->pop, FRAME_LEFT_FOOTER, "Please select a class/class-instance", XV_SHOW, TRUE, NULL);	
}

/*
 * Notify callback function for `instance_field'.
 */
Panel_setting
delete_instance_typed(item, event)
	Panel_item	item;
	Event		*event;
{
	delete_instances_pop_objects	*ip = (delete_instances_pop_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
	char *	value = (char *) xv_get(item, PANEL_VALUE);
	
        char *the_name, *the_whole_name, *none, *some, *the_attribute;
        int length, character, occurrence, conflict, rows, already;
        Rectobj the_element, the_other, temp, the_class;
        Rectobj_list *the_guys, *class_list, *instance_array_pointer;
        Array_tile the_instances_owner, the_classes, the_instances_array;

        if ((length = strlen(value)) > 16) {
            xv_set(ip->pop, FRAME_LEFT_FOOTER, "Names are 16 characters or less!!", NULL);
            xv_set(item, PANEL_VALUE, "Error", NULL);
         } else {
           if ((!isalpha(value[0]))  && (value[0] != '_'))  {
              xv_set(ip->pop, FRAME_LEFT_FOOTER, "Names start with alphabetic or underscore", NULL);
              xv_set(item, PANEL_VALUE,"Error" , NULL);
           } else {
             for(character =  1; character < length; character++) {
                 if ((!isalnum(value[character])) && (value[character] != '_')) {
                    xv_set(ip->pop, FRAME_LEFT_FOOTER, "Names include alphanumeric and underscore", NULL);
                    xv_set(item, PANEL_VALUE, "Error ", NULL);
                    break;
                 }
             }
          }
        }
        if(strcmp(value, "Error")) {
        /* the name is bona-fide but it is not known if it is already in use then check for its existence 
         * in some other class instances
         */
        the_classes = (Array_tile) xv_get(ip->pop, XV_KEY_DATA, FUNC); 
	the_class = (Rectobj) xv_get(ip->instances_list, XV_KEY_DATA, OPER);
        class_list = (Rectobj_list *) xv_get(the_classes, RECTOBJ_CHILDREN);
        conflict = 0;
        list_for(class_list) {
           temp = RECTOBJ_LIST_HANDLE(class_list);
           if(temp != the_class) {
             instance_array_pointer = (Rectobj_list *) xv_get(temp, RECTOBJ_CHILDREN);
             list_for(instance_array_pointer) {
                the_instances_owner = RECTOBJ_LIST_HANDLE(instance_array_pointer);
             }
             the_guys = (Rectobj_list *) xv_get(the_instances_owner, RECTOBJ_CHILDREN);
             list_for(the_guys) { /* the instances */
                the_element = RECTOBJ_LIST_HANDLE(the_guys);
                none = strdup((char *) xv_get(the_element, DRAWTEXT_STRING));
                if(!strcmp(none, value)) { conflict = 1; }
             }
           }
        }
        if(conflict) 
          xv_set(ip->pop, FRAME_LEFT_FOOTER, "This name used for other instance class", NULL);

        else {        
          if((int) xv_get(ip->instances_list, PANEL_LIST_NROWS)) { /* there are instances then just add */
            rows = (int) xv_get(ip->instances_list, PANEL_LIST_NROWS);
            already = 0;
            for(occurrence = 0 ; occurrence < rows ; occurrence++) { /* check the name is not already in the list */
               none = strdup((char *) xv_get(ip->instances_list, PANEL_LIST_STRING, occurrence));
               if(!strcmp(none, value)) { /* is on the list just select it */
                  xv_set(ip->instances_list, PANEL_LIST_SELECT, occurrence, TRUE, NULL);
                  already = 1;
               }               
            }
            if(!already) { /* create an entry */
                 the_instances_array = (Array_tile) xv_get(the_class, XV_KEY_DATA, INSTANCES);
                 some = strdup(value);
                 (void) xv_create(the_instances_array, DRAWTEXT,
                            DRAWTEXT_STRING, some, 
                            XV_SHOW, FALSE,
                            NULL);
                 xv_set(ip->instances_list, 
                      PANEL_LIST_INSERT, (int) xv_get(ip->instances_list, PANEL_LIST_NROWS), 
                      PANEL_LIST_STRING, (int) xv_get(ip->instances_list, PANEL_LIST_NROWS), some,
                      PANEL_LIST_SELECT, (int) xv_get(ip->instances_list, PANEL_LIST_NROWS), TRUE,
                      NULL);
            }
          } else { /* there is no instances array, create one */
            the_instances_array = (Array_tile) xv_create(the_class, ARRAY_TILE,  
                                       XV_SHOW, FALSE, 
                                       NULL);
            some = strdup(value);
            (void) xv_create(the_instances_array, DRAWTEXT,
                            DRAWTEXT_STRING, some, 
                            XV_SHOW, FALSE,
                            NULL);
            xv_set(the_class, XV_KEY_DATA, INSTANCES, the_instances_array, NULL);
            xv_set(ip->instances_list, 
                      PANEL_LIST_INSERT, (int) xv_get(ip->instances_list, PANEL_LIST_NROWS), 
                      PANEL_LIST_STRING, (int) xv_get(ip->instances_list, PANEL_LIST_NROWS), some,
                      PANEL_LIST_SELECT, (int) xv_get(ip->instances_list, PANEL_LIST_NROWS), TRUE,
                      NULL);
          }
        }
        }
	
	return panel_text_notify(item, event);
}

