#include "extra_menu.hpp"

#include "renderer.hpp"
#include "common.hpp"
#include "themes.hpp"
#include "graphics.hpp"
#include "config.hpp"
#include "updater.hpp"

#include "busy_indicator.hpp"
#include "shutdown.hpp"

#ifdef c_music
#include "audio.hpp"
#include "audio_s.hpp"
#endif

ExtraMenuItem::ExtraMenuItem(const std::string c, const std::string& s, TimeFv *cb)
  : command(c), shortcut(s), callback(cb)
{}

void ExtraMenu::add_item(const ExtraMenuItem& e)
{
  items.push_back(e);
}

ExtraMenu::ExtraMenu(const std::string& h)
  : header(h), pos(0), o(Overlay("extra menu"))
{}

void ExtraMenu::cleanup()
{
  Render *render = Render::get_instance();
  
  render->image_mut.enterMutex();
  render->device->wait_for_output_done();
  o.cleanup();
  render->image_mut.leaveMutex();
}

void ExtraMenu::mainloop()
{
#ifdef c_music
  Audio_s *audio_state = Audio_s::get_instance();
  Audio *audio = Audio::get_instance();

  if (audio_state->fullscreen_info)
    audio->print_audio_fullscreen(); // cleanup
#endif

  Config *conf = Config::get_instance();

  conf->s_sam(true);

  BusyIndicator &busy_indicator = BusyIndicator::get_instance();
  Shutdown &sd = Shutdown::get_instance();

  busy_indicator.idle();

  Updater &updater = Updater::get_instance();

  bool audio_fullscreen_running = true;

  if (!updater.timer.status("audio_fullscreen"))
    audio_fullscreen_running = false;
  else
    updater.timer.deactivate("audio_fullscreen");

  Input_master *input_master = Input_master::get_instance();

  Input input;
  
  bool update_needed = true;

  while (!(input.command == "back" && input.mode == "general") &&
	 !(input.command == "second_action" && input.mode == "general"))
    {
      if (update_needed)
	print();

      input = input_master->device->get_input();
      
      if (sd.is_enabled()) {
      	sd.cancel();
      	continue;
      }

      update_needed = true;

      if (input.command == "prev")
	{
	  if (pos != 0)
	    --pos;
	  else
	    pos = items.size()-1;
 	}
      else if (input.command == "next")
 	{
	  if (pos != items.size()-1)
	    ++pos;
	  else
	    pos = 0;
 	}
      else if (input.command == "action")
	{
	  busy_indicator.busy_no_print();

	  // FIXME: evil hack
	  if (vector_lookup(items, pos).command != gettext("Zoom"))
	    cleanup();

	  if (audio_fullscreen_running)
	    updater.timer.activate("audio_fullscreen");

	  vector_lookup(items, pos).callback->call();

	  // FIXME: evil hack
	  if (vector_lookup(items, pos).command == gettext("Zoom"))
	    cleanup();

	  conf->s_sam(false);

	  return;
	}
      else 
	update_needed = !general_loop_check(input, true);
    }

  cleanup();
  if (audio_fullscreen_running)
    updater.timer.activate("audio_fullscreen");
  conf->s_sam(false);
}

void ExtraMenu::print()
{
  Render *render = Render::get_instance();
  Themes *themes = Themes::get_instance();
  Config *conf = Config::get_instance();

  render->image_mut.enterMutex();
  render->device->wait_for_output_done();

  if (o.elements.size() > 0)
    o.partial_cleanup();

  int x, y, max_x = conf->p_v_res()-250, max_y = 30;

  int box_height = max_y*items.size()+30+35;

  x = (conf->p_v_res()-(max_x+30))/2;
  y = (conf->p_h_res()-(box_height))/2;

  o.add(new RObj(x-15+2, y-15+2, max_x+30+1, box_height+1, 0, 0, 0, 200, 0));
  o.add(new RObj(x-15, y-15, max_x+30, box_height,  
		 themes->dialog_background1, themes->dialog_background2, 
		 themes->dialog_background3, themes->dialog_background4, 1));

  int x_size, y_size;
  string_format::calculate_string_size(header, "Vera/20", &x_size, &y_size);

  o.add(new TObj(header, "Vera/20", (conf->p_v_res()-x_size)/2, y-5, 
		 themes->dialog_font1, themes->dialog_font2, themes->dialog_font3, 3));
  y += 35;

  if (pos == -1) 
    o.add(new RObj(x-5, y-3, max_x+10, 25+6, 0, 0, 0, 225, 2));

  int i = 0;

  for (std::vector<ExtraMenuItem>::const_iterator iter = items.begin();
       iter != items.end(); ++iter, ++i) {
    if (i == pos)
      o.add(new RObj(x-5, y-3, max_x+10, 25+6, themes->dialog_marked1, 
		     themes->dialog_marked2, themes->dialog_marked3, 
		     themes->dialog_marked4, 2));

    o.add(new TObj(iter->command, "Vera/17", x, y, themes->dialog_font1, 
		   themes->dialog_font2, themes->dialog_font3, 3));
    int x_size, y_size;
    string_format::calculate_string_size(iter->shortcut, "Vera/17", &x_size, &y_size);
    o.add(new TObj(iter->shortcut, "Vera/17", x + max_x - x_size - 5, y, 
		   themes->dialog_font1, themes->dialog_font2, 
		   themes->dialog_font3, 3));
    y += 30;
  }

  render->draw("extra menu screen", true);
  render->image_mut.leaveMutex();
}

