
 
/***************************************************************************
 *                                                                         *
 * 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>

/* slingshot headers */

#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 "all_ui.h"
#include "externs.h"

#include "constants.h"
#include "grays.h"
#include "funcs.h"

extern Array_tile   target_tile, qual_tile;

char *
retrieve_constructor()
{
  Rectobj_list *the_array_list;
  Rectobj element;
  Tree the_expression;
  Canvas_shell the_shell;
  Frame the_frame;
  int item;
  char *the_answer, *ahead;
  char temp[8196];
  int ROWS, COLS, row, col;
  char *newattr;
  char *footer;

  temp[0] = '\0';
  the_array_list = (Rectobj_list *) xv_get(target_tile, RECTOBJ_CHILDREN);
  the_shell = (Canvas_shell) xv_get(target_tile, XV_OWNER);
  /* the_frame = (Frame) xv_get(the_shell, XV_OWNER); */
  the_frame = target_frame;

  if ( (footer = (char *) xv_get(the_frame, FRAME_LEFT_FOOTER)) &&
       (footer[0] != '\0') )
    ahead = strdup( (char *) xv_get(the_frame, FRAME_LEFT_FOOTER) );
  else
    ahead = NULL;

  if ( ahead )
    if ( (char *) strstr(ahead, "delete") )
      strcpy(temp, ahead);
 
  if ( the_array_list ) { 
  
    item = 0;
    ROWS = (int) xv_get(target_tile, ARRAY_TILE_N_ROWS);
    COLS = (int) xv_get(target_tile, ARRAY_TILE_N_COLUMNS);

    for ( row = 0; row < ROWS; row++ ) {
      for ( col = 0; col < COLS; col++ ) {
	if ( xv_get(target_tile, ARRAY_TILE_POSITION, col, row) ) {
	  if ( item )	 		/* more than one */
	    strcat(temp, ", ");
	  else if ( ahead ) {
	    (void) strcpy(temp, ahead);
	    (void) strcat(temp, "(");
	  }
	  else
	    (void) strcpy(temp, "retrieve ("); 
	  element = (Rectobj) xv_get(target_tile, 
				     ARRAY_TILE_POSITION, col, row);
	  the_expression = (Tree) xv_get(element, XV_KEY_DATA, EXPRESSION_TREE);
	  newattr = (char *) xv_get(element, DRAWTEXT_STRING);
	  if ( newattr[ strlen( newattr )-2 ] == '=' )
	    strcat( temp, newattr );
	  strcat(temp, expression_constructor(the_expression, the_expression));
	  
	  item++;
	}
      }
    }
    if ( temp[0] )
      if ( !( (char *) strstr(temp, "delete") ) )
	strcat(temp, ") "); 
  }
  return temp;
}

/* This one is just check the classes array and see 
 * if there is an array attached to them, get the element
 * list them and you know what 
 */
char *
from_constructor()
{
  char temp[8196];
  Rectobj_list *the_class_children, *the_instances, *the_children;
  Rectobj the_class, the_instance, the_array, dumb;
  int item1, item2;

  temp[0] = '\0';
  the_class_children = (Rectobj_list *) xv_get(classes, RECTOBJ_CHILDREN);
  item1 = 0;
  list_for(the_class_children) {
   
    the_class = RECTOBJ_LIST_HANDLE(the_class_children);
   
    the_array = (Array_tile) xv_get(the_class, XV_KEY_DATA, INSTANCES);
    if(the_array) {   
      the_instances = (Rectobj_list *) xv_get(the_array, RECTOBJ_CHILDREN);
      if(the_instances) { /* the class is instanciated */
	if(item1) {
	  strcat(temp, ", ");
	} else { 
	  (void) strcpy(temp, "from ");
	}
	item2 = 0;
	list_for(the_instances) {/* iterate over the instances */
	  if(item2) {
	    strcat(temp, ", ");
	  }
	  the_instance = RECTOBJ_LIST_HANDLE(the_instances);
	  strcat(temp, (char *) xv_get(the_instance, DRAWTEXT_STRING));
	  item2++;
	}
	strcat(temp, " in ");
	strcat(temp, (char *) xv_get(the_class, DRAWTEXT_STRING));
	item1++; 		/* only count the instanciated classes */
      }
    } 
  }
  if(temp[0] == NULL) return " "; else return temp;
}

char *
where_constructor()
{
  Rectobj_list *the_array_list;
  Rectobj element;
  Tree the_expression;
  int item, balance;
  char *the_answer;
  char temp[8196];

  if ( ( Tree ) xv_get(qual_shell, XV_KEY_DATA, THE_ARRAY) ) {
    (void) strcpy(temp, " where ");
    strcat(temp, where_tree_constructor( (Tree) xv_get(qual_shell,
						       XV_KEY_DATA,
						       THE_ARRAY), 
                                         (Rectobj) xv_get(qual_shell,
							  XV_KEY_DATA,
							  THE_ARRAY)));
  }
  else
    temp[0] = '\0';
  return temp;
}

char *
expression_constructor(expression, node)
     Tree expression;
     Rectobj node;
{
/* first, check if node has any child 
 * if not, it is a leaf and all you have
 * to do is to return the label;
 *
 * if have children then it is an internal node
 * and you do the following:
 *
 *  1) if it is an OPER
 *      a) "("
 *      b) obtain left_child = expression_constructor(expression, left_child_node)
 *      c) obtain the node label
 *      d) obtain right_child = expression_constructor(expression, right_child_node)
 *      e) ")"
 *      f) return all the things concatenated
 * 
 *  2) if it is an FUNC
 *     a) obtain label
 *     b) "("
 *     c) obtain child = expression_constructor(expression, child)
 *     d) if more children, add "," next_child = expression_constructor(expression, next_child)
 *     e) ") "
 *     f) return all the things concatenated
 *
 *  3) if it is UNARY
 *     a) obtain label
 *     b) obtain child = expression_constructor(expression, child)
 *     c) return all the things concatenated
 *
 */
  int type, top, child_no;
  Rectobj_list *children;
  Rectobj left, right, dumb;
  char *the_answer;
  char *left_par = "(";
  char *right_par = ") ";
  char temp[8196];

  children = (Rectobj_list *) xv_get(expression, TREE_LINK_TO_LIST, node);

  if ( expression == node ) { 
    top = 1; 
  }
  else { 
    top = 0; 
  } /* to root or not to root */
 
  if ( children != NULL ) { /* cool this is not the end */
    if ( !top ) { /* this is not root so check what type is it */
      type = (int) xv_get(node, XV_KEY_DATA, TYPE);
      switch(type) {
       case OPER:
	child_no = 0;
	(void) strcpy(temp, left_par);
	list_for(children) {
	  if(child_no == 0) {
	    dumb = RECTOBJ_LIST_HANDLE(children);
	    strcat(temp, expression_constructor(expression, dumb));
	  } 
	  else {
	    strcat(temp, (char *) xv_get(node, DRAWTEXT_STRING));
	    dumb = RECTOBJ_LIST_HANDLE(children);
	    strcat(temp, expression_constructor(expression, dumb));
	  }
	  child_no++;
	}
	strcat(temp, right_par);

	/*the_answer = strdup(temp); */          
	break;
      case FUNC:
	/* Hopefully you will know the number of parameters 
	   until I put them here */
	(void) strcpy(temp, (char *) xv_get(node, DRAWTEXT_STRING));
	strcat(temp, left_par);
	child_no = 0;
	list_for(children) {
           if(!child_no) {
             dumb = RECTOBJ_LIST_HANDLE(children);
             strcat(temp, expression_constructor(expression, dumb));
           } else {
             dumb = RECTOBJ_LIST_HANDLE(children);
             strcat(temp, ", ");
             strcat(temp, expression_constructor(expression, dumb));
           }
           child_no++;
         }
         strcat(temp, right_par);
         /* the_answer = strdup(temp); */
         break;
       case UNARY:
         sprintf(temp, "%s", (char *) xv_get(node, DRAWTEXT_STRING));
         dumb = RECTOBJ_LIST_HANDLE(children);
         strcat(temp, expression_constructor(expression, dumb));
        /* the_answer = strdup(temp); */
         break;
      }
    }
    else { /* the root!!! */
     list_for(children) { /* one node under the tree */
       dumb = RECTOBJ_LIST_HANDLE(children);
       /* the_answer = strdup(expression_constructor(expression, dumb)); */
       sprintf(temp, "%s", expression_constructor(expression, dumb));
     }
   }

  } 
  else { /* a nice leaf */

    if ( !top ) { /* checking we don't have an empty tree, you never know */
      /* the_answer = strdup((char *) xv_get(node, DRAWTEXT_STRING)); */
      sprintf(temp, "%s", (char *) xv_get(node, DRAWTEXT_STRING));
    }

  }   
      
  return temp;
}

