/*  $Id: conf.c,v 1.20 2005/03/02 21:07:12 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. 
 */

#include <stdlib.h>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */

#include "lingoteach.h"
#include "lesson.h"
#include "conf.h"

/********************
 * public functions *
 ********************/

/**
 * 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)
{
     lingPrivateConfig *data = NULL;
     lingConfig *settings = NULL;
     xmlDocPtr lang = NULL;
     xmlValidCtxtPtr val = xmlNewValidCtxt ();

     if (!val)
        return NULL;

     data = malloc (sizeof (lingPrivateConfig));
     if (!data)
          return NULL;

     settings = malloc (sizeof (lingConfig));
     if (!settings)
     {
          free (data);
          return NULL;
     }
     settings->pdata = data;

     /* set application name and file */
     settings->appname = xmlStrdup (name);
     settings->langfile = xmlStrdup (file);
     
     /* load both DTDs */
     data->lang_dtd = xmlParseDTD (NULL, lang_dtd);
     if (!data->lang_dtd)
     {
          ling_conf_free_config (settings);
          return NULL;
     }

     data->lesson_dtd = xmlParseDTD (NULL, lesson_dtd);
     if (!data->lesson_dtd)
     {
          ling_conf_free_config (settings);
          return NULL;
     }

     /* build XPath context pointer for the language file */
     lang = xmlParseFile (file);
     if (!lang)
     {
          ling_conf_free_config (settings);
          return NULL;
     }

     /* validate the file first */
     if (!xmlValidateDtd (val, lang, data->lang_dtd))
     {
          xmlFreeDoc (lang);
          ling_conf_free_config (settings);
          xmlFreeValidCtxt (val);
          return NULL;
     }
     xmlFreeValidCtxt (val);
     
     data->lang = lesson_get_xpath (lang);
     if (!data->lang)
     {
          xmlFreeDoc (lang);
          ling_conf_free_config (settings);
          return NULL;
     }
     return settings;
}

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

     if (settings->appname)
          xmlFree (settings->appname);

     if (settings->langfile)
          xmlFree (settings->langfile);

     if (settings->pdata)
     {
          priv = settings->pdata;
          if (priv->lang)
               xmlXPathFreeContext (priv->lang);

          if (priv->lang_dtd)
               xmlFreeDtd (priv->lang_dtd);
          
          if (priv->lesson_dtd)
               xmlFreeDtd (priv->lesson_dtd);
     }
     free (settings->pdata);
     free (settings);
     return;
}
