/***************************************************************************
 *   Copyright (C) 2007 by Anistratov Oleg                                 *
 *   ower@users.sourceforge.net                                            *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License version 2        *
 *   as published by the Free Software Foundation;                         *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 ***************************************************************************/

#include "singlemessagewgt.h"

#include <QScrollBar>
#include <QGridLayout>
#include <QDateTime>

#include "inputtextwgt.h"
#include "chattextwgt.h"
#include "singlemessage.h"

QList<SingleMessageWgt*> SingleMessageWgt::m_newMessages;
QList<SingleMessageWgt*> SingleMessageWgt::m_openedMessages;
int                      SingleMessageWgt::m_currentNewMessage(-1);
int                      SingleMessageWgt::m_currentOpenedMessage(-1);

QSize SingleMessageWgt::m_lastSize(500, 250);
QPoint SingleMessageWgt::m_lastPosition(-1, -1);

SingleMessageWgt::SingleMessageWgt(const QString & title, const QString & message, uint destUid, const QHostAddress & addr, bool isIncoming, QWidget *parent) : /*QDialog*/QWidget(parent)
{
  init(title, message, destUid, addr, isIncoming);
}

SingleMessageWgt::SingleMessageWgt(SingleMessage* msg, bool isIncoming, QWidget * parent) : /*QDialog*/QWidget(parent)
{
  QDateTime dt;
  dt.setTime_t(msg->receiveTime());

  init(tr("Message ") + tr(isIncoming ? "from " : "to ") + msg->userName() + QString("[") + dt.toString("hh:mm:ss") + "] ",
       msg->msg(),
       msg->srcUid(),
       QHostAddress(msg->srcIp()),
       isIncoming);

  m_message = msg;
  m_message->setIsVisible(true);
  m_message->setMessageWgt(this);

  if(!msg->isIncoming())
    if(msg->isHtml())
      m_inputText->setHtml(msg->msg());
    else
      m_inputText->setPlainText(msg->msg());

  m_inputText->moveCursor(QTextCursor::End);
}

//\*****************************************************************************
SingleMessageWgt::~SingleMessageWgt()
{
  qDebug("[SingleMessageWgt::~SingleMessageWgt]\n");
}
//\*****************************************************************************
void SingleMessageWgt::retranslate()
{
  m_closeBtn       ->setText(tr("&Close"       ));
  m_sendBtn        ->setText(tr("&Send"        ));
  m_replyBtn       ->setText(tr("&Reply"       ));
  m_replyQuotedBtn ->setText(tr("Reply &Quoted"));
  m_importantChbx  ->setText(tr("Important"));
}
//\*****************************************************************************
void SingleMessageWgt::slot_reply()
{
  m_importantChbx->show();
  m_sendBtn ->show();
  m_inputText->show();

  m_replyQuotedBtn->hide();
  m_replyBtn      ->hide();

  QGridLayout* grid = qobject_cast<QGridLayout*>(this->layout());
  Q_ASSERT(grid);

  grid->removeWidget(m_replyQuotedBtn);
  grid->removeWidget(m_replyBtn);
  grid->addWidget(m_sendBtn      , 2, 0, 1, 1);
  grid->addWidget(m_closeBtn     , 2, 1, 1, 1);
  grid->addWidget(m_importantChbx, 2, 2, 1, 1);

  grid->setColumnStretch(0, 1);
  grid->setColumnStretch(1, 1);

  m_inputText->setToolTip(tr("Replying to ") + m_title + "(" + m_destAddr.toString() + ")");
  setWindowTitle(tr("Replying to ") + m_title + "(" + m_destAddr.toString() + ")");

  m_inputText->setFocus();
}
//\*****************************************************************************
void SingleMessageWgt::slot_replyQuoted()
{
  QString str = QString(">") + m_messageIn->toPlainText();
  m_quot = true;

  str.replace("\n", "\n>");
  if(str[str.size() - 1] == ('>') && str.size() > 1)
     str.resize(str.size() - 1);
  else
    str.append("\n");

  m_messageIn->text()->setFontItalic(true);
  m_messageIn->text()->setPlainText(str);

  m_importantChbx->show();
  m_sendBtn ->show();
  m_inputText->show();

  m_replyQuotedBtn->hide();
  m_replyBtn      ->hide();

  QGridLayout* grid = qobject_cast<QGridLayout*>(this->layout());
  Q_ASSERT(grid);

  grid->removeWidget(m_replyQuotedBtn);
  grid->removeWidget(m_replyBtn);
  grid->addWidget(m_sendBtn      , 2, 0, 1, 1);
  grid->addWidget(m_closeBtn     , 2, 1, 1, 1);
  grid->addWidget(m_importantChbx, 2, 2, 1, 1);

  grid->setColumnStretch(0, 1);
  grid->setColumnStretch(1, 1);

  m_inputText->setToolTip(tr("Replying to ") + m_title + "(" + m_destAddr.toString() + ")");
  setWindowTitle(tr("Replying to ") + m_title + "(" + m_destAddr.toString() + ")");

  m_inputText->setFocus();
}
//\*****************************************************************************
void SingleMessageWgt::slot_selfDestroy()
{
  if(m_message)
  {
    m_message->setIsVisible(false);
    m_message->setMessageWgt(NULL);
    m_message->setOld();
  }

  // removing object from new and opened messages lists
  if(m_newMessages.contains(this))
  {

    int idx = m_newMessages.indexOf(this);

    if(m_currentNewMessage >= idx)
      m_currentNewMessage--;

    m_newMessages.removeAll(this);
  }

  if(m_openedMessages.contains(this))
  {

    int idx = m_openedMessages.indexOf(this);

    if(m_currentOpenedMessage >= idx)
      m_currentOpenedMessage--;

    m_openedMessages.removeAll(this);
  }

  hide();
  this->~SingleMessageWgt();
}
//\*****************************************************************************
void SingleMessageWgt::slot_sendMessage()
{
  qDebug("[SingleMessageWgt::slot_sendMessage]: addr = '%s'", m_destAddr.toString().toLocal8Bit().data());

  if(m_quot)
    emit singleMessage(m_messageIn->toPlainText() + m_inputText->toPlainText(), m_destUid, m_importantChbx->checkState() == Qt::Checked);
  else
    emit singleMessage(m_inputText->toPlainText(), m_destUid, m_importantChbx->checkState() == Qt::Checked);

  slot_selfDestroy();
}
//\*****************************************************************************
void SingleMessageWgt::init(const QString & title, const QString & message, uint destUid, const QHostAddress & addr, bool isIncoming)
{
  m_isIncoming = isIncoming;
  m_quot       = false;
  m_destAddr   = addr;
  m_title      = title;
  m_destUid    = destUid;
  m_message    = NULL;

  QGridLayout*  grid;

  grid             = new QGridLayout (this);
  m_closeBtn       = new QPushButton (this);
  m_sendBtn        = new QPushButton (this);
  m_replyBtn       = new QPushButton (this);
  m_replyQuotedBtn = new QPushButton (this);
  m_messageIn      = new ChatTextWgt (this);
  m_inputText      = new InputTextWgt(this);
  m_importantChbx  = new QCheckBox   (this);

  m_messageIn->setMinimumWidth(400);
  m_inputText->setMinimumWidth(400);

  if(m_isIncoming)
  {
    grid->addWidget(m_messageIn     , 1, 0, 1, 3);

    grid->addWidget(m_replyBtn      , 2, 0, 1, 1);
    grid->addWidget(m_replyQuotedBtn, 2, 1, 1, 1);
    grid->addWidget(m_closeBtn      , 2, 2, 1, 1);

    grid->addWidget(m_inputText     , 4, 0, 1, 3);

    m_importantChbx->hide();
    m_sendBtn  ->hide();
    m_inputText->hide();

    m_messageIn->setMsg(message);
  }
  else
  {
    grid->addWidget(m_inputText     , 1, 0, 1, 3);
    grid->addWidget(m_importantChbx , 2, 2, 1, 1);
    grid->addWidget(m_sendBtn       , 2, 0, 1, 1);
    grid->addWidget(m_closeBtn      , 2, 1, 1, 1);

    grid->setColumnStretch(0, 1);
    grid->setColumnStretch(1, 1);

    m_replyBtn      ->hide();
    m_replyQuotedBtn->hide();
    m_messageIn     ->hide();

    m_inputText->setFocus();
  }

  grid->setMargin(4);

  m_messageIn->setFocus();

  resize(m_lastSize);
  if(m_lastPosition != QPoint(-1, -1))
    move(m_lastPosition);

  connect(m_replyBtn      , SIGNAL(clicked()) , this, SLOT(slot_reply      ()));
  connect(m_replyQuotedBtn, SIGNAL(clicked()) , this, SLOT(slot_replyQuoted()));
  connect(m_closeBtn      , SIGNAL(clicked()) , this, SLOT(slot_selfDestroy()));
  connect(m_sendBtn       , SIGNAL(clicked()) , this, SLOT(slot_sendMessage()));
  connect(m_inputText     , SIGNAL(wantSend()), this, SLOT(slot_sendMessage()));

  setWindowTitle(m_title + "(" + addr.toString() + ")");

  qDebug("[SingleMessageWgt::SingleMessageWgt]: addr = '%s'", m_destAddr.toString().toLocal8Bit().data());

  retranslate();

  SingleMessageWgt::addOpenedMessage(this);

  show();
}

void SingleMessageWgt::closeEvent(QCloseEvent * ev)
{
  if(m_message)
  {
    m_message->setIsVisible(false);
    m_message->setMessageWgt(NULL);
  }

  ev->ignore();
  slot_selfDestroy();
}

void SingleMessageWgt::resizeEvent(QResizeEvent* ev)
{
  m_lastSize = ev->size();
}

void SingleMessageWgt::moveEvent(QMoveEvent* ev)
{
  m_lastPosition = ev->pos();
}

void SingleMessageWgt::nextPrevMessage(const QList<SingleMessageWgt*>& msgs, int& curMsg, int direction, bool closeCurrent)
{
  int size = msgs.size();

  if(!size)
    return;

  if(closeCurrent && curMsg >= 0 && curMsg < size)
  {
    msgs[curMsg]->slot_selfDestroy();
    size = msgs.size();
  }

  if(!size)
    return;

  if(direction > 0)
    curMsg += ((curMsg < 0 || curMsg >= size - 1) ?  -curMsg : 1);
  else if(direction < 0)
    curMsg = ((curMsg <= 0) ?  (size - 1) : curMsg - 1);
  else return;

  QRect geometry = msgs[curMsg]->geometry();

  msgs[curMsg]->hide();
  msgs[curMsg]->show();
  msgs[curMsg]->setGeometry(geometry);
  msgs[curMsg]->setFocus();
}

void SingleMessageWgt::closeMessages(QList<SingleMessageWgt*>& msgs, int& curMsg)
{
  foreach(SingleMessageWgt* sm, msgs)
    sm->slot_selfDestroy();

  msgs.clear();
  curMsg = -1;
}
