/***************************************************************************
                          lconfig.h  -  description
                             -------------------
    begin                : Fri Jan 17 2003
    copyright            : (C) 2003 by Sheldon Lee Wen
    email                : leewsb@hotmail.com
 ***************************************************************************/

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

#ifndef LCONFIG_H
#define LCONFIG_H

#if __GNUC__ >= 3
   #include <fstream>
#else
   #include <fstream.h>
#endif

#include <config.h>

#include <map>
#include <vector>
#include <iostream>
#include <lineak/definitions.h>
#include <lineak/configdirectives.h>
#include <lineak/lconfigdata.h>
#include <lineak/lcommand.h>

class LKey;
class LKbd;
//class LCommand;
class LConfigData;
class LObject;

struct keycommand_info
{
   string config_name;
   string parsed_name;
   string display_name;
   unsigned int modifiers;
   LCommand command;
};

/**Lineak user config file. The LConfig class is a subclass of the LConfigData class.
  *An LConfig object contains all of the configuration file directives information in a
  *ConfigDirectives object. (Directives are all of the global configuration options that
  *are not keys and command. e.g. CdromDevice.) It also contains commands for each key
  *in the form of a map of LCommand objects, that is keyed on the key name (string).
  *@author Sheldon Lee Wen
  */
class LConfig : public LConfigData {
public:

	/**
	  There are 3 ways to instantiate an LConfig object.
		1) Default constructor, will be an empty object.
		2) Copy constructor.
		3) Constructor taking a ConfigDirectives object. This is the recommended way.
	*/
	LConfig();
	LConfig(const LConfig &rhs);
	LConfig(ConfigDirectives &directives);
	// NOTSUPPORTED ANYMORE LConfig(string ikbdtype, string icdrom, string imixer);
	LConfig & operator=(const LConfig &rhs);
	virtual ~LConfig();
	
	/**
	The setValue and getValue/getIntValue methods are exactly the same as the
	ConfigDirectives methods addValue and getValue/getIntValue. In fact, they are
	just a wrapper around them for the private ConfigDirectives variable.
	The [] operator just returns a reference a the ConfigDirectives string value
	*/
  	void setValue(string key, string value);
  	void setValue(string key, int value);
  	string getValue(string key) const;
  	int getIntValue(string key) const;
  	string& operator[](string key) { return directives[key]; }


  	/** Return a list of keynames that we have LCommands for. */
  	//const vector<string>& getCommandKeyNames();
 	/** Return a map of commands indexed by keycodes. */
  	//map<const int,  LCommand> getKeyCommandIndex(const map< string, LObject*>& skeys) ;
 	/** Return a map of commands indexed by keycodes. */
  	//map<const int,  LCommand> getKeyCommandIndex(const LKbd& keyboard) ;
	/** Return a map of commands indexed by button. */
  	//map<const unsigned int,  LCommand> getButtonCommandIndex(const map< string, LObject*>& skeys) ;
 	/** Return a map of commands indexed by button. */
  	//map<const unsigned int,  LCommand> getButtonCommandIndex(const LKbd& keyboard) ;
	void addKeycomm(const string key, keycommand_info info);
	vector<keycommand_info>& getKeycomm(const string key);
  	/** Return a command string given a key code */
	//LCommand& getCommand(const string& key);
	/** Set the command for a key */
	//void setCommand(string key, LCommand command);
	/** Add a key and command mapping. */
	//void addKey(string key, LCommand command, bool respect_toggle = false);
	/** Add a key to modifier mapping */
	//void addModifier(string key, unsigned int modifiers);
	/** Get a key's modifier mapping */
	//unsigned int getModifier(const string& key);
	/** Add a config name indexed by parsed name. This is only
	    used in the print method, where we want to print out
	    keynames as they exist in the config file, with modifiers
	    and other qualifiers. */
	//void addParsedName(string config_name, string parsed_name) {
	//   parsednames[config_name] = parsed_name;
	//}
	//inline const string& getParsedName(string config_name) { 
	//   return parsednames[config_name]; 
	//}
	inline string getFilename() const { return directives.getValue(_CD_USERCONFFILE); }

	/** The setFilename method is used to set the name of the file that the LConfig
	    was parsed from. It is necessary that the filename and keyboard type be set
	    for the isEmpty() method to work. */
	void setFilename(string file);
	/** Is the config object empty? For this to be a no, the directives object must
	    contain values for the keys conffilename and KeyboardType */
  	bool isEmpty();
	inline void setDirectives(const ConfigDirectives& directivelist) { directives = directivelist; }
	/** print */
	void print(ostream& out);
	/** clear the config object */
	void clear();
private:
	//map<const string, LCommand>  comtable;
	//map<const string, unsigned int> modtable;
	//map<const string, string> parsednames;
	map<const string, vector<keycommand_info> > keycommtable;
	ConfigDirectives directives;
	vector<string> vec;
	vector<keycommand_info> tv;
};

#endif
