#include <tdeglobalsettings.h>
#include <kdebug.h>

#include <tqvaluevector.h>
#include <tqstringlist.h>
#include <tqimage.h>
#include <tqfontmetrics.h>
#include <tqpainter.h>
#include <tqbitmap.h>

#include "frame.h"

void Frame::convertDataToPixmap(const Screen *screen)
{
    if(!height() || !width()) {
        // Assume we're not ready to go.
        return;
    }

    int w = screen->cellWidth(), h = screen->cellHeight();
    TQPixmap pix(width() * w, height() * h);
    pix.fill();

    TQBitmap mask(pix.size(), true);

    TQPainter p, p2;

    p.begin(&pix, true);
    p2.begin(&mask, true);

    p.setFont(TDEGlobalSettings::fixedFont());
    TQFontMetrics fm(p.font());
    int leadHeight = fm.leading() + fm.descent();

    for(unsigned j = 0; j < m_data.count(); ++j) {
        TQValueVector<Screen::Pixel> row = m_data[j];
        if(row.isEmpty())
            continue;

        unsigned first, last;
        for (first = 0; first < row.count() && row[first].letter == ' '; ++first)
            ;
        
        last = row.count() - 1; // Assume the end is already stripped.

        for(unsigned i = first; i <= last; ++i) {
            if(row[i].letter == m_transparentChar)
                continue;

            p2.fillRect(i * w, j * h, w, h, TQt::color1);

            p.setPen(row[i].color);
            p.fillRect(i * w, j * h, w, h, TQt::black);
            p.drawText(i * w, j * h + (h - 1 - leadHeight), TQChar(row[i].letter));
        }
    }

    pix.setMask(mask);

    TQPixmap erase(pix);
    erase.fill(TQt::black);
    erase.setMask(mask);

    m_pixmap = pix;
    m_erasePixmap = erase;

    // Clear m_data to save a wee bit of memory.
    m_data.clear();
}

Frame::Frame (TQString text, TQString mask, TQRgb defaultColor, TQChar transparent)
{
    //First, process the pixels.
    
    TQStringList rows = TQStringList::split('\n',  text, true);
    m_height = rows.size();
    m_width  = 0;
    m_transparentChar = transparent;

    for (TQStringList::iterator i = rows.begin(); i != rows.end(); ++i)
    {
        TQValueVector<Screen::Pixel> row;
        for (int pos = 0; pos < (*i).length(); ++pos)
        {
            Screen::Pixel p;
            p.letter = (*i).at(pos).unicode();
            p.color  = defaultColor;
            row.append(p);
        }
        
        m_width = TQMAX(m_width, row.size());
        m_data.append(row);
    }
    
    //Now, the colors.
    TQStringList cols = TQStringList::split('\n', mask, true);
    int y = 0;
    for (TQStringList::iterator i = cols.begin(); i != cols.end(); ++i)
    {
        if (y >= m_data.size())
            break;
            
        for (int pos = 0; pos < (*i).length() && pos < m_data[y].size(); ++pos)
        {
            switch ((*i).at(pos).unicode())
            {
                //Colors stolen from konsole, TEWidget.cpp
                case 'R':
                    m_data[y][pos].color = 0xFF5454;
                    break;
                case 'r':
                    m_data[y][pos].color = 0xB21818;
                    break;
                case 'C':
                    m_data[y][pos].color = 0x54FFFF;
                    break;
                case 'c':
                    m_data[y][pos].color = 0x18B2B2;
                    break;
                case 'Y':
                    m_data[y][pos].color = 0xFFFF54;
                    break;
                case 'y':
                    m_data[y][pos].color = 0xB26818;
                    break;
                case 'G':
                    m_data[y][pos].color = 0x54FF54;
                    break;
                case 'g':
                    m_data[y][pos].color = 0x18B218;
                    break;
                case 'B':
                    m_data[y][pos].color = 0x5454FF;
                    break;
                case 'b':
                    m_data[y][pos].color = 0x1818B2;
                    break;
                case 'M':
                    m_data[y][pos].color = 0xFF54FF;
                    break;
                case 'm':
                    m_data[y][pos].color = 0xB218B2;
                    break;
                case 'W':
                    m_data[y][pos].color = 0xFFFFFF;
                    break;
                case 'w':
                    m_data[y][pos].color = 0xB2B2B2;
                    break;
                case ' ':
                    break;
                default:
                    tqDebug("dunno about color code:'%c'", (*i).at(pos).unicode());
                    m_data[y][pos].color = 0xFFFFFF;
            }
        }
        ++y;
    }
}

void Frame::paint(Screen* scr, int x, int y)
{
    if(m_pixmap.isNull())
        convertDataToPixmap(scr);

    scr->updateSpan(x, y, m_pixmap);
}

void Frame::erase(Screen* scr, int x, int y)
{
    if(m_erasePixmap.isNull())
        convertDataToPixmap(scr);

    scr->clearSpan(x, y, m_erasePixmap);
}
