<file_sep>#include "Date.h"
#include<iostream>
using namespace std;

void Date::set_day(int day) {
   if (day < 1 || day>31)
      day = 1;
   this->day = day;
}
void Date::set_month(int month) {
   if (month < 1 || month>12)
      month = 1;
   this->month = month;
}
void Date::set_year(int year) {
   if (year < 2020||year>=2022)
      year = 2020;
   this->year = year;
}

Date::Date() {
   day = 4;
   month = 1;
   year = 2020;
}
Date::Date(int day, int month, int year) {
   set_day(day);
   set_month(month);
   set_year(year);
}

bool Date::operator==(const Date& other) const {
   return ((this->day == day) && (this->month == month) && (this->year == year));
}

void Date::deserialize(ifstream& ifs) {
   if (!ifs.is_open()) {
      cout << "Can not open this file!\n";
      return;
   }
   ifs.read((char*)&day, sizeof(day));
   ifs.read((char*)&month, sizeof(month));
   ifs.read((char*)&year, sizeof(year));
 
   if (ifs.good()) {
      cout << "Successfully deserialized!\n";
      return;
   }
   else
      cout << "Failed\n";
}
void Date::serialize(ofstream& ofs) const {
   ofs.write((const char*)&day, sizeof(day));
   ofs.write((const char*)&month, sizeof(month));
   ofs.write((const char*)&year, sizeof(year));
}

ostream& operator<<(ostream& os, const Date& obj) {
   obj.print(os);
   return os << endl;
}
void Date::print(ostream& os) const {
   os << year;
   os << "/";
   os << setw(2);
   os << setfill('0');
   os << month;
   os << "/";
   os << day;
}
int Date::compare_to(const Date& other) const
{
   if (get_day() > other.get_day())
      return -1;
   else if (get_day() < other.get_day())
   {
      return 1;
   }
   else
   {
      if (get_month() > other.get_month())
         return -1;
      else if (get_month() < other.get_month())
         return 1;
      else
      {
         if (get_year() > other.get_year())
            return -1;
         else if (get_year() < other.get_year())
            return 1;
         else
            return 0;
      }
   }
}

/*bool Date::is_leap_year(int year) {
   return((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
}
void Date::optional(int n) {
   this->day += n;
   int* this_year = nullptr;
   if (is_leap_year(year)) {
      this_year = leap;
   }
   else
      this_year = not_leap;
   if (day > this_year[month]) {
      day -= this_year[month];
      ++month;
   }
   if (month > 12) {
      month = 1;
      ++year;
   }


}*/
<file_sep>#include"RoomsList.h"


void RoomsList::Resize() {
   Room* temp = new Room[capacity*2];
   for (int i = 0; i < size; i++) 
      temp[i] = rooms[i];
   delete[] rooms;
   rooms = temp;
}
void RoomsList::Copy_From(const RoomsList& other) {
   rooms = new Room[other.capacity]; 
   for (int i = 0; i < other.size; i++)
      rooms[i] = other.rooms[i];

   capacity = other.capacity;
   size = other.size;
}
void RoomsList::Free() {
   delete[] rooms;
}

RoomsList::RoomsList() {
   capacity = 4;
   rooms = new Room[capacity];
   size = 0;
}
RoomsList::RoomsList(int new_capacity) {
   if (capacity == 0) {
      capacity = 1;
   }
   rooms = new Room[new_capacity];
   size = 0;
   capacity = new_capacity;
}
RoomsList::RoomsList(const RoomsList& other) {
   Copy_From(other);
}
RoomsList& RoomsList::operator=(const RoomsList& other) {
   if (this != &other) {
      Free();
      Copy_From(other);
   }
   return *this;
}
RoomsList::~RoomsList() {
   Free();
}

void RoomsList::push_back(const Room& new_room) {
   if (!is_valid_room_number(new_room.get_room_num()))
      return;   
   if (is_full()) 
      Resize();   
   rooms[size++] = new_room;
}

void RoomsList::shift_left(int index)
{
   for (int i = index; i < size - 1; i++)
   {
      rooms[i] = rooms[i + 1];
   }
}
int RoomsList::remove_at(int index)
{
      if (size == 0 || index > size)
      {
         return 0;
      }
      shift_left(index);
      size--;
      return 1;

   
   size--;
}


Room& RoomsList::operator[](int index) const {
    return rooms[index];
}

ostream& operator<<(ostream& os, RoomsList& obj) {
   obj.print(os);
   return os << endl;
}
void RoomsList::print(ostream& os) const {
   for (int i = 0; i < size; i++) {
      rooms[i].print();
   }
}

void RoomsList::serialize(ofstream& ofs) const {
   if (!ofs.is_open()) { return;}

   ofs.write((const char*)&size, sizeof(size));
   ofs.write((const char*)&capacity, sizeof(capacity));
   for (int i = 0; i < size; i++) {
      rooms[i].serialize(ofs);
   }
}
void RoomsList::deserialize(ifstream& ifs) {
   if (!ifs.is_open()) { return; }
   ifs.read((char*)&size, sizeof(size));
   ifs.read((char*)&capacity, sizeof(capacity));

   int len;
   ifs.read((char*)&len, sizeof(int));
   for (int i = 0; i < len; i++) {
      rooms[i].deserialize(ifs);
      push_back(rooms[i]);
   }
}
<file_sep>#include"Hotel.h"

int main() {
   Hotel::i().run();

   return 0;
}<file_sep>#ifndef HOTEL_H
#define HOTEL_H
#include"Date.h"
#include"RoomsList.h"
#include"Room.h"
#include"Reservation.h"
using namespace std;

class Hotel {
private:
   RoomsList rooms;
  
   Hotel();
   Room* get_room(int room_num) const;
   Room* get_unavailable_rooms(int from_day, int from_month, int from_year,int to_day, int to_month, int to_year);

   void display();

public:
   static Hotel& i();

   int first_free_index();
   bool contains_room(unsigned room_num) const { return get_room(room_num); };
   bool create_reservation(const Reservation& res); 
  
   void run();

   bool serialize() const;
   bool deserialize();
};
#endif // !HOTEL_H<file_sep>#include"Reservation.h"

bool has_digits(const char* str, int len)
{
   for (int i = 0; i < len; i++)
   {
      if (str[i] >= '0' && str[i] <= '9')
         return true;
   }
   return false;
}

void Reservation::Copy_From(const Reservation& other) {
   note = new char[strlen(other.note) + 1];
   strcpy(note, other.note);

   guests = other.guests;
   breakfast = other.breakfast;
}
void Reservation::Free() {
   delete[] note;
   note = nullptr;
}

Reservation::Reservation(int room_num, int from_day, int from_month, int from_year, int to_day, int to_month, int to_year,
   const char* new_note, unsigned beds, int new_guests, bool new_breakfast)  
   : Room(room_num,from_day,from_month,from_year,to_day,to_month,to_year,beds),
   note(new char[strlen(new_note) + 1]), guests(new_guests), breakfast(new_breakfast) {}

Reservation::Reservation(const Reservation& other) {
   Copy_From(other);
}
Reservation& Reservation::operator=(const Reservation& other) {
   if (this != &other) {
      Free();
      Copy_From(other);
   }
   return *this;
}
Reservation::~Reservation() {
   Free();
}

void Reservation::set_note(const char* note)
{
   //delete[] note; 
   int len = strlen(note);
   if (has_digits(note, len))
   {
      this->note[0] = '\0';
      return;
   }
   this->note = new char[len + 1];
   strcpy(this->note, note);

}

void Reservation::deserialize(ifstream& ifs) {
   if (!ifs.is_open()) {
   cout << "Can not open this file!\n"; 
   return;
   }
   size_t len;
   ifs.read((char*)&len, sizeof(len));
   note = new char[len+1];
   if (note) {
      ifs.read(note, len);
      note[len] = '\0';
   }
   ifs.read((char*)&guests, sizeof(guests));
   ifs.read((char*)&breakfast, sizeof(breakfast));

   if (ifs.good()) {
      cout << "Successfully deserialized!\n";
   }
   else
      cout << "Failed\n";
}

void Reservation::serialize(ofstream& out) const {
   size_t len = strlen(note) + 1;
   out.write((const char*)&len, sizeof(len));
   out.write((const char*)note, len);

   out.write((const char*)&guests, sizeof(guests));
   out.write((const char*)&breakfast, sizeof(breakfast));
}

void Reservation::print(ostream& os) const {
   Room::print(os);
   os << "The room has reserved by: " << note << " with "
      << guests << " guest(s)." << endl;
   if (breakfast) cout << get_price() << " EUR for breakfast.\n";
}

ostream& operator<<(ostream& os, const Reservation& r) {
   r.print(os);
   return os << endl;
}
<file_sep># Hotel
Project in Sofia University, Object-Oriented-Programming Course.
![Hotel](https://user-images.githubusercontent.com/50846039/191458123-e9b7fff0-f292-4091-a566-67124a96abec.png)
<file_sep>#ifndef ROOMSLIST_H
#define ROOMSLIST_H
#define _CRT_SECURE_NO_WARNINGS
#include"Room.h"
using namespace std;

class RoomsList {
private:
   Room* rooms;
   int size;
   int capacity;

   void Resize();
   void Copy_From(const RoomsList& other);
   void Free();

public:
   RoomsList();
   RoomsList(int new_capacity);
   RoomsList(const RoomsList& other);
   RoomsList& operator=(const RoomsList& other);
   ~RoomsList();

   void push_back(const Room& room);
   void shift_left(int index);
   int remove_at(int index);

   int get_size() const { return size; };
   int get_capacity() const { return capacity; };
   
   bool is_full() { return size == capacity; };
   bool is_valid_room_number(int room_number) { return (room_number >= 1 && room_number <= 50); };
   Room& operator[](int index) const;

   void serialize(ofstream& ofs) const;
   void deserialize(ifstream& ifs);

   friend ostream& operator<<(ostream& os, const RoomsList& obj);
   void print(ostream& os=cout) const;
};

#endif // !ROOMSLIST_H<file_sep>#include"Room.h"

Room::Room() : from_date(4,1,2020), to_date(4,1,2021), is_init(false) , beds(0),room_num(0) {}

Room::Room(int new_room_num, int from_day, int from_month, int from_year, int to_day, int to_month, int to_year, unsigned new_beds)
   :from_date(from_day,from_month,from_year),to_date(to_day,to_month,to_year) , room_num(new_room_num),beds(new_beds)
{
   if (!is_valid_date()) 
      to_date = from_date;
   
}
void Room::deserialize(ifstream& ifs) {
   if (!ifs.is_open()) {
      cout << "Can not open this file!\n";
      return;
   }
    ifs.read((char*)&from_date, sizeof(from_date));
   ifs.read((char*)&to_date, sizeof(to_date));
   ifs.read((char*)&room_num, sizeof(room_num));
   ifs.read((char*)&beds, sizeof(beds));

   if (ifs.good()) {
      cout << "Successfully deserialized!\n";
   }
   else
      cout << "Failed\n";
}
void Room::serialize(ofstream& out) const
{ 
   out.write((const char*)&from_date, sizeof(from_date));
   out.write((const char*)&to_date, sizeof(to_date));
   out.write((const char*)&room_num, sizeof(room_num));
   out.write((const char*)&beds, sizeof(beds));
  
   /*const char* n_date = from_date.get_date();
    int len = strlen(n_date)+1;
    out.write((const char*)&len, sizeof(len));
    out.write(n_date, len);

     n_date = to_date.get_date();
     len = strlen(n_date) + 1;
    out.write((const char*)&len, sizeof(len));
    out.write(n_date, len);
    */

}

void Room::print(ostream& os) const {
   os << "Room number: " << room_num << endl;
   os << "From date: "; from_date.print();
   os <<' '<<"To date: "; to_date.print();
}
ostream& operator<<(ostream& os, const Room& obj) {
      obj.print(os);
      return os << endl;
   
}<file_sep>#ifndef RESERVATION_H
#define RESERVATION_H
#include"Room.h"
#include<fstream>
#include<iostream>
using namespace std;

class Reservation : public Room {
private:
   char* note;
   int guests;
   bool breakfast;

   void Copy_From(const Reservation& other);
   void Free();

public:
   Reservation(int room_num=0, int from_day=4, int from_month=1, int from_year=2020, int to_day=4, int to_month=1, int to_year=2021,
      const char* new_note="<Unnamed>", unsigned beds=0, int new_guests=0,bool breakfast=false);
   Reservation(const Reservation& other);
   Reservation& operator=(const Reservation& other);
   ~Reservation();

   const char* get_note() const { return note; };
   void set_note(const char* note);

   int get_guests() const { return guests; };
   
   double get_price() const { return 9.9; };

   void serialize(ofstream& ofs) const;
   void deserialize(ifstream& ifs);
  
   void print(ostream& os=cout) const;
   friend ostream& operator<<(ostream& os, const Reservation& obj);
};


#endif // !RESERVATION_H
<file_sep>#ifndef ROOM_H
#define ROOM_H
#define _CRT_SECURE_NO_WARNINGS
#include"Date.h"
#include<iostream>
#include <fstream>
using namespace std;

class Room {
private:
   Date from_date;
   Date to_date;
   bool is_init;

   int room_num;
   unsigned beds;

public:
   Room();
   Room(int new_room_num,int from_day,int from_month,int from_year,int to_day,int to_month,int to_year, unsigned new_beds);

   const Date& get_from_date() const { return from_date; };
   const Date& get_to_date() const { return to_date; };

   int get_room_num() const { return room_num; };
   unsigned get_beds() const { return beds; };

   bool get_is_init() const { return is_init; };
   bool is_valid_date() { return from_date.compare_to(to_date) >= 0; };

   void serialize(ofstream& out) const;
   void deserialize(ifstream& ifs);

   void print(ostream& os=cout) const;
   friend ostream& operator<<(ostream& os, const Room& obj);

   /* void set_total_beds(int new_beds);
 int get_free_beds() const { return total_beds - reserved_beds; };
 int get_total_beds() const { return total_beds; }
 int get_reserved_beds() const { return reserved_beds; }*/

};
#endif // !ROOM_H
<file_sep>#ifndef DATE_H
#define DATE_H
#include<iomanip>
#include<iostream>
#include <fstream>
using namespace std;

class Date {
private:
   int day;
   int month;
   int year;

public:
   void set_day(int);
   void set_month(int);
   void set_year(int);
 
   int get_day() const { return day; };
   int get_month() const { return month; };
   int get_year() const { return year; };

   Date();
   Date(int day, int month, int year);

   int compare_to(const Date& other) const;

   bool operator==(const Date& other) const;
   //bool is_leap_year(int year);
   //void optional(int n);

   friend ostream& operator<<(ostream& os, const Date& obj);
   virtual void print(ostream& os=cout) const;

   void serialize(ofstream& ofs) const;
   void deserialize(ifstream& ifs);
};
#endif<file_sep>#include"Hotel.h"
#include<fstream>
#include<cstring>
using namespace std;

const char* SAVE_FILE_NAME = "hotel_system.bin";
const size_t MAX_INPUT_LEN = 128;

Hotel::Hotel(){}

int Hotel::first_free_index() {
   for (int i = 0; i < rooms.get_size(); i++) {
      if (&rooms[i] == nullptr)
         return i;
   }
   return -1;
}
Room* Hotel::get_room(int room_num) const
{
   for (int i = 0; i < rooms.get_size(); i++) {
         if (rooms[i].get_room_num() == room_num)
            return &rooms[i];
      }
      return nullptr;
}
bool Hotel::create_reservation(const Reservation& res) {
   if (get_room(res.get_room_num()) == nullptr) {
      rooms.push_back(res);
      return true;
   }
   return false;
}

Room* Hotel::get_unavailable_rooms(int from_day,int from_month,int from_year, 
                                    int to_day,int to_month,int to_year) {
   
   Date from_date(from_day, from_month, from_year);
   Date to_date(to_day, to_month, to_year);
   
   for (int i = 0; i < rooms.get_size(); i++) {
      if (from_date == rooms[i].get_from_date() && to_date == rooms[i].get_to_date())
         return &rooms[i];
   }
   return nullptr;

   /*for (int i = 0; i < rooms.get_size(); i++) {
      if((rooms[i].get_from_date().compare_to(from_date)) == 0 && (rooms[i].get_to_date().compare_to(to_date))== 0)
      return &rooms[i];
   }*/
}

Hotel& Hotel::i()
{
   static Hotel h;
   return h;
}

bool Hotel::serialize() const {
   ofstream ofs;
      ofs.open(SAVE_FILE_NAME, ios::binary);
   if (!ofs) {
      cout << "Can not open " << SAVE_FILE_NAME << "file for writing!\n";
      return false;
   }
   int len = rooms.get_size();
   ofs.write((const char*)&len, sizeof(len));
   for (int i = 0; i < len; i++)
      rooms[i].serialize(ofs);

   ofs.close();
   return true;
}
bool Hotel::deserialize() {
   ifstream ifs;
      ifs.open(SAVE_FILE_NAME, ios::binary);
   if (!ifs.is_open()) return false;

   int len=rooms.get_size();
   ifs.read((char*)&len, sizeof(len));
   for (int i = 0; i < len; i++)
      rooms.deserialize(ifs);

   ifs.close();
   return true;
}

void Hotel::run() {
   if (deserialize()) cout << "Successfully loaded " << rooms.get_size() << " room(s)" << endl;
   else
      cout << "No previous hotel system information.\n";

   cout << endl;

   display();
   cout << endl;

   char command[MAX_INPUT_LEN];
   char note[MAX_INPUT_LEN];
   int number;  
   int from_day, from_month, from_year;
   int to_day, to_month, to_year;
  
   do {
      cout << "ENTER AN OPTION: "; cin >> command;
      if (strcmp(command, "help") == 0) {
         display();
      }
      
      else if (strcmp(command, "check_in") == 0) {
         cout << "****CHECK-IN****\n";
         cout << "Room number: "; cin >> number;
         cout << "From date: "; cin >> from_day>> from_month>> from_year; 
         cout << "To Date: "; cin >> to_day >> to_month>> to_year; 
         cout << "Note: "; cin >> note;
         if (create_reservation({number,from_day,from_month,from_year,to_day, to_month, to_year,note})) {
            cout << "Room added successfully!\n";
         }
         else {
            cout << "Room " << number << " already exists!\n";
         }
         cout << endl;

      }

      else if (strcmp(command, "extras") == 0) {
         cout << "****ADDITIONAL EXTRAS FOR YOUR ROOM****\n";
         cout << "Enter your room number: "; 
         cin >> number;
         bool breakfast;
         if (contains_room(number)) {
            cout << "Do you want breakfast? Enter: 1 for YES or 0 for NO: "; cin >> breakfast;
            if (breakfast) {
               create_reservation({ number, breakfast });               
               cout << "Successfully added breakfast to your reservation!\n";             
            }
         }
         else
            cout << "Sorry, you have to check-in first!\n";
         cout << endl;
      }

      else if (strcmp(command, "available_rooms") == 0) {
         cout << "****LISTS OF AVAILABLE ROOMS****\n";
         cout << "From date: "; cin >> from_day >> from_month >> from_year;
         cout << "To date: "; cin >> to_day >> to_month >> to_year;
         Room* res = get_unavailable_rooms(from_day, from_month, from_year, to_day, to_month, to_year);
         if (res) {  cout << *res << endl; 
            return;
         }
         else 
         cout << "There are not available rooms on this dates!\n";        
         
         cout << endl;
      }

      else if (strcmp(command, "check_out") == 0) {
         cout << "Enter your room number: "; 
         cin >> number;
         if(contains_room(number)){
               for (int i = 0; i < rooms.get_size(); i++)
               rooms.remove_at(number);
            cout << "Room with number: " << number << " checked-out successfully!\n";
         }
         else {
            cout << "Room " << number << " not found! \n";
         }
         cout << endl;
      }
      
      else if (strcmp(command, "report_rooms") == 0) {
         cout << "****LISTS OF RESERVED ROOMS****\n";
         cout << "From date: "; cin >> from_day >> from_month >> from_year;
         cout << "To date: "; cin >> to_day >> to_month >> to_year;      
         Room* res = get_unavailable_rooms(from_day, from_month, from_year, to_day, to_month, to_year);
         for (int i = 0; i < rooms.get_size(); i++) {
            if(res) {
               rooms[i].print();
               cout << endl;
            }
            else
               cout << "Room from the period: " << rooms[i].get_from_date() << " - " << rooms[i].get_to_date() << " not found!\n";    
         }
           cout << endl;       
      }

      else if (strcmp(command, "find_room") == 0) {

      }
      else if (strcmp(command, "important_guest") == 0) {

      }
      else if (strcmp(command, "unavailable_room") == 0) {

      }

      else if (strcmp(command, "exit") == 0) {
         if (serialize())
            cout << "Successfully saved the system information!\n";
         else {
            cout << "Couldn't saved the system information. Exit anyway: [y/n]? : ";
            char option;
            cin.ignore(MAX_INPUT_LEN, '\n');
            cin.get(option);
            if (option == 'y' || option == 'n') 
               command[0] = '\n';          
         }
      }      
      
      else {
         cout << "Unknown command! Type 'help' for more information: " << endl;
      }
   } while (strcmp(command, "exit") != 0);
}


void Hotel::display() {
   cout << "*********** HOTEL JOANNNA MANAGEMENT SYSTEM ***********" << endl;
   cout << "help - Prints this information." << endl;
   cout << "check_in - Check-In Room" << endl;
   cout << "extras - Additional EXTRAS for the room" << endl;
   cout << "available_rooms - Available rooms" << endl;
   cout << "check_out - Chechk-Out Room" << endl;
   cout << "report_rooms - Show report of all used rooms" << endl;
   cout << "find_room - Find suitable room with a certain number of beds" << endl;
   cout << "important_guest - Find room for important guest" << endl;
   cout << "unavailable_room - Show rooms which are unavailables to use" << endl;
   cout << "exit  - saves the system and exit the program" << endl;
}
