    #include "pline.h"

    #include <ads/ListIter.h>

    #include <math.h>

    pline::pline( struct resbuf *_rb ) : ADS_ENT_OBJ( _rb )
    {
       assert(rb != NULL);
       struct resbuf *temp_rb = rb;

       while( temp_rb != NULL )
        {
          if (temp_rb->restype < 0) // possible -1 of -2

            {
              name[0] = temp_rb->resval.rlname[0];
              name[1] = temp_rb->resval.rlname[1];
            }
          else if (temp_rb->restype == 5)
            {
              _handle = temp_rb->resval.rstring;
            }
          temp_rb = temp_rb->rbnext;
        }
    }

    void pline::get_points()
    {
       ads_name ent, result;

       ent[0] = name[0];
       ent[1] = name[1];

       char seqend = 0;

       while(ads_entnext(ent, result) == RTNORM && seqend == 0)
        {
          struct resbuf *temp_rb, *point_rb;

          point_rb = temp_rb = ads_entget(result);
          assert(temp_rb != NULL);

          while (point_rb != NULL)
            {
              if (point_rb->restype  == 10 )
                {
                  vec3 point(point_rb->resval.rpoint[X],
                             point_rb->resval.rpoint[Y],
                             point_rb->resval.rpoint[Z]);
                  vertices.append(point);
                  break;
                }
               else if (point_rb->restype == -2)
                {
                  seqend++;
                  break;
                }
              point_rb = point_rb->rbnext;
            }

          ads_relrb(temp_rb);
          ent[0] = result[0];
          ent[1] = result[1];
        }
    }

    double pline::nearest(const vec3 &p)
    {
      if (vertices.isEmpty())
        get_points();

      ListIterators<vec3> iterator(vertices);

      iterator.reset();
      vec3 n, r0, r1 = *(iterator.currentItem());
      double t, temp_d, d = (p - r1).length2();

      for (iterator.next(); !iterator.isDone(); iterator.next() )
        {
          r0 = r1;
          r1 = *(iterator.currentItem());
          n = r1 - r0;
          t = (p - r0)*n/(n*n);
          if ( t > 1.0)
            temp_d = (p - r1).length2();
          else if ( t < 0.0)
            temp_d = (p - r0).length2();
          else
            temp_d = (p - (r0 + t*n)).length2();
    //      ads_printf("temp_d = %lf\n", sqrt(temp_d));

          if (temp_d < d)
            d = temp_d;
        }

      return sqrt(d);
    }

    vec3
    pline::first()
    {
      if (vertices.isEmpty())
        get_points();

        ListIterators<vec3> iterator(vertices);

      iterator.reset();
      return *(iterator.currentItem());
    }

    vec3
    pline::last()
    {
      if (vertices.isEmpty())
        get_points();

      ListIterators<vec3> iterator(vertices);
      vec3 last;

      iterator.reset();
      for (iterator.next(); !iterator.isDone(); iterator.next() )
        {
          last =  *(iterator.currentItem());
        }
      return last;
    }

    void pline::Mark(const char * text, const char *layer, ads_real height)
    {
      if (vertices.isEmpty())
        get_points();

      ListIterators<vec3> iterator(vertices);
      vec3 from, to, middle, dir;

      int total = 0;
      for (iterator.reset(); !iterator.isDone(); iterator.next() )
          total++;

      int count = 0;
      for (iterator.reset() ; (count < (total/2 - 1 )); iterator.next() )
          count++;
      from =  *(iterator.currentItem());
      iterator.next();
      to =  *(iterator.currentItem());

      dir = to  - from;
      middle = from + 0.5 *  dir;

      ads_point point = {middle[0], middle[1], middle[2]};

      dir.normalize();

      ads_real rotation =  dir[VY] < 0 ?  6.28318530718 - acos(dir[VX])
                  : acos(dir[VX]);

      struct resbuf *rb = ads_buildlist (RTDXF0, "TEXT",
                                         8, layer, // layer

                                         10, point,   // insertion point

                                         1, text,
                                         40, height,
                                         50, rotation,
                                         62, 2, // color blue

                                         0);
      assert(rb != NULL);
      int status = ads_entmake(rb);

      assert(status == RTNORM);

      ads_relrb(rb);
    }

syntax highlighted by Code2HTML, v. 0.9.1