/*
 * GNOME Basic Values
 *
 * Author:
 *    Michael Meeks <mmeeks@gnu.org>
 *
 * Copyright 2000, Helix Code, Inc.
 */
#ifndef GB_VALUE_H
#define GB_VALUE_H

#include <gb/gb.h>


#define GB_FUNDAMENTAL_TYPE  (gb_fundamental_type ())
#define GB_IS_A_FUNDAMENTAL(t) (gtk_type_is_a (t, GB_FUNDAMENTAL_TYPE))

/* Values */
#define GBTrue               TRUE
#define GBFalse              FALSE

extern const GBValue *GBTrue_value;
extern const GBValue *GBFalse_value;

/* Needs some thought, BCD + point position ? */
struct _InternalDecimale {
	guint8 point;
	guint8 data[14];
};

/* Trivial 64bit fixed point ( 4 places ) value */
struct _InternalCurrency {
	guint8 data[8];
};


/**
 *  Dates:
 *  integer part = day since 1899-12-31
 *  floating part = decimal time / 24
 *  for example 1 h 10 mn 30 s = 4.89583333333333E-02
 **/

typedef enum {
	GB_VALUE_EMPTY       =  0,
	GB_VALUE_NULL        =  1,
	GB_VALUE_INT         =  2,
	GB_VALUE_LONG        =  3,
	GB_VALUE_SINGLE      =  4,
	GB_VALUE_DOUBLE      =  5,
	GB_VALUE_CURRENCY    =  6,
	GB_VALUE_DATE        =  7,
	GB_VALUE_STRING      =  8,
	GB_VALUE_OBJECT      =  9,
	GB_VALUE_ERROR       = 10,

	/* Other types */
	GB_VALUE_BOOLEAN     = 11,
	GB_VALUE_VARIANT     = 12,
	GB_VALUE_DATA_OBJECT = 13,
	GB_VALUE_DECIMAL     = 14,
	GB_VALUE_BYTE        = 17,

	/* VB 6 only */
	GB_VALUE_USER_DEF    = 36,

	GB_VALUE_FRX	     = 37,
	GB_VALUE_LIST	     = 38,

	/* For debugging checks */
	GB_VALUE_TYPE_MAX    = 39
} GBValueType;

GtkType gb_type_int;
GtkType gb_type_long;
GtkType gb_type_single;
GtkType gb_type_double;
GtkType gb_type_string;
GtkType gb_type_boolean;
GtkType gb_type_list;

#define GB_VALUE_IS_EMPTY(v)    (!(v)->type)
#define GB_VALUE_INTEGER             GB_VALUE_LONG: \
				case GB_VALUE_INT:  \
	                        case GB_VALUE_BYTE: \
                                case GB_VALUE_DECIMAL

#define GB_VALUE_FLOAT               GB_VALUE_SINGLE:  \
                                case GB_VALUE_DOUBLE

#define GB_VALUE_NUMBER              GB_VALUE_INTEGER: \
				case GB_VALUE_FLOAT

/* See: vagrpDataType.htm */
struct _GBValue {
	GtkType gtk_type;
	union {
		GBByte              byte;
		GBBoolean           bool;
		GBInt               i;
		GBLong              l;
		GBSingle            f;
		GBDouble            d;
		GBCurrency          c;
		GBDecimal           dec;
		GBDate              date;
		GBObject           *obj;
		GBString            s;
		InternalUserDefined user;
		GBFrx		   *frx;
		GPtrArray	   *list;
	} v;
};

#define GB_VALUE_BYTE_MIN           0
#define GB_VALUE_BYTE_MAX           255
#define GB_VALUE_INT_MIN           -32768
#define GB_VALUE_INT_MAX            32767

/* Constructors */
GBValue *gb_value_new_empty        (void);
GBValue *gb_value_new_null         (void);
GBValue *gb_value_new_boolean      (GBBoolean b);
GBValue *gb_value_new_byte         (GBByte    b);
GBValue *gb_value_new_int          (GBInt     i);
GBValue *gb_value_new_long         (GBLong    l);
GBValue *gb_value_new_single       (GBSingle  f);
GBValue *gb_value_new_double       (GBDouble  d);
GBValue *gb_value_new_string       (const GBString s);
GBValue *gb_value_new_string_chars (const char *s);
GBValue *gb_value_new_object       (GBObject *);
GBValue *gb_value_new_date         (const GBDate date);
GBValue *gb_value_new_date_gdate   (const GDate *date);
GBValue *gb_value_new_date_from_str(const char *str);
GBValue *gb_value_new_time         (int hr, int min, int sec);
GBValue *gb_value_new_date_time    (const GDate *date, int hr, int min, int sec);
GBValue *gb_value_new_default      (GBEvalContext *ec, GtkType type);
GBValue *gb_value_new_frx          (const char *s);


GtkType        gb_fundamental_type       (void);
GtkType        gb_gtk_type_from_value    (GBValueType t);
GBValueType    gb_value_from_gtk_type    (GtkType     t);
char          *gb_gtk_type_name          (const char *gb_name);
char          *gb_type_name_from_gtk     (const char *gtk_name);
GtkType        gb_gtk_type_from_name     (const char *vb_type_name);

/* Destructor */
void           gb_value_destroy          (GBValue *);

GBValue       *gb_value_copy             (GBEvalContext *ec, const GBValue *);
GBValue       *gb_value_copy_byval       (GBEvalContext *ec, const GBValue *);
void           gb_value_print            (FILE *sink, const GBValue *v);

GBDouble       gb_value_get_as_double    (const GBValue *);
GBLong         gb_value_get_as_long      (const GBValue *);
GBString       gb_value_get_as_string    (const GBValue *);
GBInt          gb_value_get_as_int       (const GBValue *);
GBBoolean      gb_value_get_as_boolean   (const GBValue *);
GBDate         gb_value_get_as_date      (const GBValue *);
GDate         *gb_value_get_as_gdate     (const GBValue *);
GBInt          gb_value_time_get_hr      (const GBValue *);
GBInt          gb_value_time_get_min     (const GBValue *);
GBInt          gb_value_time_get_sec     (const GBValue *);
gboolean       gb_value_is_integer       (const GBValue *);

/* Promotions */
GBValue       *gb_value_promote         (GBEvalContext  *ec,
					 GtkType         to,
					 const GBValue  *v);

/* Functions that should be in glib */
gint           gb_strcase_equal         (gconstpointer v,
					 gconstpointer v2);
guint          gb_strcase_hash          (gconstpointer v);

/* Private */
void           gb_value_init             (void);
void           gb_value_shutdown         (void);

#endif /* GB_VALUE_H */
