
#include <stdio.h>

DECL_COMMON

static TT_CONST ttbyte * dump_file_name;

static FILE * dump_file;

static ttbyte open_dump_file(void) {
    if ((dump_file = fopen(dump_file_name, "w"))) {
	fprintf(dump_file, "%s",
		"<?xml version=\"1.0\"?>\n"
		"<TT:dump xmlns:TT=\"http://twin.sourceforge.net/libTT/xml/\">\n"
		);
	return TRUE;
    }
    return FALSE;
}

static void close_dump_file(void) {
    fprintf(dump_file, "%s", "</TT:dump>\n");
    fclose(dump_file);
}

TT_INLINE void dump_obj(ttobj o) {
    ttuint i, last;
    ttopaque id;
    TT_CONST ttbyte *name;
    ttbyte buf[64];
    ttany data;
    tt_fn type;
    
    if ((id = OBJ2ID(o))) {
	fprintf(dump_file, "  <TT:%s>\n", name = TTClassNameOf((tt_obj)id));
	sprintf(buf, "%s_field_last", name);
	last = TTGetFieldId(buf);
	for (i = 0; i < last; i++) {
	    if ((name = TTGetFieldName(i)) && (type = TTGetField_ttobj((tt_obj)id, i, &data)) && data != (ttany)0) {
		if (type == TTFN_ttstring)
		    fprintf(dump_file, "    <TT:%s value=\"%s\"/>\n", name, (ttstring)(ttopaque)data);
		else
		    fprintf(dump_file, "    <TT:%s value=\"0x%lX\"/>\n", name, (unsigned long)(ttopaque)data);
	    }
	}
	fprintf(dump_file, "  </TT:%s>\n", TTClassNameOf((tt_obj)id));
    }
}

static void dump_all(void) {
    ttbyte n;
    ttopaque i;
    ttobj o;

    if (open_dump_file()) {
	for (n = order_ttobj; n < order_n; n++) {
	    for (i = 0; i < IdTop[n]; i++) {
		if ((o = IdList[n][i]))
		    dump_obj(o);
	    }
	}
	close_dump_file();
    }
}

/*
 * We need to write down only overloaded methods (actually none).
 */

static ttbyte HWDEF(Sync)(void) {
    return 1;
}
static ttbyte HWDEF(Flush)(void) {
    return 1;
}
static ttbyte HWDEF(TimidFlush)(void) {
    return 1;
}
static ttbyte HWDEF(MainLoopOnce)(ttbyte wait) {
    return 1;
}
static void HWDEF(DeleteCallback)(ttcallback o) {
}
static void HWDEF(Close)(void) {
    dump_all();
}
static int HWDEF(ConnectionFd)(void) {
  return -1;
}
static ttuint HWDEF(GetErrno)(void) {
  return 0;
}
static ttuint HWDEF(GetErrnoDetail)(void) {
  return 0;
}
static TT_CONST ttbyte *HWDEF(StrError)(ttuint E) {
    return "";
}
static TT_CONST ttbyte *HWDEF(StrErrorDetail)(ttuint E, ttuint S) {
    return "";
}


#ifdef THIS_MODULE
ttfns InitModule(tthw *HW)
#else
ttfns _TT_xml_InitHW(tthw *HW)
#endif
{
    ttbyte *arg = TTD.HWOptions;
    
    /*
     * (*HW) must be set even if initialization fails,
     * to report error messages.
     */
    *HW = &xml_TTFNs.HW;

    dump_file_name = "libTT.xml";
    if (arg && (arg = strstr("file=", arg))) {
	dump_file_name = arg + 5;
	if ((arg = strchr(dump_file_name, ',')))
	    *arg = '\0';
    }

    return &xml_TTFNs;
}
