/*---------------------------------------------------------------------
 * $Date: 2009-08-18 15:23:20 $             $Revision: 1.3 $
 *---------------------------------------------------------------------
 * 
 *
 *             Copyright (c) 1992, Visual Edge Software Ltd.
 *
 * ALL  RIGHTS  RESERVED.  Permission  to  use,  copy,  modify,  and
 * distribute  this  software  and its documentation for any purpose
 * and  without  fee  is  hereby  granted,  provided  that the above
 * copyright  notice  appear  in  all  copies  and  that  both  that
 * copyright  notice and this permission notice appear in supporting
 * documentation,  and that  the name of Visual Edge Software not be
 * used  in advertising  or publicity  pertaining to distribution of
 * the software without specific, written prior permission. The year
 * included in the notice is the year of the creation of the work.

.VERSION
 090818		last modif

 *-------------------------------------------------------------------*/
/*---------------------------------------------------------------------
 *   File_Description_Section
 *--------------------------------------------------------------------*/

/*--- include files ---*/
#include "version.h"
#include <string.h>
#include "UxLib.h"
#include "UxLibP.h"
#include "uxdd.h"
#include "utype.h"
#include "types.h"
#include "uimx_cat.h"
#include "lib_ds.h"

/*--- macro symbolic constants ---*/
#define  HASHSIZE	100
#define  NO_ERROR 0
#define  ERROR    -1

/*--- macro functions ---*/
#define	CGETS(x, y)  UxCatGets (MC_LIBUIMX,(x),(y))

/*--- types ---*/

/*--- external functions ---*/

extern int UxStrEqual(), UxFindValue();

/*--- external variables ---*/

/*--- global variables ---*/

/*--- file global variables ---*/
M_FILE_VERSION("$Header")
DD	*DDTable[HASHSIZE];
static	int 	hash();
static DD	*DDTableLookup();
static DD 	*DDMake();
static CL_ENTRY *CLMake();

/*--- forward declaration of static functions ---*/

/*------------------------------------------------------------
 * COMMENT_BOX
 *-----------------------------------------------------------*/


/*--------------------------------------------------------------------------
NAME:		DD*  *DDMake (name, ut, xt)
INPUT:		char* name, int ut, xt
RETURN:	       	return pointer to DD entry
DESCRIPTION:	given resources name and its uimxtype Xtype,  Make an DD entry
CREATION:	17 Nov. 1989
REVISIONS:	--
--------------------------------------------------------------------------*/

static DD *DDMake (name, ut, xt)
	char	*name;
	int	ut, xt;
{
        DD* dd = (DD*) UxMalloc(sizeof(DD));

	strcpy(dd->name, name);
	dd->utype= ut;
	dd->xtype= xt;
	dd->next_cl= (CL_ENTRY *)0;
	dd->next = (DD *)0;

	return dd;
}
/*--------------------------------------------------------------------------
NAME:		CL_ENTRY  *CLMake (xtclass, ut, xt)
INPUT:		void* xtclass;
		int ut, xt
RETURN:	       	return pointer to CL entry
DESCRIPTION:	given xt class and its uimxtype Xtype,  Make a CL_Entry
CREATION:	17 Nov. 1989
REVISIONS:	--
--------------------------------------------------------------------------*/

static CL_ENTRY *CLMake (xtclass, ut, xt)
	void	*xtclass;
	int	ut, xt;
{
        CL_ENTRY* cle = (CL_ENTRY*) UxMalloc(sizeof(CL_ENTRY));

	cle->utype= ut;
	cle->xtype= xt;
	cle->next_cl= (CL_ENTRY *)0;
	cle->xtclass = xtclass;

	return cle;
}


/*--------------------------------------------------------------------------
NAME:		void UxDDInstall (name, utype, xtype)
INPUT:		char* name, int utype, xtype
RETURN:		
DESCRIPTION:    Given resource name and utype, xtype, link it to the hash table	
CREATION:	17, Nov, 1989 
REVISIONS:	--
--------------------------------------------------------------------------*/

void 	UxDDInstall (name, utype, xtype)
	char	*name;
	int	utype;
	int	xtype;
{
	DD	*np;
	int	hv;

	if (name)
           {
		if ((np = DDTableLookup (name))) {
			printf (CGETS (MS_LU_ALDRYREGISTERED,
				DS_MS_LU_ALDRYREGISTERED), name);
			return;
		}
		else {
			np = DDMake (name, utype, xtype);
			hv = hash (name);	
			np->next = DDTable[hv];
			DDTable[hv] = np;
		}
	  }
}

/*--------------------------------------------------------------------------
NAME:		void UxDDAddEntry (name, xtclass, utype, xtype)
INPUT:		char* name,*xtclass; int utype, xtype
RETURN:		
DESCRIPTION:    Given resource name and utype, xtype, link it to the hash table	
CREATION:	17, Nov, 1989 
REVISIONS:	--
--------------------------------------------------------------------------*/

void 	UxDDAddEntry (name, xtclass, utype, xtype)
	char	*name;
	void	*xtclass;
	int	utype;
	int	xtype;
{
	DD	*np;
	int	hv;
	CL_ENTRY *cl;

	if (name)
	{
		if ((np = DDTableLookup (name))){
			cl = CLMake (xtclass, utype, xtype);
			cl->next_cl= np->next_cl;
			np->next_cl=cl;
			return;
		} else {
			np = DDMake (name, utype, xtype);
			hv = hash (name);	
			np->next = DDTable[hv];
			DDTable[hv] = np;
		}
	}
}


/*--------------------------------------------------------------------------
NAME:		static DD*  DDTableLookup (name) 
INPUT:		char* name
RETURN:	        pointer to DD Entry	
DESCRIPTION:	given  an resource name return its DD entry by checking  hash 
                index
CREATION:	17 Nov. 1989 
REVISIONS:	--
--------------------------------------------------------------------------*/
static 	DD *DDTableLookup (name)
char	*name;
{
	DD	*np;

	for (np = DDTable[hash (name)];np != (DD *)0;np = np->next)
		if (UxStrEqual(name, np->name))
			return np;
	return (DD *)0;
}

/*--------------------------------------------------------------------------
NAME:		static int hash (name)
INPUT:		char* name
RETURN:	        hash table index (0-HASHSIZE)
DESCRIPTION:    given resource name to hash function get corresponding hash 
                index 
CREATION:	17  Nov 1989
REVISIONS:	--
--------------------------------------------------------------------------*/
static 	int hash (name)
char	*name;
{
	int	hv;
	
	for (hv = 0; *name != '\0';)
		hv += *name++;
	return (hv % HASHSIZE);
}

/*-------------------------------------------------------------------------- 
NAME:		DDList UxDDEntry (name)
INPUT:		char* name
RETURN:		DDList
DESCRIPTION:	given  an  name return its DDList
CREATION:	25 May 1989
REVISIONS:	10 April 1990
		-- Added class dependent dd entries.
--------------------------------------------------------------------------*/

CL_ENTRY *UxDDEntry (name, xtclass)
	char    *name;
	void	*xtclass;
{
	CL_ENTRY *cl,*rcl=0;
	DD	 *dd;
	
	if ((dd= DDTableLookup (name))){
		rcl = (CL_ENTRY *)dd;
	 	if ((cl =dd->next_cl))
			do{
				if (cl->xtclass == xtclass){
					rcl = cl;
					break;
				}
			}while ((cl=cl->next_cl));
	}
	return rcl;
}
/*--------------------------------------------------------------------------
NAME:		static int UimxToX (sw, utype, v, xtype, data, to)
INPUT:		swidget sw;
		int	utype, xtype, to; 
		XtArgVal *v;
		char	 *data;
RETURN:		status:  ERROR	NO_ERROR	
DESCRIPTION:	calls uimx convertors with the appropriate data types.
CREATION:	25 May 1989
LAST REV:	Jan 93	fix3820		UxCallConverter now used.
--------------------------------------------------------------------------*/
static 	int UimxToX (sw, utype, v, xtype, data, to)
swidget sw;
int	utype, xtype, to;
XtArgVal *v;
char	*data;
{
	char	vc;
	short	vs;
	int	stat= ERROR;

	switch (u_size (utype)){
	   case sizeof (char):
		if (to == TO_X)vc = (char)*v;
	       	stat = UxCallConverter (sw , utype, (char **)&vc, xtype, data, to);
		if (to == TO_UIMX)*v = (XtArgVal)vc;
		break;
	   case sizeof (short):
		if (to == TO_X)vs = (short)*v;
	       	stat =UxCallConverter (sw, utype,(char **)&vs, xtype, data, to);
		if (to == TO_UIMX)*v = (XtArgVal)vs;
		break;
	   default:
	       	stat = UxCallConverter (sw, utype, (char **)v, xtype, data, to);
	}
	return stat;
}

/*--------------------------------------------------------------------------
NAME:		int UxDDPutProp (sw, p, v)
INPUT:		swidget sw,  char *p, XtArgVal v
RETURN:
DESCRIPTION:	given swidget put its property pair (p, v) to proplist
CREATION:	25 May 1989
REVISIONS:	10 April 1990
		-- modified to handle class dependent dd entries.
--------------------------------------------------------------------------*/
int  	UxDDPutProp (sw, p, v)
swidget   sw;
char      *p;
XtArgVal  v;
{
	CL_ENTRY *dd;
	XtArgVal fi = v;
	char     fc = '\0';
	int      stat = ERROR;
	short	 fs =0;

	if (sw) 
	{
	    if ((dd = UxDDEntry (p, UxGetClass(sw))))
	    {
		switch (x_size (dd->xtype)){
			case sizeof (char):
			   stat= UimxToX (sw, dd->utype,&v, dd->xtype,&fc, TO_X);
			   fi = (XtArgVal)fc;
			break;	
			case sizeof (short):
			   stat= UimxToX (sw, dd->utype,&v, dd->xtype,&fs, TO_X);
			   fi = (XtArgVal)fs;
			break;
	      		default:
			   stat= UimxToX (sw, dd->utype,&v, dd->xtype,&fi, TO_X);
	     	}
		if (stat == NO_ERROR)
			stat= UxPutProp (sw, p, fi);
	    }
	}
	return  stat;
}

/*----------------------------------------------------------------------
 * NAME:	<XtArgVal UxDDGetProp (sw, p)>
 * DESCRIPTION:	<given swidget return its property p value>
 * PARAMETERS:	swidget sw 	- swidget
 *		char *p 	- property
 * RETURN:	XtArgVal
 * EXT REFS:	globals_used
 * EXT EFFECTS:	globals or other things altered
 * ASSUMPTIONS:
 * REVISIONS:   25/05/92	creation
 *	        Oct. 1989	
                checking widget is created or not. 
		10 April 1990
		-- modified to handle class dependent dd entries.
		18 Nov/91	fix3186
 *--------------------------------------------------------------------*/
XtArgVal UxDDGetProp (sw, p)
	swidget  sw;
	char     *p;
{
	CL_ENTRY *dd;
	XtArgVal v= 0, fv;
	char	fc = '\0';
	Arg	arg[2];
	short	fs;
        int err_status;
	char *xtname = p;

	/* Rename msgDialogType to dialogType so that the widget
	   understands! */
	if (UxStrEqual(p, "msgDialogType")) {
		xtname = "dialogType";
	}

	if (sw && (dd = UxDDEntry (p, UxGetClass(sw))))
	{ 
		Widget w = UxGetWidget (sw);
		switch (x_size (dd->xtype)){
			case sizeof (char):
			    if (w) {
                            	XtSetArg (arg[0], xtname,&fc);
                            	XtGetValues (w, arg,1);
			    }
			    else if (UxFindValue (sw,  p, &v)){
				fc = (char)v;
			    }
			    else {
				break;
			    }
			    if (NO_ERROR == UimxToX (sw, dd->utype,&v,
						dd->xtype,&fc, TO_UIMX))
				return v;
			break;
			case sizeof (short):
			    if (w) {
                            	XtSetArg (arg[0], xtname,&fs);
                            	XtGetValues (w , arg,1);
			    }
			    else if (UxFindValue (sw,  p, &v)) {
				fs = (short)v;
			    }
			    else {
				break;
			    }
			    if (NO_ERROR == UimxToX (sw, dd->utype,&v,
						dd->xtype,&fs, TO_UIMX))
				return v;
			break;
			default:
			    /* UxGet<Property> functions returning XmString go
			       through this default case.  We need to free the
			       string after it was converted. To know that we
			       used XtGetValues, we check for the validity
			       of the widget 'w'. */

			    if (w) {
                            	XtSetArg (arg[0], xtname,&fv);
                            	XtGetValues (w, arg,1);
			    }
			    else if (UxFindValue (sw,  p, &v)) {
				fv = v;
	         	    }
			    else {
				break;
			    }
	         	    err_status = UimxToX (sw, dd->utype,&v,
						dd->xtype,&fv, TO_UIMX);
			    if (w)
				UxFreeXValue(sw, p, fv);
			    if (err_status == NO_ERROR)
			    	return v;
		}
	  }
	  return UxGetProp (sw, p);
}

