#include <string.h>
#include "newaloc.h"
#include "netdesc.h"
#include "cgidbg.h"
#include "mkstr.h"

// void TestAlloc(const char*msg);

GenericArrayElementObject::GenericArrayElementObject(Int_LinearList&l)
{
	long size = l.number() ;
/*
 *	LogOut << "GenericArrayElementObject::ctor int list, size = " <<
 *		size << "\n" ;
 */
	if (!size) {
		// LogOut << "Setting null list\n" ;
		list = 0 ;
		return ;
	}
	int_list = new int[size+1];
	l.next(0);
	for (int i = 0 ; i < size ;i++) int_list[i] = l.get(i);
	int_list[i] = end_of_values ;
	// LogOut << "int_list[" << i << "] =  end_of_values\n" ;
}

GenericArrayElementObject::GenericArrayElementObject(String_LinearList&l)
{
	long size = l.number() ;
/*
 *	LogOut << "GenericArrayElementObject::ctor string list, size = " <<
 *		size << "\n" ;
 */
	if (!size) {
		// LogOut << "Setting null list\n" ;
		list = 0 ;
		return ;
	}
	list = new const char *[size+1];
	l.next(0);
	for (int i = 0 ; i < size ;i++) {
		char * pt  = (char*)  l.sget(i) ;
		list[i] = pt ;
	}
	list[i] = 0 ;
	// LogOut << "list[" << i << "] =  " << (void *) list[i] << "\n" ;
}

GenericArrayElement::GenericArrayElement(const char * str):
	the_type(string),
	object(str)
{
}

GenericArrayElement::GenericArrayElement(int v):
	the_type(integer),
	object(v)
{
}

GenericArrayElement::GenericArrayElement(int * l):
	the_type(int_list),
	object(l)
{
}

GenericArrayElement::GenericArrayElement(const char ** l):
	the_type(list),
	object(l)
{
}

GenericArrayElement::GenericArrayElement(ElementType type, const char * data):
    the_type(type),
	object((const char **) 0)
{
	switch(type) {
case string:
        object.string = Concatenate(data);
/*
 *		LogOut << "GenericArrayElement::ctor(" << type << ", \"" << data <<
 *			"\")\n" ;
 */
		break ;
case integer:
		MoveNBytes((char *)&(object.val), data, sizeof(object.val));
/*
 *		LogOut << "GenericArrayElement::ctor(" << type << ", " << object.val <<
 *			")\n" ;
 */
		break ;
case int_list:
case list:
case terminator:
case int_list_terminator:
case list_terminator:
		break ;
default:
        DbgError("GenericArrayElement::object_size","bad type");
	}
}



GenericArrayElement::GenericArrayElement():
	the_type(terminator),
	object((const char **)0)
{
}

int GenericArrayElement::object_size() const
{
	switch (the_type) {
case string:
		return strlen(object.string)+1;
case integer:
		return sizeof(object.val);
case terminator:
		return 0 ;
default:
		DbgError("GenericArrayElement::object_size","bad type");
case int_list:
case int_list_terminator:
case list_terminator:
case list:
		return -1 ;
	}
}

const char * GenericArrayElement::ptr_object() const
{
    switch (the_type) {
case string:
        return object.string;
case integer:
        return (char *) &(object.val);
case terminator:
        return 0 ;
case int_list:
case list_terminator:
case int_list_terminator:
case list:
default:
        DbgError("GenericArrayElement::ptr_object","bad type");
	}
}


const char ** GenericArrayElement::get_list() const
{
	if (the_type != list) DbgError("GenericArrayElement::get_list","not list");
	return object.list ;
}

int * GenericArrayElement::get_int_list() const
{
	if (the_type != int_list) DbgError("GenericArrayElement::get_int_list",
		"not int list");
	return object.int_list ;
}

static int list_length(const char ** list)
{
	int Return = 0 ;
	if (list) for(const char ** l=list;*l;l++,Return++);
	return Return ;
}

NetNodeDescription::NetNodeDescription(GenericArrayElement_LinearList * objects)
{
	// LogOut << "NetNodeDescription::NetNodeDescription(GenericArrayElement_LinearList\n" ;
#define all_of_the_members NetNodeDescriptionMembers
#include "ger_ar_lst_ctr.h"
// first 13
	// LogOut << "NetNodeDescription::NetNodeDescription(GenericArrayElement_LinearList exit\n" ;
}

NetNodeDescription::NetNodeDescription(const char * class_nm,
	const char * node_nm, int inputs, int outputs):
	class_name(class_nm),
	element_name(node_nm),
	input_channels(inputs),
	output_channels(outputs),
	driver_names(0)
{
}

	
	


NetNodeDescription::NetNodeDescription(GenericArrayElement * objects)
{
#define all_of_the_members NetNodeDescriptionMembers
#include "ger_ar_elt_ctr.h"
}

GenericArrayElement * NetNodeDescription::get_array() const
{
	// TestAlloc(" NetNodeDescription::get_array enter");
#define all_of_the_members NetNodeDescriptionMembers
#include "strct_ctr.h"
	// TestAlloc(" NetNodeDescription::get_array exit");
}

NetBufferDescription::NetBufferDescription(
	GenericArrayElement_LinearList * objects)
{
#define all_of_the_members NetBufferDescriptionMembers
#include "ger_ar_lst_ctr.h"
// second 13
}

NetBufferDescription::NetBufferDescription(GenericArrayElement * objects)
{
#define all_of_the_members NetBufferDescriptionMembers
#include "ger_ar_elt_ctr.h"
}

NetBufferDescription::NetBufferDescription(int drv_chan,const char * drv_nm):
	driver_channel(drv_chan),
	driver_name(drv_nm),
	number_outputs(0),
	destination_names(0),
	destination_input_channels(0)
{
}
	

GenericArrayElement * NetBufferDescription::get_array() const
{
#define all_of_the_members NetBufferDescriptionMembers
#include "strct_ctr.h"
}

NetworkDescription::NetworkDescription(GenericArrayElement_LinearList * objects)
{
#define all_of_the_members NetworkDescriptionMembers
#include "ger_ar_lst_ctr.h"
}

NetworkDescription::NetworkDescription(GenericArrayElement * objects)
{
#define all_of_the_members NetworkDescriptionMembers
#include "ger_ar_elt_ctr.h"
}


NetworkDescription::NetworkDescription(const char * nm, const char * cntrl):
	name(nm),
	controller_name(cntrl)
{
}

GenericArrayElement * NetworkDescription::get_array() const
{
#define all_of_the_members NetworkDescriptionMembers
#include "strct_ctr.h"
}


void GenericArrayElement_LinearList::dump() const
{
	// LogOut << "GenericArrayElement_LinearList::dump, size = " << number() << "\n" ;
	for (int i = 0 ; i < number() ; i++) {
		// LogOut << i << " " ;
		const GenericArrayElement& elt = *get(i) ;
		switch (elt.type()) {
case GenericArrayElement::string:
/*
 *			if (elt.object.string) LogOut << elt.object.string << "\n" ;
 *			else LogOut << "null\n" ;
 */
			break ;
case GenericArrayElement::integer:
			// LogOut << "integer: " << elt.object.val << "\n" ;
			break ;
case GenericArrayElement::int_list:
			{
				// LogOut << "int_list:\n" ;
				if (elt.object.int_list)
					for (int * pt = elt.object.int_list ; *pt > -1 ;pt++)
						// LogOut << "	" << *pt << "\n" ;
				break ;
			}
case GenericArrayElement::list:
			{
				// LogOut << "list:\n" ;
				if (elt.object.list)
					for (const char ** pt = elt.object.list ; *pt;pt++)
						// LogOut << "	" << *pt << "\n" ;
				break ;
			}
case GenericArrayElement::int_list_terminator:
			// LogOut << "int_list_terminator\n" ;
			break ;
case GenericArrayElement::list_terminator:
			// LogOut << "list_terminator\n" ;
			break ;
case GenericArrayElement::terminator:
			// LogOut << "terminator\n" ;
			break ;
default:
			// LogOut << "bad type\n" ;
			break ;
		}
	}
}

NetworkDescription::~NetworkDescription()
{
	// TestAlloc("deleteing NetworkDescription");
}

NetBufferDescription::~NetBufferDescription()
{
	// TestAlloc("deleteing NetBufferDescription");
	delete destination_names;
}

NetNodeDescription::~NetNodeDescription()
{
	// TestAlloc("deleteing NetNodeDescription");
	delete driver_names ;
}


