/*
   A simple implementation of a set of characters
   similar to what's available in Pascal
*/

using namespace std;
#include <iostream>
#include "CharSets.h"
#include <string>

CharSet::CharSet() // create empty set
{
  info[0] = '\0';
}

CharSet::CharSet(char *s) // create set consisting of chars from s
{
  int j=0;
  //cout << "Calling CharSet build with " << s  << endl;
  int i=strlen(s);
  info[0] = '\0';      // initialize info to a '\0' string
  while (i) {
    i = i - 1;         // move source position
    if (index (info, s[i]) == NULL) { // found a new element
       info[j] = s[i]; // insert it
       j = j + 1;      // move destination position
       info[j] = '\0'; // keep it as a string
    }
  }
  
}

CharSet CharSet::operator+ (CharSet t) // union
{
  char longstring[258]; 
  //cout << "Calling union" << endl;
  strcpy(longstring,this->info);             // insert s
  strcat(longstring,t.info); // append t
  
  CharSet result(longstring); // place into CharSet
  return result;
}

CharSet CharSet::operator+ (char t) // append
{
  char longstring[258]; 
  //cout << "Calling append" << endl;
  strcpy(longstring,this->info);             // insert s
  longstring[strlen(longstring)+1]='\0';
  longstring[strlen(longstring)]=t; 
  CharSet *result = new CharSet(longstring); // place into CharSet
  return *result;
}

CharSet CharSet::operator- (CharSet t) // set diff s - t
{
  CharSet *result = new CharSet();
  int i=strlen(this->info);
  int j=0;
  result->info[0] = '\0'; // start off with a null string
  while (i) {
    i = i - 1;         // move source position
    if (index (t.info, this->info[i]) == '\0') { // found a keeper!
       result->info[j] = this->info[i]; // insert it
       j = j + 1;      // move destination position
       result->info[j] = '\0'; // keep it as a string
    }
  }
  return *result;
}


CharSet CharSet::operator* (CharSet t) // intersection
{
  CharSet *result = new CharSet();
  int i=strlen(this->info);
  int j=0;
  result->info[0] = '\0'; // start off with a null string
  while (i) {
    i = i - 1;         // move source position
    if (index (t.info, this->info[i]) != '\0') { // found a keeper!
       result->info[j] = this->info[i]; // insert it
       j = j + 1;      // move destination position
       result->info[j] = '\0'; // keep it as a string
    }
  }
  return *result;
}

void CharSet::display ()  // display the set
{
   int i;
   cout << '{';
   for (i = 0; i < strlen(info)-1; i++)
       cout << info[i] << ", ";
   cout << info[i] << "}";
}

void CharSet::displayln ()  // display the set
{
   int i;
   cout << '{';
   for (i = 0; i < strlen(info)-1; i++)
       cout << info[i] << ", ";
   cout << info[i];
   cout << "}" << endl;
}

int CharSet::contains (char c)         // is c in the set?
{
   return (index(info,c) != NULL);
}


