/* ====================================================================
 * Copyright (c) 2003-2006, Martin Hauner
 *                          http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */

// sc
#include "LinePainter.h"
#include "sublib/PaintLine.h"
#include "sublib/Line.h"
#include "sublib/Tab.h"
#include "util/utf8.h"

// qt
#include <QtGui/QPainter>
#include <QtCore/QString>

const QColor black(0,0,0);

/**
 * construct a LinePainter.
 */
LinePainter::LinePainter()
{
}

/**
 * \brief construct a LinePainter with colors for the different text states.
 */

LinePainter::LinePainter( const QColor& nc, const QColor& wsc, const QColor& nchl, const QColor& wschl )
{
  setNormalColor(nc);
  setWhitespaceColor(wsc);

  setNormalColorHL(nchl);
  setWhitespaceColorHL(wschl);
}

LinePainter::~LinePainter()
{
}

void LinePainter::drawLine( QPainter& pp, int x, int y, const PaintLine* line )
{
  // skip empty string
  if( ! line->getSource().getStr() || ! line->getPaint().getStr() )
  {
    return;
  }

  QFontMetrics m(pp.font());

  const char*            buf     = line->getPaint();
  const PaintLine::Kind* kind    = line->getKind();

  PaintLine::Kind        outkind = kind[0];
  int                    bytes   = 0;
  int                    cnt     = 0;

  while( buf[cnt] )
  {
    if( kind[cnt] != outkind )
    {
      QString str = QString::fromUtf8( &buf[cnt-bytes], bytes );

      pp.setPen( getColor(outkind) );
      pp.drawText( x, y, str );

      x     += m.width( str );
      bytes  = 0;
    }

    outkind = kind[cnt];

    char* next      = utf8::next8(buf+cnt);
    int   byteschar = next - (buf+cnt);

    bytes += byteschar;
    cnt   += byteschar;
  }

  // flush..
  QString str = QString::fromUtf8( &buf[cnt-bytes], bytes );

  pp.setPen( getColor(outkind) );
  pp.drawText( x, y, str );
}

void LinePainter::setNormalColor( const QColor& n )
{
  _colors[normal]   = n;
}

void LinePainter::setNormalColorHL( const QColor& nhl )
{
  _colors[normalHL] = nhl;
}

void LinePainter::setWhitespaceColor( const QColor& ws )
{
  _colors[white]   = ws;
}

void LinePainter::setWhitespaceColorHL( const QColor& wshl )
{
  _colors[whiteHL] = wshl;
}

const QColor& LinePainter::getColor( unsigned int kind )
{
  switch( kind )
  {
  case PaintLine::Character:
    {
      return _colors[normal];
    }
  case PaintLine::CharacterHL:
    {
      return _colors[normalHL];
    }
  case PaintLine::Whitespace:
    {
      return _colors[white];
    }
  case PaintLine::WhitespaceHL:
    {
      return _colors[whiteHL];
    }
  }

  return black;
}
