/***************************************************************************
                          chatview.cpp  -  description
                             -------------------
    begin                : Tue Mar 25 2003
    copyright            : (C) 2003 by Giorgio A.
    email                : openc6@hotmail.com
 ***************************************************************************/

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

#include "chatview.h"
#include <qwidget.h>
#include <qtextedit.h>
#include <qlabel.h>
#include <qcursor.h>
#include <qpopupmenu.h>
#include <qstring.h>
#include <qiconset.h>
#include <qpixmap.h>
#include <qstylesheet.h>
#include <qfiledialog.h>
#include <qdatetime.h>
#include <qprogressbar.h>
#include <qcheckbox.h>
#include <qdialog.h>
#include <qhostaddress.h>
#include <qstringlist.h>
#include <qevent.h>
#include <qtextbrowser.h>
#include <qlayout.h>
#include <qcstring.h>
#include <qwmatrix.h>
#include <qtooltip.h>
#include <qcolordialog.h>
#include <qapplication.h>
#include "c6button.h"
#include "c6textedit.h"
#include "c6smiley.h"
#include "c6settings.h"
#include "c6global.h"
#include "c6pixmapcache.h"
#include "c6httpconnection.h"
#include "c6chatfontdialog.h"
#include "c6utils.h"

#define ENTER_CHAT_MSG(nick) QString("Il netfriend <b>")+nick+QString::fromUtf8("</b> è appena entrato in chat")
#define EXIT_CHAT_MSG(nick) QString("Il netfriend <b>")+nick+QString::fromUtf8("</b> è appena uscito dalla chat")
#define RECEIVE_STOP_MSG(nick,file) QString("L'utente "+nick+" ha interrotto la trasmissione del file "+file+" !")
#define RECEIVE_START_MSG(nick,file) QString("L'utente "+nick+" ha iniziato la trasmissione del file "+file+" !")
#define PICTURE_EXT ",t00.jpg"
#define END_OF_TRANSFER_MSG(filename) QString("Invio del file ")+filename+" completato con successo!"
#define TRASMIT_STOP_MSG(filename) QString("Invio del file ")+filename+" interrotto!"
#define RECEIVE_ABORT_MSG(file) QString::fromUtf8("Si è verificato un problema con la ricezione del file "+file+" !")
#define TRANSMIT_ABORT_MSG(file) QString::fromUtf8("Si è verificato un problema con la trasmissione del file "+file+" !")
#define TRANSMIT_START_MSG(filename,user) QString::fromUtf8("Stai per trasmettere il file <b>"+filename+"</b> all'utente <b>"+user+"</b>.....")

static const int PLAIN_DEFAULT_FONT_SIZE = 10;


ChatView::ChatView() : Chat(0,0)
    ,_httpData(0)
    ,_clientVersion(-1)
    ,_isMessaged(false)
    ,xferSocket(0)
    ,xferServer(0)
    ,_receiveSocket(0)
    ,_scheduledClose(false)
    ,_receiveFileStarted(false)        
    ,_transmitFileStarted(false)
    ,_boldToggled(false)
    ,_italicToggled(false)
    ,_underlineToggled(false)
    ,_currentFontNo(0)
    ,_currentFontSizePt(10)                          
{
    C6Global &global = C6Global::getInstance();
    QString path = global.getSkinPath();
    setIcon(C6PixmapCache::getInstance().getPixmap((path+"icon16x16.png")));
    setReceive(C6Settings::getInstance().getAutoAccept());

    otherChat = new C6TextEdit(frame14, 29, 30, 430, 155);
    otherChat->setFrameShape( QTextEdit::NoFrame );
    otherChat->setFrameShadow( QTextEdit::Plain );
    otherChat->setPaletteBackgroundColor(QColor(255,255,255));
    otherChatPlaceHolder->hide();
    frame14Layout->addWidget(otherChat, 0, 0 );

    MyChat->setTextFormat(QTextEdit::PlainText);

    exitButtonPlaceHolder->hide();
    exitButton = new C6Button(frame15,0,0,path+"chat_71.png",path+"chat_over_109.png");
    layout33->addWidget(exitButton);
    connect(exitButton,SIGNAL(clicked()),this,SLOT(closeChat()));
    
    QToolTip::add
            (exitButton,"Chiude la finestra di chat");
    
    sendButtonPlaceHolder->hide();
    sendButton = new C6Button(frame10_2,0,0,path+"chat_55.png",path+"chat_over_91.png",
                              path+"chat_over_91.png");
    sendButton->setMinimumSize(QSize(52,74));
    sendButton->setMaximumSize(QSize(52,74));
    layout20->addWidget(sendButton);
    connect(sendButton,SIGNAL(clicked()),this,SLOT(SendChat()));

    C6Button *fileButton = new C6Button(frame6,0,0,path+"chat_19.png",path+"chat_over_19.png",path+"chat_over_19.png");
    chooseLabelPlaceHolder->hide();
    layout25->insertWidget(0,fileButton);
    connect(fileButton,SIGNAL(clicked()),this,SLOT(fileButtonClicked()));

    QToolTip::add
            (fileButton,"Invia file");    
    
    C6Button *profileButton = new C6Button(frame6,0,0,path+"chat_21.png",path+"chat_over_21.png",path+"chat_over_21.png");
    profilePlaceHolder->hide();
    layout25->insertWidget(1,profileButton);
    connect(profileButton,SIGNAL(clicked()),this,SLOT(profileClicked()));

    QToolTip::add
            (profileButton,"Profilo utente");        
    
    C6Button *addButton = new C6Button(frame6,0,0,path+"chat_23.png",path+"chat_over_23.png",path+"chat_over_23.png");
    addPlaceHolder->hide();
    layout25->insertWidget(2,addButton);
    connect(addButton,SIGNAL(clicked()),this,SLOT(addToListClicked()));

    QToolTip::add
            (addButton,"Aggiunge il netfriend alla lista contatti"); 
       
    C6Button *stopButton = new C6Button(frame6,0,0,path+"chat_25.png",path+"chat_over_25.png",path+"chat_over_25.png");
    stopPlaceHolder->hide();
    layout25->insertWidget(3,stopButton);
    connect(stopButton,SIGNAL(clicked()),this,SLOT(autoRaiseClicked()));

    QToolTip::add
            (stopButton,"Disabilita l'auto raise di questa chat"); 
    
    
    C6Button *soundButton = new C6Button(frame6,0,0,path+"chat_41.png",path+"chat_over_41.png",path+"chat_over_41.png");
    soundPlaceHolder->hide();
    layout25->insertWidget(4,soundButton);
    connect(soundButton,SIGNAL(clicked()),this,SLOT(soundButtonClicked()));

    QToolTip::add
            (soundButton,"Attiva o disattiva i suoni");     
        
    
    C6Button *logButton = new C6Button(frame6,0,0,path+"chat_39.png",path+"chat_over_39.png",path+"chat_over_39.png");
    logPlaceHolder->hide();
    layout25->insertWidget(5,logButton);
    connect(logButton,SIGNAL(clicked()),this,SLOT(logButtonClicked()));

    QToolTip::add
            (logButton,"Log delle conversazioni con questo netfriend");     
        
    
    
    C6Button *smileyButton = new C6Button(frame9,0,0,path+"chat_37.png",path+"chat_over_37.png",path+"chat_over_37.png");
    smileyPlaceHolder->hide();
    layout50->insertWidget(0,smileyButton);
    connect(smileyButton,SIGNAL(clicked()),this,SLOT(smileyButtonClicked()));

    QToolTip::add
            (smileyButton,"Visualizza smiley");     
    
    C6Button *boldButton = new C6Button(frame9,0,0,path+"chat_18.png",path+"chat_pressed_18.png",path+"chat_over_18.png");
    boldButton->setSticky();   
    boldPlaceHolder->hide();
    layout50->insertWidget(1,boldButton);
    connect(boldButton,SIGNAL(clicked()),this,SLOT(boldButtonClicked()));

    QToolTip::add
            (boldButton,"Scrittura in grassetto");       
    
    
    C6Button *italicButton = new C6Button(frame9,0,0,path+"chat_20.png",path+"chat_pressed_20.png",path+"chat_over_20.png");
    italicPlaceHolder->hide();
    italicButton->setSticky();   
    layout50->insertWidget(2,italicButton);
    connect(italicButton,SIGNAL(clicked()),this,SLOT(italicButtonClicked()));

    QToolTip::add
            (italicButton,"Scrittura in corsivo");      
     
    C6Button *underlineButton = new C6Button(frame9,0,0,path+"chat_02.png",path+"chat_pressed_02.png",path+"chat_over_02.png");
    underlineButton->setSticky();   
    underlinePlaceHolder->hide();
    layout50->insertWidget(3,underlineButton);
    connect(underlineButton,SIGNAL(clicked()),this,SLOT(underlineButtonClicked()));

    QToolTip::add
            (underlineButton,"Scrittura in sottolineato");          
    
    
    C6Button *colorButton = new C6Button(frame9,0,0,path+"chat_12.png",path+"chat_over_12.png",path+"chat_over_12.png");
    colorPlaceHolder->hide();
    layout50->insertWidget(4,colorButton);
    connect(colorButton,SIGNAL(clicked()),this,SLOT(colorButtonClicked()));

    QToolTip::add
            (colorButton,"Cambia colore");          
        
    
    C6Button *fontButton = new C6Button(frame9,0,0,path+"chat_22.png",path+"chat_pressed_22.png",path+"chat_over_22.png");
    fontPlaceHolder->hide();
    layout50->insertWidget(5,fontButton);
    connect(fontButton,SIGNAL(clicked()),this,SLOT(fontButtonClicked()));

    QToolTip::add
            (fontButton,"Cambia font");      
    
    C6Button *stopTransmit = new C6Button(frame8,0,0,path+"chat_termina.png",path+"chat_termina_over.png");
    stopTransmitPlaceHolder->hide();
    frame8Layout->addWidget(stopTransmit,0,1);
    connect(stopTransmit,SIGNAL(clicked()),this,SLOT(stopTransmitButtonClicked()));

    QToolTip::add
            (stopTransmit,"Interrompe la trasmissione del file");         
    
    C6Button *stopReceive = new C6Button(frame8,0,0,path+"chat_termina.png",path+"chat_termina_over.png");
    stopReceivePlaceHolder->hide();
    frame8Layout->addWidget(stopReceive,0,3);
    connect(stopReceive,SIGNAL(clicked()),this,SLOT(stopReceiveButtonClicked()));

    QToolTip::add
            (stopReceive,"Interrompe la ricezione del file");        
    
    C6PixmapCache &pix = C6PixmapCache::getInstance();
    upPiecePlaceHolder->setPixmap(pix.getPixmap(path+"chat_16.png"));
    downPiecePlaceHolder->setPixmap(pix.getPixmap(path+"chat_44.png"));

    MyChat->setFocus();
   
    connect(MyChat,SIGNAL(returnPressed()),this,SLOT(IsReturnPressed()));
    connect(MyChat,SIGNAL(cursorPositionChanged(int,int)),this,SLOT(getLastCursorPos(int,int)));
    
    QWidget *upParent = reinterpret_cast<QWidget*>(aboutButtonPlaceHolder->parent());
    C6Button* aboutButton = new C6Button(upParent,0,0,path+"chat_68.png",
                                         path+"chat_over_68.png",
                                         path+"chat_over_68.png");
    QToolTip::add
            (aboutButton,"Informazioni su OpenC6");
    aboutButtonPlaceHolder->hide();
    layout34->addWidget(aboutButton);   
    connect(aboutButton,SIGNAL(clicked()),this,SLOT(aboutClicked()));
    
    _isOnline = true;
    _firstShow = true;
    _canRaise = C6Settings::getInstance().getAutoRaise();
    transmitBar->setProgress(0);
    receiveBar->setProgress(0);
    connect(receiveSwitch,SIGNAL(toggled(bool)),SLOT(receiveSwitchSlot(bool)));
    connect(otherChat,SIGNAL(execUrl(QString&)),this,SLOT(execUrlProc(QString&)));
   
    _currentWritingColor.setRgb(0x00000000);
    
    QToolTip::add
            (userPicture,"Foto del netfriend");           
    
    global.setBehaviourIfMacOSX(MyChat);
    setCustomFont();   
    setMyChatFontAndColor();   
}

ChatView::~ChatView()
{
    disconnect(_httpData, 0, 0, 0);
    delete _httpData;     
    delete xferServer;
    delete sendButton;
    delete exitButton;
    
    closeTransferSocket(&xferSocket);
    closeTransferSocket(&_receiveSocket);      
}
/** Close chat win */
void ChatView::closeChat()
{
   close();    // then go to closeEvent
}
/** handle the send button */
void ChatView::SendChat()
{
    QString tmp = MyChat->text();
    if (tmp.length() > 0)
    {
        const char winEuroHex[2]={0x80,0};     
        const QChar unicodeEuro = 0x20ac;    
        tmp.replace(unicodeEuro,QString(winEuroHex));    
        
        updateMyText(myNick,MyChat->text());
        emit Append2Log(otherNick,myNick,tmp);
        emit messageSent();      
        emit sendChatMessage(otherNick,_isOnline,tmp);      
    }
    
    MyChat->clear();
}
/** update the chat area */
void ChatView::updateMyText(QString const & nick,QString const & text)
{
    QString tmp = text;    
    tmp.replace("<","&lt;");
    tmp.replace(">","&gt;");   
    tmp = setLocalTextAttribute(tmp); 
    otherChat->showMyText(nick,tmp,C6Settings::getInstance().getTimeStampSwitch());
}

/** update the chat area */
void ChatView::updateOtherText(QString & nick,QString &text,C6Proto::C6MessageStyle* inStyle)
{
    QString tmp = text;    
    tmp.replace("<","&lt;");
    tmp.replace(">","&gt;");
    tmp = setRemoteTextAttribute(tmp,inStyle);      
    otherChat->showOtherText(nick,tmp,C6Settings::getInstance().getTimeStampSwitch());
}

void ChatView::IsReturnPressed()
{
    QString tmp = MyChat->text();
    
    tmp.remove("\n");  
    tmp.remove("\r");     

    if (tmp.length())
    {
        MyChat->setText(tmp);
        SendChat();
    }
    else
    {
        MyChat->clear();
        MyChat->setFocus();
    }
}

void ChatView::ResetChat()
{
    otherChat->clear();
}

void ChatView::addToListClicked()
{
    QPopupMenu *groups = new QPopupMenu(this);
    C6Global &global = C6Global::getInstance();
    C6PixmapCache &pix = C6PixmapCache::getInstance();
    QString path = global.getSkinPath();
     
    QStringList availableGroups = global.getAllGroups();

    for(unsigned int i=0; i < availableGroups.count(); i++)
    {
        groups->insertItem(pix.getPixmap(path+"group_folder.png"),
                            "Aggiungi a "+availableGroups[i],i);
    }

    int ret = groups->exec(QCursor::pos());

    if (ret != -1)
    {
        emit AddNickFromChat(otherNick,availableGroups[ret]);
    }
    
    delete groups;   
}

void ChatView::profileClicked()
{
    C6Global &global = C6Global::getInstance();
    C6PixmapCache &pix = C6PixmapCache::getInstance();
    QString path = global.getSkinPath();
       
    QPopupMenu profileMenu(this);   
    
    profileMenu.insertItem(pix.getPixmap(path+"profile_penguin16x16.png"),
                       "Profilo ridotto",0);  
    profileMenu.insertItem(pix.getPixmap(path+"profile_penguin16x16.png"),
                           "Profilo completo",1);      
    
    int ret = profileMenu.exec(QCursor::pos());
       
    emit showUserProfile(otherNick,(ret == 1));
}

void ChatView::autoRaiseClicked()
{
    _canRaise = Switch(_canRaise);
}

bool ChatView::Switch(bool state)
{
    C6Global &global = C6Global::getInstance();
    QString path = global.getSkinPath();
    C6PixmapCache &pix = C6PixmapCache::getInstance();

    QPopupMenu OnOff;
    QString On,Off;

    if (state)
    {
        On = path + "ok.png";
        Off = "";
    }
    else
    {
        On = "";
        Off = path + "ok.png";
    }

    OnOff.insertItem(QIconSet(pix.getPixmap(On)),"On",0);
    OnOff.insertItem(QIconSet(pix.getPixmap(Off)),"Off",1);

    return(OnOff.exec(QCursor::pos()) == 0 ? true : false);
}

void ChatView::logButtonClicked()
{
    emit ShowUserLog(otherNick);
}

void ChatView::closeEvent(QCloseEvent *e)
{ 
    if (_receiveSocket != 0)
    {
        _receiveSocket->sendEndOfTransfer();
        _scheduledClose = true;   
    }     
    else
    {          
        deleteLater();
    }      
    emit removeChatFromList(otherNick);     
}

void ChatView::soundButtonClicked()
{
    C6Settings::getInstance().setSoundSwitch(Switch(C6Settings::getInstance().getSoundSwitch()));
}

void ChatView::specialChatNotify(QString nick,C6Users::C6USER_STATUS status)
{
    if (nick != otherNick)
    {
        if (C6Users::isStatusOnline(status))
        {
            serviceMessage(ENTER_CHAT_MSG(nick));
        }
        else
        {
            if (status == C6Users::U_OFFLINE)
            {
                serviceMessage(EXIT_CHAT_MSG(nick));
            }
        }
    }
}

void ChatView::smileyButtonClicked()
{
    C6PixmapCache &pix = C6PixmapCache::getInstance();
    QString path = C6Global::getInstance().getSkinPath();
    
    C6Smiley *smile = new C6Smiley(this,"smile",true);
    smile->reparent(0,QCursor::pos(),false);
    smile->setIcon(pix.getPixmap(path+"icon16x16.png"));

    int ret = smile->exec();

    if (ret != NORESULT)
    {
        int para,index;

        MyChat->getCursorPosition(&para,&index);
        MyChat->insertAt(C6Smiley::getSmileyText(ret),para,index);
        MyChat->setCursorPosition(para,index+C6Smiley::getSmileyText(ret).length());
    }

    delete smile;
}

void ChatView::receiveSwitchSlot(bool on)
{
    if (on)
    {      
        xferOnSwitch = true;
    }      
    else
    {      
        xferOnSwitch = false;
    }      
}

void ChatView::fileButtonClicked()
{
    QString s = QFileDialog::getOpenFileName(QDir::homeDirPath(),"Tutti i file  (*.*)",
                this,"open file dialog","Seleziona un file");

    if (s.length() > 0)
    {
        transmitBar->setProgress(0);
        transmitLocalProgress = 0;
        serviceMessage(TRANSMIT_START_MSG(s,otherNick));   
        emit sendFile(s,otherNick,_clientVersion);
    }
}

void ChatView::setMyNick(QString const & nick)
{
    myNick = nick;
    myNickLabel->setText(myNick);
}

void ChatView::windowActivationChange(bool prev)
{
    Chat::windowActivationChange(prev);

    if (prev == false)
    {
        emit chatIsActive(this);
    }
}


/*!
    \fn ChatView::startTransfer()
 */
void ChatView::startTransfer(QHostAddress ip,int port,QString const &filename)
{
    transmitLocalProgress = 0;
    transmitFileName = filename;   
    
    closeTransferSocket(&xferSocket);
    
    xferSocket = new C6XferProto(ip,port,filename,getOtherNick());
    connect(xferSocket,SIGNAL(xferError(int)),this,SLOT(xferSocket_Error(int)));
    connect(xferSocket,SIGNAL(xferClosed()),this,SLOT(xferSocket_connectionClosed()));
    connect(xferSocket,SIGNAL(xferAborted()),this,SLOT(xferAborted()));
    connect(xferSocket,SIGNAL(xferProgress(int)),this,SLOT(xferProgress(int)));
    xferSocket->fire();
    _transmitFileStarted = true;    
}

void ChatView::xferSocket_Error(int)
{
    QString nick = getOtherNick();

    xferSocket->close();
    serviceMessage(TRANSMIT_ABORT_MSG(transmitFileName));   
}

void ChatView::receiveSocketError(int)
{
    _receiveFileStarted = false;   
    _receiveSocket->close();
    serviceMessage(RECEIVE_ABORT_MSG(receiveFileName));   
}

void ChatView::xferSocket_connectionClosed()
{
    if (transmitLocalProgress < 100)
    {
        serviceMessage(TRASMIT_STOP_MSG(transmitFileName));      
    }
}

void ChatView::receiveSocketConnectionClosed()
{
    if (_receiveLocalProgress < 100)
    {
        if (_scheduledClose == true)
        {
            deleteLater();     
        }
    }     
    _receiveFileStarted = false;   
}      

void ChatView::xferAborted()
{
    xferSocket->close();
}

void ChatView::xferProgress(int progress)
{
    transmitLocalProgress = progress;

    if (progress == 255)
    {      
        progress = 100;
    }      

    transmitBar->setProgress(progress);

    if (transmitLocalProgress == 255)
    {      
        serviceMessage(END_OF_TRANSFER_MSG(transmitFileName));
    }      
}


/*!
    \fn ChatView::closeTransferSocket(C6XferSocket *socket)
 */
void ChatView::closeTransferSocket(C6XferProto **socket)
{
    if (*socket != 0)
    {
       (*socket)->deleteLater(); 
       *socket = 0;
    }
}


/*!
    \fn ChatView::stopTransmitButton_clicked()
 */
void ChatView::stopTransmitButtonClicked()
{
    transmitBar->setProgress(0);       
    if (_transmitFileStarted == true)
    {        
        if ((xferSocket != 0) && (transmitLocalProgress != 255))
        {
            xferSocket->sendEndOfTransfer();      
            serviceMessage(TRASMIT_STOP_MSG(transmitFileName));
        }
    }  
    
    _transmitFileStarted = false; 
}

/*!
    \fn ChatView::isReceiveOn()
*/ 
bool ChatView::isReceiveOn()
{
    return(xferOnSwitch);
}


/*!
    \fn ChatView::activateFileServer()
 */
void ChatView::activateFileServer(QString const &ip,int port)
{
    if (ip != QString::null)
    {   
        _receiveSocket = new C6XferProto(ip,port,myNick);      
        connect(_receiveSocket,SIGNAL(signalGateway(const QString&,int)),this,SLOT(slotGateway(const QString&,int)));    
        connect(_receiveSocket,SIGNAL(xferError(int)),this,SLOT(receiveSocketError(int)));
        connect(_receiveSocket,SIGNAL(xferClosed()),this,SLOT(receiveSocketConnectionClosed()));
        connect(_receiveSocket,SIGNAL(xferAborted()),this,SLOT(receiveAborted()));
        connect(_receiveSocket,SIGNAL(receiveProgress(int)),SLOT(receiveProgress(int)));
        connect(_receiveSocket,SIGNAL(signalFileSpec(QString&, long int )),SLOT(receiveFileSpec(QString&, long int)));
    }
    else
    {          
        if (xferServer == 0)
        {
            xferServer = new C6XferServer(serverPort);
            connect(xferServer,SIGNAL(receiveProgress(int)),this,SLOT(receiveProgress(int)));
            connect(xferServer,SIGNAL(signalFileSpec(QString&,long int)),this,SLOT(receiveFileSpec(QString&, long int )));
            connect(xferServer,SIGNAL(receiveAborted()),this,SLOT(receiveAborted()));
        }
        else
        {
            xferServer->reset();    
        }             
    }   
}


/*!
    \fn ChatView::receiveProgress(int progress)
 */
void ChatView::receiveProgress(int progress)
{
    _receiveLocalProgress = progress;
    
    if (progress == 255)
    {      
        progress = 100;
    }      

    receiveBar->setProgress(progress);

    if (_receiveLocalProgress == 255)
    {      
        closeTransferSocket(&_receiveSocket);    
        serviceMessage(END_OF_RECEIVE_MSG(receiveFileName,receiveFileSize));
    }      
}


/*!
    \fn ChatView::receiveFileSpec(QString &name,long int size)
 */
void ChatView::receiveFileSpec(QString &name,long int size)
{
    receiveFileName = name;
    receiveFileSize = size;
    _receiveFileStarted = true;
    
    if (QFile::exists(C6Settings::getInstance().getFileReceivePath()+name))
    {
        QFile::remove(C6Settings::getInstance().getFileReceivePath()+name);
    }
    serviceMessage(RECEIVE_START_MSG(otherNick,receiveFileName));  
}


/*!
    \fn ChatView::receiveAborted()
 */
void ChatView::receiveAborted()
{
    if (_scheduledClose != true) 
    {      
        serviceMessage(RECEIVE_STOP_MSG(otherNick,receiveFileName));      
    } 
    _receiveFileStarted = false;        
}


/*!
    \fn ChatView::getServerPort()
 */
int ChatView::getServerPort()
{
    return(serverPort);
}


/*!
    \fn ChatView::setReceive(bool state)
 */
void ChatView::setReceive(bool state)
{
    xferOnSwitch = state;
    receiveSwitch->setChecked(xferOnSwitch);
}


/*!
    \fn ChatView::stopReceiveButton_clicked()
 */
void ChatView::stopReceiveButtonClicked()
{
    receiveBar->setProgress(0);         
    
    if (_receiveFileStarted == true)
    {      
        if (_receiveLocalProgress != 255 && _receiveLocalProgress > 0)
        {
            if (xferServer != 0)
            {             
                xferServer->stopReceive();
            }
            else
            {
                _receiveSocket->sendEndOfTransfer();
            }                     
            serviceMessage(RECEIVE_ABORT_TRANSFER_MSG(receiveFileName,otherNick));
        }
    }
    
    _receiveFileStarted = false;   
}


/*!
    \fn ChatView::getLastCursorPos(int para,int index)
 */
void ChatView::getLastCursorPos(int para,int index)
{
    curIndex = index;
}

/*!
    \fn ChatView::serviceMessage(QString mess)
 */
void ChatView::serviceMessage(QString mess)
{
    otherChat->serviceMessage(mess);
}


/*!
    \fn ChatView::execUrlProc(QString )
 */
void ChatView::execUrlProc(QString & str)
{
    if (str.contains("FILE=") == true)
    {
        emit acceptReception(str.contains("Si"),otherNick);    
    }
    else
    {      
        if (str.contains("AUTH=") == true)
        {
            emit acceptAuthorization(str.contains("Si"),otherNick);  
        }
        else 
        {                           
            emit execUrl(str);
        }      
    }      
}

void ChatView::show()
{
    if (_firstShow)
    {
        _firstShow = false;
    }
    else
        if (!isMinimized())
        {
            int x0 = x();
            int y0 = y();
            move(x0,y0);
        }

    QWidget::show();
}



/*!
    \fn ChatView::takeFocus()
 */
void ChatView::takeFocus()
{
    MyChat->setFocus();
}


/*!
    \fn ChatView::setCustomFont()
 */
void ChatView::setCustomFont()
{
    C6Global &global=C6Global::getInstance();
    QFont lfont(global.getBaseFont());
    int tmp = lfont.pointSize()-1;
    if (tmp > 2)
    {
        lfont.setPointSize(tmp);
        fileReceptionLabel->setFont(lfont);  
        lfont.setBold(true);        
        otherNickLabel->setFont(lfont);
        myNickLabel->setFont(lfont);                  
    }
}

bool ChatView::getFocus()
{
    return(MyChat->hasFocus());
}

void ChatView::requestPictureFromWeb()
{
    QString myRequestUrl =C6Settings::getInstance().getPictureUrl();
    myRequestUrl+=otherNick+PICTURE_EXT;
   
    _httpData = new C6HttpConnection(myRequestUrl);
        
    connect(_httpData,SIGNAL(bufferFull(const QString&,C6HttpConnection*)),this,SLOT(requestPictureDone(const QString&,C6HttpConnection*)));
    _httpData->get();
}

void ChatView::requestPictureDone(const QString& filename,C6HttpConnection*)
{
    QByteArray data = _httpData->getBuffer().copy();
   
    if (data.size() > 0)
    {
        QWMatrix m;
        m.scale(0.686,0.6875);

        QPixmap picture(data);
        picture = picture.xForm(m);
        userPicture->setPixmap(picture);
    }
}

void ChatView::setMessaged(bool set)
{
    _isMessaged = set;
}      

bool ChatView::isMessaged() const
{
    return(_isMessaged);
}

void ChatView::aboutClicked()
{
    emit showAbout();
}
    


/*!
    \fn ChatView::setFriendNick(QString const &nick)
 */
void ChatView::setFriendNick(QString const &nick)
{
    otherNick = nick;
    setCaption(nick);
    otherNickLabel->setText(nick);   
    requestPictureFromWeb();      
}

/*!
    \fn ChatView::setFileTransferReceivePort(int port)
 */
void ChatView::setFileTransferReceivePort(int port)
{
    serverPort = port;
}

void ChatView::setOtherClientInfo(unsigned char* data,int length)
{
    const unsigned char* maxPtr = data+length;   
    int len = *data;
    
    C6Utils::safeByteRead(const_cast<unsigned char*>(data),&len,maxPtr);     
    data+=(len+1);
    data+=9; // skip timestamp+ip    
    int numfields = 0;    
    C6Utils::safeShortRead(const_cast<unsigned char*>(data),&numfields,maxPtr);                  
    data+=2;
        
    for (int i=0; i < numfields; i++)
    {
        C6Utils::safeShortRead(const_cast<unsigned char*>(data),&len,maxPtr);         
        if ((len & 0xff00) == 0x0f00)
        {
            _clientVersion = len & 0x00ff;        
            break;    
        }       
             
        data+=2;     
    }          
}      

void ChatView::slotGateway(const QString &ip,int port)
{
    emit signalGateway(ip,port,otherNick);           
}      

/*!
    \fn ChatView::boldButtonClicked()
 */
void ChatView::boldButtonClicked()
{
    _boldToggled = !_boldToggled;
    setMyChatFontAndColor();    
}


/*!
    \fn ChatView::italicButtonClicked()
 */
void ChatView::italicButtonClicked()
{
    _italicToggled = !_italicToggled;
    setMyChatFontAndColor();   
}


/*!
    \fn ChatView::underlineButtonClicked()
 */
void ChatView::underlineButtonClicked()
{
    _underlineToggled = !_underlineToggled;
    setMyChatFontAndColor();   
}


/*!
    \fn ChatView::colorButtonClicked()
 */
void ChatView::colorButtonClicked()
{
    QColor color = QColorDialog::getColor(_currentWritingColor,this);

    if (color.isValid())
    {
        _currentWritingColor = color;      
    }
    
    setMyChatFontAndColor();   
}


/*!
    \fn ChatView::fontButtonClicked()
 */
void ChatView::fontButtonClicked()
{
    int fontSize = _currentFontSizePt;
    int fontNo = _currentFontNo;
           
    C6ChatFontDialog fontDialog(fontNo,fontSize);
    
    int ret = fontDialog.exec();     
    
    if (ret == QDialog::Accepted)
    {
        _currentFontNo = fontNo;
        _currentFontSizePt = fontSize;   
    }          
    
    setMyChatFontAndColor();
}


/*!
    \fn ChatView::isBoldToggled()
 */
bool ChatView::isBoldToggled()
{
    return _boldToggled;
}


/*!
    \fn ChatView::isItalicToggled()
 */
bool ChatView::isItalicToggled()
{
    return _italicToggled;
}


/*!
    \fn ChatView::isUnderlineToggled()
 */
bool ChatView::isUnderlineToggled()
{
    return _underlineToggled;
}


/*!
    \fn ChatView::getCurrentFontNo() const
 */
int ChatView::getCurrentFontNo() const
{
    return(_currentFontNo);
}


/*!
    \fn ChatView::getCurrentFontSizeNo() const
 */
int ChatView::getCurrentFontSizePt() const
{
    return(_currentFontSizePt);
}


/*!
    \fn ChatView::setMyChatFontAndColor()
 */
void ChatView::setMyChatFontAndColor()
{
    QFont tmp(font());    
    
    tmp.setBold(_boldToggled);   
    tmp.setUnderline(_underlineToggled);
    tmp.setItalic(_italicToggled);    
    tmp.setPointSize(_currentFontSizePt);     
    const QStringList& fontStyle = C6Settings::getInstance().getVisualChatFontStyle();   
    tmp.setFamily(fontStyle[_currentFontNo]);   
    MyChat->setPaletteForegroundColor(_currentWritingColor);
    MyChat->setFont(tmp);
}


/*!
    \fn ChatView::setLocalTextAttribute(QString const & text)
 */

QString ChatView::setLocalTextAttribute(QString const & text)
{  
    QStyleSheetItem* item = otherChat->styleSheet()->item("cfouttag");
    if (item != 0)
    {          
        item->setColor(_currentWritingColor);
        item->setFontWeight(_boldToggled == true ? QFont::Bold : QFont::Normal);
        item->setFontUnderline(_underlineToggled);    
        item->setFontSize(_currentFontSizePt);
        item->setFontItalic(_italicToggled);
        const QStringList& fontStyle = C6Settings::getInstance().getVisualChatFontStyle();    
        item->setFontFamily(fontStyle[_currentFontNo]);    
    }        
        
    return ("<cfouttag>"+text+"</cfouttag>");
}

/*!
    \fn ChatView::setRemoteTextAttribute(QString const & text)
 */

QString ChatView::setRemoteTextAttribute(QString const & text,C6Proto::C6MessageStyle* inStyle)
{   
    QColor color(0,0,0);         // black
    QStyleSheetItem* item = otherChat->styleSheet()->item("cfintag");
    
    if (inStyle != 0)
    {         
        if (item != 0)
        {          
            int red;
            int green;
            int blue;         
            inStyle->getRGB(red,green,blue);    
            
            color.setRgb(red,green,blue);   
            item->setColor(color);
            item->setFontWeight(inStyle->isBold() == true ? QFont::Bold : QFont::Normal);
            item->setFontUnderline(inStyle->isUnderline());    
            item->setFontSize(inStyle->getFontSizePt());
            item->setFontItalic(inStyle->isItalic());
            const QStringList& fontStyle = C6Settings::getInstance().getVisualChatFontStyle();
            if (fontStyle.count() > 0)         // sanity check
            {                
                item->setFontFamily(fontStyle[inStyle->getFontTypeNo()]);    
            }            
        }        
    } 
    else
    {
        if (item != 0)
        {       
            item->setColor(color);      
            item->setFontWeight(QFont::Normal);
            item->setFontUnderline(false);    
            item->setFontSize(PLAIN_DEFAULT_FONT_SIZE);
            item->setFontItalic(false);
            item->setFontFamily(QApplication::font().family());          
        }      
    }          
    
    return ("<cfintag>"+text+"</cfintag>");
}

QString ChatView::getOtherNick() const
{
    return(otherNick);
}
        
bool ChatView::canRaise() const 
{ 
    return _canRaise; 
}
    
bool ChatView::isOnline() const 
{ 
    return _isOnline; 
}   
    
void ChatView::setOnlineStatus(bool status)
{
    _isOnline = status;     
}             
    
QColor& ChatView::getCurrentWritingColor() 
{
    return _currentWritingColor;      
}             



/*!
    \fn ChatView::rebuildFontAndColor()
 */
void ChatView::rebuildFontAndColor()
{
    setMyChatFontAndColor();    
}
