#ifndef _COMPOUND_CPP_
#define _COMPOUND_CPP_

#include <iostream.h>

#include "element.h"
#include "compound.h"

Compound::Compound() : _content(0) {
  _type = ABSTRACT;
}

Compound::Compound(const Compound& orig, Type t) : Element(orig), _content(0) {
  _type = t;
  for (Element * el = orig.content(); el != 0; el = Element::next(el)) {
    add(el->copy());
  }
}

Compound::~Compound() {
  scratch();
}

void Compound::scratch() {
  Element * d = 0;
  while (_content) {
    d = _content;
    _content = Element::remove(_content);
    // This delete is cause of much trouble!
    // To debug:
    // cout << "scratch: " << ctype() << ":" << *d << endl;
    delete d;
  }
}

Element * Compound::get(int i) const {
  return Element::get(i,_content);
}

Element * Compound::next(Element * e) const {
  return Element::next(e);
}

Element * Compound::prev(Element * e) const {
  return Element::prev(e);
}

void Compound::splitBefore(Element * e) const {
  Element::splitBefore(e);
}

Element * Compound::first() const {
  return Element::first(_content);
}

Element * Compound::last() const {
  return Element::last(_content);
}

int Compound::size() const {
  int retv = 0;
  for (Element * el = Element::first(_content); el!=0; el = Element::next(el)) { retv++; }
  return retv;
}

bool Compound::empty() const {
  if (_content) return false;
  else return true;
}


void Compound::add(Element * el) {
  if (_content==0) {
    _content = el;
  } else {
    Element::append(el,_content);
  }
}

void Compound::push(Element * el) {
  if (_content==0) {
    _content = el;
  } else {
    _content = Element::preput(el,_content);
  }
}

void Compound::insertBefore(Element * ne, Element * base) {
  if ((ne!=0) && (base!=0)) {
    if (_content==0) {
      cout << "PANIC: empty compound" << endl;
    } else {
      _content = Element::insertBefore(ne,base);
    }
  }
}

void Compound::insertAfter(Element * ne, Element * base) const {
  if ((ne!=0) && (base!=0)) {
    if (_content==0) {
      cout << "PANIC: empty compound" << endl;
    } else {
      Element::insertAfter(ne,base);
    }
  }
}

void Compound::insertAt(int i, Element * el) {
  // cout << "i: " << i << ", cnt: " << _content << endl;
  if (i>-1) {
    if (i<size()) {
      Element * e = get(i);
      if (e!=0) {
	if (_content==0) {
	  _content = el;
	} else {
	  // _content = Element::preput(el,e);
	_content = Element::insertBefore(el,e);
	}
      }
    } else {
      Element::append(el,_content);
    }
  }
}

void Compound::replace(Element * e1, Element * e2) {
  //  for (Element * el = _content; el != 0; el = Element::next(el))
  // if (el==e1)
  Element::exchange(e1,e2);
  if (_content == e1) { _content = e2; }
}

void Compound::remove(Element * el) {
  if (_content==0) {
    cout << "err: remove element from empty list" << endl;
  } else {
    if (el->member(this)) _content = Element::remove(el);
  }
}

Element * Compound::cutFirst() {
  Element * retv = _content;
  _content = Element::remove(retv);
  return retv;
}

Element * Compound::cutLast() {
  Element * retv = Element::last(_content);
  _content = Element::remove(retv);
  return retv;
}

void Compound::setContent(Element * el) {
  _content = el;
}


void Compound::hide() {}

void Compound::show() {}

ostream & Compound::printContent(int depth, ostream & s) const {
  for (Element * el = _content; el != 0; el = Element::next(el)) {
    el->print(depth+1,s);
  }
  return s;
}

void Compound::flush(const char * c) const {
  cout << c << "ERR" << endl;
}



#endif
