/*
    Aeskulap Configuration - persistent configuration interface library
    Copyright (C) 2005  Alexander Pipelka

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    Alexander Pipelka
*/

#include <gconfmm.h>
#include <cstdio>
#include <iostream>

namespace Aeskulap {

static Glib::RefPtr<Gnome::Conf::Client> m_conf_client;

Configuration::Configuration() {
	if(!m_conf_client) {
		std::cout << "Gnome::Conf::init()" << std::endl;
		Gnome::Conf::init();
		m_conf_client = Gnome::Conf::Client::get_default_client();
	}

	m_conf_client->add_dir("/apps/aeskulap/preferences");
	m_conf_client->add_dir("/apps/aeskulap/presets");
	m_conf_client->add_dir("/apps/aeskulap/presets/windowlevel");

	if(!m_conf_client->dir_exists("/apps/aeskulap/presets/windowlevel/CT")) {
		add_default_presets_ct();
	}
}

std::string Configuration::get_local_aet() {
	std::string local_aet = m_conf_client->get_string("/apps/aeskulap/preferences/local_aet");

	if(local_aet.empty()) {
		local_aet = "AESKULAP";
		set_local_aet(local_aet);
	}
	
	return local_aet;
}
	
void Configuration::set_local_aet(const std::string& aet) {
	m_conf_client->set("/apps/aeskulap/preferences/local_aet", aet);
}

unsigned int Configuration::get_local_port() {
	m_conf_client = Gnome::Conf::Client::get_default_client();
	gint local_port = m_conf_client->get_int("/apps/aeskulap/preferences/local_port");

	if(local_port <= 0) {
		local_port = 6000;
		set_local_port(local_port);
	}
	
	return (unsigned int)local_port;
}
	
void Configuration::set_local_port(unsigned int port) {
	if(port <= 0) {
		port = 6000;
	}
	m_conf_client->set("/apps/aeskulap/preferences/local_port", (gint)port);
}

std::string Configuration::get_encoding() {
	std::string charset = m_conf_client->get_string("/apps/aeskulap/preferences/characterset");

	if(charset.empty()) {
		charset = "ISO_IR 100";
		set_encoding(charset);
	}
	
	return charset;
}

void Configuration::set_encoding(const std::string& encoding) {
	m_conf_client->set("/apps/aeskulap/preferences/characterset", encoding);
}

Configuration::ServerList* Configuration::get_serverlist() {
	Configuration::ServerList* list = new Configuration::ServerList;

	Gnome::Conf::SListHandle_ValueString aet_list = m_conf_client->get_string_list("/apps/aeskulap/preferences/server_aet");
	Gnome::Conf::SListHandle_ValueInt port_list = m_conf_client->get_int_list("/apps/aeskulap/preferences/server_port");
	Gnome::Conf::SListHandle_ValueString hostname_list = m_conf_client->get_string_list("/apps/aeskulap/preferences/server_hostname");
	Gnome::Conf::SListHandle_ValueString description_list = m_conf_client->get_string_list("/apps/aeskulap/preferences/server_description");
	Gnome::Conf::SListHandle_ValueString group_list = m_conf_client->get_string_list("/apps/aeskulap/preferences/server_group");
	Gnome::Conf::SListHandle_ValueBool lossy_list = m_conf_client->get_bool_list("/apps/aeskulap/preferences/server_lossy");
	Gnome::Conf::SListHandle_ValueBool relational_list = m_conf_client->get_bool_list("/apps/aeskulap/preferences/server_relational");
	
	Gnome::Conf::SListHandle_ValueString::iterator a = aet_list.begin();
	Gnome::Conf::SListHandle_ValueInt::iterator p = port_list.begin();
	Gnome::Conf::SListHandle_ValueString::iterator h = hostname_list.begin();
	Gnome::Conf::SListHandle_ValueString::iterator d = description_list.begin();
	Gnome::Conf::SListHandle_ValueString::iterator g = group_list.begin();
	Gnome::Conf::SListHandle_ValueBool::iterator l = lossy_list.begin();
	Gnome::Conf::SListHandle_ValueBool::iterator r = relational_list.begin();
	
	for(; h != hostname_list.end() && a != aet_list.end() && p != port_list.end(); a++, p++, h++) {

		std::string servername;
		if(d != description_list.end()) {
			servername = *d;
			d++;
		}
		else {
			char buffer[50];
			snprintf(buffer, sizeof(buffer), "Server%li", list->size()+1);
			servername = buffer;
		}

		ServerData& s = (*list)[servername];
		s.m_aet = *a;
		s.m_port = *p;
		s.m_hostname = *h;
		s.m_name = servername;
		s.m_lossy = false;
		s.m_relational = false;
	
		if(l != lossy_list.end()) {
			s.m_lossy = *l;
			l++;
		}

		if(g != group_list.end()) {
			s.m_group = *g;
			g++;
		}

		if(r != relational_list.end()) {
			s.m_relational = *r;
			r++;
		}

	}
	
	return list;
}

void Configuration::set_serverlist(std::vector<ServerData>& list) {
	std::vector< Glib::ustring > aet_list;
	std::vector< Glib::ustring > hostname_list;
	std::vector< int > port_list;
	std::vector< Glib::ustring > description_list;
	std::vector< Glib::ustring > group_list;
	std::vector< gboolean > lossy_list;
	std::vector< gboolean > relational_list;

	std::vector<ServerData>::iterator i;
	for(i = list.begin(); i != list.end(); i++) {
		aet_list.push_back(i->m_aet);
		hostname_list.push_back(i->m_hostname);
		port_list.push_back(i->m_port);
		description_list.push_back(i->m_name);
		group_list.push_back(i->m_group);
		lossy_list.push_back(i->m_lossy);
		relational_list.push_back(i->m_relational);
	}

	m_conf_client->set_string_list("/apps/aeskulap/preferences/server_aet", aet_list);
	m_conf_client->set_string_list("/apps/aeskulap/preferences/server_hostname", hostname_list);
	m_conf_client->set_int_list("/apps/aeskulap/preferences/server_port", port_list);
	m_conf_client->set_string_list("/apps/aeskulap/preferences/server_description", description_list);
	m_conf_client->set_string_list("/apps/aeskulap/preferences/server_group", group_list);
	m_conf_client->set_bool_list("/apps/aeskulap/preferences/server_lossy", lossy_list);
	m_conf_client->set_bool_list("/apps/aeskulap/preferences/server_relational", relational_list);
}

bool Configuration::get_windowlevel(const Glib::ustring& modality, const Glib::ustring& desc, WindowLevel& w) {
	Glib::ustring base = "/apps/aeskulap/presets/windowlevel/"+modality+"/"+desc;

	if(!m_conf_client->dir_exists(base)) {
		return false;
	}

	if(m_conf_client->get_without_default(base+"/center").get_type() == Gnome::Conf::VALUE_INVALID) {
		return false;
	}

	w.modality = modality;
	w.description = desc;
	w.center = m_conf_client->get_int(base+"/center");
	w.width = m_conf_client->get_int(base+"/width");

	return true;
}

bool Configuration::get_windowlevel_list(const Glib::ustring& modality, WindowLevelList& list) {
	if(modality.empty()) {
		return false;
	}

	Glib::ustring base = "/apps/aeskulap/presets/windowlevel/"+modality;

	std::vector< Glib::ustring > dirs = m_conf_client->all_dirs(base);
	if(dirs.size() == 0) {
		return false;
	}

	list.clear();
	
	for(unsigned int i=0; i<dirs.size(); i++) {
		WindowLevel w;
		if(get_windowlevel(modality, get_name_from_path(dirs[i]), w)) {
			list[w.description] = w;
		}
	}
	
	return true;
}

bool Configuration::set_windowlevel(const WindowLevel& w) {
	Glib::ustring base = "/apps/aeskulap/presets/windowlevel/"+w.modality+"/"+w.description;

	if(!m_conf_client->dir_exists(base)) {
		m_conf_client->add_dir(base);
	}

	m_conf_client->set(base+"/center", w.center);
	m_conf_client->set(base+"/width", w.width);
	
	return true;
}

bool Configuration::set_windowlevel_list(const Glib::ustring& modality, WindowLevelList& list) {
	Glib::ustring base = "/apps/aeskulap/presets/windowlevel/"+modality;
	WindowLevelList::iterator i;
	
	for(i = list.begin(); i != list.end(); i++) {
		i->second.modality = modality;
		set_windowlevel(i->second);
	}
	
	return true;
}

bool Configuration::unset_windowlevels(const Glib::ustring& modality) {
	Glib::ustring base = "/apps/aeskulap/presets/windowlevel/"+modality;

	std::vector< Glib::ustring > dirs = m_conf_client->all_dirs(base);
	if(dirs.size() == 0) {
		return false;
	}

	for(unsigned int i=0; i<dirs.size(); i++) {
		Glib::ustring keybase = base+"/"+get_name_from_path(dirs[i]);
		m_conf_client->unset(keybase+"/center");
		m_conf_client->unset(keybase+"/width");
	}
	
	return true;
}

} // namespace Aeskulap
