#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstring>

using namespace std;

struct structura{                           //створюємо структуру
    char namemark[124];            //задаємо параметри, назва марки телефону
    char namephone[124];      //назва телефону        
    int price;           //його ціна
};

void write(){      //підпрограма яка записує в файл нові дані
    int n;
    cout << "Enter quality records : ";   //питаємося скільки телефонів вписати за 1 раз
    cin >> n;                              //вписуємо число
    ofstream diana("diana", ios::app | ios::binary);  //створюємо об'єкт для запису в файл
    structura telephone;          //створюємо змінну типу структура
    for(int i=0; i<n; i++){         //цикл
        cout << "Enter namemark ";        //вписуємо назву марки телефону
        cin >> telephone.namemark;
        cout << "Enter namephone ";       //назву телефону
        cin >> telephone.namephone;
        cout << "Enter price ";      //його ціна
        cin >> telephone.price;
        diana.write((char*)&telephone, sizeof(structura));    //записує дані в кінець файлу як структуру
        }
    diana.close();  //закриває файл
}

void read(){     //підпрограма яка виводить на екран всі дані
    structura telephone;
    ifstream diana("diana", ios::binary);   //створюємо об'єкт для читання з нього
    int p=0;
    while (diana.read((char*)&telephone, sizeof(structura)) != NULL){        //поки є дані в файлі працює цикл який виводить ці дані
        cout << p+1 << ") " << setiosflags(ios::left) << setw(15) << telephone.namemark << setw(15) << telephone.namephone << setw(15) << telephone.price << endl;
        p++;
	}
    diana.close(); //закриваємо файл
}

void rewrite(){   //підпрограма яка редагує один з телефонів вже записаних
    int n = 0;
    int change;
    structura telephone;
    structura buff;    
    ifstream diana("diana", ios::binary); //з нашого файлу ми будем зчитувати дані 
    ofstream dianaNew("prom", ios::binary | ios::app); //і створюємо новий файл куди перепишемо всі дані з першого, але з відредагуванням
    cout << "Vvedit nomer dlya zminu : ";    
    cin >> change;
    while(diana.read((char*)&telephone, sizeof(structura)) != NULL){     //то саме шо і в підпрограмі для запису телефону, просто заново вводимо дані
        if(change-1 == n){
            cout << "New namemark : ";
            cin >> buff.namemark;
            cout << "New namephone : ";
            cin >> buff.namephone;
            cout << "New price : ";
            cin >> buff.price;
            dianaNew.write((char*)&buff, sizeof(structura));
            n++;
        }else{
            dianaNew.write((char*)&telephone, sizeof(structura));
            n++;
        }
    }
    diana.close();       //закриваємо наші файли
    dianaNew.close();
    remove("diana");    //старий видаляємо
    rename("prom", "diana");   //новий переіменовуємо як старий
}

void searh(){   //підпрограма для пошуку
    structura telephone;
    char enternamemark[124];
    char enternamephone[124];
    int number;
    int enterprice;
    cout << "On what criteria you want to search\n\t1. namemark\n\t2. namephone\n\t3. price\n\t\tEnter number : ";
    cin >> number;   //вибираємо по чому ми хочемо шукати
    switch(number){   //далі вводимо те що вибрали
        case 1 : {
            cout << "Enter namemark : ";
            cin >> enternamemark;        
            break;
        }
        case 2 : {
            cout << "Enter namephone : ";
            cin >> enternamephone;
            break;
        }
        case 3 : {
            cout << "Enter price : ";
            cin >> enterprice;
            break;
        }
        default : {      //якщо ми щось погано ввели то вибиває - помилка
            cout << "Error enter !!!";
            break;
        }
    }
    ifstream diana("diana", ios::binary);         
    while(diana.read((char *)&telephone, sizeof(telephone)) != NULL){  //відкриваємо файл і проводимо пошук
        switch(number){
            case 1 : {
                if(strcmp(enternamemark, telephone.namemark) == 0){  //якщо є співпадіння то виводимо на екран
                    cout << setiosflags(ios::left) << setw(15) << telephone.namemark << setw(15) << telephone.namephone << setw(15) << telephone.price << endl;
                }
                break;
            }
            case 2 : {
                if(strcmp(enternamephone, telephone.namephone) == 0){
                    cout << setiosflags(ios::left) << setw(15) << telephone.namemark << setw(15) << telephone.namephone << setw(15) << telephone.price << endl;
                }
                break;
            }
            case 3 : {
                if(enterprice == telephone.price){
                    cout << setiosflags(ios::left) << setw(15) << telephone.namemark << setw(15) << telephone.namephone << setw(15) << telephone.price<< endl;
                }
                break;
            }
            default : {
                cout << "Error !!!" << endl;
                break;
                }
            }
        }
    diana.close();
    }

void delet(){   // підпрограма для видалення елементу
    int n = 0;    //працює так само як і редагування тільки записує в новий файл всі дані крім видаленого елементу
    int change;
    structura telephone;
    ifstream diana("diana", ios::binary);
    ofstream dianaNew("prom", ios::binary | ios::app);
    cout << "Vvedit nomer dlya zminu : ";
    cin >> change;
    while(diana.read((char*)&telephone, sizeof(structura)) != NULL){
        if(change-1 == n){
            cout << setiosflags(ios::left) << setw(15) << telephone.namemark << setw(15) << telephone.namephone << setw(15) << telephone.price << endl;
            n++;
        }else{
            dianaNew.write((char*)&telephone, sizeof(structura));
            n++;
        }
    }
    diana.close();
    dianaNew.close();
    remove("diana");
    rename("prom", "diana");
}

void sort(){    //підпрограма для сортування
    int choice;
    int n = 0;
    structura telephone;
    structura peo[124];
    cout << "Sort : \n\t1. namemark\n\t2. namephone\n\t3. price\n\t\tEnter choice : ";
    cin >> choice;   //вибираємо по чому сортуємо
    ifstream diana("diana", ios::binary);
    ofstream dianaNew("prom", ios::binary | ios::app);
    while(diana.read((char*)&peo[n],sizeof(structura))!= NULL){
        n++;
    }
    switch(choice){   //в залежності що вибрали по тому і сортуємо
        case 1: for(int i=0; i<n; i++){   //тут марка
                    for(int j=0; j<n-1; j++){
                        if(strcmp(peo[j].namemark, peo[j+1].namemark) >0){  //strcmp порівнює числові коди строк
                            telephone=peo[j+1];                                 //класичне сортування методом бульбашки
                            peo[j+1]=peo[j];
                            peo[j]=telephone;
                        }
                    }
                }
                for(int i=0; i<n; i++){
                    dianaNew.write((char*)&peo[i], sizeof(structura));
                }
        break;
        case 2: for(int i=0; i<n; i++){           //тут то саме для назви телефону
                    for(int j=0; j<n-1; j++){
                        if(strcmp(peo[j].namephone, peo[j+1].namephone) >0){
                            telephone=peo[j+1];
                            peo[j+1]=peo[j];
                            peo[j]=telephone;
                        }
                    }
                }
                for(int i=0; i<n; i++){
                    dianaNew.write((char*)&peo[i], sizeof(structura));
                }
        break;
        case 3:
        for(int i=0; i<n; i++){           //а тут для його ціни
            for(int j=0; j<n-1; j++){
                if(peo[j].price > peo[j+1].price){
                    telephone=peo[j+1];
                    peo[j+1]=peo[j];
                    peo[j]=telephone;
                }
            }
        }
        for(int i=0; i<n; i++){
            dianaNew.write((char*)&peo[i], sizeof(structura));
        }
        break;
        default : cout << "Error !!!";
    }
    diana.close();
    dianaNew.close();
    remove("diana");
    rename("prom", "diana");
}

int main(){
    int choice;
    while(true){
        cout << "1. Write\n2. Read\n3. Rewrite\n4. Search\n5. Delete record\n6. Sort file\n\tEnter your choice : ";  //наше меню
        cin >> choice;                       //тут ми вводим з клавіатури номер який хочемо
        switch(choice){
            case 1  :   write();                        break;   //тут перечисляються можливі варіанти
            case 2  :   read();                         break;
            case 3  :   rewrite();                      break;
            case 4  :   searh();                        break;
            case 5  :   delet();                        break;
            case 6  :   sort();                         break;
            default :   cout << "Error !!! " << endl;   break;
        }
    }
    return 0;
}
