#include <conio.h>
#include <stdio.h>
#include <iostream.h>
#include <exception>
#include <stdlib.h>

class wiktor{
    private:
        int **wektor;
        int *dlugosc;
        int ilosc;

        int **temp_w;
        int *temp_d;

    public:
        wiktor() {
            wiktor::wektor = NULL;
            wiktor::dlugosc = NULL;
            wiktor::temp_w = NULL;
            wiktor::temp_d = NULL;
            wiktor::ilosc = -1;
        }

        ~wiktor() {
            if (dlugosc != NULL) {
                delete wiktor::dlugosc;
            }
            if (wektor != NULL) {
                delete wiktor::wektor;
            }
        }

        int wiktor::wyswietl() {

            if ( wiktor::dlugosc == NULL ) {
                cout << "Brak zdefiniowanych wektorow!" << endl;
                return 1;
            }
            for (int i = 0; i <= wiktor::ilosc; i++) {
                cout << "wektor " << i << "[" << wiktor::ilosc << "]: " ;
                for (int j = 0; j <= wiktor::dlugosc[i]; j++) {
                   cout << "[" << wiktor::wektor[i][j] << "] ";
                }
                cout << endl;
            }
            return 0;

        }

        int wiktor::dodaj(int dlugosc) {

             if (wiktor::ilosc >= 0) {

                wiktor::temp_w = new int*[wiktor::ilosc + 1+5];
                wiktor::temp_d = new int[wiktor::ilosc + 1+5];

                for (int i = 0; i <= wiktor::ilosc; i++) {
                    wiktor::temp_w[i] = new int[wiktor::dlugosc[i] + 1];
                }

                for (int i = 0; i <= wiktor::ilosc; i++) {
                    wiktor::temp_d[i] = wiktor::dlugosc[i];
                    for (int j = 0; j <= wiktor::dlugosc[i]; j++) {
                        wiktor::temp_w[i][j] = wiktor::wektor[i][j];
                    }
                }

                delete wiktor::dlugosc;
                delete wiktor::wektor;

            }

            wiktor::ilosc++;
            wiktor::dlugosc = new int[wiktor::ilosc + 1];
            wiktor::dlugosc[wiktor::ilosc] = dlugosc - 1;
            wiktor::wektor = new int*[wiktor::ilosc + 1];
            for (int i = 0; i <= wiktor::ilosc; i++)
                wiktor::wektor[wiktor::ilosc] = new int[wiktor::dlugosc[wiktor::ilosc] + 1];

            if (wiktor::ilosc > 0) {

                for (int i = 0; i < wiktor::ilosc; i++) {
                    wiktor::dlugosc[i] = wiktor::temp_d[i];
                    cout << wiktor::dlugosc[i];
                    for (int j = 0; j <= wiktor::dlugosc[i]; j++) {
                        cout << wiktor::dlugosc[i];
                        wiktor::wektor[i][j] = wiktor::temp_w[i][j];
                    }
                }
            }

            for (int i = 0; i <= wiktor::dlugosc[wiktor::ilosc]; i++)
                wektor[wiktor::ilosc][i] = 10 * wiktor::ilosc + i;

            if (temp_d != NULL && temp_w != NULL) {
                delete wiktor::temp_d;
                delete wiktor::temp_w;
                wiktor::temp_w = NULL;
                wiktor::temp_d = NULL;
            }

            return 0;
        }

        int wiktor::usun(int ktory) {

            if (ktory > wiktor::ilosc)
            return 1;

            temp_w = new int*[wiktor::ilosc+1];
            for (int i = 0, k = 0; i <= wiktor::ilosc; i++) {
                if (i == ktory) {
                    k++;
                }
                else {
                    temp_w[i - k] = new int[wiktor::dlugosc[i]+1];
                }
            }

            for (int i = 0, k = 0; i <= wiktor::ilosc; i++) {
                if (i == ktory) {
                    k++;
                }
                else {
                    for (int j = 0; j < wiktor::dlugosc[i]; j++) {
                        wiktor::temp_w[i - k][j] = wiktor::wektor[i][j];
                    }
                }
            }

            //DEBUG_OUTPUT for (int i = 0; i <= wiktor::ilosc; i++) { cout << "{wektor " << i << "}"; for (int j=0; j < wiktor::dlugosc[i]; j++) { cout << "[" << wiktor::wektor[i][j] << "]"; } cout << endl; }
            //DEBUG_OUTPUT for (int i = 0; i < wiktor::ilosc; i++) { cout << "{temp " << i << "}"; for (int j=0; j < wiktor::dlugosc[i]; j++) { cout << "[" << wiktor::temp_w[i][j] << "]"; } cout << endl; }

            delete[] wiktor::wektor;

            wiktor::temp_d = new int[wiktor::ilosc+1];

            for (int i = 0, k = 0; i <= wiktor::ilosc; i++) {
                if (i == ktory) {
                    k++;
                }
                else {
                    wiktor::temp_d[i - k] = wiktor::dlugosc[i];
                }
                //DEBUG_OUTPUT cout << "{{" << wiktor::temp_d[i] << "|" << wiktor::dlugosc[i] << "}}";
            }

            delete[] wiktor::dlugosc;

            wiktor::ilosc--;
            wiktor::dlugosc = new int[wiktor::ilosc+1];
            //DEBUG_OUTPUT cout << endl;
            for (int i = 0; i <= wiktor::ilosc; i++) {
                wiktor::dlugosc[i] = wiktor::temp_d[i];
                //DEBUG_OUTPUT cout << "{" << wiktor::temp_d[i] << "|" << wiktor::dlugosc[i] << "}";
            }
            //DEBUG_OUTPUT cout << "{" << wiktor::ilosc << "|" << wiktor::dlugosc[wiktor::ilosc] << "}";
            //DEBUG_OUTPUT cout << endl;

            wektor = new int*[wiktor::ilosc+1];
            for (int i = 0; i <= wiktor::ilosc; i++) {
                wiktor::wektor[i] = new int[wiktor::dlugosc[i]+1];
            }

            for (int i = 0; i <= wiktor::ilosc; i++) {
                for (int j = 0; j < wiktor::dlugosc[i]; j++) {
                    wiktor::wektor[i][j] = wiktor::temp_w[i][j];
                }
            }

            //DEBUG_OUTPUT for (int i = 0; i <= wiktor::ilosc; i++) { cout << "{te " << i << "}"; for (int j=0; j < wiktor::dlugosc[i]; j++) { cout << "[" << wiktor::temp_w[i][j] << "]"; } cout << endl; }
            //DEBUG_OUTPUT for (int i = 0; i <= wiktor::ilosc; i++) { cout << "{we " << i << "}"; for (int j=0; j < wiktor::dlugosc[i]; j++) { cout << "[" << wiktor::wektor[i][j] << "]"; } cout << endl; }

            delete[] wiktor::temp_w;

            return 0;
        }

        int wiktor::zmien_rozmiar(int ktory_wektor, int rozmiar) {

            if (ktory_wektor > wiktor::ilosc)
            return 1;

            int stary =  wiktor::dlugosc[ktory_wektor];

            temp_w = new int*[wiktor::ilosc+1];
            for (int i = 0; i <= wiktor::ilosc; i++) {
                temp_w[i] = new int[wiktor::dlugosc[i]+1];
            }

            for (int i = 0; i <= wiktor::ilosc; i++) {
                for (int j = 0; j < wiktor::dlugosc[i]; j++) {
                    wiktor::temp_w[i][j] = wiktor::wektor[i][j];
                }
            }

            //DEBUG_OUTPUT for (int i = 0; i <= wiktor::ilosc; i++) { cout << "{wektor " << i << "}"; for (int j=0; j < wiktor::dlugosc[i]; j++) { cout << "[" << wiktor::wektor[i][j] << "]"; } cout << endl; }
            //DEBUG_OUTPUT for (int i = 0; i <= wiktor::ilosc; i++) { cout << "{temp " << i << "}"; for (int j=0; j < wiktor::dlugosc[i]; j++) { cout << "[" << wiktor::temp_w[i][j] << "]"; } cout << endl; }

            delete[] wiktor::wektor;

            wiktor::dlugosc[ktory_wektor] = rozmiar;

            wektor = new int*[wiktor::ilosc+1];
            for (int i = 0; i <= wiktor::ilosc; i++) {
                wiktor::wektor[i] = new int[wiktor::dlugosc[i]+1];
            }

            for (int i = 0; i <= wiktor::ilosc; i++) {
                for (int j = 0; j < wiktor::dlugosc[i]; j++) {
                    wiktor::wektor[i][j] = wiktor::temp_w[i][j];
                }
            }

            if (stary < rozmiar) {
                for (int i = stary; i < rozmiar; i++) {
                    wiktor::wektor[ktory_wektor][i] = wiktor::wektor[ktory_wektor][i - 1] + 1;
                }
            }

            //DEBUG_OUTPUT for (int i = 0; i <= wiktor::ilosc-1; i++) { cout << "{te " << i << "}"; for (int j=0; j < wiktor::dlugosc[i]; j++) { cout << "[" << wiktor::temp_w[i][j] << "]"; } cout << endl; }
            //DEBUG_OUTPUT for (int i = 0; i <= wiktor::ilosc; i++) { cout << "{we " << i << "}"; for (int j=0; j < wiktor::dlugosc[i]; j++) { cout << "[" << wiktor::wektor[i][j] << "]"; } cout << endl; }

            delete wiktor::temp_w;

            return 0;
        }

        int wiktor::zwroc_rozmiar(int ktory_wektor) {

            if (ktory_wektor > wiktor::ilosc)
            return 0;

            return wiktor::dlugosc[ktory_wektor];

        }

        int wiktor::zwroc_element(int ktory_wektor, int ktory_element) {

            if ( !ktory_element < wiktor::dlugosc[ktory_wektor] || !ktory_wektor <= wiktor::ilosc)
                throw "err";

            return wiktor::wektor[ktory_wektor][ktory_element];
        }

        int wiktor::wpisz_element(int ktory_wektor, int ktory_element, int wartosc) {

            if ( ktory_element >= wiktor::dlugosc[ktory_wektor] || ktory_wektor > wiktor::ilosc) {
                return 1;
            }
            else {

                wiktor::wektor[ktory_wektor][ktory_element] = wartosc;
                return 0;
            }
        }

        int wiktor::testowa(void) {

            if (wektor == NULL)
                return 1;

            return 0;
        }

};

char interface() {
    clrscr();
    cout << "Program 001 v.0.1 (C) Karol Kozlowski 2005" << endl << endl;
    cout << "w. Wyswietl biezace wektory" << endl;
    cout << "1. Dodaj wektor" << endl;
    cout << "u. Usun wektor" << endl;
    cout << "e. Zmien Element" << endl;
    cout << "_. Zmien caly" << endl;
    cout << "r. Zmien Rozmiar" << endl;
    cout << "s. Podaj Rozmiar" << endl;
    cout << "d. Zwroc element" << endl;
    cout << "_. Suma Wektorow" << endl;
    cout << "_. Roznica wektorow" << endl;
    cout << "_. Pomnoz przez skalar" << endl;
    cout << "_. Pomnoz wektory skalarnie" << endl;
    cout << "?. Pomoc & Info" << endl;
    cout << "X. Wyjdz z programu" << endl;
    return getch();
}



int main(void)
{
    bool exit = false;
    wiktor w1;

    //randomize();
    //for (int i = 0, a = 5, b = 10; i<9; i++)
    //w1.dodaj(random(b - a) + a);


    do {
       switch ( char cha = tolower(interface()) ) {
            case 'w' :
                clrscr();
                cout << "[" << cha << "] Wyswietl biezace wektory" << endl << endl ;
                w1.wyswietl();
                getch();
                break;
            case '1' :
                clrscr();
                cout << "[" << cha << "] Dodaj Wektor" << endl << endl ;
                int dlugosc;
                do {
                    cout << "Podaj dlugosc wektora : ";
                    cin >> dlugosc;
                    if (dlugosc < 1 || dlugosc >= 15)
                        cout << "Wartosc nieprawidlowa!" << endl;
                } while (dlugosc < 1 || dlugosc >= 15);
                cout << endl;
                w1.dodaj(dlugosc);
                w1.wyswietl();
                getch();
                break;
            case 'u' :
                clrscr();
                cout << "[" << cha << "] Usun Wektor" << endl << endl ;
                if (!w1.wyswietl()) {
                    int ktory;
                    cout << endl << "Ktory wektor chcesz usunac : ";
                    cin >> ktory;
                    cout << endl;
                    if (w1.usun(ktory))
                        cout << "Nie ma takiego wektora!" << endl;
                    w1.wyswietl();
                }
                getch();
                break;
            case 'e' :
                clrscr();
                cout << "[" << cha << "] Zmien Element" << endl << endl ;
                if (!w1.wyswietl()) {
                    int ktory_wektor, ktory_element, wartosc;
                    cout << endl << "Element ktorego wektora chcesz zmienic : ";
                    cin >> ktory_wektor;
                    cout << "Ktory element " << ktory_wektor << " wektora chcesz zmienic : ";
                    cin >> ktory_element;
                    cout << "Podaj nowa wartosc " << ktory_element << " elementu " << ktory_wektor << " wektora : ";
                    cin >> wartosc;
                    if (w1.wpisz_element(ktory_wektor, ktory_element, wartosc)) {
                        cout << endl << "Podales nieprawidlowe wartosci!";
                    }
                    else {
                        cout << endl << "Wartosc zostala zmieniona!" << endl << endl;
                        w1.wyswietl();
                    }
                }
                getch();
                break;
            case 'r' :
                clrscr();
                cout << "[" << cha << "] Zmien Rozmiar" << endl << endl ;
                if (!w1.wyswietl()) {
                    int ktory, nowy_rozmiar;
                    cout << endl << "Rozmiar ktorego wektora chcesz zmienic : ";
                    cin >> ktory;
                    cout << "Podaj nowy rozmiar " << ktory << " wektora : ";
                    cin >> nowy_rozmiar;
                    cout << endl;

                    if (w1.zmien_rozmiar(ktory, nowy_rozmiar))
                        cout << endl << "Podales nieprawidlowe wartosci!";
                    else
                        w1.wyswietl();
                }

                getch();
                break;
            case 's' :
                clrscr();
                cout << "[" << cha << "] Rozmiar wektora" << endl << endl ;
                if (!w1.wyswietl()) {
                    int ktory;
                    cout << endl << "Rozmiar ktorego wektora : ";
                    cin >> ktory;
                    cout << endl;
                    if ( int rozmiar = w1.zwroc_rozmiar(ktory) )
                        cout << "Rozmiar wektora " << ktory << " wynosi : " << rozmiar << endl;
                    else
                        cout << "Nie ma takiego wektora!" << endl;
                }
                getch();
                break;
            case 'd' :
                clrscr();
                cout << "[" << cha << "] Zwroc Element" << endl << endl ;
                if (!w1.wyswietl()) {
                    int ktory, element;
                    cout << endl << "Element ktorego wektora chcesz dostac : ";
                    cin >> ktory;
                    cout << "Wartosc ktorego elementu " << ktory << " wektora : ";
                    cin >> element;
                    cout << endl;

                    if (int wartosc = w1.zwroc_element(ktory, element))
                        cout << element << " element " << ktory << " wektora ma wartosc : " << wartosc << endl;
                    else
                        cout << "Taki element/wektor nie istnieje" << endl;
                }
                getch();
                break;
            case '_' :
                clrscr();
                cout << "[" << cha << "] Funkcja Niezaimplementowana!" << endl << endl ;
                if (w1.testowa()) {
                    cout << "nie ma";
                }
                getch();
                break;
            case '?' :
            case '/' :
                clrscr();
                cout << "[?] Pomoc & Info" << endl << endl ;
                cout << "e-mail: 132652@student.pwr.wroc.pl";
                getch();
                break;
            case 'q':
            case 'x':
            case 27 :
                cout << "EXIT";
                exit = true;
                break;
            default :
                cout << endl << "Wybor niepoprawny, badz funkcja nie zostala zaimplementowana!" << endl;
                getch();
        }
    } while (!exit);

    return 0;
}