#include <iostream.h>
#include <assert.h>
#include <conio.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>


// klasa danych do przechowywania w liscie
class Towar {
public:
	char nazwa[32];
	int ilosc;
	double cena;

	// konstruktor
	Towar();

	void wczytaj();
	// przciazane operatory wyprowadzania, by laatwiej bylo wyswietlac towar
	friend ostream& operator<<(ostream& wy, Towar towar);
	friend ostream& operator<<(ostream& wy, Towar *towar);
};

// wezel listy
class WEZEL{
  // zaprzyjaznione klasa lista oraz operator wyprowadzania klasy lista
  friend class Lista;
  friend ostream& operator<<(ostream& wy, Lista& spis);
private:
  // konstruktor
  WEZEL(Towar *wartosc, WEZEL* pewien = 0) {
	  memcpy(&wrt, wartosc, sizeof(Towar));
	  nastepny = pewien;
  }
  // dane
  Towar wrt;
  // nastepna pozycja
  WEZEL *nastepny;
};

class Lista{
public:
  Lista()  { pierwszy = 0; ostatni = 0; }
  // destruktor
  ~Lista() { this->czysc(); }

  void dodaj(Towar*); // dodaj towar do listy
  Towar *znajdz(char *nazwa); // znajdz towar o danej nazwie
  void czysc(); // wyczysc liste
  int usun(char *nazwa); // usun towar o nazwie nazwa z listy
  friend ostream& operator<<(ostream& wy, Lista& spis); // operator wyprowadzania
private:
  WEZEL* ostatni;
  WEZEL* pierwszy;
};

// dodaj towar do lsity
void Lista::dodaj(Towar* wrt)
{
  WEZEL *wsk = new WEZEL(wrt); // tworzymy nowy element towar
  if (pierwszy == 0)
	 // jestesmy pierwszym elementem w liscie
	 pierwszy = wsk;
  else
	 // dodajemy na koniec
	 ostatni->nastepny = wsk;
  ostatni = wsk;
}

// znajdz towar o podanej nazwie
Towar *Lista::znajdz(char *nazwa)
{
 WEZEL *wsk = pierwszy;
 // zaczynamy poszukiwania od pierwszego elemenetu
 while (wsk) {
	 if (!strcmp(wsk->wrt.nazwa, nazwa))
		 // jezeli znajdziemy, zwracamy znaleziony element
		 return &wsk->wrt;
	 // jezeli nic nie mamy, lecimy dalej
	 wsk = wsk->nastepny;
 }
 // nie znalezlismy nic, zwrocmy NULL
 return NULL;
}

// operator wyprowazania dla list
ostream& operator<<(ostream& wy, Lista& spis)
{
  wy << "Lista towarow:" << endl;
  for (WEZEL *wsk = spis.pierwszy; wsk; wsk = wsk->nastepny)
		wy << wsk->wrt << endl;

  return wy;
}

// operator wyprowadzania dla towarow
ostream& operator<<(ostream& wy, Towar towar)
{
  wy << "\tNazwa: " << towar.nazwa << endl;
  wy << "\tCena: " << towar.cena << endl;
  wy << "\tIlosc: " << towar.ilosc << endl;

  return wy;
}

// i do wskaznika na towar
ostream& operator<<(ostream& wy, Towar *towar)
{
  if (!towar)
	  // towar == NULL, wychodzimy
	  return wy;
  wy << "Nazwa: " << towar->nazwa << endl;
  wy << "Cena: " << towar->cena << endl;
  wy << "Ilosc: " << towar->ilosc << endl;

  return wy;
}

// wyczysc liste
void Lista::czysc()
{
 WEZEL *wsk = pierwszy;
 while (wsk){
	WEZEL *tmcz = wsk;
	wsk = wsk->nastepny;
	delete tmcz;
 } 
 pierwszy = ostatni = 0;
}

// usun z listy towar o podanej nazwie
int Lista::usun(char *nazwa)
{
 WEZEL *wsk = pierwszy, *last;

 // element do usuniecia jest pierwszym elementem
 if (!strcmp(wsk->wrt.nazwa, nazwa)) {
	pierwszy = wsk->nastepny;
 }
 else {
	 // element jest gdzies w srodku badz na koncu, poszukujemy...
	for (; wsk && strcmp(wsk->wrt.nazwa, nazwa) ; wsk = wsk->nastepny)
		last = wsk;

	if (!wsk) 
		// przeszukalismy cala liste i nie znalezlismy elementu
		return 1;

	// mamy element, zmieniamy kolejnosc, usuwamy
	last->nastepny = wsk->nastepny;
	delete wsk;
 }

 return 0;
}

Towar::Towar()
{
	memset(nazwa, 0, sizeof(nazwa));
	ilosc = 0;
	cena = 0;
}

void Towar::wczytaj()
{
	cout << "Wczytywanie towaru..." << endl;
	cout << "\tNazwa towaru: ";
	cin >> nazwa;
	cout << "\tIlosc: ";
	cin >> ilosc;
	cout << "\tcena: ";
	cin >> cena;
}

// glowna funkcja programu
int main()
{
	char ch;
	Towar *t = NULL; // a to wskaznik na jakis towar. bedzie nam potrzebny do szukania towarow z listy
	char *nazwa;
	// nasza glowna lista
	Lista towary;

menu:
	clrscr();

	cout << "Menu." << endl;
	cout << "1. Wyswietl liste towarow." << endl;
	cout << "2. Dodaj towar do listy." << endl;
	cout << "3. Usun towar z listy." << endl;
	cout << "4. Wyszukaj towar." << endl;
	cout << "5. Wyczysc liste towarow." << endl;
	cout << "6. Zmien dane towaru." << endl;
	cout << "q. Wyjdz z programu." << endl;

	ch = getch();
	switch(ch) {
		case '1':
			clrscr();
			cout << towary;
			cout << "Wcisnij klawisz.";
			getch();
			break;
		case '2':
			clrscr();
			Towar nowytowar;
			nowytowar.wczytaj();
			t = towary.znajdz(nowytowar.nazwa);
			if (t) {
				cout << "Podales juz istniejacy towar, po prostu zwieksze jego ilosc o " << nowytowar.ilosc << "." << endl;
				t->ilosc += nowytowar.ilosc;
				t = NULL;
			}
			else {
				towary.dodaj(&nowytowar);
				cout << "Towar dodany." << endl;
			}

			cout << "Wcicnij klawisz.";
			getch();
			break;
		case '3':
			clrscr();
			nazwa = new char[64];
			cout << "Podaj nazwe towaru do usuiniecia: ";
			cin >> nazwa;
			if (towary.usun(nazwa))
				cout << "Niestety nie ma na liscie towaru " << nazwa << "." << endl;
			else
				cout << "Towar " << nazwa << " usuniety."  << endl;
			cout << "Wcisnij klawisz.";
			delete nazwa;
			getch();
			break;
		case '4':
			clrscr();
			nazwa = new char[64];
			cout << "Podaj nazwe towaru do znalezienia: ";
			cin >> nazwa;
			t = towary.znajdz(nazwa);
			if (t) {
				cout << "Znaleziono towar " << endl << t << endl;
				t = NULL;
			}
			else
				cout << "Nieznaleziono towaru " << nazwa << " ." << endl;
			cout << "Wcnisnij klawisz.";
			delete nazwa;
			getch();
			break;
		case '5':
			clrscr();
			cout << "Czy na pewno wyczysic liste towarow? t/n ";
			ch = getch();
			cout << endl;
			if (ch == 't') {
				towary.czysc();
				cout << "Lista towarow wyczyszczona." << endl;
			}
			else
				cout << "Anulowano czyszczenie listy towarow." << endl;
			cout << "Wcisnij klawisz.";
			getch();
			break;
		case '6':
			clrscr();
			nazwa = new char[64];
			cout << "Podaj nazwe towaru, w ktorym chcesz cos zmienic: ";
			cin >> nazwa;
			t = towary.znajdz(nazwa);
			if (!t)
				cout << "Nieznaleziono towaru " << nazwa << "." << endl;
			else {
				cout << "Znaleziono towar:" << endl << t;
				cout << "Podaj nowe dane." << endl;
				t->wczytaj();
				t = NULL;
			}
			cout << "Wcisnij klawisz.";
			getch();
			break;
		case 'q':
			cout << "Papa, dzieki za uzywanie :>" << endl;
			exit(0);
			break;
	}

	goto menu;
}

