/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
#ifndef IMLEXMLCONF_HH_
#define IMLEXMLCONF_HH_

#include <vector>
#include <string>
#include <libxml/tree.h>
#include "IMUtil.hh"

using namespace std;
typedef vector<string> ModuleInfoVec;

struct LEEntry {
    string lang;
    ModuleInfoVec modules;
};
struct LEHotkey {
    string modname;
    IMKeySpecList hotkeys;
};
typedef vector<LEEntry> IMModuleInfoVec;
typedef vector<LEHotkey> IMLEHotkeyInfoVec;

class LEInfo {
protected:
    IMModuleInfoVec levec;
    IMLEHotkeyInfoVec hotkeyvec;

public:
    bool addmodule(xmlChar *modulename, xmlChar *language);
    bool appendmodule(string &modulename, string &language);
    bool prependmodule(string &modulename, string &language);
    bool removemodule(string &modulename, string &language);
    bool appendhotkey(IMKeySpec hotkey, string &modname);
    bool removehotkey(IMKeySpec hotkey, string &modname);
    bool clearhotkey(string &modname);
    bool empty(void);
    IMModuleInfoVec *get_leinfo(void) {
	return &levec;
    }
    IMLEHotkeyInfoVec *get_hotkeyinfo(void) {
	return &hotkeyvec;
    }
    LEInfo(void);
};

class IMLEXMLConf {
private:
    string filename;

    string parse_text_node(xmlNodePtr &node);
    void parse_key_node(xmlNodePtr &node, string &modname);
    void parse_module_node(xmlNodePtr &node, string &language);
    void parse_le_node(xmlNodePtr &node);
    void parse_default_node(xmlNodePtr &node);
    void parse_les_node(xmlNodePtr &node);
protected:
    LEInfo le_list;

public:
    bool load(void);
    IMModuleInfoVec *get_leinfo(void) {
	return le_list.get_leinfo();
    }
    IMLEHotkeyInfoVec *get_hotkeyinfo(void) {
	return le_list.get_hotkeyinfo();
    }
    bool reload(void) {
	le_list.get_leinfo()->clear();
	return this->load();
    }
    bool empty(void) {
	return le_list.empty();
    }
    IMLEXMLConf(const char *conffile);
};

#endif /* IMLEXMLCONF_HH_ */
