/*
 * This file is part of the apvlv package
 *
 * Copyright (C) 2008 Alf.
 *
 * Contact: Alf <naihe2010@126.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.0 of
 * the License, or (at your option) any later version.
 *
 * This program 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
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */
/* @CPPFILE ApvlvParams.cc
 *
 *  Author: Alf <naihe2010@126.com>
 */
/* @date Created: 2008/09/30 00:00:00 Alf */

#include "ApvlvUtil.h"
#include "ApvlvCmds.h"
#include "ApvlvParams.h"

#include <iostream>
#include <fstream>
#include <sstream>

namespace apvlv
{
#if __cplusplus > 199711L
  ApvlvParams *gParams = nullptr;
#else
  ApvlvParams *gParams = NULL;
#endif

  ApvlvParams::ApvlvParams ()
  {
    push ("inverted", "no");
    push ("fullscreen", "no");
    push ("zoom", "fitwidth");
    push ("continuous", "yes");
    push ("autoscrollpage", "yes");
    push ("autoscrolldoc", "yes");
    push ("continuouspad", "2");
    push ("noinfo", "no");
    push ("width", "800");
    push ("height", "600");
    push ("content", "yes");
    push ("cache", "no");
    push ("pdfcache", "4");
    push ("scrollbar", "no");
    push ("visualmode", "no");
    push ("warpscan", "yes");
    push ("commandtimeout", "1000");
    push ("doubleclick", "page");
#ifdef WIN32
    push ("defaultdir", "C:\\");
#else
    push ("defaultdir", "/tmp");
#endif
    push ("guioptions", "");
    push ("autoreload", "3");
  }

  ApvlvParams::~ApvlvParams ()
  {
    mSettings.clear ();
  }

  bool ApvlvParams::loadfile (const char *filename)
  {
#if __cplusplus > 199711L
    if (filename == nullptr
#else
	if (filename == NULL
#endif
	    || g_file_test (filename, G_FILE_TEST_IS_REGULAR) == FALSE)
	  {
	    return false;
	  }

	//    debug ("load debug: %s", filename);
	string str;
	fstream os (filename, ios::in);

	if (!os.is_open ())
	  {
	    errp ("Open configure file %s error", filename);
	    return false;
	  }

	while ((getline (os, str)))
	  {
	    string argu, data, crap;
	    stringstream is (str);
	    // avoid commet line, continue next
	    is >> crap;
	    if (crap[0] == '\"' || crap == "")
	      {
		continue;
	      }
	    // parse the line like "set fullscreen=yes" or set "set zoom=1.5"
	    else if (crap == "set")
	      {
		is >> argu;
		size_t off = argu.find ('=');
		if (off == string::npos)
		  {
		    is >> crap >> data;
		    if (crap == "=")
		      {
			push (argu.c_str (), data.c_str ());
			continue;
		      }
		  }
		else if (off < 32)
		  {
		    char k[32], v[32], *p;
		    memcpy (k, argu.c_str (), off);
		    k[off] = '\0';

		    p = (char *) argu.c_str () + off + 1;
		    while (isspace (*p))
		      {
			p++;
		      }

		    g_snprintf (v, sizeof v, "%s", *p ? p : "");

		    p = (char *) v + strlen (v) - 1;
		    while (isspace (*p) && p >= v)
		      {
			p--;
		      }
		    *(p + 1) = '\0';

		    push (k, v);
		    continue;
		  }

		errp ("Syntax error: set: %s", str.c_str ());
	      }
	    // like "map n next-page"
	    else if (crap == "map")
	      {
		is >> argu;

		if (argu.length () == 0)
		  {
		    errp ("map command not complete");
		    continue;
		  }

		getline (is, data);

		while (data.length () > 0 && isspace (data[0]))
		  data.erase (0, 1);

		if (argu.length () > 0 && data.length () > 0)
		  {
                    ApvlvCmds::buildmap (argu.c_str (), data.c_str ());
		  }
		else
		  {
		    errp ("Syntax error: map: %s", str.c_str ());
		  }
	      }
	    else
	      {
		errp ("Unknown rc command: %s: %s", crap.c_str (), str.c_str ());
	      }
	  }

	return true;
	}

    bool ApvlvParams::push (const char *c, const char *s)
    {
      string cs (c), ss (s);
      mSettings[cs] = ss;
      return true;
    }

    bool ApvlvParams::push (string & ch, string & str)
    {
      mSettings[ch] = str;
      return true;
    }

    const char *ApvlvParams::values (const char *s)
    {
      string ss (s);
      map < string, string >::iterator it;
      it = mSettings.find (ss);
      if (it != mSettings.end ())
	{
	  return it->second.c_str ();
	}
#if __cplusplus > 199711L
      return nullptr;
#else
      return NULL;
#endif
    }

    int ApvlvParams::valuei (const char *s)
    {
      string ss (s);
      map < string, string >::iterator it;
      it = mSettings.find (ss);
      if (it != mSettings.end ())
	{
	  return atoi (it->second.c_str ());
	}
      return -1;
    }

    double ApvlvParams::valuef (const char *s)
    {
      string ss (s);
      map < string, string >::iterator it;
      it = mSettings.find (ss);
      if (it != mSettings.end ())
	{
	  return atof (it->second.c_str ());
	}
      return -1.0;
    }

    bool ApvlvParams::valueb (const char *s)
    {
      string ss (s);
      map < string, string >::iterator it;
      it = mSettings.find (ss);
      if (it != mSettings.end () && it->second.compare ("yes") == 0)
	{
	  return true;
	}
      return false;
    }
  }

  // Local Variables:
  // mode: c++
  // End:
