/*

  Simple config file handler.

*/

#ifndef _CONFIG_H
#define _CONFIG_H 1

#include <FL/filename.H>
#include <stdlib.h>
#include <string>
#include <sstream>
#include <fstream>
#include <map>


class Config
{
  
public:

  // constructor
  Config(std::string config_file_name)
  {
    init(config_file_name);
    load();
  }

  // get option
  std::string get(std::string name)
  {
    std::string res ("");
    if (options.count(name)) 
      res = options[name];
    return res;
  }
  // get int
  int get_i(std::string name)
  {
    std::string res = get(name);
    return atoi(res.c_str());
  }
  // get double
  double get_f(std::string name)
  {
    std::string res = get(name);
    return atof(res.c_str());
  }
  
  // set option
  bool set(std::string name, std::string value)
  {
    if ( (name.find_first_of('=') != std::string::npos) || (name.length() == 0) )
      return false;
    options[name] = value;
    return true;
  }
  // set int
  bool set(std::string name, int value)
  {
    std::stringstream ss("");
    ss << value;
    return set(name, ss.str());
  }
  //set double
  bool set(std::string name, double value)
  {
    std::stringstream ss("");
    ss << value;
    return set(name, ss.str());
  }
  
  // update config file
  bool save()
  {
    std::ofstream f (cfg_path.c_str());
    if (f.is_open())
    {
      std::map<std::string, std::string>::iterator it;
      for (it=options.begin(); it != options.end(); it++)
        f << (*it).first << "=" << (*it).second << "\n";
      f.close();
      return true;
    }
    fprintf (stderr, "Unable to save config (%s).\n",cfg_path.c_str());
    return false;
  }
  
  // load config file
  bool load()
  {
    std::string line;
    std::ifstream f (cfg_path.c_str());
    if (f.is_open())
    {
      while (! f.eof() )
      {
        getline (f,line);
        size_t pos = line.find_first_of('=');
        set(line.substr(0,pos) , line.substr(pos+1, line.length() - pos));
      }
      f.close();
      return true;
    }
    if (save()) // config didn't open, save a new one
    {
      printf ("Created new config (%s).\n",cfg_path.c_str());
      return true;
    }
    fprintf (stderr, "Unable to load config (%s).\n",cfg_path.c_str());
    return false;
  }
  
  
  
private:
  
  std::string cfg_path;
  std::map<std::string, std::string> options;
  
  void init(std::string config_file_name)
  {
    std::string win_env("$APPDATA");
    std::string env("$HOME");
    char p[FL_PATH_MAX];
    fl_filename_expand(p, win_env.c_str());
    if (win_env == p) fl_filename_expand(p, env.c_str());
    cfg_path = p;
    cfg_path += (p[0] == '/' ? "/" : "\\");
    cfg_path += config_file_name;
  }
  
  
};

#endif
