#include "skins.h"
#include "proctools/logger.h"
#include "proctools/format.h"
#include <unistd.h>
#include <iostream>
#include <algorithm>
#include <boost/bind.hpp>
#include <vdr/i18n.h>
#include <vdr/tools.h>

namespace vdr_burn
{

	using namespace std;
	using proctools::logger;
	using proctools::format;

	skin_list skin_list::instance;

	bool operator<(const skin& lhs, const skin& rhs)
	{	
		if (lhs.m_default)
			return true;
		else if (rhs.m_default)
			return false;
		else
			return lhs.m_name < rhs.m_name;
	}

	// --- skin ---------------------------------------------------------------

	std::string skin::default_background;
	std::string skin::default_button;

	skin::skin(const std::string& name, const std::string& background, 
			   const std::string& button, bool default_):
			m_default(default_),
			m_name(name),
			m_background(background.empty() ? default_background : background),
			m_button(button.empty() ? default_button : button)
	{
		replace(m_name.begin(), m_name.end(), '_', ' ');
		logger::debug(format("loaded skin {0} using {1} and {2}")
					  % m_name % m_background % m_button);
	}

	void skin::set_defaults(const std::string& background, 
							const std::string& button)
	{
		default_background = background;
		default_button = button;
	}

	// --- skin_list ----------------------------------------------------------

	skin_list::skin_list(void):
			m_strings(NULL)
	{
	}

	skin_list::~skin_list(void)
	{
		delete[] m_strings;
	}

	string skin_list::check_skin_path(const std::string& path_,
									  const std::string& fileName, bool fatal)
	{
		string path = format("{0}/{1}") % path_ % fileName;
		if (access(path.c_str(), R_OK) == -1) {
			if (fatal) {
				string msg = format("couldn't open image file {0}") % path;
				cerr << "ERROR[burn]: " << msg << ": " << strerror(errno) 
					 << endl;
				logger::error(msg);
			}
			return string();
		}
		return path;
	}

	bool skin_list::load(const std::string& path_)
	{
		string background = check_skin_path(path_, "menu-bg.png", true);
		string button     = check_skin_path(path_, "menu-button.png", true);

		if (background.empty() || button.empty())
			return false;

		skin::set_defaults(background, button);

		insert(end(), skin(tr("Default"), string(), string(), true));

		string path = format("{0}/skins") % path_;
		cReadDir dir(path.c_str());
		struct dirent *ent;
		while ((ent = dir.Next()) != NULL) {
			if (ent->d_name[0] == '.') // hide dotfiles, '.' and '..'
				continue;

			background = check_skin_path(format("{0}/{1}") % path % ent->d_name,
										 "menu-bg.png");
			button     = check_skin_path(format("{0}/{1}") % path % ent->d_name,
										 "menu-button.png");

			if (!background.empty() || !button.empty())
				insert(end(), skin(ent->d_name, background, button));
		}
		sort(begin(), end());

		return true;
	}

	const char * const *skin_list::get_strings(void)
	{
		if (m_strings == NULL) {
			m_strings = new const char*[size()];
			transform(begin(), end(), m_strings, 
					  bind( &string::c_str, 
							bind( &skin::get_name, _1 )
					 ));
		}
		return m_strings;
	}

}
