#include <set>
#include <algorithm>
#include <iostream>
using namespace std;
class MusicType
{
friend class Application;
public:
MusicType (const int id, const int genre, const string& music,
const string& artist, const string& album, const string& lyrics) {
m_id = id; m_genre = genre; m_music = music; m_artist = artist;
m_album = album; m_lyrics = lyrics;
}
MusicType (const MusicType& other) {
if (m_id != other.m_id && m_genre != other.m_genre &&
m_music != other.m_music && m_artist != other.m_artist &&
m_album != other.m_album && m_lyrics != other.m_lyrics) {
m_id = other.m_id; m_genre = other.m_genre;
m_music = other.m_music; m_artist = other.m_artist;
m_album = other.m_album; m_lyrics = other.m_lyrics;
}
}
const bool operator< (const MusicType& other) const {
return (m_id < other.m_id);
}
private:
int m_id, m_genre;
string m_music, m_artist, m_album, m_lyrics;
};
class GenreType
{
friend class Application;
public:
GenreType (const int id, const string& genre) {
m_id = id; m_genre = genre;
}
GenreType (const GenreType& other) {
if (m_id != other.m_id && m_genre != other.m_genre) {
m_id = other.m_id;
m_genre = other.m_genre; m_music = other.m_music;
}
}
const bool operator< (const GenreType& other) const {
return (m_id < other.m_id);
}
private:
int m_id;
string m_genre;
set<int> m_music;
};
class Application
{
public:
Application (void) {
m_genre.insert (GenreType(1, string("발라드")));
m_genre.insert (GenreType(2, string("힙합")));
m_genre.insert (GenreType(3, string("팝송")));
}
void insertMusic (const string& music, const string& artist, const string& album,
const string& genre, const string& lyrics) {
int genre_id;
auto genre_iter = find_if (m_genre.begin (), m_genre.end (),
[&](const auto& x)
{ return (x.m_genre == genre); });
if (genre_iter == m_genre.end ()) {
genre_id = (--genre_iter)->m_id + 1;
genre_iter = (m_genre.insert (GenreType(genre_id, genre))).first;
} else
genre_id = genre_iter->m_id;
auto music_iter = find_if (m_music.begin (), m_music.end (),
[&](const auto& x) { return ((x.m_genre == genre_id) &&
(x.m_music == music) &&
(x.m_artist == artist) &&
(x.m_album == album) &&
(x.m_lyrics == lyrics)); });
if (music_iter == m_music.end ()) {
int music_id = m_music.empty () ? 1 : (--music_iter)->m_id + 1;
m_music.insert (MusicType(music_id, genre_id, music, artist, album, lyrics));
const_cast<GenreType&>(*genre_iter).m_music.insert (music_id);
}
}
void eraseMusic (const int music_id) {
auto music_iter = find_if (m_music.begin (), m_music.end (),
[&](const auto& x) { return (x.m_id == music_id); });
if (music_iter != m_music.end ()) {
int genre_id = music_iter->m_genre;
auto genre_iter = find_if (m_genre.begin (), m_genre.end (),
[&](const auto& x) { return (x.m_id == genre_id); });
const_cast<GenreType&>(*genre_iter).m_music.erase (genre_iter->m_music.find (music_id));
if (genre_id > 3 && genre_iter->m_music.empty ())
m_genre.erase (genre_iter);
m_music.erase (music_iter);
}
}
void print (void) {
for (auto& music: m_music) {
auto genre_iter = find_if (m_genre.begin (), m_genre.end (),
[&](const auto& x)
{ return (x.m_id == music.m_genre); });
cout << "ID: " << music.m_id;
cout << " Music: " << music.m_music;
cout << " Artist: " << music.m_artist;
cout << " Album: " << music.m_album;
cout << " Genre: " << genre_iter->m_genre;
cout << " Lyrics: " << music.m_lyrics << endl;
for (auto id: genre_iter->m_music) {
auto music_iter = find_if (m_music.begin (), m_music.end (),
[&](const auto& x)
{ return (x.m_id == id); });
cout << " - " << id;
cout << " " << music_iter->m_music;
cout << " " << music_iter->m_artist;
cout << " " << music_iter->m_album << endl;
}
cout << endl;
}
}
private:
set<MusicType> m_music;
set<GenreType> m_genre;
};