
 
/***************************************************************************
 *                                                                         *
 * 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 <tmp/c.h>
#include <tmp/libpq-fe.h>

#include "constants.h"
#include "switches.h"
#include "first_ui.h"
#include "replace_interface_ui.h"

extern int PQtracep;
extern first_window1_objects *first_window1;
extern int tuple_fetch();

/*
 * Notify callback function for `attribute_list'.
 */
int
attribute_select_replace(item, string, client_data, op, event)
     Panel_item	item;
     char		*string;
     Xv_opaque		client_data;
     Panel_list_op	op;
     Event		*event;
{
  replace_interface_pop_objects	*ip = 
    (replace_interface_pop_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  char *temp, value[8196], *whole_thing;
  int ROWS, row, item_no;
	
  switch(op) {
  case PANEL_LIST_OP_DESELECT:
    xv_set(ip->attribute_value_field, XV_SHOW, FALSE, NULL);
    xv_set(ip->type_message, XV_SHOW, FALSE, NULL);
    
    break;

  case PANEL_LIST_OP_SELECT:
    /* Strcat the value typed in the text item with the contents of client_data 
     * PANEL_LIST_CLIENT_DATA for the value.  
     */
    ROWS = (int) xv_get(ip->attribute_list, PANEL_LIST_NROWS);
    for(row = 0 ; row < ROWS ; row++) { /* list_item selected */
      if ( xv_get(ip->attribute_list, PANEL_LIST_SELECTED, row) ) {
	item_no = row;
      }
    }
    whole_thing = (char *) client_data;
    temp = strdup(strstr(whole_thing, "::")); 
    xv_set(ip->type_message, 
	   PANEL_LABEL_STRING, temp, 
	   PANEL_CLIENT_DATA, item_no, 
	   NULL);
    strcpy(value, whole_thing);
    if ( !strcmp(temp, whole_thing) ) { /* no value */
      xv_set(ip->attribute_value_field, 
	     PANEL_VALUE, "", 
	     NULL);
    }
    else { /* value */
      value[strlen(whole_thing) - strlen(temp)] = '\0'; /* cut the value out */
      xv_set(ip->attribute_value_field, 
	     PANEL_VALUE, value, 
	     NULL);
    }
    xv_set(ip->attribute_value_field, XV_SHOW, TRUE, NULL);
    xv_set(ip->type_message, XV_SHOW, TRUE, NULL);
		
    break;

  case PANEL_LIST_OP_VALIDATE:
		
    break;

  case PANEL_LIST_OP_DELETE:
	
    break;
  }
  return XV_OK;
}

/*
 * Notify callback function for `replace_button'.
 */
void
replace_tuple_proc(item, event)
	Panel_item	item;
	Event		*event;
{
  replace_interface_pop_objects	*ip = 
    (replace_interface_pop_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  char temp[8196], query_buffer[8196], temp_q[8196], oid[512], 
       *type, *whole, *value, t_value[8196]; 
  int ROWS, row, later_item, first;

  temp[0] = '\0';
  later_item = 0;
  first = 1;
  ROWS = (int) xv_get(ip->attribute_list, PANEL_LIST_NROWS);
  for(row = 0 ; row < ROWS ; row++) { /* construct the query */
    whole = strdup((char *) xv_get(ip->attribute_list, 
				    PANEL_LIST_CLIENT_DATA, row));
    strcpy(t_value, whole);
    type = strdup(strstr(whole, "::"));
    t_value[strlen(whole) - strlen(type)] = '\0';
    value = strdup(t_value);
    if ( strcmp(whole, type) ) { /* include */
      if ( first ) {       /* first item */
	strcpy(temp, "replace ");
	strcat(temp, (char *) xv_get(ip->pop, FRAME_LABEL));
	strcat(temp, " (");
	strcat(temp, xv_get(ip->attribute_list, PANEL_LIST_STRING, row));
	strcat(temp, "\"");
	strcat(temp, value);
	strcat(temp, "\"");
	strcat(temp, type);
	first = 0;
      } 
      else { /* not first append a comma */
	strcat(temp, ", ");
	strcat(temp, xv_get(ip->attribute_list, PANEL_LIST_STRING, row));
	strcat(temp, "\"");
	strcat(temp, value);
	strcat(temp, "\"");
	strcat(temp, type);
      }
    }
  }
  if ( !first ) {
    strcat(temp, ") where ");
    sprintf(oid, "%s.oid = \"%s\"::oid", 
	    (char *) xv_get(ip->pop, FRAME_LABEL), 
	    (char *) xv_get(ip->pop, XV_KEY_DATA, TYPENAME));
    strcat(temp, oid);
  }
  strcpy(query_buffer, temp);
     
         

  
  xv_set(ip->pop, FRAME_LEFT_FOOTER, "Replace submitted", NULL);
  
  if ( Verbose )
    textsw_insert(first_window1->textpane3, "\n", 1);
                  
  strcpy(temp_q, clean_query(query_buffer));
 
  if ( Verbose ) {
    textsw_insert(first_window1->textpane3,
		  "Query sent to Postgres Backend:\n", 32);
    textsw_insert(first_window1->textpane3, temp_q, strlen(temp_q));
    textsw_insert(first_window1->textpane3, "\n", 1); 
  }
 
  if (handle_execution(temp_q, first_window1) == 1)
    backend_error( "Postgres backend returned error" );
  else { 
    xv_set(first_window1->window1, FRAME_LEFT_FOOTER, "No errors", NULL); 
    if ( temp_q[0] ) {
      insert_in_command_stack(temp_q);
	    
      for(row = 0 ; row < ROWS ; row++) { /* cut the values from 
					     the client_datas */
	whole = strdup((char *) xv_get(ip->attribute_list, 
				       PANEL_LIST_CLIENT_DATA, row));
	type = strdup(strstr(whole, "::"));
	xv_set(ip->attribute_list, 
	       PANEL_LIST_CLIENT_DATA, row, type, 
	       NULL);
      }
    } 
  }

  if ( (char *) strstr(temp_q, "create") || 
       (char *) strstr(temp_q, "retrieve into") || 
       (char *) strstr(temp_q, "addattr") )
    update_schema();

  bzero(query_buffer, strlen(query_buffer));    /* query_buffer[0] = 0; 
						   and the buffer     */

  /* get the new values oficially */
  xv_set(ip->pop, FRAME_BUSY, TRUE, NULL);
  (void) tuple_fetch((char *) xv_get(ip->pop, FRAME_LABEL), 
		     atoi((char *) xv_get(ip->pop, FRAME_RIGHT_FOOTER)));
  xv_set(ip->pop, FRAME_BUSY, FALSE, NULL);
	
	
}

/*
 * Notify callback function for `which_tuple_setting'.
 */
void
which_tuple_proc(item, value, event)
	Panel_item	item;
	int		value;
	Event		*event;
{
	replace_interface_pop_objects	*ip = (replace_interface_pop_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
        int total_tuples, current_tuple, new_tuple;
        char new_index[100], *new_index_ptr;

        xv_set(ip->pop, FRAME_BUSY, TRUE, NULL);
        total_tuples = xv_get(ip->pop, XV_KEY_DATA, CLASS);
        current_tuple = atoi((char *) xv_get(ip->pop, FRAME_RIGHT_FOOTER));

        switch(value) {
         case 0: /* Next */
            if((total_tuples) != (current_tuple + 1)) {
             sprintf(new_index, "%d", current_tuple + 1);
             new_tuple = current_tuple + 1;
             total_tuples = tuple_fetch((char *) xv_get(ip->pop, FRAME_LABEL), new_tuple);
            } else {
             sprintf(new_index, "%d", 0);
             new_tuple = 0;
             total_tuples = tuple_fetch((char *) xv_get(ip->pop, FRAME_LABEL), new_tuple);
            }
            break;
         case 1: /* Re-read the current one */
            sprintf(new_index, "%d", current_tuple);
            new_tuple = current_tuple;
            total_tuples = tuple_fetch((char *) xv_get(ip->pop, FRAME_LABEL), new_tuple);
            break;
         case 2: /* Prior */
            if(0 > (current_tuple - 1)) {
             sprintf(new_index, "%d", total_tuples - 1);
             new_tuple = total_tuples - 1;
             total_tuples = tuple_fetch((char *) xv_get(ip->pop, FRAME_LABEL), new_tuple);
            } else {
             sprintf(new_index, "%d", current_tuple - 1);
             new_tuple = current_tuple - 1;
             total_tuples = tuple_fetch((char *) xv_get(ip->pop, FRAME_LABEL), new_tuple);
            }            
            break;
        }
if(total_tuples) {
         xv_set(ip->tuple_slider,
              PANEL_VALUE, new_tuple,
              PANEL_MAX_VALUE, total_tuples - 1,
              NULL);
        new_index_ptr = strdup(new_index);
        xv_set(ip->pop, 
                      XV_SHOW, TRUE,  
                      FRAME_LEFT_FOOTER, "tuple", 
                      FRAME_RIGHT_FOOTER, new_index_ptr,
                      NULL);
        xv_set(ip->which_tuple_setting,
                      XV_SHOW, TRUE,
                      NULL);
} else {
                   xv_set(ip->pop, 
                      FRAME_LEFT_FOOTER, "No tuples",
                      XV_KEY_DATA, CLASS, total_tuples, 
                      FRAME_RIGHT_FOOTER, "",
                      NULL);
                   xv_set(ip->which_tuple_setting,
                      XV_SHOW, FALSE,
                      NULL);
                   xv_set(ip->tuples_message,
                      XV_SHOW, FALSE,
                      NULL);                  
                   xv_set(ip->tuple_slider,
                      XV_SHOW, FALSE,
                      NULL);
        
} 
        xv_set(ip->pop, FRAME_BUSY, FALSE, NULL);	

}

/*
 * Notify callback function for `attribute_value_field'.
 */
Panel_setting
attribute_value_change_replace(item, event)
     Panel_item	item;
     Event	*event;
{
  replace_interface_pop_objects	*ip = 
    (replace_interface_pop_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  int item_list_no;
  char *type, *whole_thing, final[8192];
  char *value = (char *) xv_get(item, PANEL_VALUE);


  item_list_no = (int) xv_get(ip->type_message, PANEL_CLIENT_DATA);
  whole_thing = strdup((char *) xv_get(ip->attribute_list, 
				       PANEL_LIST_CLIENT_DATA, item_list_no));
  type = strdup(strstr(whole_thing, "::"));
  strcpy(final, value);
  strcat(final, type);
  whole_thing = strdup(final);
  xv_set(ip->attribute_list, 
	 PANEL_LIST_CLIENT_DATA, item_list_no, whole_thing, 
	 NULL);
	
  return panel_text_notify(item, event);
}

/*
 * Notify callback function for `tuple_slider'.
 */
void
replace_tuples_easy_travel(item, value, event)
     Panel_item      item;
     int             value;
     Event           *event;
{
  replace_interface_pop_objects   *ip = 
    (replace_interface_pop_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  char new_index[100], *new_index_ptr;
  int new_tuple, total_tuples;

  xv_set(ip->pop, FRAME_BUSY, TRUE, NULL);

  sprintf(new_index, "%d", value);
  new_tuple = value;
  total_tuples = tuple_fetch1((char *) xv_get(ip->pop, FRAME_LABEL), new_tuple);
  if(total_tuples) {
    new_index_ptr = strdup(new_index);
    xv_set(ip->pop, 
	   XV_SHOW, TRUE,
	   XV_KEY_DATA, CLASS, total_tuples,  
	   FRAME_LEFT_FOOTER, "tuple", 
	   FRAME_RIGHT_FOOTER, new_index_ptr,
	   NULL);
    xv_set(item, PANEL_MAX_VALUE, total_tuples - 1, NULL);

  } 
  else {
    xv_set(ip->pop, 
	   FRAME_LEFT_FOOTER, "No tuples",
	   XV_KEY_DATA, CLASS, total_tuples, 
	   FRAME_RIGHT_FOOTER, "",
	   NULL);
    xv_set(ip->which_tuple_setting,
	   XV_SHOW, FALSE,
	   NULL);
    xv_set(ip->tuples_message,
	   XV_SHOW, FALSE,
	   NULL);                  
    xv_set(ip->tuple_slider,
	   XV_SHOW, FALSE,
	   NULL);
        
  }         
  xv_set(ip->pop, FRAME_BUSY, FALSE, NULL);
        
}
