text: #include "combobox_ui.hpp"
  #include "overload.hpp"
  
  ComboBoxUi::ComboBoxUi(QComboBox *box,
  		Settings *settings,
  		const std::string &opt,
  		std::function<std::vector<SettingItem>()> itemBuilder) :
  	WidgetUi(settings, opt),
  	box(box),
  	itemBuilder(itemBuilder),
  	ignoreCallback(false)
  {
  	refresh();
  	registerCallback();
  	connectSignals();
  }
  
  void ComboBoxUi::connectSignals(){
  	connect(box, Overload<int>::of(&QComboBox::activated),
  			this, &ComboBoxUi::itemSelected);
  }
  
  void ComboBoxUi::refresh(){
  	items = itemBuilder();
  
  	for(const auto &item : items){
  		for(const auto &opt : item.opts){
  			registerCallback(opt.opt);
  		}
  		for(const auto &condClause : item.conditions){
  			for(const auto &condItem : condClause){
  				registerCallback(condItem.value.opt);
  			}
  		}
  	}
  
  	updateUiItems();
  	selectOption();
  }
  
  static bool conditionsSatisfied(
  		const std::vector<std::vector<ConditionItem>> &conds,
  		Settings *settings)
  {
  	for(const auto &condClause : conds){
  		bool orRes = false;
  		for(const auto &condItem : condClause){
  			bool val = condItem.value.val == settings->getOption(condItem.value.opt).getValue();
  
  			//negate result if negation is true
  			val = val != condItem.negation;
  
  			if(val){
  				orRes = true;
  				break;
  			}
  		}
  		if(!orRes){
  			return false;
  		}
  	}
  
  	return true;
  }
  
  void ComboBoxUi::selectOption(){
  	int i;
  	bool found = false;
  	for(i = 0; i < box->count(); i++){
  		const SettingItem &item = box->itemData(i).value<SettingItem>();
  
  		found = true;
  		for(const auto &itemOpt : item.opts){
  			if(itemOpt.val != settings->getOption(itemOpt.opt).getValue()){
  				found = false;
  				break;
  			}
  		}
  
  		if(found)
  			break;
  	}
  
  	if(found){
  		box->setCurrentIndex(i);
  	} else {
  		itemSelected(0);
  	}
  }
  
  void ComboBoxUi::optChangeCallback(Option &opt, bool suboption){
  	if(suboption || ignoreCallback)
  		return;
  
  	if(opt.getName() != this->opt)
  		updateUiItems();
  
  	selectOption();
  }
  
  void ComboBoxUi::updateUiState(){
  	selectOption();
  }
  
  void ComboBoxUi::updateUiItems(){
  	box->clear();
  
  	for(const auto &i : items){
  		if(conditionsSatisfied(i.conditions, settings)){
  			box->addItem(QString::fromStdString(i.name),
  					QVariant::fromValue(i));
  		}
  	}
  }
  
  void ComboBoxUi::itemSelected(int index){
  	const SettingItem &item = box->itemData(index).value<SettingItem>();
  
  	ignoreCallback = true;
  	for(const auto &option : item.opts){
  		settings->getOption(option.opt).setValue(option.val);
  	}
  	ignoreCallback = false;
  
  	emit changed();
  }
  
  