/**********************************************************************
 * I expect you to add appropriate documentation to this code.
 **********************************************************************/

#include <iostream.h>
#include <stdlib.h>
#include <assert.h>
#include "list.h"

void List::Free(void)
{
   ListP tmp;

   while (l != NULL)
   {
      tmp = l;
      l = l->next;
      delete tmp;
   }
}

List::~List()
{
   Free();
}

void List::Copy(const List& b)
{
   ListP newCur;
   ListP bCur;

   if (b.l == NULL)
   {
      l = NULL;
      return;
   }

   l = new ListItem;
   assert (l != NULL);
   l->exponent = b.l->exponent;
   l->coeff = b.l->coeff;

   newCur = l;   // Pointer to first item on target list.
   bCur = b.l->next;   // Pointer to second item on source list.

   while (bCur != NULL)
   {
      newCur->next = new ListItem;
      assert (newCur != NULL);
      newCur= newCur->next;
      newCur->exponent = bCur->exponent;
      newCur->coeff = bCur->coeff;
      bCur = bCur->next;
   }

   newCur->next = NULL;
}

List::List(const List& b)
{
   Copy(b);
}
      
const List& List::operator=(const List& b)
{
   if (this != &b)
   {
      Free();
      Copy(b);
   }

   return *this;
}

// It's up to the user to ensure there are no duplicate exponents on
// the list.

int List::Insert(int exp, double co)
{
   ListP tmp;

   tmp = new ListItem;
   if (tmp == NULL)
      return 0;

   tmp->exponent = exp;
   tmp->coeff = co;
   tmp->next = l;
   l = tmp;

   return 1;
}

int List::Retrieve(int exp, double& co) const
{
   ListP i;

   for (i = l; i != NULL; i = i->next)
      if (i->exponent == exp)
      {
         co = i->coeff;
         return 1;
      }

   return 0;
}

int List::Delete(int exp)
{
   ListP cur;
   ListP tmp;

   if (l == NULL)
      return 0;

   if (l->exponent == exp)
   {
      tmp = l;
      l = l->next;
      delete tmp;
      return 1;
   }

   cur = l;

   while (cur->next != NULL)
   {
      if (cur->next->exponent == exp)
      {
         tmp = cur->next;
         cur->next = cur->next->next;
         delete tmp;
         return 1;
      }

      cur = cur->next;
   }

   return 0;
}

void List::Print(void) const
{
   ListP tmp;

   cout << "----------\n";

   for (tmp = l; tmp != NULL; tmp = tmp->next)
      cout << "exp: " << tmp->exponent << "   coeff: "
           << tmp->coeff << endl;

   cout << "----------\n";
}
