/**
 *
 * $Id: glue.c,v 1.3 1996/11/12 03:53:56 miers Exp $
 *
 * Copyright (C) 1995 Free Software Foundation, Inc.
 *
 * This file is part of the GNU LessTif Library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 *  Original author:  Geoffrey W. Ritchey
 *                    codesmit@southwind.net
 *
*/ 
#include "FakeWidget.h"
#include "glue.h"
#include "uil.h"
#include <stdlib.h>
#include <ctype.h>
#include <X11/Xlib.h>
#include "MrmTypes.h"

void Check();

#define StripQuotes(s) {s++;s[strlen(s)-1] = 0;}

extern FakeWidgetList WidgetTable;
extern ExpressionList GlobalSymbolTable;
extern ExpressionList LocalSymbolTable;

/***
 ***        c is a child widget of the widget currently being defind in w.
 ***        c may not be already defined but space has been allocated for it
 ***        already and c points to that space.  This function must put that
 ***        pointer in w's list of children and set c's parent.
 ***/ 
void 
features_controls(char *w, char *c)
{
  FakeWidgetList *children = (FakeWidgetList *)c;
  FakeWidgetType *wid = (FakeWidgetType *)w;
  FakeWidgetList *widChild = FakeWidgetTypeKids(wid);

  if (NULL == c)
    return;

  FakeWidgetListAppendLists(widChild, children);
  FakeWidgetListSetParents(widChild, wid);
}

/***
 ***        a is list of attributes that describe the widget being created
 ***        in w.  'a' needs to be appended to the attribute list that w
 ***        has aquired so far.
 ***/ 
void
features_arguments(char *w, char *a)
{
  FakeWidgetType *wid = ((FakeWidgetType *) w);
  AttributeList *widAtts = FakeWidgetTypeAtts(wid);
  AttributeList *al = (AttributeList *) a;

  if (NULL == a)
    return;
  AttributeListAppendLists(widAtts, al);
}

void
features_callbacks(char *w, char *c)
{
  CallbackList *cl = (CallbackList *) c;
  FakeWidgetType *wid = ((FakeWidgetType *) w);
  CallbackList *widCalls = FakeWidgetTypeCalls(wid);

  if (NULL == cl)
    cl = CallbackListNew();
  CallbackListAppendLists(widCalls, cl);
}

/*
 ***      This is the bottom of the line,  Create space for a widget
 ***      to be defined as we move back up the stack.  It may turn out
 ***      that space the widget we are defining here has already been
 ***      forward referced.  In that case, this widget will be copied to
 ***      that one and destroyed.      
*/          
char *
Features_NULL()
{
  FakeWidgetType *wid = FakeWidgetTypeNew();
  return (char *)wid;
}

char *
InheritControls(char *w, char *name)
{
  FakeWidgetList *wil = (FakeWidgetList *) w;
  FakeWidgetType *wid;

  wid = FakeWidgetTypeNew2(name, "Inherited", 0);
  if (NULL == wil)
    wil = FakeWidgetListNew(NULL);

  FakeWidgetListAppend(wil, wid);
  return (char *) wil;
}
/*
 ***           We are referencing a widget that might not exist yet.
 ***           Look up the widget in the symbol table (Widget List)
 ***           and return its pointer if it is found. If it doesn't exit
 ***           Create the symbol table entry and return a pointer to it.
 ***           The WidgetList being built will be the list of children
 ***           of a Widget being built.
*/
char *
controllist_controllist_ID_ID(char *w, char *theClass, char *name,char managed)
{
  FakeWidgetList *wil = (FakeWidgetList *) w;
  FakeWidgetType *wid;

  wid = FakeWidgetTypeNew2(name,theClass,managed);  
  if (NULL == wil)
    wil = FakeWidgetListNew(NULL);
  FakeWidgetListUpdate(&WidgetTable, &wid);
  FakeWidgetListAppend(wil, wid);
  return (char *)wil;
}

char *control_list_ID_features(char *w, char *theType, 
			       char *wid, char managed)
{
  FakeWidgetList *wil = (FakeWidgetList *) w;
  FakeWidgetType *widget = (FakeWidgetType *) wid;

  if (NULL == wil)
    wil =  FakeWidgetListNew(NULL);
  
  FakeWidgetTypeSetName(widget, NULL, theType);
  if (!managed)
    FakeWidgetTypeUnmanage(widget);
  FakeWidgetListUpdate(&WidgetTable, &widget);
  FakeWidgetListAppend(wil, widget);
  return (char *)wil;
}
/*
 ***           We are building the attribute list for the widget currently
 ***           being built.  Each new attribute is created here.  Its name
 ***           is passed as 'n' and its value is in expr passed through 'e'.
 ***           The attribute should be added to the list in 'a' after its 
 ***           creation.
*/
char *
arglist_arglist_ID_addexpr(char *a, char *name, char *e)
{
  AttributeList *list = (AttributeList *) a;
  ExpressionType *expr = (ExpressionType *) e;

  if (NULL == list)
    list = AttributeListNew();
  if (expr)
    AttributeListAppend(list,ExpressionElementNew1(name, expr));
  return (char *) list;
}

char *
Parameter(char *pl, char *e)
{
  ParameterList *list = (ParameterList *) pl;
  ExpressionType *expr = (ExpressionType *) e;
  ParameterElement *elem = ParameterElementNew1(expr);

  if (NULL == list)
    list =  ParameterListNew();
  if (expr)
    ParameterListAppend(list, elem);
  return (char *) list;
}

char *
WidgetArgument(char *a, char *name, char *widName)
{
  AttributeList *list = (AttributeList *) a;
  ExpressionType *expr = (ExpressionType *)AddrNameNew(widName);
  ExpressionElement *elem =  ExpressionElementNew1(name, expr);
  
  if (NULL == list)
    list = AttributeListNew();
  AttributeListAppend(list, elem);
  return (char *)list;
}

char *
InsertString(char *sl, char *s)
{
  char temp[256];
  Char8Vector *StringList =  (Char8Vector *)sl;

  if (NULL == StringList)
    StringList =  Char8VectorNew();
  if ('"' == s[0])
    StripQuotes(s)
  else {
    strcpy(&temp[1], s);
    temp[0] = '~';
    s = temp;
  }
  Char8VectorAppend(StringList, Store(s));
  return (char *) StringList;
}

char *InheritCallback(char *name)
{
  CallbackType *callback =  CallbackTypeNew("Inherited", name, NULL);
  CallbackList *cb = CallbackListNew();
  CallbackListAppend(cb, callback);
  return (char *) cb;
}

char *
InheritArgument(char *a, char *name)
{
  AttributeList *list = (AttributeList *) a;
  ExpressionType *Expr = (ExpressionType *) InheritItemNew(name);
  ExpressionElement *Elem = ExpressionElementNew1(name, Expr);

  if (NULL == list)
    list = AttributeListNew();
  AttributeListAppend(list, Elem);

  return (char *) list;
}
/*
 ***           The rvalue of an equation is a string.  Set values and return.
*/
char *
expr_STRING(char *s, int CompoundString)
{
  if (CompoundString)
    return (char *) CStringNew(s);
  else { 
    StripQuotes(s);
    return (char *) Char8New(s);
  }
}

/*
 ***           The rvalue of an equation is a integer.  Set values and return.
*/
char *
prim_exp(char *s)
{
  return (char *)  IntegerNew(atoi(s));
}

char *expr_BOOL(char *s)
{
  return (char *) BooleanMNew( (Bool) s);
}

char *expr_ID(char *s)
{
  return (char *) AddrNameNew(s);
}
/*
 ***               We are building a complex string.  Just push the
 ***               strings passed in and return a pointer to the stack.
*/

char StackString[1000];

char *
string_push(char *s)
{
  strcat(StackString,s);
  return StackString;
}

void
string_clear()
{
  StackString[0] = 0;
}

/*
 ***              Here we are generating the list of callbacks in 'l'
 ***              for the widget that is currently being built.
*/
char *
callbacklist_callbacklist_PROCID_arglist(char *l, char *id, 
					 char *fn, char *parm)
{
  CallbackList *list = (CallbackList *) l;
  ParameterList *Parameters = (ParameterList *) parm;

  if (NULL == list)
    list = CallbackListNew();
  CallbackListAppend(list, CallbackTypeNew(id,fn,Parameters));
  return (char *) list;
}

/*
 ***         The widget 'w' has just been built.  Add it to the list
 ***         'wl' and to the symbol table.
*/
char *
body_OBJECT_object(char *wl,char *w)
{
  FakeWidgetType *wid = (FakeWidgetType *)w;
  FakeWidgetList *list = (FakeWidgetList *)wl;

  if (NULL == list)
    list = FakeWidgetListNew(NULL);
if (0 == strcmp(wid->theName, "layoutRTForm"))
fprintf(stderr,"HERE\n");
  FakeWidgetListUpdate(&WidgetTable, &wid);
  FakeWidgetListAppend(list, wid);
  return (char *)list;
}

void AddCallbackList(char *name, char *c)
{
  CallbackList *Callbacks = (CallbackList *) c;
  FakeWidgetType *wid =  FakeWidgetTypeNew1(name,"list");
  CallbackList *calls = (CallbackList *)wid->Callbacks;

  if (NULL != Callbacks)
    CallbackListAppendLists(calls, Callbacks);
  FakeWidgetListUpdate(&WidgetTable, &wid);
}

void AddControlList(char *name, char *c)
{
  FakeWidgetList *children = (FakeWidgetList *) c;
  FakeWidgetType *wid =  FakeWidgetTypeNew1(name, "list");
  FakeWidgetList *kids = FakeWidgetTypeKids(wid);
  
  if (NULL != children)
    FakeWidgetListAppendLists(kids, children);
  FakeWidgetListUpdate(&WidgetTable, &wid);
}

void 
AddAttributeList(char *name, char *a)
{
  AttributeList *Attributes = (AttributeList *) a;
  FakeWidgetType *wid = FakeWidgetTypeNew1(name,"list");
  AttributeList *atts = FakeWidgetTypeAtts(wid);

  AttributeListAppendLists(atts, Attributes);
  FakeWidgetListUpdate(&WidgetTable, &wid);
}

void 
ID_ID_features(char *name, char *theClass,char *w)
{
  FakeWidgetType *wid = (FakeWidgetType *) w;

  FakeWidgetTypeSetName(wid,name,theClass);
}

void MakeTable(char *VariableName, char *Ex, int global)
{
  ExpressionType *Expression = (ExpressionType *) Ex;
  if (global)
    ExpressionListAppend(&GlobalSymbolTable, 
			 ExpressionElementNew1(VariableName, Expression));
  else
    ExpressionListAppend(&LocalSymbolTable, 
			 ExpressionElementNew1(VariableName, Expression));
}

char *pixmap(char *n, char *s)
{
  Char8Vector *strings = (Char8Vector *) s;

  return (char *)  PixmapImageNew(n,strings);
}

char *AddColor(char *c, char *representation, char *l, int IsAddress)
{
  Color *color =  ColorNew(c);
  ColorTable *list = (ColorTable *) l;

  StripQuotes(representation);
  if (IsAddress)
    ColorSetAddress(color);
  if (NULL == list)
    list =  ColorTableNew();
  ColorTableAppend(list,representation,color);
  return (char *) list;
}

char *color(char *s)
{
  if ( '"' == s[0] )
    StripQuotes(s);
  return (char *)  ColorNew(s);
}

char *font(char *s)
{
  if ('"' == s[0])
    StripQuotes(s);
  return (char *) FontMNew(s);
}

char *keysym(char *s)
{
  char temp[256];

  if ( '"' == s[0] )
    StripQuotes(s)
  else {
    temp[0] = '~';
    strcpy(&temp[1], s);
    s = temp;
  }
  return (char *)  KeysymNew(s);
}

char *bitmap(char *s)
{
  StripQuotes(s);
  return (char *)  XBitmapFileNew(s);
}

char *AppendStrings(char *p1, char *p2)
{
  CString *param1 = (CString *) p1;
  CString *param2 = (CString *) p2;

  CStringAdd(param1,param2);
  ExpressionTypeDelete((ExpressionType *)param2);
  return (char *) param1;
}

char *Add(char *p1, char *p2)
{
  ExpressionType *param1 = (ExpressionType *) p1;
  ExpressionType *param2 = (ExpressionType *) p2;

  ExpressionTypeAdd(param1, param2);
  ExpressionTypeDelete(param2);
  return (char *) param1;
}

char *Subtract(char *p1, char *p2)
{
  ExpressionType *param1 = (ExpressionType *) p1;
  ExpressionType *param2 = (ExpressionType *) p2;

  ExpressionTypeSubtract(param1, param2);
  ExpressionTypeDelete(param2);
  return (char *) param1;
}

char *Multiply(char *p1, char *p2)
{
  ExpressionType *param1 = (ExpressionType *) p1;
  ExpressionType *param2 = (ExpressionType *) p2;

  ExpressionTypeMultiply(param1, param2);
  ExpressionTypeDelete(param2);
  return (char *) param1;
}

char *Divide(char *p1, char *p2)
{
  ExpressionType *param1 = (ExpressionType *) p1;
  ExpressionType *param2 = (ExpressionType *) p2;

  ExpressionTypeDivide(param1, param2);
  ExpressionTypeDelete(param2);
  return (char *) param1;

}

void Check()
{
  int a;

  if (WidgetTable.theList)
    if (WidgetTable.theList->Next)
      if (WidgetTable.theList->Next->theWidget)
	if (WidgetTable.theList->Next->theWidget->theName) {
	  a = strcmp("titleArgs", WidgetTable.theList->Next->theWidget->theName);
	  if (0 == a) {
	    fprintf(stderr,"title Arg OK\n");
	    return;
	  }
	}
  fprintf(stderr,"title Arg NOT OK\n");
}

	  
