#include <iostream> // подключение библиотеки ввода-вывода

using namespace std; // подключение стандартного пространства имён

class Page { // класс Страница
    string title; // заголовок страницы
    string text; // текст страницы
    int index; // номер страницы

    static string main_title; // статический заголовок, на который заменяется заголовок найденной страницы
    static int main_index; // статический номер, на который заменяется номер найденной страницы

    public:
    // установка статических значений
    static void set_main_fields(string _main_title, int _main_index) { main_title = _main_title; main_index = _main_index; }
    // получение статических значений
    static string get_main_title() { return main_title; }
    static int get_main_index() { return main_index; }

    Page(){ // конструктор без параметров
        cout << "\n\t\t\t\t\t\t\t\t\t\t\tConstructor " << this << " initialized.\n"; // вывод информации о инициализации конструктора
    }

    Page(string _title, string _text, int _index){ // конструктор с параметрами
        cout << "\n\t\t\t\t\t\t\t\t\t\t\tConstructor " << this << " initialized.\n"; // вывод информации о инициализации конструктора
        this->title = _title; this->text = _text; this->index = _index;
    }
/*
    Page(string _title = "default", string _text = "default", int _index = 1){ // конструктор с параметрами по умолчанию
        cout << "\n\t\t\t\t\t\t\t\t\t\t\tConstructor " << this << " initialized.\n"; // вывод информации о инициализации конструктора
        this->title = _title; this->text = _text; this->index = _index;
    }
*/
    ~Page(){ // деструктор
        cout << "\n\t\t\t\t\t\t\t\t\t\t\tDestructor " << this << " initialized.\n"; // вывод информации о инициализации деструктора
    }
    // установка значений страницы (заголовка, текста и номера)
    void set_page(string _title, string _text, int _index){ this->title = _title; this->text = _text; this->index = _index; }
    // получение размера заголовка страницы
    int get_title_size() { return this->title.size(); }
    // замена заголовка и индекса страницы на введённые пользователем
    void replace_title_and_index(){ this->title = main_title; this->index = main_index; }
    // перегрузка оператора сравнения > (больше)
    bool operator > (int _title_size){ return (title.size() > _title_size); }
    // объявление перегруженных операторов ввода-вывода дружественными для доступа приватным полям класса
    friend istream& operator>> (istream &in, Page& page);
    friend ostream& operator<< (ostream& out, Page& page);
};

istream& operator>> (istream &in, Page& page){ // перегрузка оператора ввода для прямого ввода значений страницы
    cout << "\n\tInput title: "; in >> page.title; // ввод заголовка
    cout << "\tInput text: "; in >> page.text; // ввод текста
    cout << "\tInput index: "; in >> page.index; // ввод номера страницы
    return in;
}

ostream& operator<< (ostream& out, Page& page){ // перегрузка оператора вывода для вывода значений страницы
    return out <<
    "\n\tTitle: " << page.title << // вывод заголовка
    "\n\tText: " << page.text << // вывод текста
    "\n\tIndex: " << page.index << "\n"; // вывод номера
}

int get_max_title_size(Page* pages[], int pages_count){ // функция получения индкса страницы в массиве с самым длинным заголовком
    int max_title_size = (*pages[0]).get_title_size(); // максимальный размер заголовка
    int finded_page = 0; // найденный индекс страницы в массиве

    for (int i = 0; i < pages_count; i++){ // цикл на массив объектов
        if ((*pages[i]) > max_title_size){ // сравнение длинны заголовка через перегрузку оператора сравнения
            max_title_size = (*pages[i]).get_title_size(); // присваивание максимальному размеру заголовка значение размера заголовка текущей страницы
            finded_page = i; // присваивание найденному индексу страницы значения текущего индекса элемента в массиве
        }
    }

    return finded_page; // возвращение найденного индекса страницы в массиве
}

void set_main_fields(){ // функция ввода значений статических полей класса
    string title; // новый заголовок
    int index; // новый индекс
    cout << "\tInput new title: "; cin >> title; // ввод заголовка
    cout << "\tInput new index: "; cin >> index; // ввод индекса
    Page::set_main_fields(title, index); // установка статических значений согласно введённым переменным
}
// установка значений статических полей по умолчанию во избежания ошибки "неопределённая ссылка"
string Page::main_title = ""; // пустой заголовок по умолчанию
int Page::main_index = 1; // 1 страница по умолчанию

enum UserChoice { // список возможных выборов пользователя
    DEFAULT = 1, // конструктор по умолчанию (без параметров)
    WITH_PARAMETERS = 2, // конструктор с параметрами
};

int main(){
    int choice; // выбор типа конструктора (без параметров, с параметрами)
    int finded_page; // найденный индекс страницы в массиве
    int pages_count; // количество страниц

    cout << "Input pages count: "; cin >> pages_count; // ввод количества страниц

    if (pages_count < 1){ // если количество страниц меньше 1
        cout << "Page count can't be less than 1.\n"; // вывод о некорректном вводе значения
        return 0; // завершение программы
    }

    // вывод возможных вариантов для инициализации объектов
    cout << "\nPlease, choose constructor's type:" << "\n";
    cout << "1. Default constructor (without parameters)." << "\n";
    cout << "2. Constructor with parameters." << "\n"; 
    // ввод пользователя
    cin >> choice;

    switch (choice)
    {
    case UserChoice::DEFAULT:{
        Page* pages[pages_count]; // создание динамического массива объектов
        // цикл на массив, создание экземпляра класса через конструктор бех параметров и последующий ввод значений текущего экземпляра через перегрузку оператора ввода
        for (int i = 0; i < pages_count; i++){ pages[i] = new Page(); cout << "Input " << i+1 << " page"; cin >> (*pages[i]); }
        cout << "\n"; // перенос строки
        // получение индекса страницы в массиве с наибольшей длинной заголовка
        finded_page = get_max_title_size(pages, pages_count);
        cout << "Page with max title length:" << (*pages[finded_page]); // вывод найденной страницы
        // ввод новых значений заголовка и индекс для найденной страницы
        cout << "\n\n\nInput new values of title and index for this page\n"; 
        set_main_fields();
        // замена заголовка и индекса найденной страницы на введённые пользователем
        (*pages[finded_page]).replace_title_and_index();
        cout << "\n\n\nOutput after replace\n\n"; // перенос строки
        // цикл на массив, вывод значений текущего экземпляра через перегрузку оператора вывода
        for (int i = 0; i < pages_count; i++){ cout << i+1 << " page"; cout << (*pages[i]); }
        // удаление динамических объектов
        for (int i = 0; i < pages_count; i++) delete pages[i];
        break;
    }
    case UserChoice::WITH_PARAMETERS:{
        Page* pages[pages_count]; // создание динамического массива объектов
        // цикл на массив, создание экземпляра класса через конструктор с параметрами
        for (int i = 0; i < pages_count; i++){
            string title, text; int index; // объявление переменных 
            cout << "Input " << i+1 << " page"; 
            cout << "\n\tInput title: "; cin >> title; // ввод заголовка
            cout << "\tInput text: "; cin >> text; // ввод текста
            cout << "\tInput index: "; cin >> index; // ввод номера страницы
            pages[i] = new Page(title, text, index); // создание экземпляра класса через конструктор с параметрами
        }
        cout << "\n"; // перенос строки
        // получение индекса страницы в массиве с наибольшей длинной заголовка
        finded_page = get_max_title_size(pages, pages_count);
        cout << "Page with max title length:" << (*pages[finded_page]); // вывод найденной страницы
        // ввод новых значений заголовка и индекс для найденной страницы
        cout << "\n\n\nInput new values of title and index for this page\n"; 
        set_main_fields();
        // замена заголовка и индекса найденной страницы на введённые пользователем
        (*pages[finded_page]).replace_title_and_index();
        cout << "\n\n\nOutput after replace\n\n"; // перенос строки
        // цикл на массив, вывод значений текущего экземпляра через перегрузку оператора вывода
        for (int i = 0; i < pages_count; i++){ cout << i+1 << " page"; cout << (*pages[i]); }
        // удаление динамических объектов
        for (int i = 0; i < pages_count; i++) delete pages[i];
        break;
    }
    default: // если ничего не выбрано
        cout << "\n" << "Incorrect input." << "\n\n"; // вывод о некорректном вводе
        return 0; // завершение программы
    }

    return 0; // завершение программы
}