// Martian Adam Smyth
// CS510 Assignment 1
// Set Class code file

#include "set.h"
#include <stdlib.h>
#include <iostream.h>

SetClass::~SetClass(void)
{
  LinkElement *cur;

  while(head)
  {
    cur=head;
    head=(LinkElement *)head->next();
    delete cur;
  }

  return; 
}

int SetClass::ins(LinkElement *item)
{
    LinkElement *cur;
    
    if(!head || *item < *head)
    {
       item->linkto(head);
       head = item;
       return 1;
    }

    cur=head;
    while(cur->next() && (*item > *(LinkElement*)cur->next()) )
        cur=(LinkElement*)cur->next();
    
    cur->insert(item);
    return 1;
}

int SetClass::printset(void)
{
  LinkElement *cur;

    if(!head)
         return 0;

    cur=head;
    while(cur)
    {
        cur->print(); cout<<"\n\n";
        cur=(LinkElement *)cur->next();
    }
    return 1;
}

int SetClass::del(char *key)
{
  LinkElement *cur, *temp;
  int ret = 0;

  if(!head)
    return 0;

  while( *(cur=head) == key)
  {
    head = (LinkElement *)head->next();
    delete cur;
    ret = 1;
  }

  if(ret)
    return ret;

  // A more elaborate search /could/ be done here,
  // but would require using the array-type indexing
  // and would thus not improve the speed.

  cur=head;
  while((temp=(LinkElement *)cur->next()))
  {
    if(*temp == key)
    {
      cur->linkto((LinkElement *)temp->next());
      delete temp;
      ret = 1;
    } else if(ret)
      return ret;
    cur = (LinkElement *)cur->next();
  }
}

int SetClass::init(void)  // Simplest way is just to destruct and re-construct
{
  LinkElement *cur;

  while(head)
  {
    cur=head;
    head=(LinkElement *)head->next();
    delete cur;
  }

  head = 0;

  return 1;
}

int SetClass::is_member(char *key)
{
  LinkElement *cur=head;

  while(cur)
  {
    if( *cur == key )
      return 1;
    cur = (LinkElement *)cur->next();
  }

  return 0;
}

int SetClass::is_member(LinkElement *item)
{
  LinkElement *cur=head;

  while(cur)
  {
    if( *cur == *item )
      return 1;
    cur = (LinkElement *)cur->next();
  }

  return 0;
}

SetClass* SetClass::operator||(SetClass & other)
{
  SetClass *newset = new SetClass;
  LinkElement *cur=head, *temp;

  while(cur)
  {
    temp = (LinkElement *)cur->makecopy();
    newset->ins(temp);
    cur=(LinkElement *)cur->next();
  }

  cur=other.head;
  while(cur)
  {
    if(!newset->is_member(cur))
    {
      temp = (LinkElement *)cur->makecopy();
      newset->ins(temp);
    }
    cur=(LinkElement *)cur->next();
  }

  return newset;
}

SetClass* SetClass::operator&&(SetClass & other)
{
  SetClass *newset = new SetClass;
  LinkElement *cur=head, *temp;

  while(cur)
  {
    if(other.is_member(cur))
    {
      temp = (LinkElement *)cur->makecopy();
      newset->ins(temp);
    }
    cur=(LinkElement *)cur->next();
  }

  return newset;
}

LinkElement* SetClass::operator[](int n)
{
  LinkElement *cur=head;
  int i=1;

  while(i<n && cur)
  {
    i++;
    cur=(LinkElement *)cur->next();
  }

  return cur;
}

LinkElement* SetClass::operator[](const char *s)
{
  LinkElement *cur=head;

  while(cur)
  {
    if( *cur == s )
      return cur;
    cur=(LinkElement *)cur->next();
  }
}

