/***************************************************************************
                          msnstring.cpp  -  description
                             -------------------
    begin                : Mon Jun 30 2003
    copyright            : (C) 2003 by Michael Curtis
    email                : michael@kmess.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "msnstring.h"

#include <qcolor.h>
#include <qregexp.h>
#include <qstring.h>

#include <kdebug.h>

#include "currentaccount.h"
#include "emoticoncollection.h"

// The constructor
MsnString::MsnString()
{
  currentAccount_ = CurrentAccount::instance();
  if ( currentAccount_ == 0 )
  {
    kdDebug() << "MsnString - Couldn't get the instance of the current account." << endl;
  }

  emoticons_ = EmoticonCollection::instance();
  if ( emoticons_ == 0 )
  {
    kdDebug() << "MsnString - Unable to get instance of emoticon collection." << endl;
  }

}



// The destructor
MsnString::~MsnString()
{
}



// get the text as it was given
QString & MsnString::getOriginalText()
{
  return originalText_;
}



// get the text after it has gone through the markup processor(s)
//  paying attention to the users options..
QString & MsnString::getText()
{
  return markupText_;
}



// Replace the Messenger Plus characters with HTML markup
//  I'm really concerned about the way MSN+ embeds reserved characters into the
//  text, which may cause i18n problems, but given the popularity of MSN+, this
//  really needs to be implemented.
void     MsnString::parseMessengerPlus( QString &text )
{
  bool boldFlag = false, italicFlag = false, underlineFlag = false;
  bool fontFlag = false;
  QColor color;
  QRegExp fontCapture = QRegExp( "(,{0,1})([0-9]{1,2})" );

  for ( unsigned int index = 0; index < text.length(); index++ )
  {
    switch ( text.at( index ).unicode() )
    {
      case 0x0002:
        boldFlag = !boldFlag;

        text = text.replace( index, 1, ( boldFlag ) ? "<b>"  : "</b>" );

        break;
      case 0x0003:
        fontFlag = !fontFlag;

        fontCapture.search( text, index, QRegExp::CaretAtOffset );

        switch( fontCapture.cap(2).toInt() )
        {
          case 0:
            color = QColor( "white" );
            break;
          case 1:
            color = QColor( "black" );
            break;
          case 2:
            color = QColor( "blue" );
            break;
          case 3:
            color = QColor( "green" );
            break;
          case 4:
            color = QColor( "red" );
            break;
          case 5:
            color = QColor( "brown" );
            break;
          case 6:
            color = QColor( "purple" );
            break;
          case 7:
            color = QColor( "orange" );
            break;
          case 8:
            color = QColor( "yellow" );
            break;
          case 9:
            color = QColor( "lightGreen" );
            break;
          case 10:
            color = QColor( "cyan" );
            break;
          case 11:
            color = QColor( "lightBlue" );
            break;
          case 12:
            color = QColor( "blue" );
            break;
          case 13:
            color = QColor( "pink" );
            break;
          case 14:
            color = QColor( "darkGray" );
            break;
          case 15:
            color = QColor( "gray" );
        }

        if ( fontCapture.cap(1) == "," )
        {
          // font background text
        }
        else
        {
          text = text.replace( index, fontCapture.matchedLength() + 1, "<font color=\"" + color.name() + "\">" );
        }

        break;
      case 0x0005:
        italicFlag = !italicFlag;

        text = text.replace( index, 1, ( italicFlag ) ? "<i>"  : "</i>" );

        break;
      case 0x001f:
        underlineFlag = !underlineFlag;

        text = text.replace( index, 1, ( italicFlag ) ? "<u>"  : "</u>" );

        break;
    }
  }
}



// set the text
void     MsnString::setText( QString text )
{
  originalText_ = text;

  markupText_ = originalText_;

  // MessengerPlus is quite a "low level" encoding, so do it first
  parseMessengerPlus( markupText_ );

  markupText_ = markupText_.replace( QRegExp("&"), "&amp;" );
  markupText_ = markupText_.replace( QRegExp("<"), "&lt;" );
  markupText_ = markupText_.replace( QRegExp(">"), "&gt;" );

  // Make sure ::) works by replacing :: with &3A:
  while ( markupText_.contains( "::" ) )
  {
    markupText_ = markupText_.replace( QRegExp("::"), "&3A:" );
  }

  // Insert emoticons if required
  if ( currentAccount_->getUseEmoticons() )
  {
    // Temporary disable emoticons when there are links.
    // This is a quick fix backported for 1.4.3, 1.5 has
    // a new message parser/formatter which can handle emoticons+links well.
    if( ! markupText_.contains("http:") &&
        ! markupText_.contains("https:") &&
        ! markupText_.contains("ftp:") &&
        ! markupText_.contains("mailto:") &&
        ! markupText_.contains("www.") )
    {
      emoticons_->parseEmoticons( markupText_ );
    }
  }

  // Return the &3As to :s.
  markupText_ = markupText_.replace( QRegExp("&3A"), ":" );

  // Replace any "> "s in the message with ">&nbsp;" to avoid missing spaces after emoticons
  markupText_ = markupText_.replace( QRegExp("> "), ">&nbsp;" );

  // Replace double spaces with double &nbsp;s so that they'll show properly
  markupText_ = markupText_.replace( QRegExp("  "), "&nbsp;&nbsp;" );
}


