#include "repetition.h"
// repetition.c
int repetition::insert( ent a){
  if (last)
    last->next = new NonEmptyList(a, last->next);
  else {
    last = new NonEmptyList(a,0);
    last->next = last;
  }
  return 0;
};

int repetition::append(ent a) { 
  if (last)
    last = last->next = new NonEmptyList (a, last->next);
  else {
    last = new NonEmptyList(a,0);
    last->next = last;
  }
  return 0;
};

ent repetition::get() {
  if (last == 0) cout<<"error";
  NonEmptyList *f = last->next;
  ent    r = f->e;
  if (f==last) // list empty
    last = 0;
  else
    last->next = f->next;
    delete f;
    return r;
};


/*  The new functions: list_length(), car(), and cdr() */
int repetition::list_length() {
  repetition_iterator next_item(*this);
  ent item;
  int count = 0;

  while (item = next_item())
    count++;
  return count;
};


/* car() --- returns a pointer to the first element of a list */
ent repetition::car() {
  if (last == 0) {
    cout << "error:  attempted to take the car of an empty list";
    exit(-1);
  } else
    return last->next->e;
};


/* cdr() --- error message and exit */
void repetition::cdr() {
  cout << "The cdr member function is not supported by C++-Demeter\n";
  exit(-1);
};


/* same functionality as Lisp last */
ent repetition::lastexp() {
  if (last)
    return last->e;
  else
    return 0;
};


/* same functionality as Lisp nth, (nth 0 l) = (car l) */
ent repetition::n_th(int a) {
  repetition_iterator next_arg(*this);
  NonEmptyList *each_arg;
  int x = 0;

  each_arg = (NonEmptyList *)next_arg();
  while (x != a && each_arg ) {
    each_arg = (NonEmptyList *)next_arg();
    x += 1;
  };
  return each_arg;
};


/* same functionality as Lisp concatenate */
int repetition::conc(ent a, ent b) {
  repetition *e1 = (repetition *)a;
  repetition *e2 = (repetition *)b;
  NonEmptyList *temp;

  this->last = e2->last;
  temp = e1->last->next; // save first element of first list
  e1->last->next = e2->last->next; // last element of 1st list point to first element
				   // of 2nd list
  e2->last->next = temp;	// last element of 2nd list point to first element
				// of 1st list
  return 0;
};

int repetition::concatenate( repetition *lst )
{
   if( lst )
      {
         repetition_iterator next_ent( *lst );
         ent                 each_ent;

         while( each_ent = next_ent() )
            append( each_ent );
      }

   return 0;
};

