
#include "kjs/wk_config.h"
#include "BALConfiguration.h"
#include "BCFontPlatformDataPrivateDirectFB.h"
#include <font/BTFontPlatformData.h>
#include "BTLogHelper.h"
#include <graphics/BIGraphicsDevice.h>
#include "CString.h"

#include <sys/stat.h>
#include <directfb.h>

#include "FontMapping.cpp"

IMPLEMENT_CREATE_DELETE(BIFontPlatformDataPrivate, BCFontPlatformDataPrivateDirectFB);

using WebCore::CString;
using WebCore::StringImpl;

namespace BAL {

int BCFontPlatformDataPrivateDirectFB::m_isInitialized = 0;

BCFontPlatformDataPrivateDirectFB::BCFontPlatformDataPrivateDirectFB()
{
    m_font = NULL;
    m_fontMapping = FontMapping::getInstance ();
    DBGML(MODULE_FONTS, LEVEL_INFO, "\nconstrutor(): m_isInitialized=%d\n", m_isInitialized);
}

BCFontPlatformDataPrivateDirectFB::~BCFontPlatformDataPrivateDirectFB()
{
    if (m_font) {
        m_font->Release (m_font);
        m_font = NULL;
    }
    m_fontMapping = FontMapping::releaseInstance ();
    m_isInitialized--;
    DBGML(MODULE_FONTS, LEVEL_INFO, "\ndestrutor(): m_isInitialized=%d\n", m_isInitialized);
}

int BCFontPlatformDataPrivateDirectFB::init()
{
    m_isInitialized++;
    DBGML(MODULE_FONTS, LEVEL_INFO, "\ninit(): m_isInitialized=%d\n", m_isInitialized);
    return m_isInitialized;
}

const char * BCFontPlatformDataPrivateDirectFB::getFontFileFromDescription(const FontDescription& fontDescription)
{
    std::string _family;
    std::string _face;
    std::string _style;

    //FIXME: Se pediu { 'serif', 'sans-serif', 'monospace', 'cursive', 'fantasy' }
    // (que sao as palavras reservadas para uso em <gerenric-family>)
    // entao '_family' fica vazio!!! Porque???
    _family = fontDescription.family().family().domString().latin1().data();

    switch (fontDescription.genericFamily ())
    {
        case FontDescription::SerifFamily:
            _face = "serif";
            break;
        case FontDescription::SansSerifFamily:
            _face = "sans-serif";
            break;
        case FontDescription::MonospaceFamily:
            _face = "monospace";
            break;
        case FontDescription::NoFamily:
            // FIXME: esta sempre retornando 'NoFamily' ???
            _face = "no-family";
            break;
        case FontDescription::StandardFamily:
        default:
            _face = "sans-serif";
            break;
    }

    if (fontDescription.bold () && fontDescription.italic ())
        _style = "bold-italic";
    else if (fontDescription.bold ())
        _style = "bold";
    else if (fontDescription.italic ())
        _style = "italic"; //== oblique
    else
        _style = "regular";

    DBGML(MODULE_FONTS, LEVEL_INFO, "\n_family='%s' _face='%s' _style='%s'\n", _family.c_str(), _face.c_str(), _style.c_str());

#if 0
    return m_fontMapping->fontToFile (_family+_face, _style).c_str ();
#elif 0
    return m_fontMapping->fontToFile (_face, _style).c_str ();
#else
    /* Se nao foi encontrada uma familia entao define '_famiy' como 'Default'. */
    if (_family.empty())
        _family = "default";
    /* Compatibilidade com o arquivo que já é usado pelo Astro, onde '_family' aqui é o o atributo 'face' de um 'fontEntry'. */
    return m_fontMapping->fontToFile (_family, _style).c_str ();
#endif
}

void BCFontPlatformDataPrivateDirectFB::configureFontMapping(const FontDescription& fontDescription, const AtomicString& familyName)
{
    IDirectFB* directfb = (IDirectFB*) getBIGraphicsDevice ()->getSuperInterface ();
#if 0
    const char * fontfile = getFontFileFromDescription (fontDescription, familyName);
#else
    char buffer [128];
    char * fontfile = buffer;
    strcpy (fontfile, getFontFileFromDescription (fontDescription));
#endif
    struct stat stat_s;
    if (stat(fontfile, &stat_s) == -1)
    {
        printf ("Warning: Could not open file '%s'. Using default DirectFB font.\n", fontfile);
        fontfile = NULL;
    }

    DFBResult err;
    DFBFontDescription fontdesc;
    fontdesc.flags = (DFBFontDescriptionFlags) ( DFDESC_ATTRIBUTES | DFDESC_HEIGHT );
    fontdesc.attributes = (DFBFontAttributes) (0);
    fontdesc.height = static_cast<uint> (fontDescription.specifiedSize ());
    DBGML(MODULE_FONTS, LEVEL_INFO, "\nopen font '%s' with size %d \n", fontfile, fontdesc.height);
#if 0
    fontdesc.width;
    fontdesc.index;
    fontdesc.fixed_advance;
    fontdesc.fract_height;
    fontdesc.fract_width;
#endif
    err = directfb->CreateFont (directfb, fontfile, &fontdesc, &m_font);
    if (err != DFB_OK) {
        DirectFBError ( "Could not create font.\n", err);
    }
}

bool BCFontPlatformDataPrivateDirectFB::isFixedPitch()
{
    DBGML(MODULE_FONTS, LEVEL_INFO, "\nNOT IMPLEMENTED: BCFontPlatformDataPrivateDirectFB::isFixedPitch() = false\n");
    // TODO: a implementacao nao eh mandatoria, mas pode ser uma otimizacao a ser feita.
    return false;
}

unsigned BCFontPlatformDataPrivateDirectFB::hash() const
{
    DBGML(MODULE_FONTS, LEVEL_INFO, "\nBCFontPlatformDataPrivateDirectFB::hash(%p)\n", m_font);
    uintptr_t hashCodes[1] = { reinterpret_cast<uintptr_t>(m_font) };
    return StringImpl::computeHash( reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar));
}

bool BCFontPlatformDataPrivateDirectFB::isEqual(const BIFontPlatformDataPrivate* other) const
{
    DBGML(MODULE_FONTS, LEVEL_INFO, "\nNOT IMPLEMENTED: BCFontPlatformDataPrivateDirectFB::isEqual()\n");
    // TODO: implementar mesmo. Em todos os casos retorna que sao diferentes.
    return false;
}

} //namespace BAL
