/* AbiSource
 * 
 * Copyright (C) 2002 Dom Lachowicz <cinamod@hotmail.com>
 * Copyright (C) 2004 Robert Staudinger <robsta@stereolyzer.net>
 * Copyright (C) 2005 Daniel d'Andrada T. de Carvalho
 * <daniel.carvalho@indt.org.br>
 * 
 * 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., 59 Temple Place - Suite 330, Boston, MA  
 * 02111-1307, USA.
 */
 
 
// Class definition include
#include "OO_Style.h"

// Abiword includes
#include <ut_debugmsg.h>
#include <ut_math.h>

// External includes 
#include <locale.h>
 
 
 
 
/**
 * Constructor
 * 
 */
OO_Style::OO_Style (const XML_Char** ppProps, const PD_Style* pParentStyle)
    : m_bColBreakBefore (false),
      m_bPageBreakBefore (false),
      m_pParentStyle (pParentStyle)
{
    parse (ppProps);
}





/**
 * Constructor that receives another OO_Style as one of the arguments,
 * copying its contents (I think...)
 * 
 */
OO_Style::OO_Style (const OO_Style* pOther, const XML_Char** ppProps,
                    PD_Style* pParentStyle)
    : m_bColBreakBefore (false),
      m_bPageBreakBefore (false),
      m_pParentStyle (pParentStyle)
{
    if (pOther) {
      *this = *pOther;
    }
    
    parse (ppProps);
}















/**
 * 
 * 
 */
void OO_Style::parse (const XML_Char** ppProps)
{
    const XML_Char* pVal = NULL;

    pVal = UT_getAttribute ("fo:text-align", ppProps);
    
    if (pVal) {
        if (!UT_strcmp(pVal, "end")) {
            m_align = "text-align: right;";
        } else if (!UT_strcmp(pVal, "center")) {
            m_align = "text-align: center;";
        } else if (!UT_strcmp(pVal, "justify")) {
            m_align = "text-align: justify;";
        } else {
            m_align = "text-align: left;";
        }
    }

    pVal = UT_getAttribute ("fo:font-weight", ppProps);
    if(pVal)
        if (!UT_strcmp(pVal, "bold"))
            m_fontWeight = "font-weight: bold;";
    else
        m_fontWeight = "font-weight: normal;";

    pVal = UT_getAttribute("fo:font-style", ppProps);
    if (pVal)
        if (!UT_strcmp(pVal, "italic"))
            m_fontStyle = "font-style: italic;";

    pVal = UT_getAttribute("fo:color", ppProps);
    if (pVal)
        m_color = UT_String_sprintf ("color: %s;", pVal);


    pVal = UT_getAttribute ("fo:background-color", ppProps);

        
    if(pVal)
        m_bgcolor = UT_String_sprintf ("bgcolor: %s;", pVal);

    pVal = UT_getAttribute("style:font-name", ppProps);
    if(pVal)
        m_fontName = UT_String_sprintf ("font-family: %s;", pVal);

    pVal = UT_getAttribute("fo:font-size", ppProps);
    if(pVal) {
        UT_Dimension dim = UT_determineDimension(pVal, DIM_none);
        if (dim == DIM_PERCENT && !m_pParentStyle) {
            UT_DEBUGMSG(("*** [OpenDocument] no parent style to resolve '%s'\n", pVal));
        }
        else if (dim == DIM_PERCENT && m_pParentStyle) {
            // calculate font-size based on parent's
            const XML_Char * parentFontSize = NULL;
            double fontSize = 12;
            if (m_pParentStyle->getProperty("font-size", parentFontSize)) {
                fontSize = atoi(parentFontSize) * atoi(pVal) / 100.0;
            }
            else {
                UT_DEBUGMSG(("*** [OpenDocument] using fallback font-size '%f'\n", fontSize));
            }
            m_fontSize = UT_String_sprintf ("font-size: %gpt;", rint(fontSize));
        }
        else
            m_fontSize = UT_String_sprintf ("font-size: %s;", pVal);
    }

    if (UT_getAttribute("fo:language", ppProps) && UT_getAttribute("fo:country", ppProps))
        m_lang = UT_String_sprintf ("lang: %s-%s;", UT_getAttribute("fo:language", ppProps),
            UT_getAttribute("fo:country", ppProps));

    pVal = UT_getAttribute("style:text-position", ppProps);
    if(pVal) {
        m_textPos = "text-position: ";
        if (strstr(pVal, "sup"))
            m_textPos += "superscript;";
        else if (strstr(pVal, "sub"))
            m_textPos += "subscript;";
        else
            m_textPos += "normal;";
    }

    const XML_Char * undr = NULL;
    const XML_Char * strk = NULL;
    

    undr = const_cast<const XML_Char *>(UT_getAttribute("style:text-underline-style", ppProps));
    strk = const_cast<const XML_Char *>(UT_getAttribute("style:text-line-through-style", ppProps));


    if (undr || strk) {
        m_textDecoration = "text-decoration: ";

        if(undr)
            if (UT_strcmp(undr, "none") != 0)
                m_textDecoration += "underline";

        if (undr && strk)
            m_textDecoration += ",";

        if(strk)
            if (UT_strcmp(strk, "none") != 0)
                m_textDecoration += "line-through";

        m_textDecoration += ";";
    }

    pVal = UT_getAttribute ("fo:margin-left", ppProps);
    if(pVal)
        m_marginLeft = UT_String_sprintf ("margin-left: %s;", pVal);

    pVal = UT_getAttribute ("fo:margin-top", ppProps);
    if(pVal)
        m_marginTop = UT_String_sprintf ("margin-top: %s;", pVal);

    pVal = UT_getAttribute ("fo:margin-right", ppProps);
    if(pVal)
        m_marginRight = UT_String_sprintf ("margin-right: %s;", pVal);

    pVal = UT_getAttribute ("fo:margin-bottom", ppProps);
    if(pVal)
        m_marginBottom = UT_String_sprintf ("margin-bottom: %s;", pVal);

    pVal = UT_getAttribute ("style:line-height-at-least", ppProps);
    if (pVal)
        m_lineHeight = UT_String_sprintf ("line-height: %s+;", pVal);

    pVal = UT_getAttribute ("fo:line-height", ppProps);
    if (pVal)
    if (strstr(pVal, "%") != NULL) {
        int spacing;

        sscanf (pVal, "%d%%", &spacing);
        const char * old_loc = setlocale(LC_NUMERIC, "C");
        m_lineHeight = UT_String_sprintf ("line-height: %f;", (double)spacing/100.);
        setlocale (LC_NUMERIC, old_loc);
    }
    else
        m_lineHeight = UT_String_sprintf ("line-height: %s;", pVal);

    pVal = UT_getAttribute("fo:keep-with-next", ppProps);
    if (pVal)
        m_keepWithNext = UT_String_sprintf ("keep-with-next: %s;", !UT_strcmp(pVal, "true") ? "yes" : "no");

    pVal = UT_getAttribute("style:break-inside", ppProps);
    if (pVal)
        m_keepTogether = UT_String_sprintf ("keep-together: %s;", !UT_strcmp(pVal, "avoid") ? "yes" : "no" );

    pVal = UT_getAttribute("fo:widows", ppProps);
    if (pVal) {
        int widows = 0;
        sscanf(pVal, "%d", &widows);
        m_widows = UT_String_sprintf ("widows: %d", widows);
    }

    pVal = UT_getAttribute("fo:orphans", ppProps);
    if (pVal) {
        int orphans = 0;
        sscanf (pVal, "%d", &orphans);
        m_orphans = UT_String_sprintf ("orphans: %d", orphans);
    }

    pVal = UT_getAttribute("fo:column-count", ppProps);
    if (pVal) {
        int columns = 0;
        sscanf (pVal, "%d", &columns);

        m_columns = UT_String_sprintf ("columns: %d;", columns);
    }

    pVal = UT_getAttribute ("fo:break-before", ppProps);
    if (pVal) {
        if (!strcmp (pVal, "column"))
            m_bColBreakBefore = true;
        else if (!strcmp (pVal, "page"))
            m_bPageBreakBefore = true;
    }

    m_styleProps = "";

#define APPEND_STYLE(sty) if (sty.size()) { m_styleProps += sty; }

    APPEND_STYLE(m_align);
    APPEND_STYLE(m_fontWeight);
    APPEND_STYLE(m_fontStyle);
    APPEND_STYLE(m_color);
    APPEND_STYLE(m_bgcolor);
    APPEND_STYLE(m_fontName);
    APPEND_STYLE(m_fontSize);
    APPEND_STYLE(m_lang);
    APPEND_STYLE(m_textPos);
    APPEND_STYLE(m_textDecoration);
    APPEND_STYLE(m_marginLeft);
    APPEND_STYLE(m_marginTop);
    APPEND_STYLE(m_marginRight);
    APPEND_STYLE(m_marginBottom);
    APPEND_STYLE(m_lineHeight);
    APPEND_STYLE(m_keepWithNext);
    APPEND_STYLE(m_keepTogether);
    APPEND_STYLE(m_widows);
    APPEND_STYLE(m_orphans);
    APPEND_STYLE(m_columns);

#undef APPEND_STYLE

    if (m_styleProps.size () > 0)
        m_styleProps [m_styleProps.size()-1] = 0;
}