/***************************************************************************
                          lmsensorswidget.cpp  -  description
                             -------------------
    begin                : Mon Aug 6 2001
    copyright            : (C) 2001 by 
    email                : 
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 <tqobject.h>
#include <tqobjectlist.h>
#include <tqpixmap.h>
#include <tqtimer.h>

#include <kiconloader.h>
#include <kstddirs.h>

#include "lmsensorswidget.h"


/***************************************************************************
 *  Public methods                                                         *
 ***************************************************************************/

LMSensorsWidget::LMSensorsWidget(LMSensors *lsensors,TQWidget *parent, const char *name )
                                :  TQWidget(parent,name,
                                   WStyle_Customize    |
                                   WType_TopLevel      |
                                   WStyle_StaysOnTop   |
                                   WStyle_NormalBorder |
                                   WDestructiveClose     )
{
 panelsSize= 64;
 setMinimumSize(0,0);
 setSizeIncrement(64,64);
 setBaseSize(64,64);
 //
 sensors= lsensors;
 //
 childDraging = 0;
 //
 setCaption("KSensors");
 //
 loadPalette();
 //
 loadGeneralOptions();
 //
 setBackgroundPixmap( UserIcon("ksensorsbackground.png") );
 //
 TDEConfig *cfg= TDEGlobal::config();
 cfg->setGroup("ShowWidget");
 TQRect rect(32,32,64*4,64*3);
 rect= cfg->readRectEntry ("geometry", &rect);
 move( rect.topLeft() );
 resize( rect.size() );
 //
 createSensorPanels();
 //
 infoPanels= new InfoPanels(this);
 //
 connect(sensors, TQ_SIGNAL(configChanged(const char *)), this, TQ_SLOT(slotConfigChanged(const char *)) );
}


LMSensorsWidget::~LMSensorsWidget()
{
 if(x()>=0 && y()>=0) {
   TDEConfig *cfg= TDEGlobal::config();
   cfg->setGroup("ShowWidget");
   //cfg->writeEntry("geometry" , geometry() );
   cfg->writeEntry( "geometry" , TQRect(pos(), size()) );
 }
 delete infoPanels;
}

// ******************* Protected slots ******************************

void LMSensorsWidget::slotConfigChanged(const char *name)
{
 if(name) {
    Panel *panel= (Panel *)child(name);
    Sensor *sensor= sensors->getSensor(name);
    if(sensor) {
      if(Panel::readShow(name)!= (bool)panel ) {
         if(panel) { delete panel; }
         else      (void)new LMSensorPanel(sensor, this, sensor->name() );
      }
    } else infoPanels->configChanged(name);
    panel= (Panel *)child(name);
    if(panel) loadPalette(panel);
 } else {
    loadPalette();
    loadGeneralOptions();
 }
}


/***************************************************************************
 * Private methods                                                         *
 ***************************************************************************/

void LMSensorsWidget::childEvent(TQChildEvent *e)
{
 if(e->inserted()) {
   loadDisplayConfig((Panel *)e->child());
 }
}

// ************* Draging panels and show menu ************************

void LMSensorsWidget::childEventReceived(TQEvent *e)
{
TQMouseEvent *m = (TQMouseEvent*)e;

 switch(e->type()) {
  case TQEvent::MouseButtonPress:

      if( m->button()==LeftButton ) startDragChild(m,(TQWidget *)sender());
      break;

  case TQEvent::MouseButtonRelease:

      if( m->button()==RightButton ) emit rightMouseClicked(m);
      break;
 }
}


void LMSensorsWidget::startDragChild(TQMouseEvent *m, TQWidget *w)
{
	if(childDraging==0)
	{
		childDraging= w;    
		grabMouse(sizeAllCursor);
		origMousePt = w->mapFromGlobal(m->globalPos());
		//w->move( m->globalPos()-mapToGlobal(TQPoint(0,0))-origMousePt);
		w->raise();
		w->update();
	}
}

void LMSensorsWidget::endDragChild()
{
int x= childDraging->x();
int y= childDraging->y();

 if(x<0) x=0;
 if(y<0) y=0;
 releaseMouse();
 childDraging->move(
                     ((x+childDraging->width() /2) / panelsSize) * panelsSize ,
                     ((y+childDraging->height()/2) / panelsSize) * panelsSize
                   );
 saveDisplayConfig((Panel *)childDraging);
 childDraging= 0;
}

void LMSensorsWidget::mouseMoveEvent ( TQMouseEvent *m )
{
	if(childDraging) 
	{ 
		childDraging->move(m->pos()-origMousePt);
		childDraging->update(); 
	}
}


void LMSensorsWidget::mouseReleaseEvent ( TQMouseEvent *m )
{
 if(childDraging && m->button()==LeftButton)  endDragChild();
 else
   if(m->button()==RightButton) emit rightMouseClicked(m);
}

// ********************** Panels creation ************************

void LMSensorsWidget::findUnusedPosition(int *px,int *py)
{
bool found;
uint mx,my,x,y,a[32];
TQObjectList *list= (TQObjectList *)children();

 for(y=0; y<32; y++) a[y]= 0;
 mx= 0; my= 0;
 if(list)
   for(TQWidget *obj= (TQWidget *)list->first(); obj!=0; obj= (TQWidget *)list->next())
     {
       y=obj->y()/panelsSize;
       x=obj->x()/panelsSize;
       if(x<32 && y<32) a[y]|=  (1 << x);
       if(x>mx) mx= x;
       if(y>my) my= y;
     }
 //
 for(x=0,y=0,found=false;y<=my && !found;) {
   found= ((a[y] & (1 << x))==0);
   if(!found)
     if(++x>mx) { x= 0; y++; }
 }

 if(!found) {
    x= (width()-1) / panelsSize;
    if(x>mx) { x= mx+1; y= 0;    }
    else     { x= 0;    y= my+1; }
 }
 //
 *px= x;
 *py= y;
}

void LMSensorsWidget::loadDisplayConfig(Panel *display)
{
 if(display==0) return;

 loadPalette(display);

 bool fNoCfg;
 TQPoint p(-1,-1);
 TDEConfig *cfg= TDEGlobal::config();
 cfg->setGroup(display->name());
 p= cfg->readPointEntry("showPos", &p );
 fNoCfg= (p.x()<0 || p.y()<0);
 if(fNoCfg) findUnusedPosition(&p.rx(),&p.ry());
 display->move(p.x()*panelsSize,p.y()*panelsSize);
 display->resize(panelsSize,panelsSize);
 display->show();
 if(fNoCfg) {
    saveDisplayConfig(display);
    adjustSize();
 }
 display->installEventFilter(this);
 connect(display, TQ_SIGNAL(eventReceived(TQEvent *)), this, TQ_SLOT(childEventReceived(TQEvent *)) );
}


void LMSensorsWidget::saveDisplayConfig(Panel *display)
{
TDEConfig *cfg= TDEGlobal::config();

 cfg->setGroup(display->name());
 cfg->writeEntry("show",true);
 TQPoint p= display->pos()/panelsSize;
 cfg->writeEntry("showPos",p);
}

void LMSensorsWidget::createSensorPanels()
{
 TQObjectList *chips= sensors->getSensorsChips();
 if(chips)
    for(LMSensorsChip *chip= (LMSensorsChip *)chips->first(); chip!=0; chip= (LMSensorsChip *)chips->next()) {
       TQObjectList *list= (TQObjectList *)chip->getSensors();
       if(list) {
           for(LMSensor *sensor= (LMSensor *)list->first(); sensor!=0; sensor= (LMSensor *)list->next()) {
             if( Panel::readShow(sensor->name()) )
                (void) new LMSensorPanel(sensor, this, sensor->name() );
           }
       }
    }
}

void LMSensorsWidget::resizePanels(int newSize)
{
TQObjectList *panels= (TQObjectList *)children();

 if(panels)
   for(TQWidget *panel= (TQWidget *)panels->first(); panel!=0; panel= (TQWidget *)panels->next()) {
     panel->move( (panel->x()/panelsSize)*newSize, (panel->y()/panelsSize)*newSize);
     panel->resize(newSize,newSize);
   }
 panelsSize= newSize;
 adjustSize();
}

int LMSensorsWidget::cfgReadPanelSize()
{
TDEConfig *cfg= TDEGlobal::config();
 cfg->setGroup( "ShowWidget" );
 return cfg->readNumEntry("PanelsSize",64);
}

void LMSensorsWidget::cfgWritePanelSize(int newSize)
{
TDEConfig *cfg= TDEGlobal::config();
 cfg->setGroup( "ShowWidget" );
 cfg->writeEntry("PanelsSize",newSize);
}


void LMSensorsWidget::loadGeneralOptions()
{
 int newSize= cfgReadPanelSize();
 if(panelsSize!=newSize) {
   setSizeIncrement(newSize,newSize);
   setBaseSize(newSize,newSize);
   resizePanels(newSize);
 }
}

// ************************+******** Palettes stuff ****************************

void LMSensorsWidget::loadPalette(Panel *panel)
{
  TQPalette pal= palette();
  if(panel) {
    if(cfgReadPalette(pal,panel->name(),false))  panel->setPalette(pal);
    else                                         panel->unsetPalette();
  } else {
    cfgReadPalette(pal,0,true);
    setPalette(pal);
  }
}


void LMSensorsWidget::getDefaultPalette(TQPalette &pal)
{
 pal.setColor(TQColorGroup::Background, TQt::white );
 pal.setColor(TQColorGroup::Light     , TQt::white );
 pal.setColor(TQColorGroup::Dark,       TQt::black );
 pal.setColor(TQColorGroup::Foreground, TQt::black );
 pal.setColor(TQColorGroup::Text,       TQt::black );
}


bool LMSensorsWidget::cfgReadPalette(TQPalette &pal,const char *name, bool returnDefault)
{
 TDEConfig *cfg= TDEGlobal::config();
 cfg->setGroup( name ? name : "General" );
 if (cfg->readBoolEntry("PaletteActive",false)) {
    pal.setColor(TQColorGroup::Background, cfg->readColorEntry("ColorBackground",&TQt::white) );
    pal.setColor(TQColorGroup::Light     , cfg->readColorEntry("ColorBackground",&TQt::white) );
    pal.setColor(TQColorGroup::Dark,       cfg->readColorEntry("ColorShadow"    ,&TQt::black) );
    pal.setColor(TQColorGroup::Foreground, cfg->readColorEntry("ColorValue"     ,&TQt::black) );
    pal.setColor(TQColorGroup::Text,       cfg->readColorEntry("ColorTitle"     ,&TQt::black) );
    return true;
 } else {
    if(returnDefault) {
      getDefaultPalette(pal);
      return true;
    }
 }
 return false;
}

void LMSensorsWidget::cfgWritePalette(const TQPalette &pal,const char *name)
{
 TDEConfig *cfg= TDEGlobal::config();
 TQColorGroup colors= pal.active();
 cfg->setGroup( name ? name : "General" );
 cfg->writeEntry("PaletteActive",true);
 cfg->writeEntry("ColorBackground",colors.background() );
 cfg->writeEntry("ColorShadow"    ,colors.dark()       );
 cfg->writeEntry("ColorValue"     ,colors.foreground() );
 cfg->writeEntry("ColorTitle"     ,colors.text()       );
}

void LMSensorsWidget::cfgUnsetPalette(const char *name)
{
 TDEGlobal::config()->setGroup( name ? name : "General" );
 TDEGlobal::config()->writeEntry("PaletteActive",false);
}

// *********************************** End *************************************

#include "lmsensorswidget.moc"
