    /*\
     *  Izbor elementov iz Acad baze
     *  $Id:$
    \*/

    #include "entity.h"

    /*
     * Vrne naslov elementa v extended entity data podro"cju
     * specificiranem s stringom, "ce ga ne najde, vrne NULL
     * Ce je zajetih vec aplikacij v X data potem vrne prvi string,
     * ki ga najde
     */
    union ads_u_val *
    getXdata (struct resbuf * rb, const char *name)
    {
      while (rb != NULL)
        {
          if (rb->restype == 1001)
    	      {
    	        rb = rb->rbnext;
    	        while (rb != NULL)
    	          {
    		          if (rb->restype == 1000)
    		          if (strcmp (name, rb->resval.rstring) == 0)
    		            {
    		              rb = rb->rbnext;
    		              return &(rb->resval);
    		            }
    		          rb = rb->rbnext;
    	          }
                // ads_printf("Warning: getXdata(rb, %s) not found!\n", name );

                return NULL;
    	      }
          rb = rb->rbnext;
        }
      return NULL;
    }

    /*
     * Vrne naslov vrednosti elementa v data podro"cju
     * specificiranem s selektorjem dxfval ce ga ne najde, vrne NULL
     *
     * Primer uporabe: assoc(10, rb)->rpoint
     */
    union ads_u_val *
    assoc (short dxfval, struct resbuf * rb)
    {
      while (rb != NULL)
        {
          if (rb->restype == dxfval)
    	      return &(rb->resval);
          rb = rb->rbnext;
        }
      return NULL;
    }

    /*
     * Za podan string preveri ali obstaja TAG v Xdata podrocju
     * s takim imenom
     */
    int isA(const char *name, struct resbuf *rb)
    {
      union ads_u_val *xp = getXdata(rb, "TAG");
      if (xp == NULL)
        return 0;
      int status = !strcmp(xp->rstring, name);
      return status;
    }

    /////////////////////////////////////////////////////////////////

    /** {duh} **/
    Entity::Entity()
    {
      rb = NULL;
      hasXdata = 0;
    }

    /** {duh} **/
    Entity::Entity(ads_name name)
    {
      Entity::name[0] = name[0];
      Entity::name[1] = name[1];
      rb = NULL;
      hasXdata = 0;
    }

    /** {duh} **/
    Entity::~Entity()
    {
      if (rb)  ads_relrb(rb);
    }

    /**
     ** Shrani gradnik nazaj v bazo ACAD. Ta sinhronizacija je potrebna le
     ** ce smo popravljali notranje podatke gradnika tj. resbuf
     **/
    Entity::Modify()
    {
      return (ads_entmod(rb));
    }

    /**
     ** Izbere gradnik v ACAD-u
     **/
    int Entity::Pick(char *prompt)
    {
      int status;
      status = ads_entsel(prompt, name, pickPoint);
      if (status != RTNORM)
        return (status);
      return (RTNORM);
    }

    /**
     ** Vrne /i/-to (x, y, z) koordinato gradnika
     **/
    ads_real Entity::GetPoint(int i)
    {
      if (!rb)
        Get();
      return assoc(10, rb)->rpoint[i];
    }

    /** {duh} **/
    void Entity::GetHandle()
    {
      if (!rb)
        Get();
      handle = assoc(5, rb)->rstring;
    }

    /**
     ** Poisce prvi zapis za naziv vozla v podro"cju Cybernet
     **/
    int Entity::GetNodeName()
    {
      if (!rb)
        Get();

      if (rb && hasXdata)
        {
          char *nodestr[] = { "NODE_#", "DNODE_#", "UNODE_#", "CNODE_#"};
          union ads_u_val *entity;
          for (short i = 0; i < 4; i++)
            {
              entity = getXdata(rb, nodestr[i]);
              if (entity)

                {
                  if (nodestr[i][0] != 'N')
                    {
                      nodeName =  nodestr[i];
                      nodeName += entity->rstring;
                    }
                  else
                    nodeName = entity->rstring;
                  return 0;
                }
            }
        }
      nodeName = "";
      return 1;
    }

    /** {duh} **/
    Strings Entity::GetDXFName()
    {
      if (!rb)
        Get();
      DXFname = assoc(0, rb)->rstring;
      return DXFname;
    }

    /** {duh} **/
    Strings Entity::GetLayer()
    {
      if (!rb)
        Get();
      layer = assoc(8, rb)->rstring;
      return layer;
    }

    /** {duh} **/
    void Entity::GetTag()
    {
      if (!rb)
        Get();
      tag = getXdata(rb, "TAG")->rstring;
    }

    /** {duh} **/
    struct resbuf * Entity::GetResBuf()
    {
      if (!rb)
        Get();
      return rb;
    }

    /**
     ** Iz baze ACAD vzame /resbuf/ za gradnik registriran z name in
     ** po moznosti z registriranimi aplikacijami.
     **/
    int Entity::Get()
    {
      if (rb)
        ads_relrb(rb);

      rb = ads_entgetx(name, apps);

      if (rb == NULL)
        return RTERROR;

      if (assoc(1001, rb))
        {
          hasXdata = 1;
        }
      return (RTNORM);
    }

    int Entity::Get(ads_name entname)
    {
      name[0] = entname[0];
      name[1] = entname[1];
      return Get();
    }

    /**
     ** Sprosti /resbuf/ ki ga zaseda gradnik
     **/
    void Entity::Release()
    {
      if (rb)
        {
          ads_relrb(rb);
          rb = NULL;
        }
    }

    /**
     ** Doda aplikacijo registriranim aplikacijam za vse gradnike ACAD, tako
     ** da lahko funkcije za XDATA (ads_entgetx) dostopajo do podatkov
     ** izbranih aplikacij.
     **/
    void Entity::Register(const char *appName)
    {
      struct resbuf *app;

      app = ads_buildlist(RTSTR, appName, NULL);
      app->rbnext = apps;
      apps = app;
    }

    /**
     ** Zbrise vse registrirane aplikacije
     **/
    void Entity::UnRegister()
    {
      if (apps)
        ads_relrb(apps);
      apps = NULL;
    }

    /**
     ** V XDATA podrocju pogleda, ce /tag/ ze obstaja in zamenja obstojeco
     ** vrednost z /value/. Ce /tag/ ne obstaja, ga naredi skupaj z novo
     ** vrednostjo /value/ na zacetku prve registrirane aplikacije /appName/
     ** za Entity.
     **/
    Entity::SaveTag(const char *tag, const char *value, const char *appName)
    {
      union ads_u_val *tagVal;
      if (!rb)
        Get();
      if ((tagVal = getXdata(rb, tag)) == NULL)
        {
          for (struct resbuf *srb = rb; srb->rbnext; srb = srb->rbnext)
            {
              if (srb->restype == 1001
    		          && strcmp (appName, srb->resval.rstring) == 0)
    	          {
                  struct resbuf *etag;
                  etag = ads_buildlist(1000, tag, 1000, value, NULL);
                  if (etag == NULL)
                    return RTERROR;
                  etag->rbnext->rbnext = srb->rbnext;
                  srb->rbnext = etag;
                  return RTNORM;
    	          }
            }
          srb->rbnext = ads_buildlist(1001, appName, 1000, tag, 1000, value, NULL);
          if (srb->rbnext == NULL)
            return RTERROR;
        }
      else
        {
          if (value == NULL)
            tagVal->rstring =  (char *) calloc(1,1);
          else
            {
               char *buff;
               buff = (char *)realloc(tagVal->rstring, strlen(value) + 1);
               if (buff == NULL)
                  return RTERROR;
               else
                {
                  tagVal->rstring = buff;
                  strcpy(tagVal->rstring, value);
                }
            }
          if (tagVal->rstring == NULL)
            return RTERROR;
        }
      return RTNORM;
    }

    /**
     ** Shrani celostevilcno vrednost
     **/
    Entity::SaveTag(const char *tag, int value, const char *appName)
    {
      union ads_u_val *tagVal;
      if (!rb)
        Get();
      if ((tagVal = getXdata(rb, tag)) == NULL)
        {
          for (struct resbuf *srb = rb; srb->rbnext; srb = srb->rbnext)
            {
              if (srb->restype == 1001
    		          && strcmp (appName, srb->resval.rstring) == 0)
    	          {
                  struct resbuf *etag;
                  etag = ads_buildlist(1000, tag, 1071, value, NULL);
                  etag->rbnext->rbnext = srb->rbnext;
                  srb->rbnext = etag;
                  return RTNORM;
    	          }
            }
          srb->rbnext = ads_buildlist(1001, appName, 1000, tag, 1071, value, NULL);
          if (srb->rbnext == NULL)
            return RTERROR;
        }
      else
        {
          tagVal->rlong = value;
        }
      return RTNORM;
    }

    /**
     ** Shrani realno vrednost
     **/
    Entity::SaveTag(const char *tag, ads_real value, const char *appName)
    {
      union ads_u_val *tagVal;
      if (!rb)
        Get();
      if ((tagVal = getXdata(rb, tag)) == NULL)
        {
          for (struct resbuf *srb = rb; srb->rbnext; srb = srb->rbnext)
            {
              if (srb->restype == 1001
    		          && strcmp (appName, srb->resval.rstring) == 0)
    	          {
                  struct resbuf *etag;
                  etag = ads_buildlist(1000, tag, 1040, value, NULL);
                  etag->rbnext->rbnext = srb->rbnext;
                  srb->rbnext = etag;
                  return RTNORM;
    	          }
            }
          srb->rbnext = ads_buildlist(1001, appName, 1000, tag, 1040, value, NULL);
          if (srb->rbnext == NULL)
            return RTERROR;
        }
      else
        {
          tagVal->rreal = value;
        }
      return RTNORM;
    }

    /**
     ** Poisce zapis za cev v extended entity podrocju, ce le to obstaja
     ** Vrne stevilko cevi; ce ne najde zapisa, vrne 0
     **/
    long Entity::PipeNum()
    {
      if (rb && hasXdata)
        {
          union ads_u_val *pipe;
          pipe = getXdata(rb, "PIPE_#");
          if (pipe)
            return pipe->rlong;
          pipe = getXdata(rb, "UPIPE_#");
          if (pipe)
            return pipe->rlong;
          pipe = getXdata(rb, "DPIPE_#");
          if (pipe)
            return pipe->rlong;
        }
      return 0;
    }

    struct resbuf * Entity::apps = NULL;

syntax highlighted by Code2HTML, v. 0.9.1