/*  $Id: lingoteach.h,v 1.41 2005/04/21 14:47:46 marcusva Exp $
 *  
 *  This file is part of LingoTeach, the Language Teaching program 
 *  Copyright (C) 2001-2004 Marcus von Appen. All rights reserved.
 *
 *  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 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., 675 Mass Ave, Cambridge, MA 02139, USA. 
 */

#ifndef LINGOTEACH_H
#define LINGOTEACH_H 1

#include <stdlib.h>
#include "lingdefs.h"

BEGIN_C_DECLS

/* 
 *  This file defines all functions that can be used to access
 *  data. No XML filenames should be ever visible outside this module.
 */

/**
 * Creates a new, empty lingConfig for usage.
 * The lingConfig should be freed using ling_conf_free_config().
 *
 * \param name The name of the application, which uses the library.
 * \param file The file, which contains the languages.
 * \param lang_dtd The DTD file, the language file has to validate against.
 * \param lesson_dtd The DTD file, the lessons have to validate against.
 *
 * \return A new lingConfig.
 */
lingConfig*
ling_conf_init_config (lingchar *name, lingchar *file,
                       const lingchar *lang_dtd, const lingchar *lesson_dtd);

/**
 * Frees the memory hold by a lingConfig.
 *
 * \param settings The lingConfig to free.
 */
void
ling_conf_free_config (lingConfig *settings);

/**
 * Gets a NULL terminated list of the available languages (based on the
 * language file set in the lingConfig). The return value should be freed 
 * using ling_strings_free().
 *
 * \param settings The lingConfig to use for looking up the languages.
 * \return A NULL terminated list of the languages.
 */
lingchar**
ling_lang_get_languages (lingConfig *settings);

/**
 * Gets the amount of languages contained in a lingConfig.
 *
 * \param settings The lingConfig to use for looking up the languages.
 * \return The total amount of languages or -1 on failure.
 */
int
ling_lang_get_language_amount (lingConfig *settings);

/**
 * Gets the translation of a language (based on the language
 * file set in the lingConfig). The return value should be freed using
 * ling_free().
 *
 * \param settings The lingConfig to use for looking up the languages.
 * \param language The language to translate.
 * \param translation The language, in which the translation should be 
 * returned.
 * \return A language translation or NULL, if none found or an error occured.
 */
lingchar*
ling_lang_get_lang_translation (lingConfig *settings, lingchar *language,
				lingchar *translation);

/**
 * Gets the language id of a translated language (based on the 
 * file set in the lingConfig). The return value should be freed using
 * ling_free().
 *
 * \param settings The lingConfig to use for looking up the languages.
 * \param translation The translated language.
 * \param language The language which was used for the translation.
 *
 * \return A language id or NULL, if none found or an error occured.
 */
lingchar*
ling_lang_get_trans_language (lingConfig *settings, lingchar *translation,
                              lingchar *language);

/**
 * Gets a list of translations of a passed language list (based on the 
 * language file set in the lingConfig). The return value should be freed 
 * using ling_strings_free().
 *
 * \param settings The lingConfig to use for looking up the languages.
 * \param languages The language list to translate.
 * \param translation The language, in which the translation should be 
 * returned.
 * \return A NULL terminated list of language translations.
 */
lingchar**
ling_lang_get_lang_translations (lingConfig *settings, lingchar **languages,
				 lingchar *translation);

/**
 * Creates a new, empty lingLesson. 
 * The lingLesson should be freed using ling_lesson_free().
 *
 * \return A new, empty lingLesson.
 */
lingLesson*
ling_lesson_new (void);

/**
 * Frees the memory hold by a lingLesson.
 *
 * \param lesson The lingLesson to free.
 */
void
ling_lesson_free (lingLesson *lesson);

/**
 * Creates a lingLesson from a lesson file.
 * 
 * \param filename The full qualified path of the file.
 * \param settings The settings to use for the lesson.
 * \return A new lingLesson.
 */
lingLesson*
ling_lesson_create (char *filename, lingConfig *settings);

/**
 * Adds a lingLesson to a list of lingLessons.
 *
 * \param list  The lesson list, the new lesson should be added to.
 * \param lesson The lesson to add.
 * \returns The modified list.
 */
lingLesson*
ling_lesson_add (lingLesson* list, lingLesson *lesson);

/**
 * Removes a lesson from a lingLesson list and frees it.
 *
 * \param lesson The lesson list to the lesson should be removed from.
 * \param node The lesson to remove.
 * \return The modified lesson list.
 */
lingLesson*
ling_lesson_remove (lingLesson *lesson, lingLesson *node);

/**
 * Returns the full qualified file path of the lesson.
 *
 * \param lesson The lesson for which the path should be returned.
 * \return The lesson path of the lesson.
 */
char*
ling_lesson_get_path (lingLesson *lesson);

/**
 * Sets the full qualified file path of the lesson to path and returns it.
 * The return value must not be freed.
 *
 * \param lesson The lesson for which the path should be set.
 * \param path The path to set.
 * \return The new path of the lesson or NULL on error.
 */
char*
ling_lesson_set_path (lingLesson *lesson, char *path);

/**
 * Returns the last meaning id of the given lesson.
 * 
 * \param lesson The lesson, for which the last meaning id should be returned.
 * \return The last meaning id of the lesson or -1 on failure.
 */
int
ling_lesson_get_last_meaning_id (lingLesson *lesson);

/**
 * Returns the total amount of meanings for the given lesson.
 *
 * \param lesson The lesson, the amount should be got for.
 * \return The total amount of meanings or -1 on failure.
 */
int
ling_lesson_get_meaning_amount (lingLesson *lesson);

/**
 * Returns the total amount of translations for the given lesson.
 *
 * \param lesson The lesson, the amount should be got for.
 * \return The total amount of translations or -1 on failure.
 */
int
ling_lesson_get_translation_amount (lingLesson *lesson);

/**
 * Saves a lesson into the passed file.
 * If the file does not exist, it will be automatically created, else
 * its contents will be completely overwritten.
 *
 * \param lesson The lesson to save.
 * \param filename The file to save the lesson to.
 * \return TRUE, if the lesson could be saved, else FALSE.
 */
lingbool
ling_lesson_save_lesson (lingLesson *lesson, char *filename);

/**
 * Creates a new template lesson with optional empty meanings. The function 
 * uses the application name specified in the settings as DTD indentifier.
 *
 * \param filename The lesson file to create.
 * \param meanings The amount of meaning templates to create.
 * \param settings The settings to use.
 * \return The filename on success or NULL in case of an error.
 */
char*
ling_lesson_create_template (char *filename, int meanings,
                             lingConfig *settings);

/**
 * Creates a linked list of all meanings, which are available in the given
 * lesson.
 * 
 * \param lesson The lesson, for which the meaning tree should be created.
 * \return A linked list of meanings of the lesson or NULL if an error occurs.
 */
lingMeaning*
ling_lesson_create_tree (lingLesson *lesson);

/**
 * Creates a new lingMeaning and returns it. 
 * The lingMeaning has to be freed by the user.
 *
 * \return A new, empty lingMeaning.
 */
lingMeaning*
ling_meaning_new (void);

/**
 * Creates a new lingMInfo and returns it. 
 * The lingMInfo has to be freed by the user.
 *
 * \return A new, empty lingMinfo.
 */
lingMInfo*
ling_meaning_info_new (void);

/**
 * Searches for a lingMeaning, that is the same type as the one, that is passed
 * to it. This helps to make sure, that multiple choice answers are not 
 * obvious. (Currently not functional!).
 * The lingMeaning has to be freed by the user.
 *
 * \param meaning A lingMeaning, for which a similar one should be found.
 * \return A meaning that is the same type of thing as the one that
 * is passed to it.
 */
/*
  lingMeaning*
  ling_meaning_get_similar (lingMeaning *meaning);
*/

/**
 * Gets a specific lingMeaning from the given lesson.
 * The lingMeaning has to be freed by the user.
 * 
 * \param lesson The lesson to get the meaning from.
 * \param id The id, which should be searched for.
 * \param language The language, which should be used.
 * \return a lingMeaning containing the meaning, which has the given id.
 * If none is found with the given language, the function returns NULL.
 */
lingMeaning*
ling_meaning_get_by_id (lingLesson *lesson, unsigned int id,
                        lingchar *language);

/**
 * Retrieves additional information of a meaning and returns them.
 * It also fills the info member of the meaning with the return value.
 * Note: If you free the meaning, the lingMInfo return value will be freed,
 * too!
 * \param meaning The meaning, the information should be retrieved for.
 * \returns A lingMInfo with information about the meaning.
 */
lingMInfo*
ling_meaning_get_information (lingMeaning *meaning);

/**
 * Retrieves the additional description for a specific meaning. The return
 * value has to be freed by the user using ling_free().
 *
 * \param meaning The meaning to retrieve the description for.
 * \return The description of the meaning in the given language.
 */
lingchar* 
ling_meaning_get_description (lingMeaning *meaning);

/**
 * Retrieves the phonetic transcription for the meaning. The return value
 * has to be freed by the user using ling_free().
 *
 * \param meaning The meaning to retrieve the phonetic transcription for.
 * \return The phonetic transcription of a meaning translation.
 */
lingchar*
ling_meaning_get_phonetic (lingMeaning *meaning);

/**
 * Frees the memory used by a list of lingMeaning and the lingMeanings itself.
 *
 * \param meaning The meaning list to free.
 */
void
ling_meaning_free (lingMeaning *meaning);

/**
 * Frees the memory used by a lingMeaning and the lingMeaning itself.
 *
 * \param tree The list of meanings, in which the meanings is.
 * \param node The meaning, which should be freed.
 * \return The new list without the freed meaning.
 */
lingMeaning*
ling_meaning_free_1 (lingMeaning *tree, lingMeaning *node);

/**
 * Frees the memory used by a lingMInfo and the lingMInfo itself.
 * 
 * \param info The lingMInfo to free,
 */
void 
ling_meaning_info_free (lingMInfo *info);

/**
 * Creates a lingLesson from a list of meanings. The node format is 
 * the standard lingoteach lesson format.
 * 
 * \param meaning The list of meanings to put into the lingLesson.
 * \param settings The settings to use for the lingLesson.
 * \param type The type (name) of the lesson.
 * \param sound The sound subdirectory parameter of the lesson.
 * \return the new lingLesson or NULL in case of an error.
 */ 
lingLesson*
ling_meaning_create_lesson (lingMeaning *meaning, lingConfig *settings,
			    lingchar *type, lingchar *sound);

/**
 * Adds a new meaning at the end of the given meaning list.
 *
 * \param tree The meaning list to which the meaning should be added or NULL
 * to start a new list.
 * \param meaning The meaning to add to the tree.
 * \return The new, modified meaning tree.
 */
lingMeaning*
ling_meaning_add (lingMeaning *tree, lingMeaning *meaning);

/**
 * Inserts a meaning after specific meaning into a meaning list.
 *
 * \param tree The meaning list to which the meaning should be added.
 * \param parent The parent meaning, after which the child should be added.
 * \param child The meaning to add.
 * \return The new, modified tree.
 */
lingMeaning*
ling_meaning_insert_after (lingMeaning *tree, lingMeaning *parent,
                           lingMeaning *child);

/**
 * Replaces a meaning in the given list of meanings.
 *
 * \param tree The list of meanings in which the meaning exists.
 * \param id The id of the meaning, which should be replaced.
 * \param meaning The meaning to use as replacement.
 * \return The tree with the replaced meaning or NULL in case of an error.
 */
lingMeaning*
ling_meaning_replace (lingMeaning *tree, unsigned int id,
                      lingMeaning *meaning);

/**
 * Returns the path to the sound snippet for the given meaning.
 * The result has to be freed by the user.
 *
 * \param meaning The lingMeaning the sound snippet has to be found for.
 * \return The relative path to the sound snippet of the meaning.
 */
lingchar*
ling_meaning_get_sound (lingMeaning *meaning);

/**
 * Returns the path to the images for the given meaning. The result has to be 
 * freed by the user using ling_strings_free().
 * 
 * \param meaning The lingMeaning the images have to be found for.
 * \return A NULL-terminated array containing the full qualified paths
 * of the images for that meaning.
 */
lingchar**
ling_meaning_get_images (lingMeaning *meaning);

/**
 * Allocates a chunk of memory for usage.
 *
 * \param size The amount of bytes to allocate.
 * \return A pointer to the newly allocated space.
 */
void* 
ling_malloc (size_t size);

/**
 * Frees the memory hold by a pointer, which was previously allocated
 * using ling_malloc().
 *
 * \param ptr The pointer to free.
 */
void
ling_free (void *ptr);

/**
 * Frees an array of strings, which was previously allocated by the libraray.
 *
 * \param array The string array to free.
 */
void
ling_strings_free (lingchar **array);

END_C_DECLS

#endif /* LINGOTEACH_H */
