// lista - wersja obiektowa

#include <iostream.h>
#include <string.h>
#include <conio.h>

class item
{ public:
	char name[20];
	item *next;          //wskaznik na nast element listy
};

class list
{private:
	item *head;
 public:
 	list(); // konstruktor
  list(list &l); // konstruktor kopiujacy
	~list(); // destruktor
	void wypisz(void); // wypisywanie elementow listy
	void dodaj(char *f); // dodawanie elementu f na poczatek listy

	void dodaj_na_koniec(char *f); // dodawanie elementu f na koniec listy
	void usun(char *f);      // usuwanie elementu f z listy
	list operator=(list l);  // przyrownywanie list
  list operator+(char *f); // dodawanie elementu f na poczatek list
                           // (np. lista1+"abacki"; lista1 nie jest zmieniana, zwracany wynik dodawania)
  list operator-(char *f); // usuwanie elementu f z listy
                           // (np. lista1-"abacki"; lista1 nie jest zmieniana, zwracany wynik odejmowania)
	void operator+=(char *f);// dodawanie elementu f na poczatek listy, odpowiednik funkcji dodaj
                           // (np. lista1+="abacki"; lista1 jest zmieniana, operator nic nie zwraca)
	void operator-=(char *f);// usuwanie elementu f z listy, odpowiednik funkcji usun
                           // (np. lista1-="abacki"; lista1 jest zmieniana, operator nic nie zwraca)
  void sortuj(void);       // sortowanie elementow listy
	void porzadek(char *f);  // dodawanie elementu f do listy z zachowaniem porzadku
};

list::list()
{	head=NULL;}

list::list(list &l)
{
  head=NULL;
	item *m=NULL, *n=l.head;
	while(n)
	{
		m=new item;
		strcpy(m->name,n->name);
		m->next=head;
		head=m;
		n=n->next;
	}
}

list::~list()
{
	item *m, *n=head;
	while(n)
	{
		m=n->next;
		delete n;
		n=m;
	}
}

void list::dodaj(char *f)
{
	item *n=head;
	head=new item;
	strcpy(head->name, f);
	head->next=n;
}

void list::dodaj_na_koniec(char *f)
{
  item *n=head;
  while(n)
  {
    if (!(n->next)) {
        n->next = new item;
    	strcpy(n->next->name, f);
	    n->next->next=NULL;
        break;
    }
    n=n->next;
  }
}

void list::usun(char *f) {

  item *n=head;
  if (!strcmp(head->name, f)) {
    head = head->next;
  }
  else
  {
    while(n->next)
    {
      if (!strcmp(n->next->name, f)) {
        n->next = n->next->next;
        break;
      }
      n=n->next;
    }
  }
}

list list::operator=(list l)
{
  head=NULL;
	item *m=NULL, *n=l.head;
	while(n)
	{
		m=new item;
		strcpy(m->name,n->name);
		m->next=head;
		head=m;
		n=n->next;
	}
  return *this;
}

list list::operator+(char *f)
{
  list pom;
  pom = *this;
  pom.dodaj(f);

  return pom;
}

list list::operator-(char *f)
{
  list pom;
  pom = *this;
  pom.usun(f);

  return pom;
}

void list::operator+=(char *f)
{
  dodaj(f);
}

void list::operator-=(char *f)
{
  usun(f);
}

void list::sortuj(void)
{
  item *n,*m=head;

  while(m->next)
	{
    n=m;
    while(n->next)
	  {
	  	if (strcmp(n->name,n->next->name) > 0)
      {
        char pom[20];
        strcpy(pom,n->name);
        strcpy(n->name,n->next->name);
        strcpy(n->next->name,pom);
      }
      n=n->next;
	  }
 	  m=m->next;
  }
}

void list::porzadek(char *f)
{
  item *n=head;
  if (strcmp(head->name, f)>=0) {
    dodaj(f);
  }
  else if (strcmp(head->name, f)<=0 && strcmp(head->next->name, f)>0) {
    item *tmp = head->next;
    head->next = new item;
	strcpy(head->next->name, f);
    head->next->next = tmp;
  }
  else
  {
    while(n->next)
    {
      if (strcmp(n->name, f)<=0 && (strcmp(n->next->name, f)>0 || n->next == NULL )) {

        item *tmp = n->next;
        n->next = new item;
    	strcpy(n->next->name, f);
        n->next->next = tmp;

        break;
      }
      n=n->next;
    }
    if (strcmp(n->name, f)<=0 && n->next == NULL) {
        n->next = new item;
    	strcpy(n->next->name, f);
        n->next->next = NULL;
    }
  }
}

void list::wypisz(void)
{
  item *n=head;
  if(!n) cout << "lista jest pusta";
  else
  {
    while(n)
    {
      cout << " -> " << n->name;
      n=n->next;
    }
  }
  cout << endl;
}

void main(void)
{
	clrscr();

	list lista1, lista2, lista3;

  lista1.wypisz();
	getch();

	lista1.dodaj("babacki");
	lista1.dodaj("aabacki");
	lista1.dodaj("cabacki");
	lista1.dodaj_na_koniec("wbacki");
	lista1.dodaj_na_koniec("qbacki");

  lista1.wypisz();
	getch();

//  cout << "usun qbacki" << endl;
//  lista1.usun("qbacki");
//  lista1.wypisz();
//	getch();

//  cout << "+= dabacki" << endl;
//  lista1+="dabacki";
//  lista1.wypisz();
//	getch();

//  cout << "-= cabacki" << endl  ;
//  lista1-="cabacki";
//  lista1.wypisz();
//	getch();

//  cout << "lista 2 = lista 1" << endl;
//  lista2 = lista1;
//  lista2.wypisz();
//	getch();

//  cout << "lista 2 = lista 1 + karol" << endl;
//  lista2 = lista1 + "karol";
///  lista1.wypisz();
//  lista2.wypisz();
//	getch();

//  cout << "lista 3 = lista 2 - karol" << endl;
//  lista3 = lista2 - "karol";
//  lista2.wypisz();
//  lista3.wypisz();
//	getch();

  cout << "sort" << endl;
  lista1.sortuj();
  lista1.wypisz();
  cout << "porzadek - pocz" << endl << endl;
  lista1.porzadek("aaaaabacki");
  lista1.wypisz();
  cout << "porzadek - pocz1" << endl << endl;
  lista1.porzadek("aaadacki");
  lista1.wypisz();
  cout << "porzadek - srodek" << endl << endl;
  lista1.porzadek("padacka");
  lista1.wypisz();
  cout << "porzadek - koniec" << endl << endl;
  lista1.porzadek("zbedacki");
  lista1.wypisz();
  cout << endl;
  lista1.wypisz();
  getch();
}

