/***************************************************************************
                          dockwidget.cpp  -  description
                             -------------------
    begin                : Mon Apr 23 2001
    copyright            : (C) 2001 by Dieter Landolt
    email                : dieter.landolt@secs.ch
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 <kapp.h>
#include <kglobal.h>
#include <kstandarddirs.h>
#include <kmainwindow.h>
#include <khelpmenu.h>
#include <kiconloader.h>
#include <ksimpleconfig.h>
#include <kconfig.h>
#include <klocale.h>
#include <kpopupmenu.h>
#include <kmessagebox.h>
#include <kaboutdata.h>
#include <kpixmapio.h>
#include <qevent.h>
#include <qtooltip.h>
#include <qwhatsthis.h> 
#include <qpainter.h>
#include <qpoint.h>
#include <qpixmap.h>
#include <qimage.h>
#include <qstring.h>
#include <qfile.h>
#include <kaudioplayer.h>

#include "dockwidget.h"

QPoint *DockWidget::globalPos = new QPoint::QPoint(0,0);

DockWidget::DockWidget(QWidget *parent, const char *name, DockWidget::Type type )
           : KSystemTray(parent,name) {

led_state = Undeff; // Must be unknown at start to display the rigth state
soundOffPath = QString("");
soundOnPath =  QString("");
led_type = type;
sname = new QString("");
keylocked = false;
setPixmap(paintIcon(Off));

switch (led_type) {
     case Numlock:   QToolTip::add(this, i18n("numlock is off"));
                     QWhatsThis::add(this, i18n("this is the numlock state led"));
                     sname->append(i18n("Numlock"));
                     break;
     case Capslock:  QToolTip::add(this, i18n("capslock is off"));
                     QWhatsThis::add(this, i18n("this is the capslock state led"));
                     sname->append(i18n("Capslock"));
                     break;
     case Scrollock: QToolTip::add(this, i18n("srollock is off"));
                     QWhatsThis::add(this, i18n("this is the scrollock state led"));
                     sname->append(i18n("Scrollock"));
                     break;
     default : delete this;
}

// Creating the standard helpmenu for inserting into contextmenu
KHelpMenu *help = new KHelpMenu(this,kapp->aboutData());

// Change the Restore default entrie to Preferences
contextMenu()->changeTitle(contextMenu()->idAt(0), kapp->miniIcon(), "Keyboard  Led");

QString *x = new QString(sname->ascii());

contextMenu()->insertItem(QIconSet(BarIcon("help")),i18n("&Help"), help->menu() );
contextMenu()->insertItem(x->append(i18n(" set to on")), 0);
contextMenu()->insertSeparator(-1);
contextMenu()->insertItem(QString(i18n("lock %1 key")) .arg(sname->ascii()), 1);
// contextMenu()->insertItem(QString("Initial value"), 1);
/*
TODO Change the default Menuentry from Restore to Preferences if it os possible
Wish from 10.5.2002.

for ( unsigned int i=1;i<=contextMenu()->count();i++) {
  qDebug(contextMenu()->text(contextMenu()->idAt(i)));

}

*/

// Read the special Configuration
readConfig();

connect(contextMenu(), SIGNAL(activated(int)), SLOT(menuHandler(int)));

// show();

}

DockWidget::~DockWidget(){
    delete sname; // Memory for sname return
}

void DockWidget::checkState(){
	// Temporary
	switch (led_type) {
		case Numlock   : toggleState();
                           break;
		case Capslock  : toggleState();
                           break;
		case Scrollock : toggleState();
                           break;
	}
}


void DockWidget::toggleState()
{
  setState((State)!led_state);
}

void DockWidget::toggle()
{
  toggleState();
}

// Toggle State fr Testzwecke
void DockWidget::toggle(int)
{
  toggleState();
}

void DockWidget::setState( State state )
{
  // Handels here the locking State.
  static unsigned int i = 0;
  if ( i < 100 )
      i++;

  if (led_state != state)
    {
      if(led_state != Undeff) {
        if(keylocked == true && state == Off) {
            keylocked = false;
            stateChanged(led_state);
            keylocked = true;
            return;
        }
        if(keylocked == true && state == On) {
            keylocked = false;
            stateChanged(led_state);
            keylocked = true;
            return;
        }
      }

      led_state = state;
      QString *x = new QString(sname->ascii());
      QString *y = new QString(sname->ascii());
      if ( led_state == Off ) {
         contextMenu()->changeItem(y->append(i18n(" set to on")), 0);
         if(!movOff.isNull()) {
            this->setMovie(movOff);
            movOff.restart();
            movOff.unpause(); // QT Bug Workarournd to be able to restart
         } else {
            this->setPixmap(pixOff);
         }
         if (usesounds && i > 3) {
            KAudioPlayer::play(soundOffPath);
         }
         QToolTip::add(this, x->append(i18n(" is off")));
      } else {
         contextMenu()->changeItem(y->append(i18n(" set to off")), 0);
         if(!movOn.isNull()) {
            this->setMovie(movOn);
            movOn.restart();
            movOn.unpause(); // QT Bug Workarournd to be able to restart
         } else {
            this->setPixmap(pixOn);
         }
         if (usesounds && i > 3) {
            KAudioPlayer::play(soundOnPath);
         }
         QToolTip::add(this, x->append(i18n(" is on")));
      }
      update();
      stateChanged(state);
    }
}

void DockWidget::on()
{
  setState(On);
}

void DockWidget::off()
{
  setState(Off);
}
/** Handels the Contextmenu */
void DockWidget::menuHandler(int menuitem){
  QPixmap hpix;
  switch (menuitem) {
     case(0) : toggleState();
               break;
     case(1) :
               setlocked(! keylocked);
               repaint();
               break;
     case(12): KMessageBox::about(this,"Gesamthilfe");
               kapp->invokeHelp();
               break;
     case(13): KMessageBox::about(this,"Was ist das aktivieren");
               // topLevelWidget()->enterWhatsThisMode();
               break;
     case(17): KMessageBox::about(this,"ber kkeyled");
               break;
     case(18): KMessageBox::about(this,"ber KDE");
               break;
   }
}
/** Overwrites the default Mouse Event */
void DockWidget::mousePressEvent(QMouseEvent *e){
  QWidget *pw = parentWidget();

  globalPos->setX(e->globalX() - e->x());
  globalPos->setY(e->globalY() - e->y());

  /* Need to handle show and hide since kde3.1
     they changed the handling
     Use now the switch statement to hendle it self.
  */
  switch ( e->button() ) {
  case LeftButton:
         // toggleMinimizeRestore();
         if ( pw->isVisible() ) {
            pw->hide();
         } else {
            pw->show();
         }
      break;
  default:
    KSystemTray::mousePressEvent(e);
    break;
  }
}

/** uses the hide or show dependig from bool show */
void DockWidget::changeVisible(int s){
   if(s == 2)
     this->show();
   else
     this->hide();
}
/** return the state for the led */
bool DockWidget::getState(){
     return (bool) led_state;
}
/** read's the configuration after change is notified */
void DockWidget::readConfig(){
     QString on_path;
     QString off_path;
 
     // Clear the pixmaps for a well reconfigurations    
     pixOff.resize(0,0);
     pixOn.resize(0,0);

     // setlocked(keylocked); // restore the locked settings
     // KSimpleConfig conf ("Kkeyledrc");
     KGlobal::config()->setGroup("Ledpictures");

     if(KGlobal::config()->readBoolEntry("UseTheme",false ) ) {
       usepixmap = KGlobal::config()->readBoolEntry("UsePictures",false );
       usesounds = KGlobal::config()->readBoolEntry("UseSounds",false );
     } else {
        usepixmap = false;
        usesounds = false;
     }

     if ( usesounds ) {
          switch (led_type) {
               case Numlock:
                         soundOffPath = locate("data",KGlobal::config()->readPathEntry("numoffsound_path"));
                         soundOnPath  = locate("data",KGlobal::config()->readPathEntry("numonsound_path"));
                         break;
               case Capslock:
                         soundOffPath = locate("data",KGlobal::config()->readPathEntry("capsoffsound_path"));
                         soundOnPath  = locate("data",KGlobal::config()->readPathEntry("capsonsound_path"));
                         break;
               case Scrollock:
                         soundOffPath = locate("data",KGlobal::config()->readPathEntry("scrolloffsound_path"));
                         soundOnPath  = locate("data",KGlobal::config()->readPathEntry("scrollonsound_path"));
                         break;
          }
     }
     if ( usepixmap ) {
          switch (led_type) {     
               case Numlock:
                         off_path    = locate("data",KGlobal::config()->readPathEntry("numoff_path"));
                         on_path     = locate("data",KGlobal::config()->readPathEntry("numon_path"));
                         break;
               case Capslock:  
                         off_path   = locate("data",KGlobal::config()->readPathEntry("capsoff_path"));
                         on_path    = locate("data",KGlobal::config()->readPathEntry("capson_path"));
                         break;
               case Scrollock: 
                         off_path = locate("data",KGlobal::config()->readPathEntry("scrolloff_path"));
                         on_path  = locate("data",KGlobal::config()->readPathEntry("scrollon_path"));
                         break;
               default:  usepixmap = false;
          }
          
          if (off_path != QString::null && QFile::exists(off_path) ) {
               //pixOff = QPixmap(off_path);
               movOff = QMovie(off_path);
               if(movOff.isNull()) {
                  pixOff.load(off_path);
               }
         } else {
               movOff = 0;
               pixOff = paintIcon(Off);               
         }
          if (on_path != QString::null && QFile::exists(on_path) ) {
               // pixOn = QPixmap(on_path);
               movOn = QMovie(on_path);
               if(movOn.isNull()) {
                  pixOn.load(on_path);
                }
         } else {
               movOn = 0;
               pixOn = paintIcon(On);               
          }
     } else {
               movOff = 0;
               movOn = 0;
               pixOff = paintIcon(Off);               
               pixOn = paintIcon(On);               
     }          
     if (led_state == On) {
          if(movOn.isNull()) {
            this->setMovie(QMovie(""));
            this->setPixmap(pixOn);
          } else {
            this->setMovie(movOn);
          }
     } else {
          if(movOff.isNull()) {
             this->setMovie(QMovie(""));
             this->setPixmap(pixOff);
           } else {
             this->setMovie(movOff);
           }
     }
     // QT Bug Workarournd to be to get only one Loop and not infinite 
     movOff.connectStatus(this, SLOT(slotStatusOff(int)));
     movOn.connectStatus(this, SLOT(slotStatusOn(int)));
     // QT End Workarournd
     repaint();
     // Switch config section to the group 
     KGlobal::config()->setGroup("Trayvisible");
     // show();
     switch (led_type) {
     	case Numlock: 
		if ( KGlobal::config()->readBoolEntry("Numlock",true )) {
			show();
		}
		break;
     	case Capslock:
		 if ( KGlobal::config()->readBoolEntry("Capslock",true )) {
			show();
		}
		break;
     	case Scrollock: 
		if ( KGlobal::config()->readBoolEntry("Scrollock",true )) {
			show();
		}
		break;
     }
}
/** Paints a Iconon into a pixmap and returns it to the caller.
It's the default icon, witch can be used. */
QPixmap DockWidget::paintIcon(State state){
     // Generate the Icon by Initialising 
     QPixmap pp; // = new QPixmap(width(),height());
     pp.resize(24,24);
     QPainter *d = new QPainter(&pp /* ,this */);
     d->setBrush(QColor (black));
     d->drawRect(0,0,pp.width() -4 ,pp.height() -4);	
     if (state == On) {
          d->fillRect(2,2,pp.width() -4,pp.height() -4 , QBrush (QColor(0,255,0),SolidPattern));
     } else {
          d->fillRect(2,2,pp.width() -4,pp.height() -4 , QBrush (QColor(0,128,0),SolidPattern));
     }
     d->flush();
     d->end();
     pp.resize(20,20);
     delete d; /* Remove the Painterobject after use */
     return pp;
}

/** Lets Paint */
void DockWidget::paintEvent(QPaintEvent *ev){
  KSystemTray::paintEvent(ev);
  if(keylocked == true) {
      QPainter *d = new QPainter(this);
      if(led_state == Off) {
        d->setPen(QPen(QColor (128,128,128),4));
      } else {
        d->setPen(QPen(QColor (black),4));
      }
      d->drawLine(width() -6 ,6,6,height()-6);
      d->drawEllipse(3,3,width()-5,height()-5);
      if(led_state == Off) {
        d->setPen(QPen(QColor (255,128,128),1));
      } else {
        d->setPen(QPen(QColor (red),1));
      }
      d->drawEllipse(3,3,width()-5,height()-5);
      d->drawLine(width() -6 ,6,6,height()-6);

      d->flush();
      d->end();
      delete d;
  }
}
/** to set the key locked or unlockef */
void DockWidget::setlocked(bool state){
  if(! state) {
    contextMenu()->setItemEnabled(0,true);
    contextMenu()->changeItem(1,QString(tr2i18n("lock %1 key")) .arg(sname->ascii()));
  } else {
    contextMenu()->setItemEnabled(0,false);
    contextMenu()->changeItem(1,QString(tr2i18n("unlock %1 key")) .arg(sname->ascii()));
  }
  keylocked = state;
}
