text: // license:BSD-3-Clause
  // copyright-holders:Maurizio Petrarota
  /*********************************************************************
  
      ui/optsmenu.cpp
  
      UI main options menu manager.
  
  *********************************************************************/
  
  #include "emu.h"
  #include "ui/optsmenu.h"
  
  #include "ui/custui.h"
  #include "ui/dirmenu.h"
  #include "ui/inputmap.h"
  #include "ui/miscmenu.h"
  #include "ui/selector.h"
  #include "ui/sndmenu.h"
  #include "ui/submenu.h"
  #include "ui/ui.h"
  
  #include "mame.h"
  #include "mameopts.h"
  #include "rendfont.h"
  
  
  namespace ui {
  
  //-------------------------------------------------
  //  ctor
  //-------------------------------------------------
  
  menu_simple_game_options::menu_simple_game_options(
  		mame_ui_manager &mui,
  		render_container &container,
  		std::function<void ()> &&handler)
  	: menu(mui, container)
  	, m_handler(std::move(handler))
  {
  	set_process_flags(PROCESS_LR_REPEAT);
  }
  
  //-------------------------------------------------
  //  dtor
  //-------------------------------------------------
  
  menu_simple_game_options::~menu_simple_game_options()
  {
  	ui().save_ui_options();
  	if (m_handler)
  		m_handler();
  }
  
  //-------------------------------------------------
  //  handle
  //-------------------------------------------------
  
  void menu_simple_game_options::handle(event const *ev)
  {
  	// process the menu
  	if (ev && ev->itemref)
  		handle_item_event(*ev);
  }
  
  //-------------------------------------------------
  //  populate
  //-------------------------------------------------
  
  void menu_simple_game_options::populate(float &customtop, float &custombottom)
  {
  	item_append(_(submenu::video_options()[0].description), 0, (void *)(uintptr_t)DISPLAY_MENU);
  	item_append(_("Sound Options"), 0, (void *)(uintptr_t)SOUND_MENU);
  	item_append(_(submenu::misc_options()[0].description), 0, (void *)(uintptr_t)MISC_MENU);
  	item_append(_(submenu::control_options()[0].description), 0, (void *)(uintptr_t)CONTROLLER_MENU);
  	item_append(_("General Inputs"), 0, (void *)(uintptr_t)CGI_MENU);
  	item_append(_(submenu::advanced_options()[0].description), 0, (void *)(uintptr_t)ADVANCED_MENU);
  	if (machine().options().plugins())
  		item_append(_("Plugins"), 0, (void *)(uintptr_t)PLUGINS_MENU);
  	item_append(menu_item_type::SEPARATOR);
  	item_append(_("Save Configuration"), 0, (void *)(uintptr_t)SAVE_CONFIG);
  
  	custombottom = 2.0f * ui().get_line_height() + 3.0f * ui().box_tb_border();
  	customtop = ui().get_line_height() + 3.0f * ui().box_tb_border();
  }
  
  //-------------------------------------------------
  //  handle item
  //-------------------------------------------------
  
  void menu_simple_game_options::handle_item_event(event const &menu_event)
  {
  	switch ((uintptr_t)menu_event.itemref)
  	{
  	case MISC_MENU:
  		if (menu_event.iptkey == IPT_UI_SELECT)
  		{
  			menu::stack_push<submenu>(ui(), container(), submenu::misc_options());
  			ui_globals::reset = true;
  		}
  		break;
  	case SOUND_MENU:
  		if (menu_event.iptkey == IPT_UI_SELECT)
  		{
  			menu::stack_push<menu_sound_options>(ui(), container());
  			ui_globals::reset = true;
  		}
  		break;
  	case DISPLAY_MENU:
  		if (menu_event.iptkey == IPT_UI_SELECT)
  		{
  			menu::stack_push<submenu>(ui(), container(), submenu::video_options());
  			ui_globals::reset = true;
  		}
  		break;
  	case CONTROLLER_MENU:
  		if (menu_event.iptkey == IPT_UI_SELECT)
  			menu::stack_push<submenu>(ui(), container(), submenu::control_options());
  		break;
  	case CGI_MENU:
  		if (menu_event.iptkey == IPT_UI_SELECT)
  			menu::stack_push<menu_input_groups>(ui(), container());
  		break;
  	case ADVANCED_MENU:
  		if (menu_event.iptkey == IPT_UI_SELECT)
  		{
  			menu::stack_push<submenu>(ui(), container(), submenu::advanced_options());
  			ui_globals::reset = true;
  		}
  		break;
  	case PLUGINS_MENU:
  		if (menu_event.iptkey == IPT_UI_SELECT)
  			menu::stack_push<menu_plugins_configure>(ui(), container());
  		break;
  	case SAVE_CONFIG:
  		if (menu_event.iptkey == IPT_UI_SELECT)
  			ui().save_main_option();
  		break;
  	}
  }
  
  //-------------------------------------------------
  //  perform our special rendering
  //-------------------------------------------------
  
  void menu_simple_game_options::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
  {
  	char const *const toptext[] = { _("Settings") };
  	draw_text_box(
  			std::begin(toptext), std::end(toptext),
  			origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
  			text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
  			ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
  }
  
  
  //-------------------------------------------------
  //  ctor
  //-------------------------------------------------
  
  menu_game_options::menu_game_options(
  		mame_ui_manager &mui,
  		render_container &container,
  		machine_filter_data &filter_data,
  		std::function<void ()> &&handler)
  	: menu_simple_game_options(mui, container, std::move(handler))
  	, m_filter_data(filter_data)
  	, m_main_filter(filter_data.get_current_filter_type())
  {
  	set_process_flags(PROCESS_LR_REPEAT);
  }
  
  //-------------------------------------------------
  //  dtor
  //-------------------------------------------------
  
  menu_game_options::~menu_game_options()
  {
  	m_filter_data.set_current_filter_type(m_main_filter);
  }
  
  //-------------------------------------------------
  //  handle
  //-------------------------------------------------
  
  void menu_game_options::handle(event const *ev)
  {
  	// process the menu
  	if (ev && ev->itemref)
  		handle_item_event(*ev);
  }
  
  //-------------------------------------------------
  //  populate
  //-------------------------------------------------
  
  void menu_game_options::populate(float &customtop, float &custombottom)
  {
  	// set filter arrow
  	std::string fbuff;
  
  	// add filter item
  	uint32_t arrow_flags = get_arrow_flags<uint16_t>(machine_filter::FIRST, machine_filter::LAST, m_main_filter);
  	machine_filter &active_filter(m_filter_data.get_filter(m_main_filter));
  	item_append(_("Filter"), active_filter.display_name(), arrow_flags, (void *)(uintptr_t)FILTER_MENU);
  
  	// add subitem if the filter wants it
  	if (active_filter.wants_adjuster())
  	{
  		std::string name(convert_command_glyph("^!"));
  		item_append(name, active_filter.adjust_text(), active_filter.arrow_flags(), (void *)(FILTER_ADJUST));
  	}
  
  	item_append(menu_item_type::SEPARATOR);
  
  	// add options items
  	item_append(_("Customize UI"), 0, (void *)(uintptr_t)CUSTOM_MENU);
  	item_append(_("Configure Directories"), 0, (void *)(uintptr_t)CONF_DIR);
  
  	// add the options that don't relate to the UI
  	menu_simple_game_options::populate(customtop, custombottom);
  }
  
  //-------------------------------------------------
  //  handle item
  //-------------------------------------------------
  
  void menu_game_options::handle_item_event(event const &menu_event)
  {
  	bool changed = false;
  
  	switch ((uintptr_t)menu_event.itemref)
  	{
  	case FILTER_MENU:
  		if (menu_event.iptkey == IPT_UI_LEFT || menu_event.iptkey == IPT_UI_RIGHT)
  		{
  			(menu_event.iptkey == IPT_UI_RIGHT) ? ++m_main_filter : --m_main_filter;
  			changed = true;
  		}
  		else if (menu_event.iptkey == IPT_UI_SELECT)
  		{
  			std::vector<std::string> s_sel(machine_filter::COUNT);
  			for (unsigned index = 0; index < s_sel.size(); ++index)
  				s_sel[index] = machine_filter::display_name(machine_filter::type(index));
  
  			menu::stack_push<menu_selector>(
  					ui(), container(), std::move(s_sel), m_main_filter,
  					[this] (int selection)
  					{
  						m_main_filter = machine_filter::type(selection);
  						reset(reset_options::REMEMBER_REF);
  					});
  		}
  		break;
  	case FILTER_ADJUST:
  		if (menu_event.iptkey == IPT_UI_LEFT)
  		{
  			changed = m_filter_data.get_filter(m_main_filter).adjust_left();
  		}
  		else if (menu_event.iptkey == IPT_UI_RIGHT)
  		{
  			changed = m_filter_data.get_filter(m_main_filter).adjust_right();
  		}
  		else if (menu_event.iptkey == IPT_UI_SELECT)
  		{
  			m_filter_data.get_filter(m_main_filter).show_ui(
  					ui(),
  					container(),
  					[this] (machine_filter &filter)
  					{
  						if (machine_filter::CUSTOM == filter.get_type())
  						{
  							emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
  							if (!file.open(util::string_format("custom_%s_filter.ini", emulator_info::get_configname())))
  							{
  								filter.save_ini(file, 0);
  								file.close();
  							}
  						}
  						reset(reset_options::REMEMBER_REF);
  					});
  		}
  		break;
  	case CONF_DIR:
  		if (menu_event.iptkey == IPT_UI_SELECT)
  			menu::stack_push<menu_directory>(ui(), container());
  		break;
  	case CUSTOM_MENU:
  		if (menu_event.iptkey == IPT_UI_SELECT)
  			menu::stack_push<menu_custom_ui>(ui(), container(), [this] () { reset(reset_options::REMEMBER_REF); });
  		break;
  	default:
  		menu_simple_game_options::handle_item_event(menu_event);
  		return;
  	}
  
  	if (changed)
  		reset(reset_options::REMEMBER_REF);
  }
  
  } // namespace ui
  