// used for #ifdef
#include "config.h"

#include "libfspp.hpp"

#include "theme.hpp"

#include "common.hpp"
#include "config.hpp"
#include "startmenu.hpp"
#include "gettext.hpp"

#include "graphics.hpp"
#include "shutdown.hpp"

#include <sstream>
#include <fstream>

using std::string;
using std::vector;

Theme& Theme::get_instance() 
{
  static Theme s;
  return s;
}

Theme::Theme() 
  : pos(0), cur_theme("")
{
  load();
}

vector<string> Theme::list_themes()
{
  vector<string> files;

  Config *config = Config::get_instance();

  string argv = prefix"/share/mms/themes/";

  if (config->p_homedir() != "/etc/mms/")
    argv = config->p_homedir() + "themes/";
  
  for (file_iterator<file_t, default_order> i (argv); (i != i.end ()); i.advance(false))
    {
      string filename = i->getName();
      files.push_back(filename.substr(argv.size()+1));
    }

  return files;
}

std::string Theme::mainloop()
{
  input_master->cur_map = &input_master->standard;

  Startmenu &startmenu = Startmenu::get_instance();
  startmenu.module = "theme";

  Input input;

  list_of_themes = list_themes();

  bool update_needed = true;
  
  Shutdown &sd = Shutdown::get_instance();

  while (!(input.command == "back" && 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 = list_of_themes.size()-1;
 	}
      else if (input.command == "next")
 	{
 	  if (pos != list_of_themes.size()-1)
	    ++pos;
	  else
	    pos = 0;
 	}
      else if (input.command == "action")
	{
	  if (themes->parser(vector_lookup(list_of_themes, pos), false)) {
	    cur_theme = vector_lookup(list_of_themes, pos);
	    startmenu.generate_startmenu();
	    render->set_theme();

	    render->image_mut.enterMutex();
	    render->complete_redraw();
	    render->image_mut.leaveMutex();
	  }
	}
      else
	update_needed = !general_loop_check(input);
    }
  return "";
}

void Theme::print_string_element(const string& r, const string& position, int y)
{
  if (r == position) {
    render->current.add(new PObj(themes->themes_marked_left, 68, y-1, 2, NOSCALING));
    render->current.add(new PObj(themes->themes_marked, 68+25, y-1, conf->p_v_res()-(2*68)-50, 2));
    render->current.add(new PObj(themes->themes_marked_right, 68+25+conf->p_v_res()-(2*68)-50, y-1, 2, NOSCALING));
  }

  if (r == cur_theme)
    render->current.add(new TObj(r, "Vera/17", 72, y, 
				 themes->themes_marked_font1, themes->themes_marked_font2, 
				 themes->themes_marked_font3, 3));
  else
    render->current.add(new TObj(r, "Vera/17", 72, y, 
				 themes->themes_font1, themes->themes_font2, 
				 themes->themes_font3, 3));
}

void Theme::print()
{
  render->prepare_new_image();

  render->current.add(new PObj(themes->themes_background, 0, 0, 0, SCALE_FULL));

  render->current.add(new PObj(themes->startmenu_themes, 25, 10, 2, NOSCALING));

  if (themes->show_header) {
    render->current.add(new TObj(gettext("Themes"), "Vera/28", 100, 10,
				 themes->themes_header_font1, themes->themes_header_font2, 
				 themes->themes_header_font3, 2));
  }
  
  std::ostringstream position;
  position << pos+1 << "/" << list_of_themes.size();

  int x, y;
  string_format::calculate_string_size(position.str(), "Vera/18", &x, &y);
  
  render->current.add(new TObj(position.str(), "Vera/18", conf->p_v_res()-(60+x), 20,
			       themes->themes_font1, themes->themes_font2, 
			       themes->themes_font3, 2));

  TPRSAudioFunctor<Theme> print_func(this, &Theme::print_string_element);
  print_range(list_of_themes, vector_lookup(list_of_themes, pos), pos, &print_func);
  
  render->draw("themes");

  render->image_mut.leaveMutex();
}

void Theme::load()
{
  // set the cur_theme to something sane as default in case the other things go wrong.
  cur_theme = "standard";

  std::string path = conf->p_var_data_dir() + "options";

  std::ifstream in;
  in.open(path.c_str(), std::ios::in);
  
  if (!in.is_open()) {
    DebugPrint perror(gettext("Could not open options file ") + path,
		      Print::DEBUGGING, DebugPrint::CRITICAL, "THEME");
    exit(1);
  } else {
   
    string name, value, str;
    
    while (getline(in, str)) {

      string::size_type comma = str.find(",");

      if (comma == string::npos)
	continue;
      
      name = str.substr(0,comma);
      value = str.substr(comma+1);

      if (name == "cur_theme")
 	cur_theme = value;
    }
    in.close();
  }

  themes->parser(cur_theme, true);
}
