#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <memory>
using std::string;
using std::cout;
using std::endl;
using std::vector;
using std::map;
using std::pair;
using std::shared_ptr;
using std::make_shared;
enum class ElementType { CLASS, ID, TAG };
const map<ElementType, std::string> symbol {
{ElementType::TAG, ""},
{ElementType::CLASS, "."},
{ElementType::ID, "#"}
};
ElementType ID = ID;
ElementType CLASS = CLASS;
ElementType TAG = TAG;
typedef vector<pair<ElementType, string>> ElementList;
typedef pair<ElementType, string> Style;
class CssRule {
private:
vector<Style> elements;
map<string, string> ruleset;
public:
CssRule(Style style) :elements({style}) {}
CssRule(ElementType type, string name) : elements{{type, name}} {}
CssRule(ElementList list) : elements(list) {}
void gen() {
cout << " ";
for (auto el = elements.begin(); el != elements.end(); ++el) {
if (elements.size() <= 1 || el == elements.end() - 1) {
cout << symbol.at(el->first) << el->second;
}
else {
cout << symbol.at(el->first) << el->second << ", ";
}
}
cout << " {\n" << endl;
for (auto &&rule : ruleset) {
cout << " " << rule.first << ": " << rule.second << ";\n";
}
cout << " }\n" << endl;
}
void addRule(string property, string value) { ruleset.insert({property, value}); }
};
typedef vector<shared_ptr<CssRule>> SelectorGroup;
class StyleGroup {
private:
string mediaQuery;
string mediaType;
SelectorGroup styleGroup;
public:
StyleGroup(string media, SelectorGroup styleg, string type = "all") :
mediaQuery(media), mediaType(type), styleGroup(styleg) {}
void gen() {
cout << "\n" << "@media" << " " << mediaType << " " << mediaQuery << " {\n\n";
for (auto &&style : styleGroup) {
style->gen();
}
cout << "}" << endl;
}
};