
#include "GcObject.h"

extern GcOpaqueObjectList* gcListOfListes;

unsigned int GcOpaqueObjectList::objAdd_(GcObject &obj)
{
  unsigned int n=gol_items;
  obj.gco_next_=gol_first;
  gol_first=&obj;
  ++gol_items;
  return n;
}

void GcOpaqueObjectList::registerList()
{
  this->gol_next_lst=gcListOfListes;
  gcListOfListes=this;
}

static GcOpaqueObjectList lostList;

class GcObjectServices
{
public:
  static unsigned int objRegister(GcOpaqueObjectList* lst, GcObject& obj, const char* name)
  {
    return objRegister(lst ? *lst : lostList, obj, name);
  }

  static unsigned int objRegister(GcOpaqueObjectList& lst, GcObject& obj, const char* name)
  {
    obj.gco_list_=&lst;
    const char* bname=name ? name : (lst.gol_prefix ? lst.gol_prefix : "gco");
    const unsigned int inst_n=lst.objAdd_(obj);
    setName(obj, bname, inst_n, name==0);
    return inst_n;
  }

  static void setName(GcObject& gco, const char* name)
  {
    setName(gco, name, gco.gco_instance_num_);
  }

  static void setName(GcObject& gco, const char* name, unsigned int counter, bool add_counter=false)
  {
    const char* bname=name ? name : "gco";
    unsigned int i;
    for(i=0; (i<(sizeof gco.gco_name_)-1) && bname[i]; ++i)
    {
      gco.gco_name_[i]=bname[i];
    }
    if (!name || add_counter)
    {
      unsigned int x=counter;
      for(int n=1000; n>1; n/=10)
      {
        unsigned int tmp=x/n;
        //if (tmp==0)
        //  continue;
        if (tmp>9)
          tmp=9;
        gco.gco_name_[i]='0'+tmp;
        ++i;
        x=x-(tmp*n);
      }
    }
    gco.gco_name_[i]=0;
  }
};


GcObject::GcObject(GcObject *parent, const char *name, GcOpaqueObjectList *lst):
  gco_children_(0),
  gco_name_ptr_(gco_name_)
{
  gco_instance_num_=GcObjectServices::objRegister(lst, *this, name);
  setParent(parent);
}

GcObject::~GcObject()
{
}

void GcObject::setObjName(const char *name)
{
  GcObjectServices::setName(*this, name); //gco_name_=name ? name : "<unnamed>";
}

const char* GcObject::objName() const
{
  return gco_name_;
}

void GcObject::setParent(GcObject *parent)
{
  gco_parent_=parent;
  /*
  if (parent)
  {
    gco_next_=parent->gco_children_;
    parent->gco_children_=this;
  }
  else
    gco_next_=0;
  */
}

GC_OBJ_MON_DEFINE(GcObject)
