// This may look like C code, but it is really -*- C++ -*-

#include "eureka.h"
#include "Factory.h"
#include "Widget.h"

extern CatalogIter Symbols;

WidgetFactory::WidgetFactory(int size)
{
   classTable=new HashTable(size);
}

WidgetFactory::~WidgetFactory(int size)
{
   delete classTable;
}

SymbolID WidgetFactory::RegisterClass(char* name, AWidgetClass* cl)
{
   SymbolID id = Symbols.Register(name);
   
   classTable->Enter(id, cl);

   return id;
}

void WidgetFactory::UnRegisterClass(SymbolID id)
{
   classTable->Delete(id);
}

AWidgetClass& WidgetFactory::RetrieveClass(char* classname)
{
   AWidgetClass* wc = (AWidgetClass*)classTable->Find(Symbols.Register(classname));
   if(wc)
     return *wc;
   else{
      Error("No such widget class: %s\n", classname);
      return *(AWidgetClass*)0;
   }
}

AWidget* WidgetFactory::CreateWidget(char* name, char* classname, AWidget& parent)
{
   return CreateWidget(name, Symbols.Register(classname), parent);
}

AWidget* WidgetFactory::CreateWidget(char* name, SymbolID cl, AWidget& parent)
{
   AWidgetClass* wc = classTable->Find(cl);

   if(wc)
     return wc->CreateWidget(name,parent);
   else{
      Error("No such widget class: %s\n", Symbols.String(cl));
      return (AWidget*)0;
   }
}

void WidgetFactory::Display(AWidget& w)
{
   classTable->reset();

   AWidgetClass& command = RetrieveClass("command");

   if(&command == 0){
      Error("Cannot create Widget Factory!\n",0);
      Exit(2);
   }
   char* n = command.name();

   Debug("Found widget: %s\n", n);

   AWidgetClass* wc;

   while(wc = (AWidgetClass*)classTable->dnext()){
      Debug("Factory: displaying widget: %s\n", wc->name());
      command.CreateWidget(wc->name(), w);
   }
}

