//$Id: ircwindow.cpp,v 1.7 1997/11/30 12:16:43 parallax Exp $

#include "irc.h"
#include "ircapp.h"
#include "ircwindow.h"
#include <qkeycode.h>
#include <qclipbrd.h>
#include <string.h>                    
#include <qmlined.h>
#include <time.h>
#include <qregexp.h>
#include <qpopmenu.h>
#include <qdatetm.h>

CommandEntry::CommandEntry ( QWidget *parent, const char *n)
        : QLineEdit ( parent, n )
{
    history = new QList<QString>();
    CHECK_PTR(history);
    history->setAutoDelete(true);
    connect(this, SIGNAL(returnPressed()), SLOT(slotReturnPressed()) );
}

CommandEntry::~CommandEntry()
{
    delete history;
}



void CommandEntry::keyPressEvent( QKeyEvent *e ) 
{
    if ( e->state() & ControlButton ) {
        QString txt = text();
        switch ( e->key() ) {
            case Key_B:
                txt += 0x02;
                setText(txt);
                break;
            case Key_U:
                txt += 0x1F;
                setText(txt);
                break;
            case Key_I:
                txt += 0x16;
                setText(txt);
                break;
            case Key_K:
                txt += 0x03;
                setText(txt);
                break;
            case Key_O:
                txt += 0x0F;
                setText(txt);
                break;
            default:
                QLineEdit::keyPressEvent(e);
        }
        return;
    }
       
    if (e->key() == Key_Up)
    {
        QString *str = history->prev();
        if (str)
            setText(*str);
        else
            history->first();
        return;
    }
    
    if (e->key() == Key_Down)
    {
        QString *str = history->next();
        if (str)
                setText(*str);
        else
            history->last();   
        return;
    }
    
    QLineEdit::keyPressEvent(e); 

}

void CommandEntry::slotReturnPressed()
{
    if (history->count() > HISTORY_LENGTH)
        history->remove((unsigned int)0);
    history->remove(history->getLast()); // remove the ""
    history->append(new QString(text()));
    history->append(new QString(""));
}

    
IrcWindow::IrcWindow( QWidget *parent, const char *n)
        : QWidget ( parent, n)
{
    setFocusPolicy(StrongFocus); 
    commandArea = new CommandEntry (this, "commandArea");
    //commandArea->setFrame(FALSE);
    connect(commandArea, SIGNAL(returnPressed()), this, SLOT(HandleCommand()) );
    outputArea = new OutputWidget(this, "output Area");
    outputArea->setBackgroundColor(QColor(white)); // default in case we have no theme
    mdiWin = NULL;
//    UpdateCaption();
}

void IrcWindow::SetMDIWindow(MDIWindow *w)
{
    mdiWin = w;
}

IrcWindow::~IrcWindow()
{
    
}

void IrcWindow::ApplyTheme()
{
     if (mdiWin)
        SetMDIThemeProperties();
     IrcApp::SetThemeProperties(commandArea, Settings::theme.commandLine);
     IrcApp::SetThemeProperties(outputArea, Settings::theme.chatArea);
}

void IrcWindow::SetMDIThemeProperties()
{
    IrcApp::SetThemeProperties(mdiWin, Settings::theme.channelWindows);
    QLabel *caption = mdiWin->Caption();
    IrcApp::SetThemeProperties(caption, Settings::theme.titleBars);
}

void IrcWindow::ReceiveOutput(KProcess *, char *buff, int len)
{
    QString str(buff, len);
//    ParseInput(str);
}

void IrcWindow::Output ( const char *string, int messageType )
{
    QString s(string);
    if (Settings::timestamp)
    {
        if (messageType != Output::SERVER_MESSAGE && messageType != Output::INFO \
            && messageType != Output::INTERNAL_MESSAGE)
        {
            QString tm;
            tm.sprintf("[%s] ", (QTime::currentTime()).toString().data());
            s.prepend(tm);
        }
    }
    const char *color = 0;
    const char *icon = 0;
    QFont f = outputArea->font();
    switch (messageType)
    {
        case Output::ACTION:
            f = IrcApp::ThemeFont(outputArea, Settings::theme.actionTxt);        
            icon = "star.gif";
            // icon = true;
            color = Settings::theme.actionTxt.textColor;
            break;
        case Output::NOTICE:
            f = IrcApp::ThemeFont(outputArea, Settings::theme.noticeTxt);        
            icon = "notice.gif";
            //icon = true;
            // color = 0x00f80000;
            color =  Settings::theme.noticeTxt.textColor;
            break;
        case Output::SERVER_MESSAGE:
            f = IrcApp::ThemeFont(outputArea, Settings::theme.serverTxt);    
            icon = "server.gif";
            color = Settings::theme.serverTxt.textColor;
            // icon = true;
            //color = 0x0000f8f8;
            break;
            
        case Output::OWN:
            f = IrcApp::ThemeFont(outputArea, Settings::theme.ownTxt);
            color = Settings::theme.ownTxt.textColor;
            break;
        case Output::INFO:
        case Output::INTERNAL_MESSAGE:
            icon = "info.gif";
            // icon = true;
            f = IrcApp::ThemeFont(outputArea, Settings::theme.internalTxt);
            color = Settings::theme.internalTxt.textColor;
            break;
        case Output::PRIVMESSAGE:
             f = IrcApp::ThemeFont(outputArea, Settings::theme.privmsgTxt);
            color = Settings::theme.privmsgTxt.textColor;
            break;
        case Output::ERROR:
            icon ="error.gif";
             f = IrcApp::ThemeFont(outputArea, Settings::theme.errorTxt);
            color = Settings::theme.errorTxt.textColor;
            break;
    }
    
    QColor c;
    if (!color)
        c = outputArea->colorGroup().text();
    else
        c = QColor(color);
    
    outputArea->SetCurrentColor(c);
     if (icon)
    {
        QString str = "icons/";
        str += icon;
        outputArea->InsertPixmap(IrcApp::GetFile(str));
    }
     QString str;
    // now deal with all those control characters
     outputArea->SetCurrentFont(f);
    int i=0;
    while (s[i])
    {
        if (s[i] < 0x20)
        { // must be a control character
            outputArea->InsertText(str);
            str = "";
            switch (s[i])
            {
                case 0x02: // CTRL-B is bold
                    f.setBold(!f.bold());
                    break;
                case 0x16: //CTRL-V is inverse
                    outputArea->SetInverse(!(outputArea->IsInverse()));
                    break;
                case 0x1F:   // CTRL-_ toggles underline on/off
                    f.setUnderline(!f.underline());
                    break;
                case 0x0F: // CTRL-O turns everything off
                    f.setBold(false);
                    f.setUnderline(false);
                    outputArea->SetInverse(false);
                    break;
                default:
                    debug("Unknown control character: %d", s[i]);
                    str += s[i];
            }
            outputArea->SetCurrentFont(f);
        }
        else
               str += s[i];
        i++;
    }
    outputArea->InsertText(str);
    outputArea->UpdateLastRow();
    outputArea->NewLine();
    // now reset to defaults
    f = outputArea->CurrentFont();
    f.setBold(FALSE);
    f.setUnderline(FALSE);
    outputArea->SetCurrentFont(f);
    outputArea->SetInverse(FALSE);
    
    if (Settings::debug)
        debug(s);
    /* 
    // now handle our logging
    switch(type)
    {
        case STATUS:
            if (Settings::logStatus)
                AddToLog(s, name());
            break;
        case MESSAGE:
            if (Settings::logMessages)
                AddToLog(s, name());
            break;
        case CHANNEL:
            if (Settings::logChannels)
                AddToLog(s, name());
            break;
    }
    */
}

void IrcWindow::resizeEvent ( QResizeEvent * )
{
    int windowWidth = width();
    commandArea->setGeometry ( 0, (height() - COMMAND_AREA_HEIGHT ),
                               windowWidth,
                               COMMAND_AREA_HEIGHT );
    outputArea->setGeometry(0,0,windowWidth, height()-COMMAND_AREA_HEIGHT );
}

void IrcWindow::HandleFocus()
{
    commandArea->setFocus();
}

void IrcWindow::UpdateCaption()
{
    setCaption(name());
}
        
void IrcWindow::ScreenInput(const char *newText)
{
    if ((QString(newText)).right(1) == "\n") // wait for an endline, then process command
        HandleCommand();
}

void IrcWindow::HandleCommand( )
{
    QString text = commandArea->text();
    commandArea->setText(NULL); // now clear our minds like a table...
    // if (text.right(2) == "\r\n")
    if (text != "" && text != "\n")
        ParseInput((const char *)text);    
}


void IrcWindow::ParseInput ( const char *input)
{
    if (input[0] == '/')
    {
        input++;
        IrcApp::HandleEvent(Event::PARSE_INPUT, input, name());
    }
}

void IrcWindow::AddToLog( const char *str, const char *nm)
{
    QString fileName = Settings::fileDir.copy();
    fileName += "/logs/" + (QString(nm)).lower() + ".log";
    QFile file(fileName);
    if (!file.open(IO_WriteOnly | IO_Append))
    {
        fopen(fileName.data(), "w+");
        if (!file.open(IO_WriteOnly | IO_Append))
        {
            warning("Could not create a log file: %s", fileName.data());
            return;
        }
    }

    QString out(str);
    file.writeBlock(out, out.length());
    file.close();
}

#include "ircwindow.moc"
