+#include "category.h"
+#include "choicecondition.h"
+#include "filter.h"
+#include "rangecondition.h"
+#include "theme.h"
+
+using namespace std;
+using namespace Msp;
+
+Category::Category():
+ condition(0),
+ font_size(1.0f),
+ order(0),
+ sound_type(0),
+ sound_volume(100)
+{ }
+
+Category::Category(const Category &other):
+ condition(other.condition ? other.condition->clone() : 0),
+ font_size(other.font_size),
+ border_color(other.border_color),
+ order(other.order),
+ sound_type(other.sound_type),
+ sound_volume(other.sound_volume)
+{ }
+
+Category &Category::operator=(const Category &other)
+{
+ delete condition;
+ condition = (other.condition ? other.condition->clone() : 0);
+ font_size = other.font_size;
+ border_color = other.border_color;
+ order = other.order;
+ sound_type = other.sound_type;
+ sound_volume = other.sound_volume;
+ return *this;
+}
+
+Category::~Category()
+{
+ delete condition;
+}
+
+void Category::create_statements(list<FilterStatement> &st, const Theme &theme) const
+{
+ st.clear();
+ st.push_back(FilterStatement());
+ st.back().add_line(format("SetFontSize %d", static_cast<int>(font_size*theme.get_base_font_size()+0.5)));
+ if(!border_color.empty())
+ {
+ const Color &color = theme.get_color(border_color);
+ st.back().add_line(format("SetBorderColor %d %d %d", color.r, color.g, color.b));
+ }
+ if(sound_type)
+ st.back().add_line(format("PlayAlertSound %d %d", sound_type, sound_volume));
+ if(condition)
+ condition->add_lines(st);
+}
+
+
+Category::Loader::Loader(Category &c, CompoundCondition *n):
+ DataFile::ObjectLoader<Category>(c),
+ compound(n)
+{
+ add("alert_sound", &Category::sound_type, &Category::sound_volume);
+ add("and", &Loader::and_);
+ add("base_type", &Loader::condition<BaseTypeCondition>);
+ add("border_color", &Category::border_color);
+ add("class", &Loader::condition<ClassCondition>);
+ add_range<DropLevelCondition>("drop_level");
+ add("font_size", &Category::font_size);
+ add_range<HeightCondition>("height");
+ add_range<ItemLevelCondition>("item_level");
+ add("linked_colors", &Loader::linked_colors);
+ add_range<LinkedSocketsCondition>("linked_sockets");
+ add_range<SocketsCondition>("sockets");
+ add("or", &Loader::or_);
+ add("order", &Category::order);
+ add_range<QualityCondition>("quality");
+ add_range<RarityCondition>("rarity");
+ add_range<WidthCondition>("width");
+}
+
+template<typename T>
+void Category::Loader::add_range(const string &keyword)
+{
+ add(keyword, &Loader::condition<T>);
+ add(keyword, &Loader::condition_range<T>);
+ add("min_"+keyword, &Loader::condition_min<T>);
+ add("max_"+keyword, &Loader::condition_max<T>);
+}
+
+void Category::Loader::add_condition(Condition *cond)
+{
+ if(compound)
+ compound->add(cond);
+ else if(!obj.condition)
+ obj.condition = cond;
+ else
+ {
+ compound = new AndCondition;
+ compound->add(obj.condition);
+ compound->add(cond);
+ obj.condition = compound;
+ }
+}
+
+void Category::Loader::and_()
+{
+ RefPtr<AndCondition> cond = new AndCondition;
+ Loader sub_ldr(obj, cond.get());
+ load_sub_with(sub_ldr);
+ add_condition(cond.release());
+}
+
+template<typename T>
+void Category::Loader::condition(typename T::Type value)
+{
+ add_condition(new T(value));
+}
+
+template<typename T>
+void Category::Loader::condition_max(typename T::Type max)
+{
+ add_condition(new T(T::Traits::get_min(), max));
+}
+
+template<typename T>
+void Category::Loader::condition_min(typename T::Type min)
+{
+ add_condition(new T(min, T::Traits::get_max()));
+}
+
+template<typename T>
+void Category::Loader::condition_range(typename T::Type min, typename T::Type max)
+{
+ add_condition(new T(min, max));
+}
+
+void Category::Loader::linked_colors(const LinkedColorsCondition::Colors &colors)
+{
+ add_condition(new LinkedColorsCondition(colors));
+}
+
+void Category::Loader::or_()
+{
+ RefPtr<OrCondition> cond = new OrCondition;
+ Loader sub_ldr(obj, cond.get());
+ load_sub_with(sub_ldr);
+ add_condition(cond.release());
+}