/*  instance.c   */
/*  Copyright 1989 Mountain Math Software  */
/*  All Rights Reserved                    */
#include <stream.h>
#include <fstream.h>
#include "mknodey.h"
#include "instance.h"
#include "domknode.h"
#include "debug.h"

class NodeInstance {
	const char * Name ;
	Compound * ParamList ;
	Compound * Des ;
public:
	NodeInstance(const char * name, Compound * list, Compound * des)
		{Name =name; ParamList = list ; Des = des;}
	void EmitInstance();
};




class NodeInstanceList: public SingleList {
public:
	ErrCode Insert(NodeInstance *nt) {return SingleList::Insert(nt);}
	ErrCode Append(NodeInstance *nt) {return SingleList::Append(nt);}
	NodeInstance * Get()   {return (NodeInstance *) SingleList::Get();}
	NodeInstance * Pop() {return (NodeInstance *) SingleList::Pop();}
	NodeInstance * GetNFromTop(int N) ;
	NodeInstance * GetNthEntry(int N) ;
	NodeInstanceList(){;}
	int Size(){return SingleList::Size();}
} ;

class NodeInstanceListIterator: public SingleListIterator {
public:
	NodeInstanceListIterator(NodeInstanceList& df):
		SingleListIterator((SingleList&) df){}
	NodeInstance * operator()()
		{return (NodeInstance *) Next();}
};

NodeInstanceList TheNodeInstances ;

void EmitConstant(Compound * Const)
{
	switch (Const->Type) {
case TypeInt:
		*CppOut << Const->Item.Int ;
		break ;
case TypeDouble:
		*CppOut << Const->Item.Dbl->String ;
		break ;
case TypeString:
		*CppOut << "\"" << Const->Item.Str << "\"" ;
		break ;
case TypeName:
case TypeText:
case TypeTerm:
case TypeCompound:
case TypeDescription:
case TypeList:
case TypeSize:
case TypeParameter:
case TypeParamFunc:
case TypeScaledType:
		DbgError("EmitConstant", "bad type");
	}
}

void FoundNodeInstance(const char * Name, Compound * ParamList, Compound * Des)
{
	if (CheckBase("instance")) return ;
	TheNodeInstances.Append(new NodeInstance(Name,ParamList,Des));
}
	

void NodeInstance::EmitInstance()
{
	*CppOut << "\tnew " << NodeName << "(\"" << Name << "\"" ;
	Compound * Const ;
	if (ParamList->Type != TypeList) DbgError("FoundNodeInstance",
		"parameter list bad");
	CompoundListIterator Next(*(ParamList->Item.List)) ;
	while (Const = Next()) {
		*CppOut << ", " ;
		EmitConstant(Const);
	}
	*CppOut << ");\n" ;
	delete ParamList ;
	// still have to use Des
}

void EmitNodeInstances()
{
	NodeInstance * Instance ;
	while (Instance = TheNodeInstances.Get()) Instance->EmitInstance();
}

