//
// C++ Implementation: c6chatroom
//
// Description:
//
//
// Author: Giorgio A. <openc6@hotmail.com>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "c6chatroom.h"
#include "c6pixmapcache.h"
#include <qlayout.h>
#include <qlistbox.h>
#include <qstring.h>
#include <qpopupmenu.h>
#include <qptrlist.h>
#include <qinputdialog.h>
#include <qpushbutton.h>
#include <qlabel.h>
#include <qpainter.h>
#include <qfont.h>
#include <qtooltip.h>
#include "c6textedit.h"
#include "c6button.h"
#include "c6smiley.h"
#include "c6settings.h"
#include "c6global.h"
#include "c6invitedialog.h"
#include <qmessagebox.h>

class BoldListBoxItem : public QListBoxText
{

public :
    BoldListBoxItem(QListBox *box,const QString &name):QListBoxText(box,name)
    {}

protected:
    virtual void paint(QPainter *painter)
    {
        painter->save();
        QFont lfont(painter->font());
        lfont.setBold(true);
        painter->setFont(lfont);
        QListBoxText::paint(painter);
        painter->restore();
    }
};


class RoomDynamicTip : public QToolTip
{
    public:
        RoomDynamicTip(QWidget* parent,QString const& tipText) 
            : QToolTip(parent),
            _parent(parent),
            _tipText(tipText)            
            {}

    protected:
        virtual void maybeTip(const QPoint & pos)
        {
            tip(_parent->geometry(),_tipText);                
        }
    private :
        QWidget* _parent;          
        QString const& _tipText;  
};

C6ChatRoom::C6ChatRoom()
        : ChatRoom(0,0),
        _isKicked(false)
{
    C6Global &global = C6Global::getInstance();
    QString path = global.getSkinPath();
    C6PixmapCache &pix = C6PixmapCache::getInstance();

    setIcon(C6PixmapCache::getInstance().getPixmap(path+"icon16x16.png"));   
      
    C6Button* exitButton = new C6Button(frame15,0,0,path+"chat_71.png",path+"chat_over_109.png");
    exitButtonPlaceHolder->hide();
    layout33->addWidget(exitButton);
    connect(exitButton,SIGNAL(clicked()),this,SLOT(exitClicked()));

    QToolTip::add
        (exitButton,"Esce dalla stanza");

    sendButtonPlaceHolder->hide();
    C6Button* 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(sendText()));

    channel = new C6TextEdit(frame14, 0, 0, 0, 0);
    channel->setFrameShape( QTextEdit::NoFrame );
    channel->setFrameShadow( QTextEdit::Plain );
    channel->setPaletteBackgroundColor(QColor(255,255,255));
    otherChatPlaceHolder->hide();
    frame14Layout->addWidget(channel, 0, 0 );
    connect(channel,SIGNAL(execUrl(QString&)),this,SLOT(execUrlProc(QString&)));

    C6Button *smileyButton = new C6Button(frame9,0,0,path+"chat_37.png",path+"chat_over_37.png",path+"chat_over_37.png");
    smileyPlaceHolder->hide();
    layout13_2->addWidget(smileyButton);
    connect(smileyButton,SIGNAL(clicked()),this,SLOT(emoticonsClicked()));

    QToolTip::add
        (smileyButton,"Visualizza smiley");

    C6Button *logButton = new C6Button(frame9,0,0,path+"chat_40.png",path+"chat_over_40.png",path+"chat_over_40.png");
    logPlaceHolder->hide();
    layout13_2->addWidget(logButton);
    connect(logButton,SIGNAL(clicked()),this,SLOT(showLog()));
   
    QToolTip::add
        (logButton,"Log delle conversazioni di questa stanza");
    
    C6Button *kickButton = new C6Button(frame6,0,0,path+"chatroom_01.png",path+"chatroom_over_01.png",path+"chatroom_over_01.png");
    kickPlaceHolder->hide();
    layout18->addWidget(kickButton);
    connect(kickButton,SIGNAL(clicked()),this,SLOT(kickClicked()));

    QToolTip::add
            (kickButton,"Caccia fuori dalla stanza l'utente selezionato");

    C6Button *roomListButton = new C6Button(frame6,0,0,path+"chat_room_25.png",path+"chat_room_over_25.png",path+"chat_room_over_25.png");
    roomListPlaceHolder->hide();
    layout18->addWidget(roomListButton);
    connect(roomListButton,SIGNAL(clicked()),this,SLOT(channelListClicked()));

    QToolTip::add
        (roomListButton,"Lista delle stanze aperte");

    C6Button *inviteButton = new C6Button(frame6,0,0,path+"chatroom_invite.png",path+"chatroom_invite_over.png",path+"chatroom_invite_over.png");
    invitePlaceHolder->hide();
    layout18->addWidget(inviteButton);
    connect(inviteButton,SIGNAL(clicked()),this,SLOT(inviteNetfriend()));

    QToolTip::add
        (inviteButton,"Invita un netriend in questa stanza");

    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()));

    userListMenu = new QPopupMenu(this);
    userListMenuChild = new QPopupMenu(userListMenu);

    userListMenu->insertItem(QIconSet(pix.getPixmap(path+"filetypes.png")),"Inizia chat",INITCHAT);
    userListMenu->insertItem(QIconSet(pix.getPixmap(path+"kick16x16.png")),"Kick",KICK);
    userListMenu->insertItem(QIconSet(pix.getPixmap(path+"color_line.png")),"Guarda log",USRLOG);
    userListMenu->insertItem(QIconSet(pix.getPixmap(path+"login-photo.png")),"Profilo completo",PROFILE);
    userListMenu->insertItem(QIconSet(pix.getPixmap(path+"login-photo.png")),"Profilo ridotto",ALLPROFILE);
    userListMenu->insertItem(QIconSet(pix.getPixmap(path+"edit_add.png")),"Aggiungi nick a",userListMenuChild);

    connect(friendList,SIGNAL(contextMenuRequested(QListBoxItem *,const QPoint &)),this,
            SLOT(showMenus(QListBoxItem *,const QPoint &)));
    connect(friendList,SIGNAL(doubleClicked(QListBoxItem *)),this,SLOT(doubleClicked(QListBoxItem *)));
    connect(MyChat,SIGNAL(returnPressed()),this,SLOT(IsReturnPressed()));
    connect(MyChat,SIGNAL(cursorPositionChanged(int,int)),this,SLOT(getLastCursorPos(int,int)));

    new RoomDynamicTip(roomName,_roomTopic);    
    
    updateColorFont();
    global.setBehaviourIfMacOSX(MyChat);
    global.setBehaviourIfMacOSX(friendList);
    setCustomFont();   
}


C6ChatRoom::~C6ChatRoom()
{
    delete channel;
}


/*!
    \fn C6ChatRoom::getroomName()
 */
const QString & C6ChatRoom::getRoomName() const
{
    return(_roomName);
}


/*!
    \fn C6ChatRoom::updateUserList(QStringList *list)
 */
void C6ChatRoom::updateUserList(QMap<QString,int>& users)
{
    friendList->clear();
    QMap<QString,int>::iterator it;    
    
    for (it = users.begin(); it != users.end(); it++)
    {
        updateTheList(it.key(),false);
    }

    userCount->setText("Utenti: "+QString::number(users.size()));
}


/*!
    \fn C6ChatRoom::serviceMessage(QString mess)
 
    send mess to the channell
 */
void C6ChatRoom::serviceMessage(QString mess)
{
    channel->serviceMessage(mess,C6Settings::getInstance().getRoomTimeStamp());
}

/** update the chat area */
void C6ChatRoom::updateMyText(QString &nick,QString &text)
{
    QString tmpLog  = nick+" - "+text;
    QString tmp = text;    
    
    tmp.replace("<","&lt;");
    tmp.replace(">","&gt;");   
    
    channel->showMyText(nick,tmp,C6Settings::getInstance().getRoomTimeStamp());
    emit append2Log(_roomName,tmpLog);
}

/** update the chat area */
void C6ChatRoom::updateOtherText(QString &nick,QString &text)
{
    QString tmpLog  = nick+" - "+text;    
    QString tmp = text;    
    tmp.replace("<","&lt;");
    tmp.replace(">","&gt;");   
    
    channel->showOtherText(nick,tmp,C6Settings::getInstance().getRoomTimeStamp());
    emit append2Log(_roomName,tmpLog);
}

/** handle the send button */
void C6ChatRoom::sendText()
{
    if (_isKicked == false)
    {
        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,tmp);
            emit sendToRoom(_roomName,tmp,0);
        }

        MyChat->clear();
        MyChat->setFocus();
    }
}

/** No descriptions */
void C6ChatRoom::IsReturnPressed()
{
    if (_isKicked == false)
    {
        QString tmp = MyChat->text();

        tmp.remove("\n");
        tmp.remove("\r");

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

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


/*!
    \fn C6ChatRoom::exitClicked()
 */
void C6ChatRoom::exitClicked()
{
    close();
}


/*!
    \fn C6ChatRoom::updateTheList(QString &name,C6 action)
 */
void C6ChatRoom::updateTheList(QString const& name,bool isExitFromRoom)
{
    if (isExitFromRoom)
    {
        QListBoxItem *item = friendList->findItem(name,0);

        if (item)
        {
            friendList->takeItem(item);
        }
    }
    else
    {
        if (name == _myNick)
        {
            BoldListBoxItem *item = new BoldListBoxItem(friendList,name);
        }
        else
        {
            friendList->insertItem(name);
        }
    }

    userCount->setText("Utenti: "+QString::number(friendList->count()));
}



/*!
    \fn C6ChatRoom::showMenus(QListViewItem *item,const QPoint & pos)
 */
void C6ChatRoom::showMenus(QListBoxItem *item,const QPoint & pos)
{
    if (item != 0)
    {         
        C6Global &global = C6Global::getInstance();
        C6PixmapCache &pix = C6PixmapCache::getInstance();
        QString path = global.getSkinPath();
    
        QStringList groups = C6Global::getInstance().getAllGroups();
        userListMenuChild->clear();
        for (unsigned int i =0;i < groups.count(); i++)
        {
            userListMenuChild->insertItem(pix.getPixmap(path+"group_folder.png"),groups[i],i+MOVE);
        }
    
        int ret = userListMenu->exec(pos);
    
        if (ret != -1)
        {
            emit menuUserAction(_roomName,item->text(),static_cast<USER_MENU_ACTIONS>(ret));
        }
    }   
}


/*!
    \fn C6ChatRoom::doubleClicked(QListViewItem * item)
 */
void C6ChatRoom::doubleClicked(QListBoxItem * item)
{
    if (item != 0)
    {      
        emit menuUserAction(_roomName,item->text(),INITCHAT);
    }     
}


/*!
    \fn C6ChatRoom::execUrlProc(QString url)
 */
void C6ChatRoom::execUrlProc(QString & url)
{
    emit execUrl(url);
}

void C6ChatRoom::closeEvent ( QCloseEvent * e )
{
    emit exitFromRoom(_roomName);
    deleteLater();
}

/*!
    \fn C6ChatRoom::emoticonsClicked()
 */
void C6ChatRoom::emoticonsClicked()
{
    C6Global &global = C6Global::getInstance();
    QString path = global.getSkinPath();

    C6Smiley *smile = new C6Smiley(this,"smile",true);
    smile->reparent(0,QCursor::pos(),false);
    smile->setIcon(QPixmap(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;
}


/*!
    \fn C6ChatRoom::requestProfile()
 */
void C6ChatRoom::kickClicked()
{
    if (friendList->selectedItem() != 0)
    {               
        QString selectedItem = friendList->selectedItem()->text();    
        emit menuUserAction(_roomName,selectedItem,static_cast<USER_MENU_ACTIONS>(KICK));   
    }
    else
    {
        QMessageBox box("Attenzione","Selezionare un utente dalla lista!",QMessageBox::Warning,
                        QMessageBox::Ok,QMessageBox::NoButton,
                        QMessageBox::NoButton,this);
        box.exec();      
    }            
}


/*!
    \fn C6ChatRoom::showLog()
 */
void C6ChatRoom::showLog()
{
    emit signalRoomLog(_roomName);
}


/*!
    \fn C6ChatRoom::channelListClicked()
 */
void C6ChatRoom::channelListClicked()
{
    QPtrList<C6ChatRoom> *list = reinterpret_cast<QPtrList<C6ChatRoom>*>(C6Global::getInstance().getRoomListPtr());
    if (list != 0)
    {
        QPopupMenu channelListMenu;

        for(unsigned int i=0; i < list->count(); i++)
        {
            if (list->at(i) !=0)
            {            
                if(list->at(i)->getRoomName().compare(_roomName) != 0)
                {            
                    channelListMenu.insertItem(list->at(i)->getRoomName(),i);
                }
            }                     
        }

        if (channelListMenu.count())
        {
            int ret = channelListMenu.exec(QCursor::pos());

            if (ret >= 0)
            {
                QString tmp = list->at(ret)->getRoomName();
                emit switchToRoom(tmp);
            }
        }
    }
}

#include "c6chatroom.moc"


/*!
    \fn C6ChatRoom::updateColorFont()
 */
void C6ChatRoom::updateColorFont()
{
    C6Settings &settings = C6Settings::getInstance();
    MyChat->setFont(QFont(settings.getFontStyle(),settings.getFontSize(),settings.getFontWeight()));
   //MyChat->setPaletteForegroundColor(settings.getForegndColor());
  //  channel->setFont(QFont(settings.getFontStyle(),settings.getFontSize()));
}


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


/*!
    \fn C6ChatRoom::setCustomFont()
 */
void C6ChatRoom::setCustomFont()
{
    C6Global &global=C6Global::getInstance();
    QFont lfont(global.getBaseFont());

    MyChat->setFont(lfont);
    int tmp = lfont.pointSize()-1;

    if (tmp > 2)
    {
        friendList->setFont(lfont);      
        lfont.setPointSize(tmp);
        lfont.setBold(true);
        roomName->setFont(lfont);
        myNick->setFont(lfont);
        userCount->setFont(lfont);
    }
}


/*!
    \fn C6ChatRoom::inviteNetfriend()
 */
void C6ChatRoom::inviteNetfriend()
{
    C6InviteDialog *invite = new C6InviteDialog(this);
    connect(invite,SIGNAL(sendSelected(const QStringList&,const QString&)),
            this,SLOT(sendSelected(const QStringList&,const QString&)));
    connect(invite,SIGNAL(showAbout()),this,SLOT(aboutClicked()));
    invite->exec();

    disconnect(invite,0,0,0);
    delete invite;
}


/*!
    \fn C6ChatRoom::sendSelected(const QString &)
 */
void C6ChatRoom::sendSelected(const QStringList &nick,const QString &message)
{
    emit inviteSelected(_roomName,nick,message);
}

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

void C6ChatRoom::setKicked()
{
    friendList->clear();
    userCount->setText("Utenti: "+QString::number(0));   
    _isKicked = true;
}

/*!
    \fn C6ChatRoom::setRoomName(Qstring const &,QString const & roomTopic)
 */
void C6ChatRoom::setRoomName(QString const & name,QString const & roomTopic)
{
    _roomName = name;
    _roomTopic = roomTopic;
    
    QString text = QString::fromAscii(name);
    
    if (roomTopic.length() > 0)
    {
        text+=" - "+roomTopic+" -";     
    }              
    
    roomName->setText(text);    
}


/*!
    \fn C6ChatRoom::setMyNick(QString const &)
 */
void C6ChatRoom::setMyNick(QString const &nick)
{
    _myNick = nick;
    myNick->setText(QString::fromAscii(_myNick));   
}


/*!
    \fn C6ChatRoom::setRoomCaption(QString const & roomName,int roomAttribute)
 */
void C6ChatRoom::setRoomCaption(QString const & roomName,int roomAttribute)
{
    setCaption(QString::fromAscii("Stanza: " +roomName));
}
