/*
  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) version 2.
*/

/*
  Copyright (C) 2008 Eli J. MacKenzie <argonel at gmail.com>
*/



#include "queuetuner.h"
#include "server.h"
#include "ircqueue.h"
#include "channel.h"
#include "viewcontainer.h"
#include "konversationapplication.h"

#include <tqtoolbutton.h>
#include <tqspinbox.h>
#include <tqpopupmenu.h>
#include <tqevent.h>

#include <kdebug.h>
#include <tdeapplication.h>
#include <kiconloader.h>
#include <tdemessagebox.h>
#include <kstdguiitem.h>
#include <tdelocale.h>


QueueTuner::QueueTuner(TQWidget* parent, ViewContainer *container)
: QueueTunerBase(parent), m_server(0), m_timer(this, "qTuner"),
    m_vis(Preferences::self()->showQueueTunerItem()->value())
{
    m_closeButton->setIconSet(kapp->iconLoader()->loadIconSet("window-close", TDEIcon::Toolbar, 16));
    connect(m_closeButton, TQ_SIGNAL(clicked()), TQ_SLOT(close()));
    connect(container, TQ_SIGNAL(frontServerChanging(Server*)), TQ_SLOT(setServer(Server*)));
    connect(&m_timer, TQ_SIGNAL(timeout()), TQ_SLOT(timerFired()));

    connect(m_slowRate, TQ_SIGNAL(valueChanged(int)), TQ_SLOT(slowRateChanged(int)));
    connect(m_slowType, TQ_SIGNAL(activated(int)), TQ_SLOT(slowTypeChanged(int)));
    connect(m_slowInterval, TQ_SIGNAL(valueChanged(int)), TQ_SLOT(slowIntervalChanged(int)));

    connect(m_normalRate, TQ_SIGNAL(valueChanged(int)), TQ_SLOT(normalRateChanged(int)));
    connect(m_normalType, TQ_SIGNAL(activated(int)), TQ_SLOT(normalTypeChanged(int)));
    connect(m_normalInterval, TQ_SIGNAL(valueChanged(int)), TQ_SLOT(normalIntervalChanged(int)));

    connect(m_fastRate, TQ_SIGNAL(valueChanged(int)), TQ_SLOT(fastRateChanged(int)));
    connect(m_fastType, TQ_SIGNAL(activated(int)), TQ_SLOT(fastTypeChanged(int)));
    connect(m_fastInterval, TQ_SIGNAL(valueChanged(int)), TQ_SLOT(fastIntervalChanged(int)));
}

QueueTuner::~QueueTuner()
{
}

//lps, lpm, bps, kbps
static void rateToWidget(IRCQueue::EmptyingRate& rate, TQSpinBox *r, TQComboBox* t, TQSpinBox *i)
{
    r->setValue(rate.m_rate);
    t->setCurrentItem(rate.m_type);
    i->setValue(rate.m_interval/1000);
}

void QueueTuner::serverDestroyed(TQObject* ref)
{
    if (ref == m_server)
        setServer(0);
}

void QueueTuner::setServer(Server* newServer)
{
    const char *w=0;
    bool toShow=false;
    if (!m_server && newServer)
    {
        toShow=true;
        w="showing";
    }
    else if (!newServer && m_server)
    {
        hide();
        w="hiding";
    }
    else
        w="unchanged";
    // since this is tied to the new signal, we assume we're only getting called with a change

    m_server = newServer;

    if (toShow)
        show();

    if (m_server)
    {
        connect(m_server, TQ_SIGNAL(destroyed(TQObject*)), TQ_SLOT(serverDestroyed(TQObject*)));

        getRates();
    }
}

void QueueTuner::getRates()
{
    if (!m_server) // you can only get the popup if there is a server, but.. paranoid
        return;

    rateToWidget(m_server->m_queues[0]->getRate(), m_slowRate, m_slowType, m_slowInterval);
    rateToWidget(m_server->m_queues[1]->getRate(), m_normalRate, m_normalType, m_normalInterval);
    rateToWidget(m_server->m_queues[2]->getRate(), m_fastRate, m_fastType, m_fastInterval);
}

void QueueTuner::timerFired()
{
    if (m_server)
    {
        IRCQueue *q=0;

        q=m_server->m_queues[0];
        m_slowAge->setNum(q->currentWait()/1000);
        m_slowBytes->setNum(q->bytesSent());
        m_slowCount->setNum(q->pendingMessages());
        m_slowLines->setNum(q->linesSent());

        q=m_server->m_queues[1];
        m_normalAge->setNum(q->currentWait()/1000);
        m_normalBytes->setNum(q->bytesSent());
        m_normalCount->setNum(q->pendingMessages());
        m_normalLines->setNum(q->linesSent());

        q=m_server->m_queues[2];
        m_fastAge->setNum(q->currentWait()/1000);
        m_fastBytes->setNum(q->bytesSent());
        m_fastCount->setNum(q->pendingMessages());
        m_fastLines->setNum(q->linesSent());

        m_srverBytes->setNum(m_server->m_encodedBytesSent);
        m_globalBytes->setNum(m_server->m_bytesSent);
        m_globalLines->setNum(m_server->m_linesSent);
        m_recvBytes->setNum(m_server->m_bytesReceived);
    }
}

void QueueTuner::open()
{
    Preferences::setShowQueueTuner(true);
    show();
}

void QueueTuner::close()
{
    Preferences::setShowQueueTuner(false);
    QueueTunerBase::close();
}

void QueueTuner::show()
{
    if (m_server && Preferences::showQueueTuner())
    {
        QueueTunerBase::show();
        m_timer.start(500);

    }
}

void QueueTuner::hide()
{
    QueueTunerBase::hide();
    m_timer.stop();
}

void QueueTuner::slowRateChanged(int v)
{
    if (!m_server) return;
    int &r=m_server->m_queues[0]->getRate().m_rate;
    r=v;
}

void QueueTuner::slowTypeChanged(int v)
{
    if (!m_server) return;
    IRCQueue::EmptyingRate::RateType &r=m_server->m_queues[0]->getRate().m_type;
    r=IRCQueue::EmptyingRate::RateType(v);
}

void QueueTuner::slowIntervalChanged(int v)
{
    if (!m_server) return;
    int &r=m_server->m_queues[0]->getRate().m_interval;
    r=v*1000;
}

void QueueTuner::normalRateChanged(int v)
{
    if (!m_server) return;
    int &r=m_server->m_queues[1]->getRate().m_rate;
    r=v;
}

void QueueTuner::normalTypeChanged(int v)
{
    if (!m_server) return;
    IRCQueue::EmptyingRate::RateType &r=m_server->m_queues[1]->getRate().m_type;
    r=IRCQueue::EmptyingRate::RateType(v);
}

void QueueTuner::normalIntervalChanged(int v)
{
    if (!m_server) return;
    int &r=m_server->m_queues[1]->getRate().m_interval;
    r=v*1000;
}

void QueueTuner::fastRateChanged(int v)
{
    if (!m_server) return;
    int &r=m_server->m_queues[2]->getRate().m_rate;
    r=v;
}

void QueueTuner::fastTypeChanged(int v)
{
    if (!m_server) return;
    IRCQueue::EmptyingRate::RateType &r=m_server->m_queues[2]->getRate().m_type;
    r=IRCQueue::EmptyingRate::RateType(v);
}

void QueueTuner::fastIntervalChanged(int v)
{
    if (!m_server) return;
    int &r=m_server->m_queues[2]->getRate().m_interval;
    r=v*1000;
}

void QueueTuner::contextMenuEvent(TQContextMenuEvent* e)
{
    TQPopupMenu p(this);
    p.insertItem("Reset...", 1);
    int id = p.exec(e->globalPos());
    if (id > 0)
    {

        TQString question(i18n("This cannot be undone, are you sure you wish to reset to default values?"));
        int x = KMessageBox::warningContinueCancel(this, question, i18n("Reset Values"), KStdGuiItem::reset(), TQString(), KMessageBox::Dangerous);
        if ( x == KMessageBox::Continue)
        {
            Server::_resetRates();
            getRates();
        }
    }
    e->accept();
}

#include "queuetuner.moc"
