/* 
 * $Id: MyGLSDImportModule.cpp,v 1.7 2006/03/05 05:00:09 ozawa Exp $
 *
 * GLSD external sample module program.
 *
 * Copyright 2005- ONGS Inc.
 * 
 * author: Masanori OZAWA (ozawa@ongs.co.jp)
 * version: $Revision: 1.7 $
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY ONGS INC ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL ONGS INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * The views and conclusions contained in the software and documentation are
 * those of the authors and should not be interpreted as representing official
 * policies, either expressed or implied, of the ONGS Inc.
 * 
 */

#include "xdtptypes.h"
#include "MyGLSDImportModule.h"

#include "Utilities.h"
#include "URLTool.h"
#include "XMLTool.h"

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// MyGLSDImportModule

MyGLSDImportModule::MyGLSDImportModule()
{
}

MyGLSDImportModule::~MyGLSDImportModule()
{
}

void MyGLSDImportModule::treatPostDocument(xmlDocPtr aDocument)
{
    GLSDImportModuleAdapter::treatPostDocument(aDocument);

    int count;
    XDTP::XMLTool tool;
    xmlNodePtr root = xmlDocGetRootElement(aDocument);
    xmlNodeSetPtr nodes;
    xmlXPathObjectPtr obj = tool.getNodeList(root, "//import[@type=\"text/import-test\"]");

    if (obj) {
        nodes = obj->nodesetval;
        
        for (count = 0; count < nodes->nodeNr; count++) {
            if (!transform(aDocument, nodes->nodeTab[count])) {
                THROW("MyGLSDImportModule: transform failed.");
            }
        }
        
        xmlXPathFreeObject(obj);
    }
}

bool MyGLSDImportModule::transform(xmlDocPtr aDocument, xmlNodePtr aNode)
{
    Glib::ustring ref;
    Glib::ustring caption;
    Glib::ustring encoding;

    if (!getImportAttributes(aNode, ref, caption, encoding)) {
        return false;
    }
    
    if ("html" == m_OutputType) {
        return tohtml(aDocument, aNode, ref, caption, encoding);
    }
    // otherwise, no operation.
    
    return true;
}

bool MyGLSDImportModule::tohtml
    (xmlDocPtr aDocument, xmlNodePtr aNode,
     const Glib::ustring& aRef,
     const Glib::ustring& aCaption,
     const Glib::ustring& anEncoding)
{
    // get stylesheet
    xmlNodePtr comment = getStyleSheet(aDocument, "text/css");

    if (comment) {
        Glib::ustring content = (comment->content ? (const char*)comment->content : "");
        Glib::ustring::size_type pos = content.find("pre.import-test");
        
        if (Glib::ustring::npos == pos) {
            content += LINE_SEP;
            content += "   pre.import-test {" LINE_SEP;
            content += "     text-align: left;" LINE_SEP;
            content += "     border: solid thin silver;" LINE_SEP;
            content += "     margin: 1.0em 0 0 0;" LINE_SEP;
            content += "     padding: 0.5em 1.0em 1.0em 0.5em;" LINE_SEP;
            content += "   }" LINE_SEP;
            content += "   div.import-test {" LINE_SEP;
            content += "     text-align: center;" LINE_SEP;
            content += "     margin: 0.5em 0 1.5em 0;" LINE_SEP;
            content += "     overflow: auto;" LINE_SEP;
            content += "   }" LINE_SEP;
            xmlNodeSetContent(comment, (const xmlChar*)content.c_str());
        }
    }
    
    // import file
    xmlNodePtr pre = xmlNewNode(NULL, (const xmlChar*)"pre");
    if (!pre) THROW("Out of memory!");
    xmlSetProp(pre, (const xmlChar*)"class", (const xmlChar*)"import-test");
    xmlAddChild(pre, xmlNewText((const xmlChar*)LINE_SEP));
    
    bool bSuccess = false;
    std::string tmpfile;
    try {
        Glib::RefPtr<Glib::IOChannel> ioc = getIOChannel(aRef, tmpfile);
        setEncoding(ioc, anEncoding);
        
        Glib::ustring line;
        
        while (ioc->read_line(line) == Glib::IO_STATUS_NORMAL) {
            xmlAddChild(pre, xmlNewText((const xmlChar*)line.c_str()));
        }
        ioc->close();

		bSuccess = true;
    }
    catch (XDTP::Exception exception) {
        exception.print(stderr);
    }
    catch (Glib::Error error) {
        std::string msg = Glib::locale_from_utf8(error.what());
        fprintf(stderr, "%s (%s)" LINE_SEP, msg.c_str(), aRef.c_str());
    }
	catch (std::exception exception) {
		fprintf(stderr, "%s (%s)" LINE_SEP, exception.what(), aRef.c_str());
	}
    catch (...) {
        fprintf(stderr, "MyGLSDImportModule: unknown error occured. (%s)" LINE_SEP,
				aRef.c_str());
    }

    if (0 < tmpfile.length()) {
        remove(tmpfile.c_str());
    }
    if (!bSuccess) return false;

    xmlNodePtr block = xmlNewNode(NULL, (const xmlChar*)"blockquote");
    if (!block) {
		xmlFreeNode(pre);
		THROW("Out of memory!");
	}
    xmlSetProp(block, (const xmlChar*)"cite", (const xmlChar*)aRef.c_str());
    xmlAddChild(block, pre);

    xmlNodePtr title = xmlNewNode(NULL, (const xmlChar*)"div");
    if (!title) {
		xmlFreeNode(block);
		THROW("Out of memory!");
	}
    xmlSetProp(title, (const xmlChar*)"class", (const xmlChar*)"import-test");
    xmlAddChild(title, xmlNewText((const xmlChar*)("XML Source " + aCaption).c_str()));
    
    xmlFreeNode(xmlReplaceNode(aNode, title));
    
    xmlAddPrevSibling(title, block);
    
    return true;
}


syntax highlighted by Code2HTML, v. 0.9.1