From b844597fd23bc57aa97e231fc90eecfd6322cecc Mon Sep 17 00:00:00 2001 From: Syndamia Date: Sat, 7 May 2022 08:28:27 +0300 Subject: Reorganized whole architecture --- src/ConsoleInterface/Command.cpp | 18 --- src/ConsoleInterface/Command.h | 16 --- src/ConsoleInterface/Menu.cpp | 90 ------------- src/ConsoleInterface/Menu.h | 27 ---- src/ConsoleInterface/Toolbox.cpp | 99 -------------- src/ConsoleInterface/Toolbox.hpp | 76 ----------- src/Date/Date.cpp | 74 ----------- src/Date/Date.h | 33 ----- src/EventSystem/Event.cpp | 76 ----------- src/EventSystem/Event.h | 41 ------ src/EventSystem/EventSystem.cpp | 127 ------------------ src/EventSystem/EventSystem.h | 46 ------- src/EventSystem/Reservation.cpp | 37 ------ src/EventSystem/Reservation.h | 29 ----- src/EventSystem/StatusCodes.h | 25 ---- src/EventSystem/Ticket.cpp | 45 ------- src/EventSystem/Ticket.h | 26 ---- src/Generic/ConsoleInterface/Command.cpp | 18 +++ src/Generic/ConsoleInterface/Command.h | 16 +++ src/Generic/ConsoleInterface/Menu.cpp | 90 +++++++++++++ src/Generic/ConsoleInterface/Menu.h | 27 ++++ src/Generic/ConsoleInterface/Toolbox.cpp | 99 ++++++++++++++ src/Generic/ConsoleInterface/Toolbox.hpp | 76 +++++++++++ src/Generic/Date/Date.cpp | 74 +++++++++++ src/Generic/Date/Date.h | 33 +++++ src/Generic/List/List.hpp | 213 +++++++++++++++++++++++++++++++ src/Generic/List/OrderedList.hpp | 36 ++++++ src/Generic/String/String.cpp | 68 ++++++++++ src/Generic/String/String.h | 27 ++++ src/List/List.hpp | 213 ------------------------------- src/List/OrderedList.hpp | 36 ------ src/Models/Event.cpp | 76 +++++++++++ src/Models/Event.h | 41 ++++++ src/Models/Hall.cpp | 34 +++++ src/Models/Hall.h | 25 ++++ src/Models/Reservation.cpp | 37 ++++++ src/Models/Reservation.h | 29 +++++ src/Models/Ticket.cpp | 45 +++++++ src/Models/Ticket.h | 26 ++++ src/Services/EventSystem.cpp | 127 ++++++++++++++++++ src/Services/EventSystem.h | 46 +++++++ src/Services/StatusCodes.h | 25 ++++ src/String/String.cpp | 68 ---------- src/String/String.h | 27 ---- src/UserInterface/VenueConsoleUI.cpp | 201 +++++++++++++++++++++++++++++ src/UserInterface/VenueConsoleUI.h | 8 ++ src/Venue/Hall.cpp | 34 ----- src/Venue/Hall.h | 25 ---- src/Venue/Venue.cpp | 32 ----- src/Venue/Venue.h | 25 ---- src/VenueConsoleUI.cpp | 201 ----------------------------- src/VenueConsoleUI.h | 8 -- 52 files changed, 1497 insertions(+), 1554 deletions(-) delete mode 100644 src/ConsoleInterface/Command.cpp delete mode 100644 src/ConsoleInterface/Command.h delete mode 100644 src/ConsoleInterface/Menu.cpp delete mode 100644 src/ConsoleInterface/Menu.h delete mode 100644 src/ConsoleInterface/Toolbox.cpp delete mode 100644 src/ConsoleInterface/Toolbox.hpp delete mode 100644 src/Date/Date.cpp delete mode 100644 src/Date/Date.h delete mode 100644 src/EventSystem/Event.cpp delete mode 100644 src/EventSystem/Event.h delete mode 100644 src/EventSystem/EventSystem.cpp delete mode 100644 src/EventSystem/EventSystem.h delete mode 100644 src/EventSystem/Reservation.cpp delete mode 100644 src/EventSystem/Reservation.h delete mode 100644 src/EventSystem/StatusCodes.h delete mode 100644 src/EventSystem/Ticket.cpp delete mode 100644 src/EventSystem/Ticket.h create mode 100644 src/Generic/ConsoleInterface/Command.cpp create mode 100644 src/Generic/ConsoleInterface/Command.h create mode 100644 src/Generic/ConsoleInterface/Menu.cpp create mode 100644 src/Generic/ConsoleInterface/Menu.h create mode 100644 src/Generic/ConsoleInterface/Toolbox.cpp create mode 100644 src/Generic/ConsoleInterface/Toolbox.hpp create mode 100644 src/Generic/Date/Date.cpp create mode 100644 src/Generic/Date/Date.h create mode 100644 src/Generic/List/List.hpp create mode 100644 src/Generic/List/OrderedList.hpp create mode 100644 src/Generic/String/String.cpp create mode 100644 src/Generic/String/String.h delete mode 100644 src/List/List.hpp delete mode 100644 src/List/OrderedList.hpp create mode 100644 src/Models/Event.cpp create mode 100644 src/Models/Event.h create mode 100644 src/Models/Hall.cpp create mode 100644 src/Models/Hall.h create mode 100644 src/Models/Reservation.cpp create mode 100644 src/Models/Reservation.h create mode 100644 src/Models/Ticket.cpp create mode 100644 src/Models/Ticket.h create mode 100644 src/Services/EventSystem.cpp create mode 100644 src/Services/EventSystem.h create mode 100644 src/Services/StatusCodes.h delete mode 100644 src/String/String.cpp delete mode 100644 src/String/String.h create mode 100644 src/UserInterface/VenueConsoleUI.cpp create mode 100644 src/UserInterface/VenueConsoleUI.h delete mode 100644 src/Venue/Hall.cpp delete mode 100644 src/Venue/Hall.h delete mode 100644 src/Venue/Venue.cpp delete mode 100644 src/Venue/Venue.h delete mode 100644 src/VenueConsoleUI.cpp delete mode 100644 src/VenueConsoleUI.h (limited to 'src') diff --git a/src/ConsoleInterface/Command.cpp b/src/ConsoleInterface/Command.cpp deleted file mode 100644 index d3d058c..0000000 --- a/src/ConsoleInterface/Command.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "Command.h" -#include - -Command::Command() : Command("", nullptr) {} - -Command::Command(const char* nameInMenu, void (*exec)()) { - strcpy(this->nameInMenu, nameInMenu); - this->exec = exec; -} - -void Command::run() const { - if (exec != nullptr) - exec(); -} - -const char* Command::get_nameInMenu() const { - return nameInMenu; -} diff --git a/src/ConsoleInterface/Command.h b/src/ConsoleInterface/Command.h deleted file mode 100644 index d00b277..0000000 --- a/src/ConsoleInterface/Command.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef HEADER_CONSOLEINTERFACE_COMMAND -#define HEADER_CONSOLEINTERFACE_COMMAND - -class Command { - char nameInMenu[256]; - void (*exec)(); - -public: - Command(); - Command(const char* nameInMenu, void (*exec)()); - void run() const; - - const char* get_nameInMenu() const; -}; - -#endif diff --git a/src/ConsoleInterface/Menu.cpp b/src/ConsoleInterface/Menu.cpp deleted file mode 100644 index 0b27d48..0000000 --- a/src/ConsoleInterface/Menu.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "Menu.h" -#include "Toolbox.hpp" -#include - -Menu::Menu() : Menu("Menu", false, false) {} - -Menu::Menu(const char* title, bool backExistsApp, bool isSubMenu) : menuOptions() { - this->backExistsApp = backExistsApp; - this->isSubMenu = isSubMenu; - strcpy(this->title, title); -} - -Menu::Menu(const char* title, bool backExistsApp, bool isSubMenu, const Command* commands, unsigned commandCount) { - this->backExistsApp = backExistsApp; - this->isSubMenu = isSubMenu; - menuOptions = List(commands, commandCount); - strcpy(this->title, title); -} - -void Menu::addCommand(const Command& command) { - menuOptions.add(command); -} - -enum MessageType { - NoPrint, - Success, - Warning, - Error, -}; -String msg; -MessageType msgType; - -void Menu::registerError(const char* message) const { - msg = message; - msgType = Error; -} - -void Menu::registerWarning(const char* message) const { - msg = message; - msgType = Warning; -} - -void Menu::registerSuccess(const char* message) const { - msg = message; - msgType = Success; -} - -void Menu::navigate() const { - if (menuOptions.get_count() == 0) { - printLine("Menu is empty!"); - return; - } - - unsigned buffer = 1; // We immedeately read the value of buffer, so this is fine - - while (buffer != 0) { - clear(); - if (isSubMenu) - subTitleBox(title); - else - titleBox(title); - - switch(msgType) { - case Error: errorBox(msg.get_cstr()); msgType = NoPrint; break; - case Warning: warningBox(msg.get_cstr()); msgType = NoPrint; break; - case Success: successBox(msg.get_cstr()); msgType = NoPrint; break; - case NoPrint: printLine(""); break; - } - printLine(""); - - resetOrderedList(0); - if (backExistsApp) - printOrderedListElem("Exit"); - else - printOrderedListElem("Go Back"); - - for (unsigned i = 0; i < menuOptions.get_count(); i++) - printOrderedListElem(menuOptions[i].get_nameInMenu()); - - _printInputBoxLabel("Execute No [0-"); - print(menuOptions.get_count()); - print("]: "); - read(buffer); - - if (buffer > menuOptions.get_count()) - registerError("Invalid menu option!"); - else if (buffer > 0) - menuOptions[buffer - 1].run(); - } -} diff --git a/src/ConsoleInterface/Menu.h b/src/ConsoleInterface/Menu.h deleted file mode 100644 index 2501871..0000000 --- a/src/ConsoleInterface/Menu.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef HEADER_CONSOLEINTERFACE_MENU -#define HEADER_CONSOLEINTERFACE_MENU - -#include "Command.h" -#include "../List/List.hpp" - -class Menu { - char title[256]; - List menuOptions; - - bool backExistsApp; - bool isSubMenu; - -public: - Menu(); - Menu(const char* title, bool backExistsApp, bool isSubMenu); - Menu(const char* title, bool backExistsApp, bool isSubMenu, const Command* commands, unsigned commandCount); - - void addCommand(const Command& command); - - void registerError(const char* message) const; - void registerWarning(const char* message) const; - void registerSuccess(const char* message) const; - void navigate() const; -}; - -#endif diff --git a/src/ConsoleInterface/Toolbox.cpp b/src/ConsoleInterface/Toolbox.cpp deleted file mode 100644 index 1f2e42c..0000000 --- a/src/ConsoleInterface/Toolbox.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include "Toolbox.hpp" - -void clear() { - // Clears console on Linux - // Source: https://stackoverflow.com/a/52895729/12036073 - std::cout << u8"\033[2J\033[1;1H"; -} - -int orderedListIndex = 1; - -void resetOrderedList(int starter) { - orderedListIndex = starter; -} - -void titleBox(const char* title) { - std::cout << std::endl << "=== " << title << " ===" << std::endl; -} - -void subTitleBox(const char* title) { - std::cout << std::endl << "--- " << title << " ---" << std::endl; -} - -void successBox(const char* message) { - std::cout << " " << message << std::endl; -} - -void warningBox(const char* message) { - std::cout << " " << message << std::endl; -} - -void errorBox(const char* message) { - std::cout << " " << message << std::endl; -} - -void __printTableHeaderNumber(unsigned number) { - std::cout << ":" << ((number < 100) ? " " : "") << number << ((number < 10) ? " " : ""); -} - -void __printTableColumnHeader(unsigned start, unsigned count) { - std::cout << ": "; - for (unsigned i = 0; i < count; i++) - __printTableHeaderNumber(start++); - std::cout << ":" << std::endl; - - for (unsigned i = 0; i <= count; i++) - std::cout << "===="; - std::cout << "=" << std::endl; -} - -void __printTableLine(unsigned columns) { - std::cout << ":==="; - for (unsigned i = 0; i < columns; i++) - std::cout << "+---"; - std::cout << ":" << std::endl; -} - -void table(unsigned startNumber, unsigned columns, const char* items) { - __printTableColumnHeader(startNumber, columns); - - __printTableHeaderNumber(startNumber); - for (unsigned i = 0, colInd = 0, rowInd = 0; items[i] != '\0'; i++, (++colInd) %= columns) { - if (colInd == 0 && i != 0) { - std::cout << ":" << std::endl; - __printTableLine(columns); - __printTableHeaderNumber((++rowInd) + startNumber); - } - - std::cout << ((colInd == 0) ? "║ " : "| ") << items[rowInd * columns + colInd] << " "; - } - std::cout << ":" << std::endl; -} - -void _printOrderedListBeginning() { - std::cout << "[" << orderedListIndex++ << "] "; -} - -void _printInputBoxLabel(const char* label) { - std::cout << "(+) " << label; -} - -void _printInputSubBoxLabel(const char* label) { - std::cout << " "; - _printInputBoxLabel(label); -} - -void __inputLineBoxGetInput(char* output, unsigned maxWidth) { - std::cin.ignore(); - std::cin.getline(output, maxWidth); -} - -void inputLineBox(const char* label, char* output, unsigned maxWidth) { - _printInputBoxLabel(label); - __inputLineBoxGetInput(output, maxWidth); -} - -void inputLineSubBox(const char* label, char* output, unsigned maxWidth) { - _printInputSubBoxLabel(label); - __inputLineBoxGetInput(output, maxWidth); -} diff --git a/src/ConsoleInterface/Toolbox.hpp b/src/ConsoleInterface/Toolbox.hpp deleted file mode 100644 index ed5d6ac..0000000 --- a/src/ConsoleInterface/Toolbox.hpp +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef HEADER_CONSOLEINTERFACE_TOOLBOX -#define HEADER_CONSOLEINTERFACE_TOOLBOX - -#include "../String/String.h" -#include - -#define MAX_LINE_WIDTH 1024 - -void clear(); -void titleBox(const char* title); -void subTitleBox(const char* title); - -void successBox(const char* message); -void warningBox(const char* message); -void errorBox(const char* message); - -void table(unsigned startNumber, unsigned columns, const char* items); - -void inputLineBox(const char* label, char* output, unsigned maxWidth); -void inputLineSubBox(const char* label, char* output, unsigned maxWidth); -void resetOrderedList(int starter = 1); - -void _printInputBoxLabel(const char* label); -void _printInputSubBoxLabel(const char* label); -void _printOrderedListBeginning(); - -template -void read(T* storage) { - std::cin >> storage; -} - -template -void read(T& storage) { - std::cin >> storage; -} - -template -void print(const T* item) { - std::cout << item; -} - -template -void printLine(const T* item) { - std::cout << item << std::endl; -} - -template -void print(const T& item) { - std::cout << item; -} - -template -void printLine(const T& item) { - std::cout << item << std::endl; -} - - -template -void printOrderedListElem(const T& elem) { - _printOrderedListBeginning(); - printLine(elem); -} - -template -void inputBox(const char* label, T* output) { - _printInputBoxLabel(label); - std::cin >> *output; -} - -template -void inputSubBox(const char* label, T* output) { - _printInputSubBoxLabel(label); - std::cin >> *output; -} - -#endif diff --git a/src/Date/Date.cpp b/src/Date/Date.cpp deleted file mode 100644 index 4732b0c..0000000 --- a/src/Date/Date.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "Date.h" - -/* Private */ - -bool Date::isLeapYear() { - // Implements https://en.wikipedia.org/wiki/Leap_year#Gregorian_calendar - return year % 400 == 0 || year % 100 != 0 || year % 4 == 0; -} - -unsigned short Date::daysInMonth() { - if (month == 2) - return 28 + isLeapYear(); - if (month <= 7) - return 30 + month % 2; - return 31 - month % 2; -} - -/* Public */ - -Date::Date() : Date(01, 05, 2022) {} - -Date::Date(unsigned short day, unsigned short month, unsigned short year) { - this->day = day; - this->month = month; - this->year = year; -} - -int Date::compare(const Date& other) const { - if (year < other.year || month < other.month || day < other.day) - return -1; - return year > other.year || month > other.month || day > other.day; -} - -unsigned short Date::get_day() const { - return day; -} -bool Date::set_day(unsigned short newDay) { - if (newDay == 0 || newDay > daysInMonth()) - return false; - day = newDay; - return true; -} - -unsigned short Date::get_month() const { - return month; -} -bool Date::set_month(unsigned short newMonth) { - if (newMonth == 0 || newMonth > 12) - return false; - month = newMonth; - return true; -} - -unsigned short Date::get_year() const { - return year; -} -bool Date::set_year(unsigned short newYear) { - year = newYear; - return true; -} - -/* Outside of class */ - -std::istream& operator>>(std::istream& istr, Date& dt) { - unsigned short d, M, y; - istr >> d >> M >> y; - dt = Date(d, M, y); - return istr; -} - -std::ostream& operator<<(std::ostream& ostr, const Date& dt) { - ostr << dt.get_day() << "." << dt.get_month() << "." << dt.get_year(); - return ostr; -} diff --git a/src/Date/Date.h b/src/Date/Date.h deleted file mode 100644 index 5d1ff62..0000000 --- a/src/Date/Date.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HEADER_DATETIME -#define HEADER_DATETIME - -#include -#include - -class Date { - unsigned short day; - unsigned short month; - unsigned short year; - - bool isLeapYear(); - unsigned short daysInMonth(); - -public: - Date(); - Date(unsigned short day, unsigned short month, unsigned short year); - int compare(const Date& other) const; - - unsigned short get_day() const; - bool set_day(unsigned short newDay); - - unsigned short get_month() const; - bool set_month(unsigned short newMonth); - - unsigned short get_year() const; - bool set_year(unsigned short newYear); -}; - -std::istream& operator>>(std::istream& istr, Date& dt); -std::ostream& operator<<(std::ostream& ostr, const Date& dt); - -#endif diff --git a/src/EventSystem/Event.cpp b/src/EventSystem/Event.cpp deleted file mode 100644 index e6105eb..0000000 --- a/src/EventSystem/Event.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "Event.h" -#include "Reservation.h" -#include "StatusCodes.h" - -Event::Event() : Event(nullptr, "", Date()) {} - -Event::Event(const Hall* hall, String name, Date date) : tickets(), reservations() { - this->hall = hall; - this->name = name; - this->date = date; -} - -const OrderedList& Event::get_tickets() const { - return tickets; -} - -const OrderedList& Event::get_reservations() const { - return reservations; -} - -const Hall& Event::get_hall() const { - return *hall; -} - -const String& Event::get_name() const { - return name; -} - -const Date& Event::get_date() const { - return date; -} - -StatusCode Event::reserveTicket(const Ticket& ticket, const char* password, const char* note) { - if (tickets.contain(ticket)) return E_TicketAlreadyBought; - if (reservations.contain(ticket)) return E_TicketAlreadyReserved; - - reservations.insert(Reservation(ticket, password, note)); - return Success; -} - -StatusCode Event::cancelReservation(unsigned row, unsigned seat) { - return cancelReservation(Ticket(row, seat)); -} - -StatusCode Event::cancelReservation(const Ticket& ticket) { - unsigned ind = reservations.findIndex(ticket); - if (ind == reservations.get_count()) - return W_TicketHadNotBeenReserved; - - reservations.removeAt(ind); - return Success; -} - -StatusCode Event::buyTicket(const Ticket& ticket) { - if (tickets.contain(ticket)) return E_TicketAlreadyBought; - if (reservations.contain(ticket)) return E_TicketAlreadyReserved; - - tickets.insert(ticket); - return Success; -} - -StatusCode Event::buyTicketFromReservation(const Reservation& reservation, const char* password) { - unsigned resInd = reservations.findIndex(reservation); - if (resInd == reservations.get_count()) return E_ReservationDoesNotExist; - - if (!reservations[resInd].validPassword(password)) return E_WrongReservationPassword; - - reservations.removeAt(resInd); - tickets.insert(reservation.get_ticket()); - return Success; -} - -int Event::compare(const Event& other) { - // TODO: improve - return name.compare(other.name); -} diff --git a/src/EventSystem/Event.h b/src/EventSystem/Event.h deleted file mode 100644 index 43ad5d9..0000000 --- a/src/EventSystem/Event.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef HEADER_EVENTSYSTEM_EVENT -#define HEADER_EVENTSYSTEM_EVENT - -#include "../List/OrderedList.hpp" -#include "../Date/Date.h" -#include "../String/String.h" -#include "../Venue/Hall.h" -#include "Ticket.h" -#include "Reservation.h" -#include "StatusCodes.h" - -class Event { - const Hall* hall; - String name; - Date date; - OrderedList tickets; - OrderedList reservations; - -public: - Event(); - Event(const Hall* hall, String name, Date date); - - const Hall& get_hall() const; - const String& get_name() const; - const Date& get_date() const; - const OrderedList& get_tickets() const; - const OrderedList& get_reservations() const; - - StatusCode reserveTicket(const Ticket& ticket, const char* password, const char* note); - - StatusCode cancelReservation(unsigned row, unsigned seat); - StatusCode cancelReservation(const Ticket& ticket); - - StatusCode buyTicket(const Ticket& ticket); - - StatusCode buyTicketFromReservation(const Reservation& reservation, const char* password); - - int compare(const Event& other); -}; - -#endif diff --git a/src/EventSystem/EventSystem.cpp b/src/EventSystem/EventSystem.cpp deleted file mode 100644 index 95bd1c4..0000000 --- a/src/EventSystem/EventSystem.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#include "EventSystem.h" -#include "StatusCodes.h" - -/* Private */ - -void EventSystem::updateSoonestUpcoming() { - -} - -unsigned EventSystem::indexOfEvent(const Date& date) { - // TODO: make binary search - for (unsigned i = indSoonestUpcoming; i < events.get_count(); i++) { - if (events[i].get_date().compare(date) == 0) - return i; - } - return events.get_count(); -} - -unsigned EventSystem::indexOfEvent(const char* name, const Date& date) { - unsigned ind = indexOfEvent(date); - if (ind < events.get_count() && events[ind].get_name().compare(name) == 0) - return ind; - return events.get_count(); -} - -/* Public */ - -EventSystem::EventSystem() { - events = OrderedList(); - indSoonestUpcoming = 0; -} - -EventSystem::EventSystem(const Event* events, unsigned eventCount) { - this->events = OrderedList(events, eventCount); - indSoonestUpcoming = 0; - updateSoonestUpcoming(); -} - -StatusCode EventSystem::createEvent(const Hall* hall, String name, Date date) { - if (indexOfEvent(date) < events.get_count()) - return E_EventWillOverlap; - - events.insert(Event(hall, name, date)); - return Success; -} - -StatusCode EventSystem::cancelEvent(const char* name, const Date& date) { - unsigned ind = indexOfEvent(name, date); - if (ind == events.get_count()) - return E_EventDoesNotExist; - - events.removeAt(ind); - return Success; -} - -StatusCode EventSystem::reserveTicket(const char* name, const Date& date, const char* password, const char* note, unsigned seatRow, unsigned seatColumn) { - return reserveTicket(name, date, password, note, Ticket(seatRow, seatColumn)); -} - -StatusCode EventSystem::reserveTicket(const char* name, const Date& date, const char* password, const char* note, const Ticket& ticket) { - unsigned ind = indexOfEvent(name, date); - if (ind == events.get_count()) - return E_EventDoesNotExist; - - return events[ind].reserveTicket(ticket, password, note); -} - -StatusCode EventSystem::cancelTicketReservation(const char* name, const Date& date, unsigned seatRow, unsigned seatColumn) { - return cancelTicketReservation(name, date, Ticket(seatRow, seatColumn)); -} - -StatusCode EventSystem::cancelTicketReservation(const char* name, const Date& date, const Ticket& ticket) { - unsigned ind = indexOfEvent(name, date); - if (ind == events.get_count()) - return E_EventDoesNotExist; - - return events[ind].cancelReservation(ticket); -} - -StatusCode EventSystem::buyTicket(const char* name, const Date& date, unsigned row, unsigned seat) { - return buyTicket(name, date, Ticket(row, seat)); -} - -StatusCode EventSystem::buyTicket(const char* name, const Date& date, const Ticket& ticket) { - unsigned ind = indexOfEvent(name, date); - if (ind == events.get_count()) - return E_EventDoesNotExist; - - return events[ind].buyTicket(ticket); -} - -StatusCode EventSystem::buyTicket(const char* name, const Date& date, unsigned row, unsigned seat, const char* password) { - return buyTicket(name, date, Ticket(row, seat), password); -} - -StatusCode EventSystem::buyTicket(const char* name, const Date& date, const Ticket& ticket, const char* password) { - unsigned ind = indexOfEvent(name, date); - if (ind == events.get_count()) - return E_EventDoesNotExist; - - return events[ind].buyTicketFromReservation(Reservation(ticket), password); -} - - -const Hall* EventSystem::queryEventHall(const char* name, const Date& date) { - unsigned ind = indexOfEvent(name, date); - if (ind == events.get_count()) - return nullptr; - - return &events[ind].get_hall(); -} - -OrderedList EventSystem::queryTickets(const char* name, const Date& date) { - unsigned ind = indexOfEvent(name, date); - if (ind == events.get_count()) - return OrderedList(); - - return events[ind].get_tickets(); -} - -OrderedList EventSystem::queryReservations(const char* name, const Date& date) { - unsigned ind = indexOfEvent(name, date); - if (ind == events.get_count()) - return OrderedList(); - - return events[ind].get_reservations(); -} diff --git a/src/EventSystem/EventSystem.h b/src/EventSystem/EventSystem.h deleted file mode 100644 index 4eeac61..0000000 --- a/src/EventSystem/EventSystem.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef HEADER_EVENTSYSTEM -#define HEADER_EVENTSYSTEM - -#include "../List/OrderedList.hpp" -#include "../Date/Date.h" - -#include "Event.h" -#include "StatusCodes.h" - -class EventSystem { - OrderedList events; - unsigned indSoonestUpcoming; - - void updateSoonestUpcoming(); - unsigned indexOfEvent(const Date& date); - unsigned indexOfEvent(const char* name, const Date& date); - -public: - EventSystem(); - EventSystem(const Event* events, unsigned eventCount); - - StatusCode createEvent(const Hall* hall, String name, Date date); - StatusCode cancelEvent(const char* name, const Date& date); - - StatusCode reserveTicket(const char* name, const Date& date, const char* password, const char* note, unsigned seatRow, unsigned seatColumn); - StatusCode reserveTicket(const char* name, const Date& date, const char* password, const char* note, const Ticket& ticket); - - StatusCode cancelTicketReservation(const char* name, const Date& date, unsigned seatRow, unsigned seatColumn); - StatusCode cancelTicketReservation(const char* name, const Date& date, const Ticket& ticket); - - StatusCode buyTicket(const char* name, const Date& date, unsigned row, unsigned seat); - StatusCode buyTicket(const char* name, const Date& date, const Ticket& ticket); - StatusCode buyTicket(const char* name, const Date& date, unsigned row, unsigned seat, const char* password); - StatusCode buyTicket(const char* name, const Date& date, const Ticket& ticket, const char* password); - - const Hall* queryEventHall(const char* name, const Date& date); - OrderedList queryTickets(const char* name, const Date& date); - OrderedList queryReservations(const char* name, const Date& date); - - void queryMostVisited(); - void queryInsufficientlyVisited(); - void reportBoughtTickets(Date start, Date end, unsigned hall); - void reportReservations(unsigned eventIndex); -}; - -#endif diff --git a/src/EventSystem/Reservation.cpp b/src/EventSystem/Reservation.cpp deleted file mode 100644 index 26278b2..0000000 --- a/src/EventSystem/Reservation.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "Reservation.h" -#include -#include - -Reservation::Reservation() : Reservation(Ticket(), "", "") {} - -Reservation::Reservation(const Ticket& ticket) : Reservation(ticket, "", "") {} - -Reservation::Reservation(const Ticket& ticket, const char* password, const char* note) { - this->ticket = ticket; - strcpy(this->password, password); - strcpy(this->note, note); -} - -bool Reservation::validPassword(const char* password) const { - return !strcmp(this->password, password); -} - -const Ticket& Reservation::get_ticket() const { - return ticket; -} - -void Reservation::read(std::istream& istr) { - ticket.read(istr); - istr.read(password, sizeof(password)); - istr.read(note, sizeof(note)); -} - -void Reservation::write(std::ostream& ostr) const { - ticket.write(ostr); - ostr.write(password, sizeof(password)); - ostr.write(note, sizeof(note)); -} - -int Reservation::compare(const Reservation& other) const { - return ticket.compare(other.ticket); -} diff --git a/src/EventSystem/Reservation.h b/src/EventSystem/Reservation.h deleted file mode 100644 index 1a415b5..0000000 --- a/src/EventSystem/Reservation.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef HEADER_EVENTSYSTEM_RESERVATION -#define HEADER_EVENTSYSTEM_RESERVATION - -#include "Ticket.h" -#include -#include - -#define PASSWORD_LEN 8 -#define NOTE_LEN 32 - -class Reservation { - Ticket ticket; - char password[PASSWORD_LEN]; - char note[NOTE_LEN]; - -public: - Reservation(); - Reservation(const Ticket& ticket); - Reservation(const Ticket& ticket, const char* password, const char* note); - - bool validPassword(const char* password) const; - const Ticket& get_ticket() const; - - void read(std::istream& istr); - void write(std::ostream& ostr) const; - int compare(const Reservation& other) const; -}; - -#endif diff --git a/src/EventSystem/StatusCodes.h b/src/EventSystem/StatusCodes.h deleted file mode 100644 index 4068cd3..0000000 --- a/src/EventSystem/StatusCodes.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef HEADER_EVENTSYSTEM_STATUSCODES -#define HEADER_EVENTSYSTEM_STATUSCODES - -enum StatusCode { - Success, - - - W_TicketHadNotBeenReserved, - - - E_Generic, - E_DoesntExist, - - E_HallDoesntExist, - - E_EventWillOverlap, - E_EventDoesNotExist, - - E_TicketAlreadyBought, - E_TicketAlreadyReserved, - E_ReservationDoesNotExist, - E_WrongReservationPassword, -}; - -#endif diff --git a/src/EventSystem/Ticket.cpp b/src/EventSystem/Ticket.cpp deleted file mode 100644 index e37cccf..0000000 --- a/src/EventSystem/Ticket.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "Ticket.h" - -Ticket::Ticket() : Ticket(0, 0) {} - -Ticket::Ticket(unsigned row, unsigned seat) { - this->row = row; - this->seat = seat; -} - -unsigned Ticket::get_row() const { - return row; -} - -unsigned Ticket::get_seat() const { - return seat; -} - -void Ticket::read(std::istream& istr) { - istr.read((char*)&row, sizeof(row)); - istr.read((char*)&row, sizeof(seat)); -} - -void Ticket::write(std::ostream& ostr) const { - ostr.write((const char*)&row, sizeof(row)); - ostr.write((const char*)&seat, sizeof(seat)); -} - -int Ticket::compare(const Ticket& other) const { - if (row == other.row) - return (seat > other.seat) - (seat < other.seat); - return (row > other.row) - (row < other.row); -} - -/* General */ - -std::istream& operator>>(std::istream& istr, Ticket& ticket) { - unsigned row, seat; - istr >> row >> seat; - ticket = Ticket(row, seat); - return istr; -} - -std::ostream& operator<<(std::ostream& ostr, const Ticket& ticket) { - return ostr << ticket.get_row() << " " << ticket.get_seat(); -} diff --git a/src/EventSystem/Ticket.h b/src/EventSystem/Ticket.h deleted file mode 100644 index 5d26e35..0000000 --- a/src/EventSystem/Ticket.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef HEADER_EVENTSYSTEM_TICKET -#define HEADER_EVENTSYSTEM_TICKET - -#include -#include - -class Ticket { - unsigned row; - unsigned seat; - -public: - Ticket(); - Ticket(unsigned row, unsigned seat); - - unsigned get_row() const; - unsigned get_seat() const; - - void read(std::istream& istr); - void write(std::ostream& ostr) const; - int compare(const Ticket& other) const; -}; - -std::istream& operator>>(std::istream& istr, Ticket& ticket); -std::ostream& operator<<(std::ostream& ostr, const Ticket& ticket); - -#endif diff --git a/src/Generic/ConsoleInterface/Command.cpp b/src/Generic/ConsoleInterface/Command.cpp new file mode 100644 index 0000000..d3d058c --- /dev/null +++ b/src/Generic/ConsoleInterface/Command.cpp @@ -0,0 +1,18 @@ +#include "Command.h" +#include + +Command::Command() : Command("", nullptr) {} + +Command::Command(const char* nameInMenu, void (*exec)()) { + strcpy(this->nameInMenu, nameInMenu); + this->exec = exec; +} + +void Command::run() const { + if (exec != nullptr) + exec(); +} + +const char* Command::get_nameInMenu() const { + return nameInMenu; +} diff --git a/src/Generic/ConsoleInterface/Command.h b/src/Generic/ConsoleInterface/Command.h new file mode 100644 index 0000000..d00b277 --- /dev/null +++ b/src/Generic/ConsoleInterface/Command.h @@ -0,0 +1,16 @@ +#ifndef HEADER_CONSOLEINTERFACE_COMMAND +#define HEADER_CONSOLEINTERFACE_COMMAND + +class Command { + char nameInMenu[256]; + void (*exec)(); + +public: + Command(); + Command(const char* nameInMenu, void (*exec)()); + void run() const; + + const char* get_nameInMenu() const; +}; + +#endif diff --git a/src/Generic/ConsoleInterface/Menu.cpp b/src/Generic/ConsoleInterface/Menu.cpp new file mode 100644 index 0000000..0b27d48 --- /dev/null +++ b/src/Generic/ConsoleInterface/Menu.cpp @@ -0,0 +1,90 @@ +#include "Menu.h" +#include "Toolbox.hpp" +#include + +Menu::Menu() : Menu("Menu", false, false) {} + +Menu::Menu(const char* title, bool backExistsApp, bool isSubMenu) : menuOptions() { + this->backExistsApp = backExistsApp; + this->isSubMenu = isSubMenu; + strcpy(this->title, title); +} + +Menu::Menu(const char* title, bool backExistsApp, bool isSubMenu, const Command* commands, unsigned commandCount) { + this->backExistsApp = backExistsApp; + this->isSubMenu = isSubMenu; + menuOptions = List(commands, commandCount); + strcpy(this->title, title); +} + +void Menu::addCommand(const Command& command) { + menuOptions.add(command); +} + +enum MessageType { + NoPrint, + Success, + Warning, + Error, +}; +String msg; +MessageType msgType; + +void Menu::registerError(const char* message) const { + msg = message; + msgType = Error; +} + +void Menu::registerWarning(const char* message) const { + msg = message; + msgType = Warning; +} + +void Menu::registerSuccess(const char* message) const { + msg = message; + msgType = Success; +} + +void Menu::navigate() const { + if (menuOptions.get_count() == 0) { + printLine("Menu is empty!"); + return; + } + + unsigned buffer = 1; // We immedeately read the value of buffer, so this is fine + + while (buffer != 0) { + clear(); + if (isSubMenu) + subTitleBox(title); + else + titleBox(title); + + switch(msgType) { + case Error: errorBox(msg.get_cstr()); msgType = NoPrint; break; + case Warning: warningBox(msg.get_cstr()); msgType = NoPrint; break; + case Success: successBox(msg.get_cstr()); msgType = NoPrint; break; + case NoPrint: printLine(""); break; + } + printLine(""); + + resetOrderedList(0); + if (backExistsApp) + printOrderedListElem("Exit"); + else + printOrderedListElem("Go Back"); + + for (unsigned i = 0; i < menuOptions.get_count(); i++) + printOrderedListElem(menuOptions[i].get_nameInMenu()); + + _printInputBoxLabel("Execute No [0-"); + print(menuOptions.get_count()); + print("]: "); + read(buffer); + + if (buffer > menuOptions.get_count()) + registerError("Invalid menu option!"); + else if (buffer > 0) + menuOptions[buffer - 1].run(); + } +} diff --git a/src/Generic/ConsoleInterface/Menu.h b/src/Generic/ConsoleInterface/Menu.h new file mode 100644 index 0000000..2501871 --- /dev/null +++ b/src/Generic/ConsoleInterface/Menu.h @@ -0,0 +1,27 @@ +#ifndef HEADER_CONSOLEINTERFACE_MENU +#define HEADER_CONSOLEINTERFACE_MENU + +#include "Command.h" +#include "../List/List.hpp" + +class Menu { + char title[256]; + List menuOptions; + + bool backExistsApp; + bool isSubMenu; + +public: + Menu(); + Menu(const char* title, bool backExistsApp, bool isSubMenu); + Menu(const char* title, bool backExistsApp, bool isSubMenu, const Command* commands, unsigned commandCount); + + void addCommand(const Command& command); + + void registerError(const char* message) const; + void registerWarning(const char* message) const; + void registerSuccess(const char* message) const; + void navigate() const; +}; + +#endif diff --git a/src/Generic/ConsoleInterface/Toolbox.cpp b/src/Generic/ConsoleInterface/Toolbox.cpp new file mode 100644 index 0000000..1f2e42c --- /dev/null +++ b/src/Generic/ConsoleInterface/Toolbox.cpp @@ -0,0 +1,99 @@ +#include "Toolbox.hpp" + +void clear() { + // Clears console on Linux + // Source: https://stackoverflow.com/a/52895729/12036073 + std::cout << u8"\033[2J\033[1;1H"; +} + +int orderedListIndex = 1; + +void resetOrderedList(int starter) { + orderedListIndex = starter; +} + +void titleBox(const char* title) { + std::cout << std::endl << "=== " << title << " ===" << std::endl; +} + +void subTitleBox(const char* title) { + std::cout << std::endl << "--- " << title << " ---" << std::endl; +} + +void successBox(const char* message) { + std::cout << " " << message << std::endl; +} + +void warningBox(const char* message) { + std::cout << " " << message << std::endl; +} + +void errorBox(const char* message) { + std::cout << " " << message << std::endl; +} + +void __printTableHeaderNumber(unsigned number) { + std::cout << ":" << ((number < 100) ? " " : "") << number << ((number < 10) ? " " : ""); +} + +void __printTableColumnHeader(unsigned start, unsigned count) { + std::cout << ": "; + for (unsigned i = 0; i < count; i++) + __printTableHeaderNumber(start++); + std::cout << ":" << std::endl; + + for (unsigned i = 0; i <= count; i++) + std::cout << "===="; + std::cout << "=" << std::endl; +} + +void __printTableLine(unsigned columns) { + std::cout << ":==="; + for (unsigned i = 0; i < columns; i++) + std::cout << "+---"; + std::cout << ":" << std::endl; +} + +void table(unsigned startNumber, unsigned columns, const char* items) { + __printTableColumnHeader(startNumber, columns); + + __printTableHeaderNumber(startNumber); + for (unsigned i = 0, colInd = 0, rowInd = 0; items[i] != '\0'; i++, (++colInd) %= columns) { + if (colInd == 0 && i != 0) { + std::cout << ":" << std::endl; + __printTableLine(columns); + __printTableHeaderNumber((++rowInd) + startNumber); + } + + std::cout << ((colInd == 0) ? "║ " : "| ") << items[rowInd * columns + colInd] << " "; + } + std::cout << ":" << std::endl; +} + +void _printOrderedListBeginning() { + std::cout << "[" << orderedListIndex++ << "] "; +} + +void _printInputBoxLabel(const char* label) { + std::cout << "(+) " << label; +} + +void _printInputSubBoxLabel(const char* label) { + std::cout << " "; + _printInputBoxLabel(label); +} + +void __inputLineBoxGetInput(char* output, unsigned maxWidth) { + std::cin.ignore(); + std::cin.getline(output, maxWidth); +} + +void inputLineBox(const char* label, char* output, unsigned maxWidth) { + _printInputBoxLabel(label); + __inputLineBoxGetInput(output, maxWidth); +} + +void inputLineSubBox(const char* label, char* output, unsigned maxWidth) { + _printInputSubBoxLabel(label); + __inputLineBoxGetInput(output, maxWidth); +} diff --git a/src/Generic/ConsoleInterface/Toolbox.hpp b/src/Generic/ConsoleInterface/Toolbox.hpp new file mode 100644 index 0000000..ed5d6ac --- /dev/null +++ b/src/Generic/ConsoleInterface/Toolbox.hpp @@ -0,0 +1,76 @@ +#ifndef HEADER_CONSOLEINTERFACE_TOOLBOX +#define HEADER_CONSOLEINTERFACE_TOOLBOX + +#include "../String/String.h" +#include + +#define MAX_LINE_WIDTH 1024 + +void clear(); +void titleBox(const char* title); +void subTitleBox(const char* title); + +void successBox(const char* message); +void warningBox(const char* message); +void errorBox(const char* message); + +void table(unsigned startNumber, unsigned columns, const char* items); + +void inputLineBox(const char* label, char* output, unsigned maxWidth); +void inputLineSubBox(const char* label, char* output, unsigned maxWidth); +void resetOrderedList(int starter = 1); + +void _printInputBoxLabel(const char* label); +void _printInputSubBoxLabel(const char* label); +void _printOrderedListBeginning(); + +template +void read(T* storage) { + std::cin >> storage; +} + +template +void read(T& storage) { + std::cin >> storage; +} + +template +void print(const T* item) { + std::cout << item; +} + +template +void printLine(const T* item) { + std::cout << item << std::endl; +} + +template +void print(const T& item) { + std::cout << item; +} + +template +void printLine(const T& item) { + std::cout << item << std::endl; +} + + +template +void printOrderedListElem(const T& elem) { + _printOrderedListBeginning(); + printLine(elem); +} + +template +void inputBox(const char* label, T* output) { + _printInputBoxLabel(label); + std::cin >> *output; +} + +template +void inputSubBox(const char* label, T* output) { + _printInputSubBoxLabel(label); + std::cin >> *output; +} + +#endif diff --git a/src/Generic/Date/Date.cpp b/src/Generic/Date/Date.cpp new file mode 100644 index 0000000..4732b0c --- /dev/null +++ b/src/Generic/Date/Date.cpp @@ -0,0 +1,74 @@ +#include "Date.h" + +/* Private */ + +bool Date::isLeapYear() { + // Implements https://en.wikipedia.org/wiki/Leap_year#Gregorian_calendar + return year % 400 == 0 || year % 100 != 0 || year % 4 == 0; +} + +unsigned short Date::daysInMonth() { + if (month == 2) + return 28 + isLeapYear(); + if (month <= 7) + return 30 + month % 2; + return 31 - month % 2; +} + +/* Public */ + +Date::Date() : Date(01, 05, 2022) {} + +Date::Date(unsigned short day, unsigned short month, unsigned short year) { + this->day = day; + this->month = month; + this->year = year; +} + +int Date::compare(const Date& other) const { + if (year < other.year || month < other.month || day < other.day) + return -1; + return year > other.year || month > other.month || day > other.day; +} + +unsigned short Date::get_day() const { + return day; +} +bool Date::set_day(unsigned short newDay) { + if (newDay == 0 || newDay > daysInMonth()) + return false; + day = newDay; + return true; +} + +unsigned short Date::get_month() const { + return month; +} +bool Date::set_month(unsigned short newMonth) { + if (newMonth == 0 || newMonth > 12) + return false; + month = newMonth; + return true; +} + +unsigned short Date::get_year() const { + return year; +} +bool Date::set_year(unsigned short newYear) { + year = newYear; + return true; +} + +/* Outside of class */ + +std::istream& operator>>(std::istream& istr, Date& dt) { + unsigned short d, M, y; + istr >> d >> M >> y; + dt = Date(d, M, y); + return istr; +} + +std::ostream& operator<<(std::ostream& ostr, const Date& dt) { + ostr << dt.get_day() << "." << dt.get_month() << "." << dt.get_year(); + return ostr; +} diff --git a/src/Generic/Date/Date.h b/src/Generic/Date/Date.h new file mode 100644 index 0000000..5d1ff62 --- /dev/null +++ b/src/Generic/Date/Date.h @@ -0,0 +1,33 @@ +#ifndef HEADER_DATETIME +#define HEADER_DATETIME + +#include +#include + +class Date { + unsigned short day; + unsigned short month; + unsigned short year; + + bool isLeapYear(); + unsigned short daysInMonth(); + +public: + Date(); + Date(unsigned short day, unsigned short month, unsigned short year); + int compare(const Date& other) const; + + unsigned short get_day() const; + bool set_day(unsigned short newDay); + + unsigned short get_month() const; + bool set_month(unsigned short newMonth); + + unsigned short get_year() const; + bool set_year(unsigned short newYear); +}; + +std::istream& operator>>(std::istream& istr, Date& dt); +std::ostream& operator<<(std::ostream& ostr, const Date& dt); + +#endif diff --git a/src/Generic/List/List.hpp b/src/Generic/List/List.hpp new file mode 100644 index 0000000..7088f2e --- /dev/null +++ b/src/Generic/List/List.hpp @@ -0,0 +1,213 @@ +#ifndef HEADER_LIST +#define HEADER_LIST + +#include +#include + +template +class List { +protected: + T* elements; + unsigned length; + unsigned count; + + void resize(); + void free(); + void copyFrom(const List& other); + +public: + List(const T* elements, unsigned elementsCount); + void add(const T& element); + void insertAt(const T& element, unsigned index); + bool removeAt(unsigned index); + unsigned findIndex(const T& element) const; + bool contain(const T& element) const; + T& operator[](unsigned index); + const T& operator[](unsigned index) const; + + std::istream& read(std::istream& istr); + std::ostream& write(std::ostream& ostr) const; + + unsigned get_length() const; + unsigned get_count() const; + + List(); + List& operator=(const List& other); + List(const List& other); + ~List(); + + List(List&& other); + List& operator=(List&& other); +}; + +/* Private */ + +template +void List::resize() { + length = (length == 0) ? 8 : length << 1; + T* temp = new T[length]; + for (int i = 0; i < count; i++) + temp[i] = elements[i]; + delete[] elements; + elements = temp; +} + +template +void List::free() { + delete[] elements; +} + +template +void List::copyFrom(const List& other) { + elements = new T[other.length]; + for (int i = 0; i < other.count; i++) + elements[i] = other.elements[i]; + length = other.length; + count = other.count; +} + +/* Public */ + +template +List::List(const T* elements, unsigned elementsCount) { + length = 8; + count = elementsCount; + this->elements = new T[length]; + for (unsigned i = 0; i < count; i++) + this->elements[i] = elements[i]; +} + +template +void List::add(const T& element) { + if (length == count) resize(); + + elements[count++] = element; +} + +template +void List::insertAt(const T& element, unsigned index) { + if (index >= count) add(element); + if (length == count) resize(); + + for (unsigned i = count; i > index; i--) + elements[i] = elements[i - 1]; + + elements[index] = element; + count++; +} + +template +bool List::removeAt(unsigned index) { + if (index >= count) return false; + + for (int i = index; i < count; i++) + elements[i] = elements[i + 1]; + count--; + return true; +} + +template +unsigned List::findIndex(const T& element) const { + unsigned ind = 0; + while (ind < count && elements[ind].compare(element) != 0) + ind++; + return ind; +} + +template +bool List::contain(const T& element) const { + return findIndex(element) < count; +} + +template +T& List::operator[](unsigned index) { + return elements[index]; +} + +template +const T& List::operator[](unsigned index) const { + return elements[index]; +} + +template +std::istream& List::read(std::istream& istr) { + istr.read((char*)&length, sizeof(length)); + istr.read((char*)&count, sizeof(count)); + + delete[] elements; + elements = new T[length]; + + for (int i = 0; i < count; i++) + elements[i].read(istr); // disgusting + + return istr; +} + +template +std::ostream& List::write(std::ostream& ostr) const { + ostr.write((const char*)&length, sizeof(length)); + ostr.write((const char*)&count, sizeof(count)); + + for (int i = 0; i < count; i++) + elements[i].write(ostr); // disgusting + + return ostr; +} + +template +unsigned List::get_length() const { + return length; +} + +template +unsigned List::get_count() const { + return count; +} + +// Rule of 4 + +template +List::List() : List(nullptr, 0) {} + +template +List& List::operator=(const List& other) { + if (this != &other) { + free(); + copyFrom(other); + } + return *this; +} + +template +List::List(const List& other) { + copyFrom(other); +} + +template +List::~List() { + free(); +} + +// Move semantics + +template +List::List(List&& other) { + length = other.length; + count = other.count; + elements = other.elements; + other.elements = nullptr; +} + +template +List& List::operator=(List&& other) { + if (this != &other) { + free(); + length = other.length; + count = other.count; + elements = other.elements; + other.elements = nullptr; + } + return *this; +} + +#endif diff --git a/src/Generic/List/OrderedList.hpp b/src/Generic/List/OrderedList.hpp new file mode 100644 index 0000000..4396d33 --- /dev/null +++ b/src/Generic/List/OrderedList.hpp @@ -0,0 +1,36 @@ +#ifndef HEADER_ORDEREDLIST +#define HEADER_ORDEREDLIST + +#include "List.hpp" + +template +class OrderedList : public List { +public: + OrderedList(); + OrderedList(const T* elements, unsigned elementsCount); + + void add(const T& element) = delete; + void insertAt(const T& element, unsigned index) = delete; + + void insert(const T& element); + // unsigned findIndex(const T& element) const; TODO: binary search +}; + +template +OrderedList::OrderedList() : OrderedList(nullptr, 0) {} + +template +OrderedList::OrderedList(const T* elements, unsigned elementsCount) : List::List(elements, elementsCount) {} + +template +void OrderedList::insert(const T& element) { + if (List::length == List::count) List::resize(); + + unsigned insertionInd = 0; + while (List::elements[insertionInd].compare(element) < 0 && insertionInd < List::count) + insertionInd++; + + List::insertAt(element, insertionInd); +} + +#endif diff --git a/src/Generic/String/String.cpp b/src/Generic/String/String.cpp new file mode 100644 index 0000000..055f48e --- /dev/null +++ b/src/Generic/String/String.cpp @@ -0,0 +1,68 @@ +#include "String.h" +#include + +/* Private */ + +void String::free() { + delete[] str; +} + +void String::copyFrom(const String& other) { + str = new char[other.length]; + strcpy(str, other.str); + length = other.length; +} + +/* Public */ + +String::String(const char* str) { + length = strlen(str) + 1; // capture terminating zero + this->str = new char[length]; + strcpy(this->str, str); +} + +const char* String::get_cstr() const { + return str; +} + +String::String() : String("") {} + +String::String(const String& other) { + copyFrom(other); +} + +String& String::operator=(const String& other) { + if (this != &other) { + free(); + copyFrom(other); + } + return *this; +} + +String::~String() { + free(); +} + +String::String(String&& other) { + str = other.str; + other.str = nullptr; + length = other.length; +} + +String& String::operator=(String&& other) { + if (this != &other) { + delete[] str; + str = other.str; + other.str = nullptr; + length = other.length; + } + return *this; +} + +int String::compare(const String& other) const { + return strcmp(str, other.str); +} + +char String::operator[](unsigned index) { + return str[index]; +} diff --git a/src/Generic/String/String.h b/src/Generic/String/String.h new file mode 100644 index 0000000..85bb284 --- /dev/null +++ b/src/Generic/String/String.h @@ -0,0 +1,27 @@ +#ifndef HEADER_STRING +#define HEADER_STRING + +class String { + char* str; + unsigned length; + + void free(); + void copyFrom(const String& other); + +public: + String(const char* str); + const char* get_cstr() const; + + String(); + String(const String& other); + String& operator=(const String& other); + ~String(); + + String(String&& other); + String& operator=(String&& other); + + int compare(const String& other) const; + char operator[](unsigned index); +}; + +#endif diff --git a/src/List/List.hpp b/src/List/List.hpp deleted file mode 100644 index 7088f2e..0000000 --- a/src/List/List.hpp +++ /dev/null @@ -1,213 +0,0 @@ -#ifndef HEADER_LIST -#define HEADER_LIST - -#include -#include - -template -class List { -protected: - T* elements; - unsigned length; - unsigned count; - - void resize(); - void free(); - void copyFrom(const List& other); - -public: - List(const T* elements, unsigned elementsCount); - void add(const T& element); - void insertAt(const T& element, unsigned index); - bool removeAt(unsigned index); - unsigned findIndex(const T& element) const; - bool contain(const T& element) const; - T& operator[](unsigned index); - const T& operator[](unsigned index) const; - - std::istream& read(std::istream& istr); - std::ostream& write(std::ostream& ostr) const; - - unsigned get_length() const; - unsigned get_count() const; - - List(); - List& operator=(const List& other); - List(const List& other); - ~List(); - - List(List&& other); - List& operator=(List&& other); -}; - -/* Private */ - -template -void List::resize() { - length = (length == 0) ? 8 : length << 1; - T* temp = new T[length]; - for (int i = 0; i < count; i++) - temp[i] = elements[i]; - delete[] elements; - elements = temp; -} - -template -void List::free() { - delete[] elements; -} - -template -void List::copyFrom(const List& other) { - elements = new T[other.length]; - for (int i = 0; i < other.count; i++) - elements[i] = other.elements[i]; - length = other.length; - count = other.count; -} - -/* Public */ - -template -List::List(const T* elements, unsigned elementsCount) { - length = 8; - count = elementsCount; - this->elements = new T[length]; - for (unsigned i = 0; i < count; i++) - this->elements[i] = elements[i]; -} - -template -void List::add(const T& element) { - if (length == count) resize(); - - elements[count++] = element; -} - -template -void List::insertAt(const T& element, unsigned index) { - if (index >= count) add(element); - if (length == count) resize(); - - for (unsigned i = count; i > index; i--) - elements[i] = elements[i - 1]; - - elements[index] = element; - count++; -} - -template -bool List::removeAt(unsigned index) { - if (index >= count) return false; - - for (int i = index; i < count; i++) - elements[i] = elements[i + 1]; - count--; - return true; -} - -template -unsigned List::findIndex(const T& element) const { - unsigned ind = 0; - while (ind < count && elements[ind].compare(element) != 0) - ind++; - return ind; -} - -template -bool List::contain(const T& element) const { - return findIndex(element) < count; -} - -template -T& List::operator[](unsigned index) { - return elements[index]; -} - -template -const T& List::operator[](unsigned index) const { - return elements[index]; -} - -template -std::istream& List::read(std::istream& istr) { - istr.read((char*)&length, sizeof(length)); - istr.read((char*)&count, sizeof(count)); - - delete[] elements; - elements = new T[length]; - - for (int i = 0; i < count; i++) - elements[i].read(istr); // disgusting - - return istr; -} - -template -std::ostream& List::write(std::ostream& ostr) const { - ostr.write((const char*)&length, sizeof(length)); - ostr.write((const char*)&count, sizeof(count)); - - for (int i = 0; i < count; i++) - elements[i].write(ostr); // disgusting - - return ostr; -} - -template -unsigned List::get_length() const { - return length; -} - -template -unsigned List::get_count() const { - return count; -} - -// Rule of 4 - -template -List::List() : List(nullptr, 0) {} - -template -List& List::operator=(const List& other) { - if (this != &other) { - free(); - copyFrom(other); - } - return *this; -} - -template -List::List(const List& other) { - copyFrom(other); -} - -template -List::~List() { - free(); -} - -// Move semantics - -template -List::List(List&& other) { - length = other.length; - count = other.count; - elements = other.elements; - other.elements = nullptr; -} - -template -List& List::operator=(List&& other) { - if (this != &other) { - free(); - length = other.length; - count = other.count; - elements = other.elements; - other.elements = nullptr; - } - return *this; -} - -#endif diff --git a/src/List/OrderedList.hpp b/src/List/OrderedList.hpp deleted file mode 100644 index 4396d33..0000000 --- a/src/List/OrderedList.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef HEADER_ORDEREDLIST -#define HEADER_ORDEREDLIST - -#include "List.hpp" - -template -class OrderedList : public List { -public: - OrderedList(); - OrderedList(const T* elements, unsigned elementsCount); - - void add(const T& element) = delete; - void insertAt(const T& element, unsigned index) = delete; - - void insert(const T& element); - // unsigned findIndex(const T& element) const; TODO: binary search -}; - -template -OrderedList::OrderedList() : OrderedList(nullptr, 0) {} - -template -OrderedList::OrderedList(const T* elements, unsigned elementsCount) : List::List(elements, elementsCount) {} - -template -void OrderedList::insert(const T& element) { - if (List::length == List::count) List::resize(); - - unsigned insertionInd = 0; - while (List::elements[insertionInd].compare(element) < 0 && insertionInd < List::count) - insertionInd++; - - List::insertAt(element, insertionInd); -} - -#endif diff --git a/src/Models/Event.cpp b/src/Models/Event.cpp new file mode 100644 index 0000000..e6105eb --- /dev/null +++ b/src/Models/Event.cpp @@ -0,0 +1,76 @@ +#include "Event.h" +#include "Reservation.h" +#include "StatusCodes.h" + +Event::Event() : Event(nullptr, "", Date()) {} + +Event::Event(const Hall* hall, String name, Date date) : tickets(), reservations() { + this->hall = hall; + this->name = name; + this->date = date; +} + +const OrderedList& Event::get_tickets() const { + return tickets; +} + +const OrderedList& Event::get_reservations() const { + return reservations; +} + +const Hall& Event::get_hall() const { + return *hall; +} + +const String& Event::get_name() const { + return name; +} + +const Date& Event::get_date() const { + return date; +} + +StatusCode Event::reserveTicket(const Ticket& ticket, const char* password, const char* note) { + if (tickets.contain(ticket)) return E_TicketAlreadyBought; + if (reservations.contain(ticket)) return E_TicketAlreadyReserved; + + reservations.insert(Reservation(ticket, password, note)); + return Success; +} + +StatusCode Event::cancelReservation(unsigned row, unsigned seat) { + return cancelReservation(Ticket(row, seat)); +} + +StatusCode Event::cancelReservation(const Ticket& ticket) { + unsigned ind = reservations.findIndex(ticket); + if (ind == reservations.get_count()) + return W_TicketHadNotBeenReserved; + + reservations.removeAt(ind); + return Success; +} + +StatusCode Event::buyTicket(const Ticket& ticket) { + if (tickets.contain(ticket)) return E_TicketAlreadyBought; + if (reservations.contain(ticket)) return E_TicketAlreadyReserved; + + tickets.insert(ticket); + return Success; +} + +StatusCode Event::buyTicketFromReservation(const Reservation& reservation, const char* password) { + unsigned resInd = reservations.findIndex(reservation); + if (resInd == reservations.get_count()) return E_ReservationDoesNotExist; + + if (!reservations[resInd].validPassword(password)) return E_WrongReservationPassword; + + reservations.removeAt(resInd); + tickets.insert(reservation.get_ticket()); + return Success; +} + +int Event::compare(const Event& other) { + // TODO: improve + return name.compare(other.name); +} diff --git a/src/Models/Event.h b/src/Models/Event.h new file mode 100644 index 0000000..43ad5d9 --- /dev/null +++ b/src/Models/Event.h @@ -0,0 +1,41 @@ +#ifndef HEADER_EVENTSYSTEM_EVENT +#define HEADER_EVENTSYSTEM_EVENT + +#include "../List/OrderedList.hpp" +#include "../Date/Date.h" +#include "../String/String.h" +#include "../Venue/Hall.h" +#include "Ticket.h" +#include "Reservation.h" +#include "StatusCodes.h" + +class Event { + const Hall* hall; + String name; + Date date; + OrderedList tickets; + OrderedList reservations; + +public: + Event(); + Event(const Hall* hall, String name, Date date); + + const Hall& get_hall() const; + const String& get_name() const; + const Date& get_date() const; + const OrderedList& get_tickets() const; + const OrderedList& get_reservations() const; + + StatusCode reserveTicket(const Ticket& ticket, const char* password, const char* note); + + StatusCode cancelReservation(unsigned row, unsigned seat); + StatusCode cancelReservation(const Ticket& ticket); + + StatusCode buyTicket(const Ticket& ticket); + + StatusCode buyTicketFromReservation(const Reservation& reservation, const char* password); + + int compare(const Event& other); +}; + +#endif diff --git a/src/Models/Hall.cpp b/src/Models/Hall.cpp new file mode 100644 index 0000000..98b8cbb --- /dev/null +++ b/src/Models/Hall.cpp @@ -0,0 +1,34 @@ +#include "Hall.h" + +Hall::Hall() : Hall(0, 0, 0) {} + +Hall::Hall(int index, unsigned rowCount, unsigned seatsPerRow) { + this->index = index; + this->rowCount = rowCount; + this->seatsPerRow = seatsPerRow; +} + +int Hall::get_index() const { + return index; +} +void Hall::set_index(int index) { + this->index = index; +} + +unsigned Hall::get_rowCount() const { + return rowCount; +} +void Hall::set_rowCount(unsigned rowCount) { + this->rowCount = rowCount; +} + +unsigned Hall::get_seatsPerRow() const { + return seatsPerRow; +} +void Hall::set_seatsPerRow(unsigned seatsPerRow) { + this->seatsPerRow = seatsPerRow; +} + +int Hall::compare(const Hall& other) { + return (index > other.get_index()) - (index < other.get_index()); +} diff --git a/src/Models/Hall.h b/src/Models/Hall.h new file mode 100644 index 0000000..bd2f82a --- /dev/null +++ b/src/Models/Hall.h @@ -0,0 +1,25 @@ +#ifndef HEADER_HALL +#define HEADER_HALL + +class Hall { + int index; + unsigned rowCount; + unsigned seatsPerRow; + +public: + Hall(); + Hall(int index, unsigned rowCount, unsigned seatsPerRow); + + int get_index() const; + void set_index(int index); + + unsigned get_rowCount() const; + void set_rowCount(unsigned rowCount); + + unsigned get_seatsPerRow() const; + void set_seatsPerRow(unsigned seatsPerRow); + + int compare(const Hall& other); +}; + +#endif diff --git a/src/Models/Reservation.cpp b/src/Models/Reservation.cpp new file mode 100644 index 0000000..26278b2 --- /dev/null +++ b/src/Models/Reservation.cpp @@ -0,0 +1,37 @@ +#include "Reservation.h" +#include +#include + +Reservation::Reservation() : Reservation(Ticket(), "", "") {} + +Reservation::Reservation(const Ticket& ticket) : Reservation(ticket, "", "") {} + +Reservation::Reservation(const Ticket& ticket, const char* password, const char* note) { + this->ticket = ticket; + strcpy(this->password, password); + strcpy(this->note, note); +} + +bool Reservation::validPassword(const char* password) const { + return !strcmp(this->password, password); +} + +const Ticket& Reservation::get_ticket() const { + return ticket; +} + +void Reservation::read(std::istream& istr) { + ticket.read(istr); + istr.read(password, sizeof(password)); + istr.read(note, sizeof(note)); +} + +void Reservation::write(std::ostream& ostr) const { + ticket.write(ostr); + ostr.write(password, sizeof(password)); + ostr.write(note, sizeof(note)); +} + +int Reservation::compare(const Reservation& other) const { + return ticket.compare(other.ticket); +} diff --git a/src/Models/Reservation.h b/src/Models/Reservation.h new file mode 100644 index 0000000..1a415b5 --- /dev/null +++ b/src/Models/Reservation.h @@ -0,0 +1,29 @@ +#ifndef HEADER_EVENTSYSTEM_RESERVATION +#define HEADER_EVENTSYSTEM_RESERVATION + +#include "Ticket.h" +#include +#include + +#define PASSWORD_LEN 8 +#define NOTE_LEN 32 + +class Reservation { + Ticket ticket; + char password[PASSWORD_LEN]; + char note[NOTE_LEN]; + +public: + Reservation(); + Reservation(const Ticket& ticket); + Reservation(const Ticket& ticket, const char* password, const char* note); + + bool validPassword(const char* password) const; + const Ticket& get_ticket() const; + + void read(std::istream& istr); + void write(std::ostream& ostr) const; + int compare(const Reservation& other) const; +}; + +#endif diff --git a/src/Models/Ticket.cpp b/src/Models/Ticket.cpp new file mode 100644 index 0000000..e37cccf --- /dev/null +++ b/src/Models/Ticket.cpp @@ -0,0 +1,45 @@ +#include "Ticket.h" + +Ticket::Ticket() : Ticket(0, 0) {} + +Ticket::Ticket(unsigned row, unsigned seat) { + this->row = row; + this->seat = seat; +} + +unsigned Ticket::get_row() const { + return row; +} + +unsigned Ticket::get_seat() const { + return seat; +} + +void Ticket::read(std::istream& istr) { + istr.read((char*)&row, sizeof(row)); + istr.read((char*)&row, sizeof(seat)); +} + +void Ticket::write(std::ostream& ostr) const { + ostr.write((const char*)&row, sizeof(row)); + ostr.write((const char*)&seat, sizeof(seat)); +} + +int Ticket::compare(const Ticket& other) const { + if (row == other.row) + return (seat > other.seat) - (seat < other.seat); + return (row > other.row) - (row < other.row); +} + +/* General */ + +std::istream& operator>>(std::istream& istr, Ticket& ticket) { + unsigned row, seat; + istr >> row >> seat; + ticket = Ticket(row, seat); + return istr; +} + +std::ostream& operator<<(std::ostream& ostr, const Ticket& ticket) { + return ostr << ticket.get_row() << " " << ticket.get_seat(); +} diff --git a/src/Models/Ticket.h b/src/Models/Ticket.h new file mode 100644 index 0000000..5d26e35 --- /dev/null +++ b/src/Models/Ticket.h @@ -0,0 +1,26 @@ +#ifndef HEADER_EVENTSYSTEM_TICKET +#define HEADER_EVENTSYSTEM_TICKET + +#include +#include + +class Ticket { + unsigned row; + unsigned seat; + +public: + Ticket(); + Ticket(unsigned row, unsigned seat); + + unsigned get_row() const; + unsigned get_seat() const; + + void read(std::istream& istr); + void write(std::ostream& ostr) const; + int compare(const Ticket& other) const; +}; + +std::istream& operator>>(std::istream& istr, Ticket& ticket); +std::ostream& operator<<(std::ostream& ostr, const Ticket& ticket); + +#endif diff --git a/src/Services/EventSystem.cpp b/src/Services/EventSystem.cpp new file mode 100644 index 0000000..95bd1c4 --- /dev/null +++ b/src/Services/EventSystem.cpp @@ -0,0 +1,127 @@ +#include "EventSystem.h" +#include "StatusCodes.h" + +/* Private */ + +void EventSystem::updateSoonestUpcoming() { + +} + +unsigned EventSystem::indexOfEvent(const Date& date) { + // TODO: make binary search + for (unsigned i = indSoonestUpcoming; i < events.get_count(); i++) { + if (events[i].get_date().compare(date) == 0) + return i; + } + return events.get_count(); +} + +unsigned EventSystem::indexOfEvent(const char* name, const Date& date) { + unsigned ind = indexOfEvent(date); + if (ind < events.get_count() && events[ind].get_name().compare(name) == 0) + return ind; + return events.get_count(); +} + +/* Public */ + +EventSystem::EventSystem() { + events = OrderedList(); + indSoonestUpcoming = 0; +} + +EventSystem::EventSystem(const Event* events, unsigned eventCount) { + this->events = OrderedList(events, eventCount); + indSoonestUpcoming = 0; + updateSoonestUpcoming(); +} + +StatusCode EventSystem::createEvent(const Hall* hall, String name, Date date) { + if (indexOfEvent(date) < events.get_count()) + return E_EventWillOverlap; + + events.insert(Event(hall, name, date)); + return Success; +} + +StatusCode EventSystem::cancelEvent(const char* name, const Date& date) { + unsigned ind = indexOfEvent(name, date); + if (ind == events.get_count()) + return E_EventDoesNotExist; + + events.removeAt(ind); + return Success; +} + +StatusCode EventSystem::reserveTicket(const char* name, const Date& date, const char* password, const char* note, unsigned seatRow, unsigned seatColumn) { + return reserveTicket(name, date, password, note, Ticket(seatRow, seatColumn)); +} + +StatusCode EventSystem::reserveTicket(const char* name, const Date& date, const char* password, const char* note, const Ticket& ticket) { + unsigned ind = indexOfEvent(name, date); + if (ind == events.get_count()) + return E_EventDoesNotExist; + + return events[ind].reserveTicket(ticket, password, note); +} + +StatusCode EventSystem::cancelTicketReservation(const char* name, const Date& date, unsigned seatRow, unsigned seatColumn) { + return cancelTicketReservation(name, date, Ticket(seatRow, seatColumn)); +} + +StatusCode EventSystem::cancelTicketReservation(const char* name, const Date& date, const Ticket& ticket) { + unsigned ind = indexOfEvent(name, date); + if (ind == events.get_count()) + return E_EventDoesNotExist; + + return events[ind].cancelReservation(ticket); +} + +StatusCode EventSystem::buyTicket(const char* name, const Date& date, unsigned row, unsigned seat) { + return buyTicket(name, date, Ticket(row, seat)); +} + +StatusCode EventSystem::buyTicket(const char* name, const Date& date, const Ticket& ticket) { + unsigned ind = indexOfEvent(name, date); + if (ind == events.get_count()) + return E_EventDoesNotExist; + + return events[ind].buyTicket(ticket); +} + +StatusCode EventSystem::buyTicket(const char* name, const Date& date, unsigned row, unsigned seat, const char* password) { + return buyTicket(name, date, Ticket(row, seat), password); +} + +StatusCode EventSystem::buyTicket(const char* name, const Date& date, const Ticket& ticket, const char* password) { + unsigned ind = indexOfEvent(name, date); + if (ind == events.get_count()) + return E_EventDoesNotExist; + + return events[ind].buyTicketFromReservation(Reservation(ticket), password); +} + + +const Hall* EventSystem::queryEventHall(const char* name, const Date& date) { + unsigned ind = indexOfEvent(name, date); + if (ind == events.get_count()) + return nullptr; + + return &events[ind].get_hall(); +} + +OrderedList EventSystem::queryTickets(const char* name, const Date& date) { + unsigned ind = indexOfEvent(name, date); + if (ind == events.get_count()) + return OrderedList(); + + return events[ind].get_tickets(); +} + +OrderedList EventSystem::queryReservations(const char* name, const Date& date) { + unsigned ind = indexOfEvent(name, date); + if (ind == events.get_count()) + return OrderedList(); + + return events[ind].get_reservations(); +} diff --git a/src/Services/EventSystem.h b/src/Services/EventSystem.h new file mode 100644 index 0000000..4eeac61 --- /dev/null +++ b/src/Services/EventSystem.h @@ -0,0 +1,46 @@ +#ifndef HEADER_EVENTSYSTEM +#define HEADER_EVENTSYSTEM + +#include "../List/OrderedList.hpp" +#include "../Date/Date.h" + +#include "Event.h" +#include "StatusCodes.h" + +class EventSystem { + OrderedList events; + unsigned indSoonestUpcoming; + + void updateSoonestUpcoming(); + unsigned indexOfEvent(const Date& date); + unsigned indexOfEvent(const char* name, const Date& date); + +public: + EventSystem(); + EventSystem(const Event* events, unsigned eventCount); + + StatusCode createEvent(const Hall* hall, String name, Date date); + StatusCode cancelEvent(const char* name, const Date& date); + + StatusCode reserveTicket(const char* name, const Date& date, const char* password, const char* note, unsigned seatRow, unsigned seatColumn); + StatusCode reserveTicket(const char* name, const Date& date, const char* password, const char* note, const Ticket& ticket); + + StatusCode cancelTicketReservation(const char* name, const Date& date, unsigned seatRow, unsigned seatColumn); + StatusCode cancelTicketReservation(const char* name, const Date& date, const Ticket& ticket); + + StatusCode buyTicket(const char* name, const Date& date, unsigned row, unsigned seat); + StatusCode buyTicket(const char* name, const Date& date, const Ticket& ticket); + StatusCode buyTicket(const char* name, const Date& date, unsigned row, unsigned seat, const char* password); + StatusCode buyTicket(const char* name, const Date& date, const Ticket& ticket, const char* password); + + const Hall* queryEventHall(const char* name, const Date& date); + OrderedList queryTickets(const char* name, const Date& date); + OrderedList queryReservations(const char* name, const Date& date); + + void queryMostVisited(); + void queryInsufficientlyVisited(); + void reportBoughtTickets(Date start, Date end, unsigned hall); + void reportReservations(unsigned eventIndex); +}; + +#endif diff --git a/src/Services/StatusCodes.h b/src/Services/StatusCodes.h new file mode 100644 index 0000000..4068cd3 --- /dev/null +++ b/src/Services/StatusCodes.h @@ -0,0 +1,25 @@ +#ifndef HEADER_EVENTSYSTEM_STATUSCODES +#define HEADER_EVENTSYSTEM_STATUSCODES + +enum StatusCode { + Success, + + + W_TicketHadNotBeenReserved, + + + E_Generic, + E_DoesntExist, + + E_HallDoesntExist, + + E_EventWillOverlap, + E_EventDoesNotExist, + + E_TicketAlreadyBought, + E_TicketAlreadyReserved, + E_ReservationDoesNotExist, + E_WrongReservationPassword, +}; + +#endif diff --git a/src/String/String.cpp b/src/String/String.cpp deleted file mode 100644 index 055f48e..0000000 --- a/src/String/String.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "String.h" -#include - -/* Private */ - -void String::free() { - delete[] str; -} - -void String::copyFrom(const String& other) { - str = new char[other.length]; - strcpy(str, other.str); - length = other.length; -} - -/* Public */ - -String::String(const char* str) { - length = strlen(str) + 1; // capture terminating zero - this->str = new char[length]; - strcpy(this->str, str); -} - -const char* String::get_cstr() const { - return str; -} - -String::String() : String("") {} - -String::String(const String& other) { - copyFrom(other); -} - -String& String::operator=(const String& other) { - if (this != &other) { - free(); - copyFrom(other); - } - return *this; -} - -String::~String() { - free(); -} - -String::String(String&& other) { - str = other.str; - other.str = nullptr; - length = other.length; -} - -String& String::operator=(String&& other) { - if (this != &other) { - delete[] str; - str = other.str; - other.str = nullptr; - length = other.length; - } - return *this; -} - -int String::compare(const String& other) const { - return strcmp(str, other.str); -} - -char String::operator[](unsigned index) { - return str[index]; -} diff --git a/src/String/String.h b/src/String/String.h deleted file mode 100644 index 85bb284..0000000 --- a/src/String/String.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef HEADER_STRING -#define HEADER_STRING - -class String { - char* str; - unsigned length; - - void free(); - void copyFrom(const String& other); - -public: - String(const char* str); - const char* get_cstr() const; - - String(); - String(const String& other); - String& operator=(const String& other); - ~String(); - - String(String&& other); - String& operator=(String&& other); - - int compare(const String& other) const; - char operator[](unsigned index); -}; - -#endif diff --git a/src/UserInterface/VenueConsoleUI.cpp b/src/UserInterface/VenueConsoleUI.cpp new file mode 100644 index 0000000..65e5240 --- /dev/null +++ b/src/UserInterface/VenueConsoleUI.cpp @@ -0,0 +1,201 @@ +#include "VenueConsoleUI.h" +#include "List/OrderedList.hpp" +#include "String/String.h" +#include "Date/Date.h" +#include "EventSystem/StatusCodes.h" +#include "EventSystem/Reservation.h" +#include "EventSystem/EventSystem.h" +#include "ConsoleInterface/Menu.h" +#include "ConsoleInterface/Toolbox.hpp" + +Venue* v; +Menu mainMenu("FMI Ticket System", true, false), ticketManagementMenu("Ticket management", false, true), eventManagementMenu("Event management", false, true), reportsMenu("Report management", false, true); + +void handleStatusCode(StatusCode sc, Menu menu) { + switch (sc) { + case Success: + menu.registerSuccess("Success!"); break; + case W_TicketHadNotBeenReserved: + menu.registerWarning("Ticket hadn't been reserved. Nothing changed."); break; + case E_EventDoesNotExist: + menu.registerError("Event doesn't exist!"); break; + case E_TicketAlreadyBought: + menu.registerError("Ticket was already bought!"); break; + case E_TicketAlreadyReserved: + menu.registerError("Ticket was already reserved!"); break; + case E_ReservationDoesNotExist: + menu.registerError("Reservation doesn't exist!"); break; + case E_WrongReservationPassword: + menu.registerError("Wrong reservation password!"); break; + default: + menu.registerError("An unhandled status code was returned!"); break; + } +} + +/* Ticket Management */ + +void command_freeSeats() { + char name[MAX_LINE_WIDTH]; + inputLineSubBox("Enter event name: ", name, MAX_LINE_WIDTH); + Date date; + inputSubBox("Enter event date: ", &date); + + const Hall* hall = v->get_es().queryEventHall(name, date); + if (hall == nullptr) { + handleStatusCode(E_HallDoesntExist, ticketManagementMenu); + return; + } + + OrderedList tickets = v->get_es().queryTickets(name, date); + OrderedList reservations = v->get_es().queryReservations(name, date); + + unsigned tableSize = hall->get_rowCount() * hall->get_seatsPerRow(); + char tableData[tableSize + 1]; + + for (unsigned ind = 0, row = 1; row <= hall->get_rowCount(); row++) { + for (unsigned seat = 1; seat <= hall->get_seatsPerRow(); seat++, ind++) { + if (tickets.contain(Ticket(row, seat))) + tableData[ind] = 'B'; + else if (reservations.contain(Ticket(row, seat))) + tableData[ind] = 'R'; + else + tableData[ind] = ' '; + } + } + + tableData[tableSize] = '\0'; + table(1, hall->get_seatsPerRow(), tableData); + + char tmp; + inputLineBox("[Press enter to continue]", &tmp, 1); +} + +void command_reserveTicket() { + char name[MAX_LINE_WIDTH]; + inputLineSubBox("Enter event name: ", name, MAX_LINE_WIDTH); + Date date; + inputSubBox("Enter event date: ", &date); + Ticket tic; + inputSubBox("Enter row and seat: ", &tic); + char password[PASSWORD_LEN]; + inputSubBox("Enter password [Max 8 characters]: ", &password); + char note[NOTE_LEN]; + inputSubBox("Enter note [Max 32 characters]: ", ¬e); + + handleStatusCode(v->get_es().reserveTicket(name, date, password, note, tic), ticketManagementMenu); +} + +void command_cancelReservation() { + char name[MAX_LINE_WIDTH]; + inputLineSubBox("Enter event name: ", name, MAX_LINE_WIDTH); + Date date; + inputSubBox("Enter event date: ", &date); + Ticket tic; + inputSubBox("Enter row and seat: ", &tic); + + handleStatusCode(v->get_es().cancelTicketReservation(name, date, tic), ticketManagementMenu); +} + +void command_buyTicket() { + bool reserved; + inputSubBox("Is ticket reserved? [0/1]: ", &reserved); + char name[MAX_LINE_WIDTH]; + inputLineSubBox("Enter event name: ", name, MAX_LINE_WIDTH); + Date date; + inputSubBox("Enter event date: ", &date); + Ticket tic; + inputSubBox("Enter row and seat: ", &tic); + + if (reserved) { + char pass[PASSWORD_LEN]; + inputLineSubBox("Enter reservation password: ", pass, PASSWORD_LEN); + handleStatusCode(v->get_es().buyTicket(name, date, tic, pass), ticketManagementMenu); + } + else + handleStatusCode(v->get_es().buyTicket(name, date, tic), ticketManagementMenu); +} + +void submenu_ticketManagement() { + ticketManagementMenu.navigate(); +} + +/* Event Management */ + +void command_createEvent() { + unsigned hallIndex; + inputSubBox("Enter hall index: ", &hallIndex); + if (!v->hallExists(hallIndex)) { + eventManagementMenu.registerError("Invalid hall index!"); + return; + } + + char name[MAX_LINE_WIDTH]; + inputLineSubBox("Enter event name: ", name, MAX_LINE_WIDTH); + Date date; + inputSubBox("Enter event date: ", &date); + + handleStatusCode(v->get_es().createEvent(&v->getHall(hallIndex), name, date), eventManagementMenu); +} + +void command_cancelEvent() { + char name[MAX_LINE_WIDTH]; + inputLineSubBox("Enter event name: ", name, MAX_LINE_WIDTH); + Date date; + inputSubBox("Enter event date: ", &date); + + handleStatusCode(v->get_es().cancelEvent(name, date), eventManagementMenu); +} + +void command_mostWatched() { + +} + +void command_belowWatchers() { + +} + +void submenu_eventManagement() { + eventManagementMenu.navigate(); +} + +/* Report Management */ + +void command_reservationsList() { + +} + +void command_boughtTickets() { + +} + +void submenu_reportManagement() { + reportsMenu.navigate(); +} + +/* Main */ + + +void init() { + mainMenu.addCommand(Command("Ticket Management", submenu_ticketManagement)); + mainMenu.addCommand(Command("Event Management", submenu_eventManagement)); + mainMenu.addCommand(Command("Report Management", submenu_reportManagement)); + + ticketManagementMenu.addCommand(Command("Print Seats", command_freeSeats)); + ticketManagementMenu.addCommand(Command("Reserve Ticket", command_reserveTicket)); + ticketManagementMenu.addCommand(Command("Cancel Ticket Reservation", command_cancelReservation)); + ticketManagementMenu.addCommand(Command("Buy Ticket", command_buyTicket)); + + eventManagementMenu.addCommand(Command("Create Event", command_createEvent)); + eventManagementMenu.addCommand(Command("Cancel Event", command_cancelEvent)); + eventManagementMenu.addCommand(Command("Query - Most Watched", command_mostWatched)); + eventManagementMenu.addCommand(Command("Query - Below 10% watchers", command_belowWatchers)); + + reportsMenu.addCommand(Command("Reservations List", command_reservationsList)); + reportsMenu.addCommand(Command("Bought Tickets", command_boughtTickets)); +} + +void runUI(Venue& venue) { + v = &venue; + init(); + mainMenu.navigate(); +} diff --git a/src/UserInterface/VenueConsoleUI.h b/src/UserInterface/VenueConsoleUI.h new file mode 100644 index 0000000..f96076a --- /dev/null +++ b/src/UserInterface/VenueConsoleUI.h @@ -0,0 +1,8 @@ +#ifndef HEADER_VENUECONSOLEUI +#define HEADER_VENUECONSOLEUI + +#include "Venue/Venue.h" + +void runUI(Venue& venue); + +#endif diff --git a/src/Venue/Hall.cpp b/src/Venue/Hall.cpp deleted file mode 100644 index 98b8cbb..0000000 --- a/src/Venue/Hall.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "Hall.h" - -Hall::Hall() : Hall(0, 0, 0) {} - -Hall::Hall(int index, unsigned rowCount, unsigned seatsPerRow) { - this->index = index; - this->rowCount = rowCount; - this->seatsPerRow = seatsPerRow; -} - -int Hall::get_index() const { - return index; -} -void Hall::set_index(int index) { - this->index = index; -} - -unsigned Hall::get_rowCount() const { - return rowCount; -} -void Hall::set_rowCount(unsigned rowCount) { - this->rowCount = rowCount; -} - -unsigned Hall::get_seatsPerRow() const { - return seatsPerRow; -} -void Hall::set_seatsPerRow(unsigned seatsPerRow) { - this->seatsPerRow = seatsPerRow; -} - -int Hall::compare(const Hall& other) { - return (index > other.get_index()) - (index < other.get_index()); -} diff --git a/src/Venue/Hall.h b/src/Venue/Hall.h deleted file mode 100644 index bd2f82a..0000000 --- a/src/Venue/Hall.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef HEADER_HALL -#define HEADER_HALL - -class Hall { - int index; - unsigned rowCount; - unsigned seatsPerRow; - -public: - Hall(); - Hall(int index, unsigned rowCount, unsigned seatsPerRow); - - int get_index() const; - void set_index(int index); - - unsigned get_rowCount() const; - void set_rowCount(unsigned rowCount); - - unsigned get_seatsPerRow() const; - void set_seatsPerRow(unsigned seatsPerRow); - - int compare(const Hall& other); -}; - -#endif diff --git a/src/Venue/Venue.cpp b/src/Venue/Venue.cpp deleted file mode 100644 index 01c6a95..0000000 --- a/src/Venue/Venue.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "Venue.h" - -Venue::Venue() : halls(), es() {} - -Venue::Venue(const Hall* halls, unsigned hallCount) : es() { - this->halls = List(halls, hallCount); -} - -Venue::Venue(const Hall* halls, unsigned hallCount, const EventSystem& es) { - this->halls = List(halls, hallCount); - this->es = es; -} - -bool Venue::hallExists(unsigned hallIndex) const { - return halls.contain(Hall(hallIndex, 0, 0)); -} - -bool Venue::hallExists(const Hall& hall) const { - return this->halls.contain(hall); -} - -const List& Venue::get_halls() const { - return this->halls; -} - -const Hall& Venue::getHall(unsigned hallIndex) const { - return this->halls[this->halls.findIndex(Hall(hallIndex, 0, 0))]; -} - -EventSystem& Venue::get_es() { - return this->es; -} diff --git a/src/Venue/Venue.h b/src/Venue/Venue.h deleted file mode 100644 index 8c0f53e..0000000 --- a/src/Venue/Venue.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef HEADER_VENUE -#define HEADER_VENUE - -#include "../List/List.hpp" -#include "Hall.h" -#include "../EventSystem/EventSystem.h" - -class Venue { - List halls; - EventSystem es; - -public: - Venue(); - Venue(const Hall* halls, unsigned hallCount); - Venue(const Hall* halls, unsigned hallCount, const EventSystem& es); - - bool hallExists(unsigned hallIndex) const; - bool hallExists(const Hall& hall) const; - - const List& get_halls() const; - const Hall& getHall(unsigned hallIndex) const; - EventSystem& get_es(); -}; - -#endif diff --git a/src/VenueConsoleUI.cpp b/src/VenueConsoleUI.cpp deleted file mode 100644 index 65e5240..0000000 --- a/src/VenueConsoleUI.cpp +++ /dev/null @@ -1,201 +0,0 @@ -#include "VenueConsoleUI.h" -#include "List/OrderedList.hpp" -#include "String/String.h" -#include "Date/Date.h" -#include "EventSystem/StatusCodes.h" -#include "EventSystem/Reservation.h" -#include "EventSystem/EventSystem.h" -#include "ConsoleInterface/Menu.h" -#include "ConsoleInterface/Toolbox.hpp" - -Venue* v; -Menu mainMenu("FMI Ticket System", true, false), ticketManagementMenu("Ticket management", false, true), eventManagementMenu("Event management", false, true), reportsMenu("Report management", false, true); - -void handleStatusCode(StatusCode sc, Menu menu) { - switch (sc) { - case Success: - menu.registerSuccess("Success!"); break; - case W_TicketHadNotBeenReserved: - menu.registerWarning("Ticket hadn't been reserved. Nothing changed."); break; - case E_EventDoesNotExist: - menu.registerError("Event doesn't exist!"); break; - case E_TicketAlreadyBought: - menu.registerError("Ticket was already bought!"); break; - case E_TicketAlreadyReserved: - menu.registerError("Ticket was already reserved!"); break; - case E_ReservationDoesNotExist: - menu.registerError("Reservation doesn't exist!"); break; - case E_WrongReservationPassword: - menu.registerError("Wrong reservation password!"); break; - default: - menu.registerError("An unhandled status code was returned!"); break; - } -} - -/* Ticket Management */ - -void command_freeSeats() { - char name[MAX_LINE_WIDTH]; - inputLineSubBox("Enter event name: ", name, MAX_LINE_WIDTH); - Date date; - inputSubBox("Enter event date: ", &date); - - const Hall* hall = v->get_es().queryEventHall(name, date); - if (hall == nullptr) { - handleStatusCode(E_HallDoesntExist, ticketManagementMenu); - return; - } - - OrderedList tickets = v->get_es().queryTickets(name, date); - OrderedList reservations = v->get_es().queryReservations(name, date); - - unsigned tableSize = hall->get_rowCount() * hall->get_seatsPerRow(); - char tableData[tableSize + 1]; - - for (unsigned ind = 0, row = 1; row <= hall->get_rowCount(); row++) { - for (unsigned seat = 1; seat <= hall->get_seatsPerRow(); seat++, ind++) { - if (tickets.contain(Ticket(row, seat))) - tableData[ind] = 'B'; - else if (reservations.contain(Ticket(row, seat))) - tableData[ind] = 'R'; - else - tableData[ind] = ' '; - } - } - - tableData[tableSize] = '\0'; - table(1, hall->get_seatsPerRow(), tableData); - - char tmp; - inputLineBox("[Press enter to continue]", &tmp, 1); -} - -void command_reserveTicket() { - char name[MAX_LINE_WIDTH]; - inputLineSubBox("Enter event name: ", name, MAX_LINE_WIDTH); - Date date; - inputSubBox("Enter event date: ", &date); - Ticket tic; - inputSubBox("Enter row and seat: ", &tic); - char password[PASSWORD_LEN]; - inputSubBox("Enter password [Max 8 characters]: ", &password); - char note[NOTE_LEN]; - inputSubBox("Enter note [Max 32 characters]: ", ¬e); - - handleStatusCode(v->get_es().reserveTicket(name, date, password, note, tic), ticketManagementMenu); -} - -void command_cancelReservation() { - char name[MAX_LINE_WIDTH]; - inputLineSubBox("Enter event name: ", name, MAX_LINE_WIDTH); - Date date; - inputSubBox("Enter event date: ", &date); - Ticket tic; - inputSubBox("Enter row and seat: ", &tic); - - handleStatusCode(v->get_es().cancelTicketReservation(name, date, tic), ticketManagementMenu); -} - -void command_buyTicket() { - bool reserved; - inputSubBox("Is ticket reserved? [0/1]: ", &reserved); - char name[MAX_LINE_WIDTH]; - inputLineSubBox("Enter event name: ", name, MAX_LINE_WIDTH); - Date date; - inputSubBox("Enter event date: ", &date); - Ticket tic; - inputSubBox("Enter row and seat: ", &tic); - - if (reserved) { - char pass[PASSWORD_LEN]; - inputLineSubBox("Enter reservation password: ", pass, PASSWORD_LEN); - handleStatusCode(v->get_es().buyTicket(name, date, tic, pass), ticketManagementMenu); - } - else - handleStatusCode(v->get_es().buyTicket(name, date, tic), ticketManagementMenu); -} - -void submenu_ticketManagement() { - ticketManagementMenu.navigate(); -} - -/* Event Management */ - -void command_createEvent() { - unsigned hallIndex; - inputSubBox("Enter hall index: ", &hallIndex); - if (!v->hallExists(hallIndex)) { - eventManagementMenu.registerError("Invalid hall index!"); - return; - } - - char name[MAX_LINE_WIDTH]; - inputLineSubBox("Enter event name: ", name, MAX_LINE_WIDTH); - Date date; - inputSubBox("Enter event date: ", &date); - - handleStatusCode(v->get_es().createEvent(&v->getHall(hallIndex), name, date), eventManagementMenu); -} - -void command_cancelEvent() { - char name[MAX_LINE_WIDTH]; - inputLineSubBox("Enter event name: ", name, MAX_LINE_WIDTH); - Date date; - inputSubBox("Enter event date: ", &date); - - handleStatusCode(v->get_es().cancelEvent(name, date), eventManagementMenu); -} - -void command_mostWatched() { - -} - -void command_belowWatchers() { - -} - -void submenu_eventManagement() { - eventManagementMenu.navigate(); -} - -/* Report Management */ - -void command_reservationsList() { - -} - -void command_boughtTickets() { - -} - -void submenu_reportManagement() { - reportsMenu.navigate(); -} - -/* Main */ - - -void init() { - mainMenu.addCommand(Command("Ticket Management", submenu_ticketManagement)); - mainMenu.addCommand(Command("Event Management", submenu_eventManagement)); - mainMenu.addCommand(Command("Report Management", submenu_reportManagement)); - - ticketManagementMenu.addCommand(Command("Print Seats", command_freeSeats)); - ticketManagementMenu.addCommand(Command("Reserve Ticket", command_reserveTicket)); - ticketManagementMenu.addCommand(Command("Cancel Ticket Reservation", command_cancelReservation)); - ticketManagementMenu.addCommand(Command("Buy Ticket", command_buyTicket)); - - eventManagementMenu.addCommand(Command("Create Event", command_createEvent)); - eventManagementMenu.addCommand(Command("Cancel Event", command_cancelEvent)); - eventManagementMenu.addCommand(Command("Query - Most Watched", command_mostWatched)); - eventManagementMenu.addCommand(Command("Query - Below 10% watchers", command_belowWatchers)); - - reportsMenu.addCommand(Command("Reservations List", command_reservationsList)); - reportsMenu.addCommand(Command("Bought Tickets", command_boughtTickets)); -} - -void runUI(Venue& venue) { - v = &venue; - init(); - mainMenu.navigate(); -} diff --git a/src/VenueConsoleUI.h b/src/VenueConsoleUI.h deleted file mode 100644 index f96076a..0000000 --- a/src/VenueConsoleUI.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef HEADER_VENUECONSOLEUI -#define HEADER_VENUECONSOLEUI - -#include "Venue/Venue.h" - -void runUI(Venue& venue); - -#endif -- cgit v1.3.1-23-gd82d