/* languagemanager.h
 *
 * Copyright (C) 2004-2005 Jae Jang
 * Copyright (C) 2005-2006 Rob Page
 * Copyright (C) 2006 Dodji Seketeli
 * Copyright (C) 2009, 2010, 2011 Krzesimir Nowak
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/// \file
/// \brief LanguageManager class

#include <vector>

#include <glibmm/object.h>
#include <gtksourceviewmm/language.h>

_DEFS(gtksourceviewmm,gtksourceview)
_PINCLUDE(glibmm/private/object_p.h)

namespace Gsv
{
_CC_INCLUDE(gtksourceview/gtksourcelanguagemanager.h)
_CC_INCLUDE(gtksourceview/gtksourceview-typebuiltins.h)

/** Class which provides access to SourceLanguages.
 *
 * LanguageManager is a class which processes language description files
 * and creates and stores Language objects, and provides API to access
 * them.
 *
 * Use get_default() to retrieve the default instance of LanguageManager,
 * and guess_language() to get a Language for given file name and content
 * type.
 */
class LanguageManager : public Glib::Object
{
  _CLASS_GOBJECT(LanguageManager, GtkSourceLanguageManager, GTK_SOURCE_LANGUAGE_MANAGER, Glib::Object, GObject)
protected:
  _CTOR_DEFAULT()

public:

  /** Creates a new language manager.
   *
   * If you do not need more than one language manager or a private language
   * manager instance then use get_default() instead.
   *
   * @return A LanguageManager.
   */
  _WRAP_CREATE()

  /** Returns the default LanguageManager instance.
   *
   * @return A LanguageManager.
   */
  _WRAP_METHOD(static Glib::RefPtr<LanguageManager> get_default(), gtk_source_language_manager_get_default, refreturn)

#m4 _CONVERSION(`const gchar**',`std::vector<std::string>',`Glib::ArrayHandler<std::string>::array_to_vector($3, Glib::OWNERSHIP_NONE)')

  /** Gets the list directories where language manager looks for language files.
   *
   * @return An array containg a list of language files directories.
   */
  _WRAP_METHOD(std::vector<std::string> get_search_path() const, gtk_source_language_manager_get_search_path)

#m4 _CONVERSION(`const std::vector<std::string>&',`gchar**',`const_cast<gchar**>(Glib::ArrayHandler<std::string>::vector_to_array($3).data())')

  /** Sets the list of directories where the language manager looks for language
   *  files.
   *
   * @note At the moment this function can be called only before the language
   * files are loaded for the first time. In practice to set a custom search
   * path for a LanguageManager, you have to call this function right
   * after creating it.
   *
   * @param dirs An empty string terminated array of strings.
   */
  _WRAP_METHOD(void set_search_path(const std::vector<std::string>& dirs), gtk_source_language_manager_set_search_path)

  /** Resets the list of directories where the language manager looks for
   *  language files to default.
   *
   * @note At the moment this function can be called only before the language
   * files are loaded for the first time. In practice to set a custom search
   * path for a LanguageManager, you have to call this function right
   * after creating it.
   */
  void reset_search_path();

  /** Returns the ids of the available languages.
   *
   * @return An array of string containing the ids of the available languages.
   */
  _WRAP_METHOD(std::vector<std::string> get_language_ids() const, gtk_source_language_manager_get_language_ids)

  /** Gets the Language identified by the given @a id in the language
   *  manager.
   *
   * @param id A language id.
   *
   * @return A Language, or empty Glib::RefPtr if there is no language
   * identified by the given @a id.
   */
  _WRAP_METHOD(Glib::RefPtr<Language> get_language(const std::string& id), gtk_source_language_manager_get_language, refreturn)

  /** Gets the Language identified by the given @a id in the language
   *  manager.
   *
   * @param id A language id.
   *
   * @return A Language, or empty Glib::RefPtr if there is no language
   * identified by the given @a id.
   */
  _WRAP_METHOD(Glib::RefPtr<const Language> get_language(const std::string& id) const, gtk_source_language_manager_get_language, constversion, refreturn)

  /** Picks a Language for given file name and content type,
   *  according to the information in lang files.
   *
   * Either @a filename or @a content_type may be an empty string. This function
   * can be used as follows:
   *
   * @code
   * Glib::RefPtr<Language> lang;
   * lang = lm->guess_language(filename, Glib::ustring());
   * buffer->set_language(lang);
   * @endcode
   *
   * or
   *
   * @code
   * Glib::RefPtr<Language> lang;
   * bool result_uncertain = FALSE;
   * Glib::ustring content_type;
   *
   * content_type = Gio::content_type_guess(filename, 0, 0, &result_uncertain);
   * if (result_uncertain)
   * {
   *   content_type.clear();
   * }
   *
   * lang = lm->guess_language(filename, content_type);
   * buffer->set_language(lang);
   * @endcode
   *
   * etc. Use get_mime_types() and get_globs() if you need full control over
   * file -> language mapping.
   *
   * @param filename A filename, or empty string.
   * @param content_type A content type (as in GIO API), or empty string.
   *
   * @return A Language, or empty Glib::RefPtr if there is no suitable
   * language for given @a filename and/or @a content_type.
   */
  _WRAP_METHOD(Glib::RefPtr<Language> guess_language(const std::string& filename, const std::string& content_type), gtk_source_language_manager_guess_language, refreturn)

  /** Picks a Language for given file name and content type,
   *  according to the information in lang files.
   *
   * Either @a filename or @a content_type may be an empty string. This function
   * can be used as follows:
   *
   * @code
   * Glib::RefPtr<LanguageManager> lm = LanguageManager::get_default();
   * Glib::RefPtr<Language> lang;
   * Glib::RefPtr<Buffer> buffer = Buffer::create();
   * lang = lm->guess_language(filename, Glib::ustring());
   * buffer->set_language(lang);
   * // or just:
   * // Glib::RefPtr<Buffer> buffer = Buffer::create(lang);
   * @endcode
   *
   * or
   *
   * @code
   * Glib::RefPtr<Language> lang;
   * Glib::RefPtr<LanguageManager> lm = LanguageManager::get_default();
   * Glib::RefPtr<Buffer> buffer = Buffer::create();
   * bool result_uncertain = FALSE;
   * Glib::ustring content_type;
   *
   * content_type = Gio::content_type_guess(filename, 0, 0, &result_uncertain);
   * if (result_uncertain)
   * {
   *   content_type.clear();
   * }
   *
   * lang = lm->guess_language(filename, content_type);
   * buffer->set_language(lang);
   * // or just:
   * // Glib::RefPtr<Buffer> buffer = Buffer::create(lang);
   * @endcode
   *
   * etc. Use Language::get_mime_types() and Language::get_globs()
   * if you need full control over file -> language mapping.
   *
   * @param filename A filename, or empty string.
   * @param content_type A content type (as in GIO API), or empty string.
   *
   * @return A Language, or empty Glib::RefPtr if there is no suitable
   * language for given @a filename and/or @a content_type.
   */
  _WRAP_METHOD(Glib::RefPtr<const Language> guess_language(const std::string& filename, const std::string& content_type) const, gtk_source_language_manager_guess_language, refreturn, constversion)

  _WRAP_PROPERTY("search-path", std::vector<std::string>)
  _WRAP_PROPERTY("language-ids", std::vector<std::string>)
};

} /* namespace Gsv */

