/* 
 * $Id: ImportImage.cpp,v 1.14 2006/03/05 05:00:09 ozawa Exp $
 *
 * Copyright 2005- ONGS Inc. All rights reserved.
 * 
 * author: Masanori OZAWA (ozawa@ongs.co.jp)
 * version: $Revision: 1.14 $
 *
 * 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 "xdtp.h"
#include "modules/imports/ImportImage.h"
#include "URI.h"
#include "Utilities.h"
#include "URLTool.h"
#include "XMLTool.h"

using namespace XDTP;

ImportImage::ImportImage()
{
}

ImportImage::~ImportImage()
{
}

/**
 * XSL変換後のXML文章を保存する直前に呼び出されます。
 * 
 * @param aDocument XML文章
 */
void ImportImage::treatPostDocument(xmlDocPtr aDocument)
{
    GLSDImportModuleAdapter::treatPostDocument(aDocument);
    
    int count;
    XMLTool tool;
    xmlNodePtr node;
    xmlNodePtr root = xmlDocGetRootElement(aDocument);
    xmlNodeSetPtr nodes;
    xmlXPathObjectPtr obj = tool.getNodeList(root, "//import");
    const char *pTmp;
    Glib::ustring type;

    if (obj) {
        nodes = obj->nodesetval;
        
        for (count = 0; count < nodes->nodeNr; count++) {
            node = nodes->nodeTab[count];
            pTmp = (const char*)xmlGetProp(node, (const xmlChar*)"type");
            type = (pTmp ? pTmp : "");
            if (pTmp) xmlFree((xmlChar*)pTmp);
            
            type = type.lowercase();
            if (6 < type.length() && "image/" == type.substr(0, 6)) {
                if (!transform(aDocument, node)) {
                    THROW("ImportImage: transform failed.");
                }
            }
        }
        
        xmlXPathFreeObject(obj);
    }
}

bool ImportImage::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 imageToHTML(aDocument, aNode, ref, caption, encoding);
    }
    else if ("xhtml" == m_OutputType) {
        return imageToXHTML(aDocument, aNode, ref, caption, encoding);
    }
    else if ("text" == m_OutputType) {
        return preserveImport(aDocument, aNode, ref, caption, encoding);
    }
    // otherwise, do not operation.
    
    return true;
}

bool ImportImage::imageToHTML(xmlDocPtr aDocument, xmlNodePtr aNode,
                              const Glib::ustring& aRef,
                              const Glib::ustring& aCaption,
                              const Glib::ustring& anEncoding)
{
    // スタイルシートを取得
    xmlNodePtr comment = getStyleSheet(aDocument, "text/css");

    if (comment) {
        // スタイルシートにイメージのスタイルの指定があるか確認
        Glib::ustring content = (comment->content ? (const char*)comment->content : "");
        Glib::ustring::size_type pos = content.find("img.image");
        
        if (Glib::ustring::npos == pos) {
            // スタイルシートにイメージのスタイルを追加
            content += LINE_SEP;
            content += "   img.image {" LINE_SEP;
            content += "     border: solid thin black;" LINE_SEP;
            content += "   }" LINE_SEP;
            content += "   div.image {" LINE_SEP;
            content += "     margin-top: 1.0mm;" LINE_SEP;
            content += "     margin-bottom: 1.5em;" LINE_SEP;
            content += "     text-align: center;" LINE_SEP;
            content += "   }" LINE_SEP;
            xmlNodeSetContent(comment, (const xmlChar*)content.c_str());
        }
    }

    // img エレメントを構築
    xmlNodePtr title;
    xmlNodePtr img;
    xmlNodePtr div;
    
    title = xmlNewNode(NULL, (const xmlChar*)"div");
    if (!title) THROW("Out of memory!");
    xmlSetProp(title, (const xmlChar*)"class", (const xmlChar*)"image");
    xmlAddChild(title, xmlNewText((const xmlChar*)aCaption.c_str()));
    
    img = xmlNewNode(NULL, (const xmlChar*)"img");
    if (!img) {
        xmlFreeNode(title);
        THROW("Out of memory!");
    }
    xmlSetProp(img, (const xmlChar*)"class", (const xmlChar*)"image");
    xmlSetProp(img, (const xmlChar*)"alt", (const xmlChar*)aCaption.c_str());
    xmlSetProp(img, (const xmlChar*)"src", (const xmlChar*)aRef.c_str());

    // イメージのサイズを調べ,ブラウザ表示(A4サイズを想定)の幅
    // を越えるようであれば,最大値まで縮小して表示するようにし,
    // 画像に元画像へのリンクを持たせるようにする。
    IMAGE_INFO info;
    URLTool::getImageInfo(normalizeURL(aRef), info);

    if (556 < info.width) {
        char buf[16] = {0};
        int newWidth = 556;
        int newHeight = (int) ((double)info.height * (double)newWidth / (double)info.width);
        
        memset(buf, 0, sizeof(buf));
        snprintf(buf, sizeof(buf) -1, "%d", newWidth);
        xmlSetProp(img, (const xmlChar*)"width", (const xmlChar*)buf);
        snprintf(buf, sizeof(buf) -1, "%d", newHeight);
        xmlSetProp(img, (const xmlChar*)"height", (const xmlChar*)buf);

        xmlNodePtr link = xmlNewNode(NULL, (const xmlChar*)"a");
        if (!link) {
            xmlFreeNode(img);
            xmlFreeNode(title);
            THROW("Out of memory!");
        }
        xmlSetProp(link, (const xmlChar*)"href", (const xmlChar*)aRef.c_str());
        xmlAddChild(link, img);
        
        div = xmlNewNode(NULL, (const xmlChar*)"div");
        if (!div) {
            xmlFreeNode(link);
            xmlFreeNode(title);
            THROW("Out of memory!");
        }
        xmlSetProp(div, (const xmlChar*)"align", (const xmlChar*)"center");
        xmlAddChild(div, link);
    }
    else {
        div = xmlNewNode(NULL, (const xmlChar*)"div");
        if (!div) {
            xmlFreeNode(title);
            THROW("Out of memory!");
        }
        xmlSetProp(div, (const xmlChar*)"align", (const xmlChar*)"center");
        xmlAddChild(div, img);
    }
    // イメージサイズ調整、ここまで↑

    xmlFreeNode(xmlReplaceNode(aNode, div));
    xmlAddNextSibling(div, title);
    
    return true;
}

bool ImportImage::imageToXHTML(xmlDocPtr aDocument, xmlNodePtr aNode,
                               const Glib::ustring& aRef,
                               const Glib::ustring& aCaption,
                               const Glib::ustring& anEncoding)
{
    return imageToHTML(aDocument, aNode, aRef, aCaption, anEncoding);
}


syntax highlighted by Code2HTML, v. 0.9.1