/*
 *
 * Copyright (C) 2002 Stefan Hellwig <stefan@stefanhellwig.de>
 *
 *   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 <dcopclient.h>
#include <dcopobject.h>
#include <kapplication.h>
#include <kdebug.h>
#include <qdatastream.h>
  
#include "savercontrol.h"

SaverControl::SaverControl()
{
    // Check DCOP configuration facilities
    // Check if KDE screensaver is enabled
    getSaverDCOPIface();
    saverWasEnabled = isScreenSaverEnabled();
}


SaverControl::~SaverControl()
{
    // At the end: enable screensaver if it has been active on startup
    disableScreenSaver( false );
}

bool SaverControl::getSaverDCOPIface()
{
    // Try to find the DCOP interface of the KDE screensaver. If it is found, we use
    // it to communicate with it in order to (de-)activate the KDE screensaver.

    dcop_KDESaver = kapp->dcopClient()->findObject( "kdesktop",
                                                    "KScreensaverIface",
                                                    "",
                                                    dcop_data,
                                                    dcop_screenSaverApp,
                                                    dcop_screenSaverObj );
    if ( dcop_KDESaver ) {
      return true;
    } else {
      return false;
    }
}

bool SaverControl::isScreenSaverEnabled()
{
    // Use DCOP to communicate with the KDE screensaver. This way we can find
    // out if it is currently enabled. That's the more elegant way than to scan
    // the screensaver's configuration file.

    bool enabled = false;

    QByteArray data, replyData;
    QCString replyType;
    if ( !kapp->dcopClient()->call( dcop_screenSaverApp, dcop_screenSaverObj, "isEnabled()",
                                    data, replyType, replyData) ) {
      kdWarning() << "SaverControl: Error in DCOP communication. Unable to get status of KDE Screensaver" << endl;
    } else {
      QDataStream reply(replyData, IO_ReadOnly);
      if (replyType == "bool") {
        reply >> enabled;
        kdDebug() << "SaverControl: KDE's screensaver isEnabled() returned " << enabled << endl;
      } else {
        kdWarning() << "SaverControl: Error in DCOP communication. Unexpected return type." << endl;
      }
    }
    return enabled;
}


void SaverControl::disableScreenSaver( bool disable )
{
    if ( !dcop_KDESaver ) return;

    if ( disable ) {
        QByteArray data;
        QDataStream arg(data, IO_WriteOnly);
        arg << false;
        if ( !kapp->dcopClient()->send( dcop_screenSaverApp, dcop_screenSaverObj, "enable(bool)", data ) ) {
          kdWarning() << "SaverControl: Error in DCOP communication. Unable to disable KDE Screensaver." << endl;
        } else {
          kdDebug() << "SaverControl: KDE screensaver successfully disabled." << endl;
        }
    } else {
        if ( saverWasEnabled ) {
            QByteArray data;
            QDataStream arg(data, IO_WriteOnly);
            arg << true;
            if ( !kapp->dcopClient()->send( dcop_screenSaverApp, dcop_screenSaverObj, "enable(bool)", data ) ) {
              kdWarning() << "SaverControl: Error in DCOP communication. Unable to enable KDE Screensaver." << endl;
            } else {
              kdDebug() << "SaverControl: KDE screensaver successfully enabled." << endl;
            }
        }
    }
}

bool SaverControl::getSaverStatus()
{
    bool        DCOP_KDESaver;
    QByteArray  DCOP_data;
    QCString    DCOP_screenSaverApp, DCOP_screenSaverObj;

    // Try to find the DCOP interface of the KDE screensaver. If it is found, we use
    // it to communicate with it in order to get the current setting of the screensaver.

    DCOP_KDESaver = kapp->dcopClient()->findObject( "kdesktop",
                                                    "KScreensaverIface",
                                                    "",
                                                    DCOP_data,
                                                    DCOP_screenSaverApp,
                                                    DCOP_screenSaverObj );
    if ( !DCOP_KDESaver ) return false;

    bool enabled = false;

    QByteArray data, replyData;
    QCString replyType;
    if ( !kapp->dcopClient()->call( DCOP_screenSaverApp, DCOP_screenSaverObj, "isEnabled()",
                                    data, replyType, replyData) ) {
      kdWarning() << "SaverControl: Error in DCOP communication. Unable to get status of KDE Screensaver" << endl;
    } else {
      QDataStream reply(replyData, IO_ReadOnly);
      if (replyType == "bool") {
        reply >> enabled;
      }
    }
    return enabled;
}

bool SaverControl::disableSaver()
{
    QByteArray  DCOP_data;
    QCString    DCOP_screenSaverApp, DCOP_screenSaverObj;

    // Try to find the DCOP interface of the KDE screensaver. If it is found, we use
    // it to communicate with it in order to (de-)activate the KDE screensaver.

    kapp->dcopClient()->findObject( "kdesktop",
                                    "KScreensaverIface",
                                    "",
                                    DCOP_data,
                                    DCOP_screenSaverApp,
                                    DCOP_screenSaverObj );
    QByteArray data;
    QDataStream arg(data, IO_WriteOnly);
    arg << false;
    if ( !kapp->dcopClient()->send( DCOP_screenSaverApp, DCOP_screenSaverObj, "enable(bool)", data ) ) {
      kdWarning() << "SaverControl: Error in DCOP communication. Unable to disable KDE Screensaver." << endl;
      return false;
    } else {
      kdDebug() << "SaverControl: KDE screensaver successfully disabled." << endl;
      return true;
    }
}

bool SaverControl::enableSaver()
{
    QByteArray  DCOP_data;
    QCString    DCOP_screenSaverApp, DCOP_screenSaverObj;

    // Try to find the DCOP interface of the KDE screensaver. If it is found, we use
    // it to communicate with it in order to (de-)activate the KDE screensaver.

    kapp->dcopClient()->findObject( "kdesktop",
                                    "KScreensaverIface",
                                    "",
                                    DCOP_data,
                                    DCOP_screenSaverApp,
                                    DCOP_screenSaverObj );
    
    QByteArray data;
    QDataStream arg(data, IO_WriteOnly);
    arg << true;
    if ( !kapp->dcopClient()->send( DCOP_screenSaverApp, DCOP_screenSaverObj, "enable(bool)", data ) ) {
      kdWarning() << "SaverControl: Error in DCOP communication. Unable to enable KDE Screensaver." << endl;
      return false;
    } else {
      kdDebug() << "SaverControl: KDE screensaver successfully enabled." << endl;
      return true;
    }
}

bool SaverControl::toggleSaver( bool enable ) {

  if( enable ) {
    return enableSaver();
  } else {
    return disableSaver();
  }
}
