/* This file is part of the KDE project
   Copyright (C) 2001 Simon Hausmann <hausmann@kde.org>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the Artistic License.
*/


#include "topic.h"

#include <tqapplication.h>
#include <tqtimer.h>
#include <tqregexp.h>
#include <tqlayout.h>
#include <tqtextedit.h>
#include <tqtooltip.h>

#include <tdeapplication.h>
#include <kdebug.h>
#include <tdelocale.h>
#include <krun.h>
#include <tdepopupmenu.h>
#include <kstringhandler.h>
#include <tdefiledialog.h>
#include <tdeio/job.h>

#include "ksopts.h"
#include "ksparser.h"


KSircTopic::KSircTopic( TQWidget *parent, const char *name )
    : KActiveLabel( parent, name )
{
    m_editor = 0;
    m_doEdit = false;
    m_height = 0;
//    setBackgroundColor( colorGroup().light() );
    setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
    setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ) );
    setTextFormat( RichText );
    setWordWrap(TQTextEdit::NoWrap);
    doResize();
//    setAlignment( alignment() | WordBreak );
}

void KSircTopic::setText( const TQString &_text)
{
    m_text = _text; /* save a raw copy for us */
    TQString text = _text;

    TQString richText( "<font color=\"%1\">" );
    richText = richText.arg( ksopts->textColor.name() );

    text.replace('&', "&amp;");
    text.replace('<', "&lt;");
    text.replace('>', "&gt;");

    text.replace('~', "~~");

    // ### a bit of a hack: turn '&lt;nick&gt; message' into
    // <span>&lt;nick&gt;<span> message' . span itself isn't supported but it
    // enforces the creation of separate item objects and hence separate
    // drawing of '<nick>' and 'message' , which is needed for BiDi users,
    // according to UV Kochavi <uv1st@yahoo.com> , to prevent output like
    // '<nick message<' , which is supposedly a bug in TQt's reordering.  The
    // same is done for [nick] and >nick< to catch queries.
    TQRegExp bidiRe( "^(&lt;\\S+&gt;)(.+)$" );
    text.replace( bidiRe, TQString::fromLatin1( "<span>\\1</span>\\2" ) );
    TQRegExp bidiRe2( "^(\\[\\S+\\])(.+)$" );
    text.replace( bidiRe2, TQString::fromLatin1( "<span>\\1</span>\\2" ) );
    TQRegExp bidiRe3( "^(&gt;\\S+&lt;)(.+)$" );
    text.replace( bidiRe3, TQString::fromLatin1( "<span>\\1</span>\\2" ) );

    KSParser parser;
    richText += parser.parse( text );
    richText += "</font>";

    richText = KStringHandler::tagURLs( richText );
    KActiveLabel::setText(richText);

    doResize();

}

void KSircTopic::contentsMouseDoubleClickEvent( TQMouseEvent * )
{
    m_doEdit = true;
}

void KSircTopic::contentsMouseReleaseEvent( TQMouseEvent *e )
{
    if ( m_doEdit ) {
        m_doEdit = false;

        if ( m_editor )
            return;

        doResize();

        m_editor = new KSircTopicEditor( this );

        connect( m_editor, TQ_SIGNAL( returnPressed() ),
                 this, TQ_SLOT( setNewTopic() ) );
        connect( m_editor, TQ_SIGNAL( resized() ),
                 this, TQ_SLOT( slotEditResized() ) );
        connect( m_editor, TQ_SIGNAL( destroyed() ),
                 this, TQ_SLOT( doResize() ) );

        /*
         * If you don't do this order
         * the size really breaks and you get
         * a huge widget
         */
        m_editor->setGeometry( geometry() );
        m_editor->setFocus();
        m_editor->show();

        m_editor->setText( m_text );
        TQToolTip::remove(this);

    }
    KActiveLabel::contentsMouseReleaseEvent(e);
}

void KSircTopic::setNewTopic()
{
    TQString topic = m_editor->text().stripWhiteSpace();

    /*
     * don't change the channel display
     * test since if it is set we'll get it
     * from the server.  If we can't set the topic
     * don't make it look like it was set
     */
    TQTimer::singleShot( 0, m_editor, TQ_SLOT( close() ) );
    disconnect( m_editor, TQ_SIGNAL( resized() ),
             this, TQ_SLOT( slotEditResized() ) );
    doResize();
    emit topicChange( topic );
}

void KSircTopic::slotEditResized( )
{
    setFixedHeight( m_editor->height() );
}


void KSircTopic::doResize()
{

    int h;
    TQFontMetrics metrics( currentFont() );

    h = metrics.lineSpacing()+8;
    m_height = h;
    setFixedHeight( h );


    TQToolTip::remove(this);
    TQStringList sep = TQStringList::split(" ", m_text);
    int len = 0;
    TQString brok;
    TQStringList::Iterator it = sep.begin();
    for(; it != sep.end(); ++it) {
        brok += *it + " ";
        len += (*it).length();
        if(len >= 50){
            brok += "\n";
            len = 0;
        }
    }

    TQToolTip::add(this, brok);

}

void KSircTopic::fontChange(TQFont &f)
{
    KActiveLabel::fontChange(f);
    doResize();
}

KSircTopicEditor::KSircTopicEditor( TQWidget *parent, const char *name )
    : TQTextEdit( parent, name )
{
    setWFlags( WDestructiveClose );
    setFocusPolicy( TQWidget::ClickFocus );
    connect( this, TQ_SIGNAL( textChanged () ), this, TQ_SLOT( slotMaybeResize() ) );
}

void KSircTopicEditor::keyPressEvent( TQKeyEvent *ev )
{
    if ( ev->key() == Key_Escape )
    {
        ev->accept();
        TQTimer::singleShot( 0, this, TQ_SLOT( close() ) );
        return;
    }
    else if ( ev->key() == Key_Return )
    {
        ev->accept();
        emit returnPressed();
        return;
    }
    TQTextEdit::keyPressEvent( ev );
}

void KSircTopicEditor::focusOutEvent( TQFocusEvent * fe )
{
    // we don't want to quit editing when someone brings up TQLE's popup
    // menu
    if ( fe->reason() == TQFocusEvent::Popup  )
    {
        TQWidget *focusw = tqApp->focusWidget();
        if ( focusw && m_popup && focusw == m_popup )
            return;
    }

    TQTimer::singleShot( 0, this, TQ_SLOT( close() ) );
}

TQPopupMenu *KSircTopicEditor::createPopupMenu( const TQPoint &pos )
{
    TQPopupMenu *popup = TQTextEdit::createPopupMenu( pos );
    m_popup = popup;
    return popup;
}

void KSircTopicEditor::slotMaybeResize()
{
    if(text().contains("\n")){
        TQString s = text();
        s.replace('\n', " ");
        setText(s);
        setCursorPosition(0, s.length());
    }

    TQFontMetrics metrics( currentFont() );

    int h = metrics.lineSpacing() * lines()+8;
    setFixedHeight( h );
    emit resized();
}

#include "topic.moc"
