
/***************************************************************************
 *                                                                         *
 *   KCPULoad is copyright (c) 1999-2000, Markus Gustavsson                *
 *                         (c) 2002, Ben Burton                            *
 *                                                                         *
 *   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 "icontoggleaction.h"
#include "kcpudock.h"
#include "kcpuload.h"
#include "kcpuproc.h"

#include <tdeaction.h>
#include <tdeconfig.h>
#include <tdelocale.h>
#include <tdepopupmenu.h>

KCPULoad::KCPULoad(TQWidget *parent, const char *name) :
        StatPopup(true, parent, name) {
    // Create the /proc reading class and check for SMP.
    proc = new KCPUProc();
    supportSMP = proc->hasSMP();

    // Set up actions and read the config file.
    setupActions();

    // the vector must not be reallocated during resizing because the class
    // that it contains (Reading) cannot be copied safely
    r.reserve(proc->cpu.size());

    // Create system tray windows.
    resizeReadings(supportSMP && actSMP->isChecked() ? proc->cpu.size() : 1);

    // Initialise the pop-up window.
    readPopupState();

    // Off we go!
    requestResize();
    if (isActive())
        startUpdates();
}

KCPULoad::~KCPULoad() {
    delete proc;
}

void KCPULoad::setSMP(bool set) {
    if (! supportSMP)
        return;

    resizeReadings(set ? proc->cpu.size() : 1);

    requestResize();
    if (isActive())
        takeReading();

    config->setGroup("General Options");
    config->writeEntry("SMP", set);
    config->sync();
}

TQString KCPULoad::dockName(int which) const {
    return i18n("CPU %1").arg(which+1);
}

TQColor KCPULoad::defaultDockColor(int which) const {
    static const TQColor c[] = {
        TQColor(0, 255, 0),
        TQColor(255, 0, 0),
        TQColor(255, 255, 0),
        TQColor(0, 255, 255)
    };
    return c[which % (sizeof(c)/sizeof(c[0]))];
}

void KCPULoad::setupCustomActions() {
    if (supportSMP) {
        bool bVal = config->readBoolEntry("SMP", false);
        actSMP = new IconToggleAction(i18n("Enable S&MP"), "smp",
            i18n("S&MP Enabled"), "smpon", 0, coll, "smp");
        actSMP->setChecked(bVal);
        connect(actSMP, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(setSMP(bool)));
    }
}

void KCPULoad::insertCustomItems(TDEPopupMenu* menu) {
    if (supportSMP) {
        actSMP->plug(menu);
        menu->insertSeparator();
    }
}

void KCPULoad::takeReadingInternal() {
      proc->readLoad();
  
    if (r.size() > 1) {
          if (isSplit()) {
            for (int i = 0; i < r.size(); i++) {
                r[i].upper = proc->cpu[i].userPercent();
                r[i].lower = proc->cpu[i].systemPercent();
            }
          } else {
            for (int i = 0; i < r.size(); i++) {
                r[i].upper = proc->cpu[i].totalPercent();
            }
          }
    } else if (r.size() > 0) {
          if (isSplit()) {
            r[0].upper = proc->all.userPercent();
            r[0].lower = proc->all.systemPercent();
          } else {
            r[0].upper = proc->all.totalPercent();
          }
      }
  
      if (isVisible()) {
        if (r.size() > 1) {
              if (isSplit()) {
		TQString user =
                    i18n("Current CPU User: %1%")
                    .arg(proc->all.userPercent());
                TQString sys =
                    i18n("Current CPU System: %1%")
                    .arg(proc->all.systemPercent());
                for (int i = 0; i < r.size(); i++) {
                    user += i18n(", C%1: %2%").arg(i+1).arg(r[i].upper);
                    sys  += i18n(", C%1: %2%").arg(i+1).arg(r[i].lower);
                }
                fullReading = i18n("%1.\n%2.").arg(user, sys);
              } else {
                TQString total =
                    i18n("Current CPU usage: %1%")
                    .arg(proc->all.totalPercent());
                for (int i = 0; i < r.size(); i++) {
                    total += i18n(", C%1: %2%").arg(i+1).arg(r[i].upper);
                }
                fullReading = i18n("%1.").arg(total);
              }
        } else if (r.size() > 0) {
              if (isSplit()) {
                  fullReading = i18n(
                      "Current CPU User: %1%.\n"
                      "Current CPU System: %2%.")
                    .arg(r[0].upper).arg(r[0].lower);
              } else {
                fullReading = i18n("Current CPU usage: %1%.").arg(r[0].upper);
              }
          }
      }
  }
  
void KCPULoad::resizeReadings(int n)
{
    int i = r.size();
    r.resize(n);
    for (; i < n; i++) {
        // action is needed by KCPUDock constructor
        r[i].Init(i, this);
        KCPUDock* dock = new KCPUDock(i, this);
        dock->setCPULabel(i+1);
        r[i].dock = dock;
    }
    // special case single CPU or total
    if (n == 1) {
        static_cast<KCPUDock*>(r[0].dock)->setCPULabel(0);
    } else if (n > 1) {
        static_cast<KCPUDock*>(r[0].dock)->setCPULabel(1);
    }
}

#include "kcpuload.moc"
