/*
 * 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
{
    ApvlvParams *gParams = nullptr;

    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 ("fix_width", "0");
      push ("fix_height", "0");
      push ("content_follow_mode", "file");
      push ("background", "");
      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 (filename == nullptr
          || 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.empty ())
            {
              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);
      auto it = mSettings.find (ss);
      if (it != mSettings.end ())
        {
          return it->second.c_str ();
        }
      return nullptr;
    }

    int ApvlvParams::valuei (const char *s)
    {
      string ss (s);
      auto it = mSettings.find (ss);
      if (it != mSettings.end ())
        {
          return int (strtol (it->second.c_str (), nullptr, 10));
        }
      return -1;
    }

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

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