/*
This source file is part of Scol
For the latest info, see http://www.scolring.org

Copyright (c) 2011 Stephane Bisaro, aka Iri <iri@irizone.net>

This program 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 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt

For others informations, please contact us from http://www.scolring.org/
*/


#include "main.h"

#if defined _WIN32 || defined __WIN32__
cbmachine ww;
#endif
mmachine  mm;

/* PRIVATE */





/*
void s_xml_cb_isStandAlone (void *user_data)
{
    int cb;
    xmlParserCtxtPtr xml;
    s_xml s;
    mmachine m;

    xml = (xmlParserCtxtPtr) user_data;
    s = xml->userData;
    m = s->sub->sm;

    MMechostr(MSKDEBUG, "s_xml_cb_isStandAlone : entering ...\n");

    cb = OBJbeginreflex (m, ObjSax2, (int) s, S_LIBXML2_CB_ISTANDALONE);
    if (cb)
    {
        MMechostr (0, "s_xml_cb_isStandAlone : no callback 'IS_STANDALONE' defined, error %d\n", cb);
        return;
    }

    MMpush (m, ITOM (xml->standalone));
    OBJcallreflex (m, 1);
    return;
}
*/




/*res = xmlParseDocument (s->xml);
    if ((res == -1) || (s->xml->wellFormed != 1))
    {
        MMechostr(MSKDEBUG, "S_xml2ReadFromFile error : xml resource not loaded\n");
        MMpull (m);
        MMpush (m, NIL);
        return 0;
    }*/

int s_xml2read (xmlParserCtxtPtr xml)
{
    int res;

    /*if (flag == 0)
        return xmlSAXUserParseFile (&(s->sax), s, s->filename);

    else if (flag == 1)
    {
        int len;

        len = strlen (s->buffer);
        return xmlSAXUserParseMemory (&(s->sax), s, s->buffer, len);
    }
    else
        return (int) NULL;*/

    /*if (flag == 0)
        s->xml = xmlCreateFileParserCtxt (s->sub->filename);
    else if (flag == 1)
        s-> xml = xmlCreateMemoryParserCtxt (s->sub->buffer, strlen (s->sub->buffer));
    else
        return (int) NULL;*/

    /*s->xml->sax = (&(s->sax));
    s->xml->userData = (void *) s->sub;*/
    res = xmlParseDocument (xml);

    return res;
}






int S_xml2Read2 (mmachine m)
{
    int ms;
    xmlParserCtxtPtr xml;
    s_xml s;

    MMechostr(MSKDEBUG, "S_xml2Read : entering ...\n");

    ms = MMpull (m);
    if (ms == NIL)
    {
        MMechostr(MSKDEBUG, "S_xml2Read error : object is nil\n");
        MMpush (m, NIL);
        return 0;
    }

    xml = (xmlParserCtxtPtr) MMfetch (m, MTOP (ms), S_LIBSAX2_HANDLE);
    /*s = xml->userData;*/
    int res = xmlParseDocument (xml);
MMechostr(MSKDEBUG, "S_xml2Read : res = %d \n", res);
    /*if (xmlCtxtReadFile (xml, s->sub->filename, NULL, XML_PARSE_DTDVALID) == NULL)
    {
        MMechostr(MSKDEBUG, "S_xml2Read error : unable to parse\n");
        MMpush (m, NIL);
        return 0;
    }*/
    MMpush (m, 0);
    return 0;
}


int S_xml2CreateFromFile2 (mmachine m)
{
    int mchannel, mfile;
    xmlParserCtxtPtr xml;
    s_xml s;

    MMechostr(MSKDEBUG, "S_xml2CreateFromFile : entering ...\n");

    mfile = MMpull (m);
    mchannel = MMget (m, 0);

    if (mchannel == NIL)
    {
        MMechostr(MSKDEBUG, "S_xml2CreateFromFile error : channel is nil\n");
        MMpull (m);
        MMpush (m, NIL);
        return 0;
    }
    else if (mfile == NIL)
    {
        MMechostr(MSKDEBUG, "S_xml2CreateFromFile error : the file is nil\n");
        MMpull (m);
        MMpush (m, NIL);
        return 0;
    }

    s = malloc (sizeof (struct S_xml));
    if (s == NULL)
    {
        MMechostr(MSKDEBUG, "S_xml2CreateFromFile error : not enough memory\n");
        MMpull (m);
        MMpush (m, NIL);
        return 0;
    }
    s->sub = malloc (sizeof (struct Subxml));
    /*s->sub->filename = malloc (sizeof (char) * (MMsizestr (m,MTOP (mfile))+32));
    s_xml2_replaceFilename (MMstartstr (m, MTOP (mfile)), (&(s->sub->filename)));*/
    s->sub->filename = MMstartstr (m, MTOP (mfile));

    /*s->sax = { 0 };*/
    s->sub->sm = m;
    xml = xmlCreateFileParserCtxt (s->sub->filename);
    /*xml = xmlNewParserCtxt ();*/
    if (xml == NULL)
    {
        MMechostr(MSKDEBUG, "S_xml2CreateFromFile error : xml resource not loaded\n");
        MMpull (m);
        MMpush (m, NIL);
        return 0;
    }

    xmlSAXHandler sax = { 0 };
    /*sax.startDocument = s_xml2_cb_documentStart;
    xml->sax = &sax;*/
    /*xml->sax->startDocument = s_xml2_cb_documentStart;*/
    xml->sax = (&(s->sax));
   /* xml->sax->startDocument = s_xml2_cb_documentStart;*/
    xml->userData = (void *) s;

    /*xmlSAXUserParseFile (s->sax, s, s->filename);*/
    /*s->xml->sax = &sax;*/

    /*res = xmlParseDocument (s->xml);
    if ((res == -1) || (s->xml->wellFormed != 1))
    {
        MMechostr(MSKDEBUG, "S_xml2ReadFromFile error : xml resource not loaded\n");
        MMpull (m);
        MMpush (m, NIL);
        return 0;
    }*/

    s_xml2create_object (m, xml);
    return 0;
}












int XML2Version (mmachine m)
{
    MMechostr (MSKDEBUG, "XML2Version : entering\n");

    MMpush (m, LIBXML_VERSION);
    return 0;
}







char* libxml2common_name[COMMON_LIBXML2_PKG_NB] =
{
    "_xml2Version"
};

int (*libxml2common_fun[COMMON_LIBXML2_PKG_NB]) (mmachine m) =
{
    XML2Version
};

int libxml2common_narg[COMMON_LIBXML2_PKG_NB] =
{
    0   /* _xml2Version */
};

char* libxml2common_type[COMMON_LIBXML2_PKG_NB] =
{
    "fun [] I"                          /* _xml2Version */
};

int COMMON_loadPackage (mmachine m)
{
    int k = 0;
    k = PKhardpak (m, "LIBXML2_COMMONengine", COMMON_LIBXML2_PKG_NB, libxml2common_name, libxml2common_fun, libxml2common_narg, libxml2common_type);
    return k;
}










/* loads xml2 scol apis */
int SCOLinitLIBXML2class (mmachine m)
{
    int k = 0;

    MMechostr (MSKDEBUG, "SCOLinitLIBXML2class library : entering\n");

    /* hack MS Windows */
    if (!xmlFree)
        xmlMemGet (&xmlFree, &xmlMalloc, &xmlRealloc, NULL);

    if ((k = COMMON_loadPackage (m))) return k;
    if ((k = SSAX_loadPackage (m))) return k;
    if ((k = READER_loadPackage (m))) return k;
    if ((k = TREE_loadPackage (m))) return k;
    return k;
}


/* Hard load and unload the library */
#if defined _WIN32 || defined __WIN32__

#define SCOL_LIBXML2_PLUGIN_EXPORT __declspec (dllexport)
#define SCOL_LIBXML2_PLUGIN_EXPORT_ARG (mmachine m, cbmachine w)

#elif defined linux || defined __linux

#define SCOL_LIBXML2_PLUGIN_EXPORT
#define SCOL_LIBXML2_PLUGIN_EXPORT_ARG (mmachine m)

#else

#error no platform supported

#endif

SCOL_LIBXML2_PLUGIN_EXPORT int ScolLoadPlugin SCOL_LIBXML2_PLUGIN_EXPORT_ARG
{
    ww = w;
    mm = m;

    SCOLinitplugin (w);
    return SCOLinitLIBXML2class (m);
}


SCOL_LIBXML2_PLUGIN_EXPORT int ScolUnloadPlugin()
{
    xmlCleanupParser ();
    xmlMemoryDump ();
    MMechostr (MSKDEBUG, "LIBXML2 library : released\n");
    return 0;
}
