/*
 * power.cpp
 *
 * Copyright (c) 1999 Paul Campbell <paul@taniwha.com>
 *
 * Requires the Qt widget libraries, available at no cost at
 * http://www.troll.no/
 *
 *  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.
 *
 *  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.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <iostream.h>

#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>

#include <qfileinfo.h>
#include <qstring.h>
#include <qhbuttongroup.h>
#include <qlayout.h>

#include <klocale.h>
#include <kconfig.h>
#include <stdio.h>
#include <knumvalidator.h>

#include "power.h"
#include "portable.h"
#include "version.h"

PowerConfig::PowerConfig (QWidget * parent, const char *name)
  : KCModule(parent, name)
{
	editwait = 0;
	powerOff = 0;
	nopowerOff = 0;
	apm = laptop_portable::has_power_management();

	if (!apm) {
		QVBoxLayout *top_layout = new QVBoxLayout(this, 12, 5);

		QLabel* explain = laptop_portable::no_power_management_explanation(this);
		top_layout->addWidget(explain, 0);

		top_layout->addStretch(1);

		top_layout->activate();

	} else {
		int can_standby = laptop_portable::has_standby();
		int can_suspend = laptop_portable::has_suspend();
		int can_hibernate = laptop_portable::has_hibernation();

		if (!can_standby && !can_suspend && !can_hibernate)
			apm = 0;
		if (!apm) {
			QVBoxLayout *top_layout = new QVBoxLayout(this, 12, 5);

			QLabel* explain = laptop_portable::how_to_do_suspend_resume(this);
			top_layout->addWidget(explain, 0);

			top_layout->addStretch(1);

			top_layout->activate();
		} else {
			QVBoxLayout *top_layout = new QVBoxLayout(this, 12, 5);

			QHBoxLayout *box0 = new QHBoxLayout;
			top_layout->addLayout(box0, 0);

			QGroupBox* box1 = new QGroupBox(i18n("Not Powered:"), this);
			box0->addWidget(box1, 0);
			QVBoxLayout *a0 = new QVBoxLayout(box1, 20, 3);
			a0->addSpacing(8);

			nopowerBox = new QButtonGroup("", 0, "disconnect");
			if (can_suspend) {
				nopowerSuspend = new QRadioButton(i18n("Suspend"), box1, "nosuspend");
				nopowerSuspend->setMinimumSize(nopowerSuspend->sizeHint());
				a0->addWidget(nopowerSuspend, 0);
				nopowerBox->insert(nopowerSuspend);
			} else {
				nopowerSuspend = NULL;
			}
			if (can_standby) {
				nopowerStandby = new QRadioButton(i18n("Standby"), box1, "nostandby");
				nopowerStandby->setMinimumSize(nopowerStandby->sizeHint());
				a0->addWidget(nopowerStandby, 0);
				nopowerBox->insert(nopowerStandby);
			} else {
				nopowerStandby = NULL;
			}
			if (can_hibernate) {
				nopowerHibernate = new QRadioButton(i18n("Hibernate"), box1, "nohibernate");
				nopowerHibernate->setMinimumSize(nopowerHibernate->sizeHint());
				a0->addWidget(nopowerHibernate, 0);
				nopowerBox->insert(nopowerHibernate);
			} else {
				nopowerHibernate = NULL;
			}
			nopowerOff = new QRadioButton(i18n("Off"), box1, "nooff");
			nopowerOff->setMinimumSize(nopowerOff->sizeHint());
			a0->addWidget(nopowerOff, 0);
			nopowerBox->insert(nopowerOff);

  			connect(nopowerBox, SIGNAL(clicked(int)), this, SLOT(configChanged()));

			QLabel* noedlabel = new QLabel(i18n("Wait for (mins):"), box1);
			noedlabel->setMinimumSize(noedlabel->sizeHint());
			a0->addWidget(noedlabel, 0);

			noeditwait = new QLineEdit(box1);
			noeditwait->setMinimumSize(noeditwait->sizeHint());
                        noeditwait->setValidator(new KIntValidator( noeditwait ));
  			connect(noeditwait, SIGNAL(textChanged(const QString&)), this, SLOT(configChanged()));
			a0->addWidget(noeditwait, 0);


			QGroupBox* box2 = new QGroupBox(i18n("Powered:"), this);
			box0->addWidget(box2, 0);
			QVBoxLayout *a1 = new QVBoxLayout(box2, 20, 3);
			a1->addSpacing(8);



			powerBox = new QButtonGroup("", 0, "connect");
			if (can_suspend) {
				powerSuspend = new QRadioButton(i18n("Suspend"), box2, "suspend");
				powerSuspend->setMinimumSize(powerSuspend->sizeHint());
				a1->addWidget(powerSuspend, 0);
				powerBox->insert(powerSuspend);
			} else {
				powerSuspend = NULL;
			}
			if (can_standby) {
				powerStandby = new QRadioButton(i18n("Standby"), box2, "standby");
				powerStandby->setMinimumSize(powerStandby->sizeHint());
				a1->addWidget(powerStandby, 0);
				powerBox->insert(powerStandby);
			} else {
				powerStandby = NULL;
			}
			if (can_hibernate) {
				powerHibernate = new QRadioButton(i18n("Hibernate"), box2, "hibernate");
				powerHibernate->setMinimumSize(powerHibernate->sizeHint());
				a1->addWidget(powerHibernate, 0);
				powerBox->insert(powerHibernate);
			} else {
				powerHibernate = NULL;
			}
			powerOff = new QRadioButton(i18n("Off"), box2, "off");
			powerOff->setMinimumSize(powerOff->sizeHint());
			a1->addWidget(powerOff, 0);
			powerBox->insert(powerOff);

  			connect(powerBox, SIGNAL(clicked(int)), this, SLOT(configChanged()));
			QLabel* edlabel = new QLabel(i18n("Wait for (mins):"), box2);
			edlabel->setMinimumSize(edlabel->sizeHint());
			a1->addWidget(edlabel, 0);

			editwait = new QLineEdit(box2);
			editwait->setMinimumSize(editwait->sizeHint());
                        editwait->setValidator(new KIntValidator( editwait ));
  			connect(editwait, SIGNAL(textChanged(const QString&)), this, SLOT(configChanged()));
			a1->addWidget(editwait, 0);

			box0->addStretch(1);

			QLabel* explain = new QLabel(i18n("This panel configures the behavior of the automatic\npower-down feature - it works as a sort of extreme\nscreen-saver, you can configure different timeouts\nand behaviors depending on whether or not your\nlaptop is plugged in to the power.\n"), this);
			explain->setMinimumSize(explain->sizeHint());
			top_layout->addWidget(explain, 0);

			if (can_standby) {
				QLabel* explain3 = new QLabel(i18n("Different laptops may respond to 'standby' in\ndifferent ways - in many it's only a temporary\nstate and may not be useful for you."), this);
				explain3->setMinimumSize(explain3->sizeHint());
				top_layout->addWidget(explain3, 0);
			}

			top_layout->addStretch(1);

			QHBoxLayout *v1 = new QHBoxLayout;
			top_layout->addLayout(v1, 0);
			v1->addStretch(1);
			QString s1 = LAPTOP_VERSION;
			QString s2 = i18n("Version: ")+s1;
			QLabel* vers = new QLabel(s2, this);
			vers->setMinimumSize(vers->sizeHint());
			v1->addWidget(vers, 0);


			top_layout->activate();
		}
	}

  	config =  new KConfig("kcmlaptoprc");

	load();
}


void PowerConfig::save()
{
  if (editwait) {
      	power = getPower();
      	nopower = getNoPower();
	edit_wait = editwait->text();
	noedit_wait = noeditwait->text();
  }

  config->setGroup("LaptopPower");
  config->writeEntry("NoPowerSuspend", nopower);
  config->writeEntry("PowerSuspend", power);
  config->writeEntry("PowerWait", edit_wait);
  config->writeEntry("NoPowerWait", noedit_wait);
  config->sync();
	changed(false);
    ::system("klaptopdaemon&");
}

void PowerConfig::load()
{
  config->setGroup("LaptopPower");
  nopower = config->readNumEntry("NoPowerSuspend", (nopowerStandby?1:nopowerSuspend?2:0));
  power = config->readNumEntry("PowerSuspend", 0);
  edit_wait = config->readEntry("PowerWait", "20");
  noedit_wait = config->readEntry("NoPowerWait", "5");

  // the GUI should reflect the real values
  if (editwait) {
	editwait->setText(edit_wait);
	noeditwait->setText(noedit_wait);
   	setPower(power, nopower);
  }
	changed(false);
}

void PowerConfig::defaults()
{
  setPower(1, 0);
  edit_wait = "20";
  noedit_wait = "5";
  if (editwait) {
	editwait->setText(edit_wait);
        noeditwait->setText(noedit_wait);
  }
}

int  PowerConfig::getNoPower()
{
  if (!apm)
	return(nopower);
  if (nopowerHibernate && nopowerHibernate->isChecked())
    return 3;
  if (nopowerStandby && nopowerStandby->isChecked())
    return 1;
  if (nopowerSuspend && nopowerSuspend->isChecked())
    return 2;
  return(0);
}

int  PowerConfig::getPower()
{
  if (!apm || !powerOff)
	return(power);
  if (powerHibernate && powerHibernate->isChecked())
    return 3;
  if (powerStandby && powerStandby->isChecked())
    return 1;
  if (powerSuspend && powerSuspend->isChecked())
    return 2;
  return(0);
}

void PowerConfig::setPower(int p, int np)
{
  if (!apm || nopowerOff == 0)
	return;
  if (nopowerSuspend) {
	nopowerSuspend->setChecked(FALSE);
  } else {
	if (np == 2) np = 0;
  }
  if (nopowerStandby) {
	nopowerStandby->setChecked(FALSE);
  } else {
	if (np == 1) np = 0;
  }
  if (nopowerHibernate) {
	nopowerHibernate->setChecked(FALSE);
  } else {
	if (np == 3) np = 0;
  }
  nopowerOff->setChecked(FALSE);
  switch (np) {
  case 0: nopowerOff->setChecked(TRUE);break;
  case 1: nopowerStandby->setChecked(TRUE);break;
  case 2: nopowerSuspend->setChecked(TRUE);break;
  case 3: nopowerHibernate->setChecked(TRUE);break;
  }
  if (powerSuspend) {
	powerSuspend->setChecked(FALSE);
  } else {
	if (p == 2) np = 0;
  }
  if (powerStandby) {
	powerStandby->setChecked(FALSE);
  } else {
	if (p == 1) np = 0;
  }
  if (powerHibernate) {
	powerHibernate->setChecked(FALSE);
  } else {
	if (p == 3) np = 0;
  }
  powerOff->setChecked(FALSE);
  switch (p) {
  case 0: powerOff->setChecked(TRUE);break;
  case 1: powerStandby->setChecked(TRUE);break;
  case 2: powerSuspend->setChecked(TRUE);break;
  case 3: powerHibernate->setChecked(TRUE);break;
  }
}



void PowerConfig::configChanged()
{
  emit changed(true);
}


QString PowerConfig::quickHelp() const
{
  return i18n("<h1>Laptop Power Control</h1>This module allows you to "
	"control the power settings of your laptop");

}

#include "power.moc"
