/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Authors: Jean Le Feuvre
 *			Copyright (c) Telecom ParisTech 2000-2012
 *					All rights reserved
 *
 *  This file is part of GPAC / common tools sub-project
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  GPAC 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#ifndef _GF_CONFIG_FILE_H_
#define _GF_CONFIG_FILE_H_

#ifdef __cplusplus
extern "C" {
#endif

/*!
 *	\file <gpac/config_file.h>
 *	\brief configuration file.
 */

/*!
*	\addtogroup cfg_grp Configuration File
*	\ingroup utils_grp
*	\brief Configuration File object
*
*	This section documents the configuration file object of the GPAC framework.
*	This file is formatted as the INI file mode of WIN32 in sections and keys.\n
*\note For more information on the GPAC configuration file itself, please refer to the GPAC configuration help provided with GPAC.
*	@{
*/

#include <gpac/tools.h>


typedef struct __tag_config GF_Config;

/*!
 *	\brief configuration file initialization
 *
 * Constructs a configuration file from fileName. If fileName is NULL, the default GPAC configuration file is loaded with the
 * proper module directory, font directory and other default options. If fileName is non-NULL no configuration file is found,
 * a "light" default configuration file is created.
 *\param file name of the configuration file, or NULL for default file
 *\param new_cfg Boolean set to true if a new configuration file has been created
 *\return the configuration file object, NULL if the file could not be created
 */
GF_Config *gf_cfg_init(const char *file, Bool *new_cfg);

/*!
 *	\brief configuration file constructor
 *
 * Constructs a configuration file.
 *\param filePath directory the file is located in
 *\param fileName name of the configuration file
 *\return the configuration file object, NULL if the file does not exist
 */
GF_Config *gf_cfg_new(const char *filePath, const char *fileName);
/*!
 *	\brief alternative configuration file constructor
 *
 * Constructs a configuration file. If file does not exist, configuration will be still created
 *\param filePath directory the file is located in
 *\param fileName name of the configuration file
 *\return the configuration file object, never NULL, even if file does not exist
 */
GF_Config *gf_cfg_force_new(const char *filePath, const char *fileName);
/*!
 *	\brief configuration file destructor
 *
 *Destroys the configuration file and saves it if needed.
 *\param cfgFile the target configuration file
 */
void gf_cfg_del(GF_Config *cfgFile);
/*!
 *	\brief configuration file destructor
 *
 *Destroys the configuration file and removes the file  from disk.
 *\param cfgFile the target configuration file
 */
void gf_cfg_remove(GF_Config *cfgFile);
/*!
 *	\brief configuration saving
 *
 *Saves the configuration file if modified.
 *\param cfgFile the target configuration file
 */
GF_Err gf_cfg_save(GF_Config *cfgFile);
/*!
 *	\brief key value query
 *
 *Gets a key value from its section and name.
 *\param cfgFile the target configuration file
 *\param secName the desired key parent section name
 *\param keyName the desired key name
 *\return the desired key value if found, NULL otherwise.
 */
const char *gf_cfg_get_key(GF_Config *cfgFile, const char *secName, const char *keyName);
/*!
 *	\brief key value query ignoring case
 *
 *Gets a key value from its section and name. Comparison is performed while ignoring case.
 *\param cfgFile the target configuration file
 *\param secName the desired key parent section name (case ignored)
 *\param keyName the desired key name (case ignored)
 *\return the desired key value if found, NULL otherwise.
 */
const char *gf_cfg_get_ikey(GF_Config *cfgFile, const char *secName, const char *keyName);
/*!
 *	\brief key value update
 *
 *Sets a key value from its section and name.
 *\param cfgFile the target configuration file
 *\param secName the desired key parent section name
 *\param keyName the desired key name
 *\param keyValue the desired key value
 *\note this will also create both section and key if they are not found in the configuration file
 */
GF_Err gf_cfg_set_key(GF_Config *cfgFile, const char *secName, const char *keyName, const char *keyValue);
/*!
 *	\brief section count query
 *
 *Gets the number of sections in the configuration file
 *\param cfgFile the target configuration file
 *\return the number of sections
 */
u32 gf_cfg_get_section_count(GF_Config *cfgFile);
/*!
 *	\brief section name query
 *
 *Gets a section name based on its index
 *\param cfgFile the target configuration file
 *\param secIndex 0-based index of the section to query
 *\return the section name if found, NULL otherwise
 */
const char *gf_cfg_get_section_name(GF_Config *cfgFile, u32 secIndex);
/*!
 *	\brief key count query
 *
 *Gets the number of keys in a section of the configuration file
 *\param cfgFile the target configuration file
 *\param secName the target section
 *\return the number of keys in the section
 */
u32 gf_cfg_get_key_count(GF_Config *cfgFile, const char *secName);
/*!
 *	\brief key count query
 *
 *Gets the number of keys in a section of the configuration file
 *\param cfgFile the target configuration file
 *\param secName the target section
 *\param keyIndex 0-based index of the key in the section
 *\return the key name if found, NULL otherwise
 */
const char *gf_cfg_get_key_name(GF_Config *cfgFile, const char *secName, u32 keyIndex);

/*!
 *	\brief key insertion
 *
 *Inserts a new key in a given section. Returns an error if a key with the given name
 *already exists in the section
 *\param cfgFile the target configuration file
 *\param secName the target section
 *\param keyName the name of the target key
 *\param keyValue the value for the new key
 *\param index the 0-based index position of the new key
 */
GF_Err gf_cfg_insert_key(GF_Config *cfgFile, const char *secName, const char *keyName, const char *keyValue, u32 index);

/*!
 *	\brief section destrouction
 *
 *Removes all entries in the given section
 *\param cfgFile the target configuration file
 *\param secName the target section
 */
void gf_cfg_del_section(GF_Config *cfgFile, const char *secName);

/*!
 * get a sub key (separator is ':') in a given key in a given section. Returns an error if the key does not exist
 *\param cfgFile the target configuration file
 *\param secName the target section
 *\param keyName the name of the target key
 *\param sub_index the 0-based index position of the sub key*/
const char *gf_cfg_get_sub_key(GF_Config *cfgFile, const char *secName, const char *keyName,u32 sub_index);

/*!
 * Get the full filename associated with this config file
 * The caller is responsible for freeing memory
 * \param iniFile The Configuration
 * \return a newly allocated filename
 */
char * gf_cfg_get_filename(GF_Config *iniFile);

/*!
 * Set the full filename associated with this config file
 * \param iniFile The Configuration
 * \param fileName new filename for the config
 * \return erroro code
 */
GF_Err gf_cfg_set_filename(GF_Config *iniFile, const char * fileName);


/*!
 * Do not save results to file
 * \param iniFile The Configuration
 * \return error code
 */
GF_Err gf_cfg_discard_changes(GF_Config *iniFile);

/*! @} */

#ifdef __cplusplus
}
#endif


#endif		/*_GF_CONFIG_FILE_H_*/

