/**************************************************************************
  kooldock.cpp  -  description
  -------------------
  begin                : Tue Jun 10 22:18:34 BST 2003
  copyright            : (C) 2003 by KoolDock team
  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 <stdlib.h>
#include <math.h>
#include <algorithm>

#include <tqpixmap.h>
#include <tqimage.h>
#include <tqpainter.h>
#include <tqcursor.h>
#include <tqdir.h>
#include <tqstringlist.h>
#include <tqvaluelist.h>
#include <tqtooltip.h>
#include <tqrect.h>
#include <tqfile.h>
#include <tqtextstream.h>
#include <tqbrush.h>
#include <tqpoint.h>
#include <tqfont.h>
#include <tqdatetime.h>

#include <twin.h>
#include <kprocess.h>
#include <netwm_def.h>
#include <tdemessagebox.h>
#include <tdelocale.h>
#include <tdecmdlineargs.h>
#include <krun.h>
#include <kurifilter.h>
#include <kpixmapio.h>
#include <kstandarddirs.h>
#include <tdeaboutapplication.h>
#include <tqlistbox.h>
#include <keditlistbox.h>

// for "renicing" the bar
#include <sys/time.h>
#include <sys/resource.h>


#include "kooldock.h"

#include <tdeconfig.h>
#include <kdebug.h>
#include "setupdialogprg.h"

#include <algorithm>
#include <dcopclient.h>
//#include <iostream>
#include <tqdatastream.h>

KoolDock::KoolDock(TQWidget* parent, const char* name) :
  TQWidget(parent, name, WStyle_Customize | WStyle_NoBorder | WNoAutoErase | WDestructiveClose | WStyle_StaysOnTop)
{
  // Default configuration paths
  progPath = locateLocal("data", "kooldock");
  menuPath = progPath + TQString("/menu/");
  confFile = locateLocal("config", "kooldockrc");

  lockSetTab= false; // disables changing opened tab in preferences window
  setupdlg  = new SetupDialogPrg();  // create the setup dialog object.

  connect(setupdlg, TQ_SIGNAL(apply()), TQ_SLOT(chkRestart()));
  perf = new TQTime();

  reloadIcons = true;

  // Menu definitions
  deskpopup = new TDEPopupMenu();
  appMenu   = new TDEPopupMenu();
  godesk    = new TDEPopupMenu;
  tasklist  = new TDEPopupMenu;
  popup     = new TDEPopupMenu;
  advMenu   = new TDEPopupMenu;

  connect(popup, TQ_SIGNAL(aboutToShow()), TQ_SLOT(aboutToShow()));
  connect(popup, TQ_SIGNAL(aboutToHide()), TQ_SLOT(aboutToHide()));
  connect(appMenu, TQ_SIGNAL(aboutToShow()), TQ_SLOT(aboutToShow()));
  connect(appMenu, TQ_SIGNAL(aboutToHide()), TQ_SLOT(aboutToHide()));
  connect(deskpopup, TQ_SIGNAL(aboutToShow()), TQ_SLOT(menuShow()));
  connect(appMenu, TQ_SIGNAL(highlighted(int)), this, TQ_SLOT(menuX(int)));
  connect(godesk, TQ_SIGNAL(activated(int)), this, TQ_SLOT(goToDesktop(int)));
  connect(tasklist, TQ_SIGNAL(activated(int)), this, TQ_SLOT(goToWindow(int)));
  connect(deskpopup, TQ_SIGNAL(activated(int)), this, TQ_SLOT(sendToDesktop(int)));
  menuCount = 0;
  init(); //initialization
}

KoolDock::~KoolDock()
{
  if (xosdw) delete(xosdw);
  if (clipw) delete(clipw);
  if (info) delete(info);
  if (wm) delete(wm);
  if (setupdlg) delete(setupdlg);
  if (rootpix) delete(rootpix);
  if (trackTimer) delete(trackTimer);
  if (mTimer) delete(mTimer);
  if (mkbigTimer) delete(mkbigTimer);
  if (mksmallTimer) delete(mksmallTimer);
  if (onChangeTimer) delete(onChangeTimer);
  if (_filterData) delete(_filterData);
}

void KoolDock::mTimerEnd() // mouse emulation timer
{
  if (menuCount > 0) {
    return; // a popup is still opened - disable scrolling
  }
  TQPoint pointer = TQCursor::pos();
  lastXPos = pointer.x() - rx; // remember current mouse position (relative to window position)
  lastYPos = pointer.y() - ry;
  int px, py, pw, ph;
  int mpx = pointer.x();
  int mpy = pointer.y();

  if (fExpanded && !mksmallTimer->isActive()) {
    px = x1;
  }
  else {
    px = x0;
  }
  if ((fOrientation & 2) == 2) {
    py = 0;
  }
  else {
    py = dh - h;
  }
  pw = w;
  ph = h;
  if ((fOrientation & 1) == 1) {
    std::swap(px, py);
    std::swap(pw, ph);
    std::swap(mpx, mpy);
  }
  if (xinerama == 1) {
    px += XinPreviousWidth;
  }

  if (fHidden == 1) {
    if ((pointer.y() >= py) && (pointer.y() <= (py + ph)) && (pointer.x() >= px) && (pointer.x() <= (px + pw))) {
      mMoveEvent(pointer.x() - rx, pointer.y() - ry);
    }
    else {
      debug(TQString("mTimer1Leave: %1 %2 %3 %4 %5 %6").arg(pointer.x()).arg(pointer.y()).arg(dh - h).arg(ry).arg(rx).arg(x + w));
      onleaveEvent(NULL);
    }
  }
  else {
    if (pointer.y() >= py && pointer.y() <= (py + ph) && pointer.x() >= px && pointer.x() <= (px + pw)) {
      if (fExpanded && !mksmallTimer->isActive()) {
        mMoveEvent(pointer.x() - rx, pointer.y() - ry);
      }
      else {
        debug(TQString("mTimer2EnterEv: %1 %2").arg(pointer.x() - rx).arg(pointer.y() - ry));
        if ((mpx >= firstX) && (mpx <= firstX+tmpw)) {
          enterEvent(NULL);
        }
      }
    }
    else {
      if (fExpanded) {
        debug(TQString("mTimer2Leave"));
        onleaveEvent(NULL);
      }
    }
  }
  if (fSteppy == 1) {
    if (!mkbigTimer->isActive() || !mksmallTimer->isActive()) {
      mMoveEvent(pointer.x() - rx, pointer.y() - ry);
    }
  }
}

void KoolDock::trackTimerEnd()
{

  TQPoint pointer;
  pointer = TQCursor::pos();
  int px = pointer.x();
  int py = pointer.y();
  if ((fOrientation & 1) == 1) {
    std::swap(px, py);
  }
  if ((fOrientation & 2) == 2) {
    py = dh - py;
  }
  if ((py + 2 >= dh) && (px > x0) && (px < x0 + w0)){
    if (track2active == false) {
      TQTimer::singleShot(hideTimer, this, TQ_SLOT(trackTimer2End()));
    }
    track2active = true;
  }
}

void KoolDock::trackTimer2End()
{
  TQPoint pointer = TQCursor::pos();
  int px = pointer.x();
  int py = pointer.y();
  if ((fOrientation & 1) == 1) {
    std::swap(px, py);
  }
  if ((fOrientation & 2) == 2) {
    py = dh - py;
  }
  if (((py + 2) >= dh) && (px > x0) && (px < x0 + w0)) {
    if (mksmallTimer->isActive() == true) {
      mksmallTimerstop();
    }
    move(0, rdh);
    raise();
    trackTimer->stop();
    getBottomBG();
    if (h1 > h0) {
      getTopBG();
    }
    debug(TQString("tracktimer: grabWindow(%1, %2, %3, %4)").arg(x1).arg(dh - h1).arg(w1).arg(h1));
    resize2(w, h);
    Ybase = iwBig2;
    enterEvent(NULL);
  }
  track2active = false;
}

void KoolDock::paintEvent(TQPaintEvent *)
{
  // Draw backgound, icons, and all that stuff over the widget.
  if (initialization && (ptPart == 5)) {
    return;
  }
  TQPainter p;
  p.begin(&offscr, this);

  int i;
  int ii;

  debug(TQString("painting"));

  // draw background (new engine)
  TQImage TempBG;
  TQPixmap TempScaledLeft;
  TQPixmap TempScaledRight;
  int p3,p4=0,p5=0,p6,p7,p8,p9,p10;
  if (w < dw) {
    Offset = 0;
  }
  int bgY = 0;
  if (fExpanded == true) {
    bgY = h1 - h0 + Ybase;
  }
  lastX = cur_cx[items.count() - 1] - iSize[items.count() - 1] / 2 + adjust;
  lastX += iSize[items.count() - 1];
  if (ii_first == 0) {
    firstX = cur_cx[0] - iSize[0] / 2 - iSpace / 2 + adjust + soffset - eoffset + x;
  }
  else {
    firstX = cur_cx[0] - iSize[0] / 2 - iSpace / 2 + SPACE_W + x;
  }
  lastX += soffset;
  tmpw = lastX + x - firstX + iSpace / 2;
  if (ii_last < (int) items.count() - 1) {
    tmpw += eoffset;
  }
  if ((ii_first == ii_last) && (ii_first > 0)) {
    tmpw -= adjust;
  }
  int p1 = 0;
  int p2 = 0;
  KPixmapIO pixio;

  if (!fLeftImg.isEmpty()) {
    TempBG = pixio.convertToImage(LeftImg);
    if ((fOrientation & 1) == 1) {
      p1 = LeftImg.height();
    }
    else {
      p1 = LeftImg.width();
    }
    p2 = h0;
    if ((fOrientation & 1) == 1) {
      std::swap(p1, p2);
    }
    if (scaleMax) {
      TempScaledLeft = TQPixmap(TempBG.scale(p1, p2, TQImage::ScaleMin));
    }
    else {
      TempScaledLeft = TQPixmap(TempBG.scale(p1, p2));
    }
    p2 = 0;
    if ((fOrientation & 1) == 1) {
      p1 = TempScaledLeft.height();
    }
    else {
      p1 = TempScaledLeft.width();
    }
  }
  if (!fRightImg.isEmpty()) {
    TempBG = pixio.convertToImage(RightImg);
    if ((fOrientation & 1) == 1) {
      p2 = RightImg.height();
    }
    else {
      p2 = RightImg.width();
    }
    p3 = h0;
    if ((fOrientation & 1) == 1) {
      std::swap(p2, p3);
    }
    if (scaleMax) {
      TempScaledRight = TQPixmap(TempBG.scale(p2, p3, TQImage::ScaleMin));
    }
    else {
      TempScaledRight = TQPixmap(TempBG.scale(p2, p3));
    }
    if ((fOrientation & 1) == 1) {
      p2 = TempScaledRight.height();
    }
    else {
      p2 = TempScaledRight.width();
    }
  }
  if (oldtmpw < tmpw) {
    p10 = oldfirstX - Offset - p1;
    p8  = oldtmpw + p1 + p2;
  }
  else {
    p10 = firstX - Offset - p1;
    p8  = tmpw + p1 + p2;
  }

  oldfirstX = firstX;
  oldtmpw = tmpw;

  if (p10 < 0) {
    p10 = 0;
  }
  if ((p8 + p10) > dw) {
    p8 = dw - p10;
  }
  p1 = p10;
  p2 = 0;
  p3 = p8;
  p4 = h1 - h0;
  p5 = p10;
  p6 = h1 - h0;
  p7 = p8;
  p8 = h0;
  p9 = p10;
  p10 = 0;
  if ((fOrientation & 2) == 2) {
    p6 = 0;
    p2 = h0;
  }
  if ((fOrientation & 1) == 1) {
    std::swap(p1, p2);
    std::swap(p3, p4);
    std::swap(p5, p6);
    std::swap(p7, p8);
    std::swap(p9, p10);
  }
  if ((h1 - h0) > 0) {
    bitBlt(&offscr, p1, p2, &topBg, p9, p10, p3, p4);  // Put the top background
  }
  bitBlt(&offscr, p5, p6, &bottomBg, p5, p6, p7, p8);  // Put the rest of the background
  if (dockOpacity > 0) {
    p1 = firstX - Offset;
    if ((fOrientation & 2) == 2) {
      p2 = 0;
    }
    else {
      p2 = h1 - h0 + Ybase;
    }
    p3 = tmpw;
    p4 = h0 - Ybase;
    if (p4 > 0) {
      if ((fOrientation & 1) == 1) {
        std::swap(p1, p2);
        std::swap(p3, p4);
      }
      bitBlt(&offscr, p1, p2, &bottomBgf, p1, p2, p3, p4);
    }
  }
  // End drawing background

  // Left side image
  p1 = 0;
  p5 = 0;
  p6 = 0;
  if (!fLeftImg.isEmpty()) {
    if ((fOrientation & 1) == 1) {
      p1 = TempScaledLeft.height();
    }
    else {
      p1 = TempScaledLeft.width();
    }

    p4 = firstX - Offset - p1;
    if (fNWideBg && (p4 < 0)) {
      p4 = 0;
    }
    p5 = p4 + p1;
    if ((fOrientation & 2) == 2) {
      if (fExpanded == 1) {
        p2 = -Ybase;
      }
      else {
        p2 = 0;
      }
    }
    else {
      if (fExpanded == 1) {
        p2 = bgY;
      }
      else {
        p2 = h1 - h0;
      }
    }
    if ((fOrientation & 1) == 1) {
      std::swap(p2, p4);
    }
    bitBlt(&offscr, p4, p2, &TempScaledLeft);
  }
  // Right side image
  if (!fRightImg.isEmpty()) {
    if ((fOrientation & 1) == 1) {
      p1 = TempScaledRight.height();
    }
    else {
      p1 = TempScaledRight.width();
    }

    p2 = firstX - Offset + tmpw;
    if (fNWideBg && (p2>dw-p1)) {
      p2 = dw - p1;
    }
    p6 = p2;
    if ((fOrientation & 2) == 2) {
      if (fExpanded == 1) {
        p3 = -Ybase;
      }
      else {
        p3 = 0;
      }
    }
    else {
      if (fExpanded == 1) {
        p3 = bgY;
      }
      else {
        p3 = h1 - h0;
      }
    }
    if ((fOrientation & 1) == 1) {
      std::swap(p2, p3);
    }
    bitBlt(&offscr, p2, p3, &TempScaledRight);
  }

  // Center image
  if (!fCenterImg.isEmpty()) {
    TempBG = pixio.convertToImage(CenterImg);
    // hack!! to optimize drawing speed, scale the background image only when it's
    // necessary, I prefer to use a bit more memory than loosing speed.
    // -- Matias
    if ((fOrientation & 1) == 1) {
      p1 = TempScaledCenter.height();
    }
    else {
      p1 = TempScaledCenter.width();
    }
    if (p1 != (p6 - p5)) {
      p2 = p6 - p5;
      p3 = h0;
      if ((fOrientation & 1) == 1) {
        std::swap(p2, p3);
      }
      TempScaledCenter = TQPixmap(TempBG.scale(p2, p3));
    }
    p1 = p5;
    if ((fOrientation & 2) == 2) {
      if (fExpanded) {
        p2 = -Ybase;
      }
      else {
        p2 = 0;
      }
    }
    else {
      if (fExpanded == 1) {
        p2 = bgY;
      }
      else {
        p2 = h1 - h0;
      }
    }
    if ((fOrientation & 1) == 1) {
      std::swap(p1, p2);
    }
    bitBlt(&offscr, p1, p2, &TempScaledCenter);
  }
  // End drawing the backgound

  // Draw borders
  if (fShowBorders) {
    p1 = firstX - Offset;
    p3 = SPACE_W;
    p4 = h0;
    p5 = tmpw;
    p6 = SPACE_W;
    p7 = tmpw - SPACE_W + firstX - Offset;
    p2 = h1 - h0 + Ybase;
    p8 = p2;
    p9 = p1;
    p10 = p2;
    if ((fOrientation & 2) == 2) {
      p2 = -Ybase;
      p8 = -Ybase;
      p10 = p4 - Ybase - 1;
    }
    if ((fOrientation & 1) == 1) {
      std::swap(p1, p2);
      std::swap(p3, p4);
      std::swap(p5, p6);
      std::swap(p7, p8);
      std::swap(p9, p10);
    }
    p.fillRect(TQRect(p1, p2, p3, p4), TQBrush(borderColor));
    p.fillRect(TQRect(p9, p10, p5, p6), TQBrush(borderColor));
    p.fillRect(TQRect(p7, p8, p3, p4), TQBrush(borderColor));
  }
  // End drawing borders

  Item *item;
  // New icon drawing engine
  int Ypos; // Y position
  int Xpos; // X position
  KPixmap *currentIcon;   // current icon pixmap

  for (i = 0; i < (int) items.count(); i++) {
    item = items.at(i);
    // Start setting the icon position
    if (i < ii_first) {
      // left side icons
      Xpos = cur_cx[i] - iwSmall / 2 + SPACE_W - Offset;
    }
    else if ((i >= ii_first) && (i <= ii_last)) {
      // Zoomed icons (center)
      Xpos = cur_cx[i] - iSize[i] / 2 + adjust - Offset + soffset - eoffset;
      if ((i == ii_first) && (i == (int) items.count() - 1) && (i > 0)) {
        Xpos = cur_cx[i - 1] + iwSmall / 2 + SPACE_W - Offset + iSpace;
      }
    }
    else if (i > ii_last) {
      // Right side icons
      Xpos = cur_cx[i] - iwSmall / 2 + adjust + SPACE_W - 2 - Offset;
    } // End getting icon positions
    if ((fOrientation & 2) == 2) {
      Ypos = iy - Ybase;
    }
    else {
      Ypos = h1 - iy - iSize[i] + Ybase;
    }

    // Now, get the icon image
    if ((Xpos < dw) && ((Xpos + iwBig2) > 0)) {
      currentIcon = new KPixmap(*item->getIcon(iSize[i]));
      if (items.at (i)->wIcon == true) {
        for (ii = 0; ii < (int) witems.count(); ii++) {
          if (items.at(i)->getId() == witems.at(ii)->getId()) {
            currentIcon = new KPixmap(*witems.at(ii)->getIcon(iSize[i]));
          }
        }
      }

      // Misc icon effects and animations
      if (iOnClick == i) {
        // Highlight the clicked icon
        KPixmapEffect::fade(*currentIcon, ((float) 50) * 0.01, TQColor("#FFFFFF"));
        TQTimer::singleShot(10 * 60, this, TQ_SLOT(unhighlight()));  // Unhighlight the icon in 1 second
      }

      // Notify animation
      if (fShowNotification && item->isAnimed()) {
        KPixmapEffect::fade(*currentIcon, ((float) animValue) * 0.01, TQColor("#FFFFFF"));
      }

      // Let's apply an effect to the active window in TaskBar
      if ((item->getId() == wm->activeWindow()) && (item->getId() != 0)) {
        KPixmapEffect::fade(*currentIcon, ((float) 60) * 0.01, TQColor("#FFFFFF"));
      }
      // End drawing icon effects

      Xpos += x;
      if ((fOrientation & 1) == 1) {
        std::swap(Xpos, Ypos);
      }
      // Draw the icon on the widget in its respective position
      bitBlt(&offscr, Xpos, Ypos, currentIcon);
      // Destroy the unused currentIcon pixmap.
      delete currentIcon;
    }
  } // End drawing icons

  // Draw the seperators between launcher and taskbar, and between tasbar and systray
  if (fShowTaskbar && ((numLaunchers > 0 && ((int) items.count() > numLaunchers)) || ((fShowKMenu == 1) && (items.count() > 1)))) {
    i = numLaunchers - 1;
    if ((i >= 0) && (i < (int) items.count() - 1)) {
      Xpos = xFromIndex(i) + xFromIndex(i + 1) + iSize[i];
      p1= Xpos / 2 - Offset + x;
      p3 = SPACE_W;
      p4 = h0;
      if (fExpanded == 0) {
        p2 = h1 - h0;
        if ((fOrientation & 2) == 2) {
          p2 = 0;
        }
      }
      else if ((signed) items.count() > numLaunchers) {
        p2 = h1 - h0 + Ybase;
        if ((fOrientation & 2) == 2) {
          p2 = -Ybase;
        }
      }
      if ((fOrientation & 1) == 1) {
        p.fillRect(TQRect(p2, p1, p4, p3), TQBrush(sepColor));
      }
      else {
        p.fillRect(TQRect(p1, p2, p3, p4), TQBrush(sepColor));
      }
    }
  }
  if ((fSystray == 1) && (numSystray > 0)) {
    i = items.count() - numSystray - 1;
    if ((i >= 0) && (i < (int) items.count() - 1)) {
      Xpos = xFromIndex(i) + xFromIndex(i + 1) + iSize[i];
      p1 = Xpos / 2 - Offset + x;
      p3 = SPACE_W;
      p4 = h0;
      if (h == h0) {
        p2 = h;
        if ((fOrientation & 2) == 2) {
          p2 = 0;
        }
      }
      else {
        p2 = h1 - h0 + Ybase;
        if ((fOrientation & 2) == 2) {
          p2 = -Ybase;
        }
      }
      if ((fOrientation &1) == 1) {
        p.fillRect(TQRect(p2, p1, p4, p3), TQBrush(sepColor));
      }
      else {
        p.fillRect(TQRect(p1, p2, p3, p4), TQBrush(sepColor));
      }
    }
  }
  p.end();

  // Finally update the widget
  if ((fOrientation & 1) == 1) {
    bitBlt(this, 0, 0, &offscr, 0, 0, h1, dh, TQt::CopyROP);
  }
  else {
    bitBlt(this, 0, 0, &offscr, 0, 0, dw, h1, TQt::CopyROP);
  }

  //Preparing mask
  TQBitmap bm(size(), true);
  TQPainter mp;

  mp.begin(&bm, this);
  mp.setPen(TQt::black);
  mp.fillRect(rect(), TQt::black);
  mp.fillRect(TQRect(0, 0, 1, 1), TQt::white);
  p1 = 0;
  p2 = 0;
  if (!fLeftImg.isEmpty()) {
    if ((fOrientation & 1) == 1) {
      p1 = TempScaledLeft.height();
    }
    else {
      p1 = TempScaledLeft.width();
    }
  }
  if (!fRightImg.isEmpty()) {
    if ((fOrientation & 1) == 1) {
      p2 = TempScaledRight.height();
    }
    else {
      p2 = TempScaledRight.width();
    }
  }
  p3 = firstX - Offset - p1;
  if ((fOrientation & 2) == 2) {
    p4 = 0;
  }
  else {
    if (fExpanded) {
      p4 = 0;
    }
    else {
      p4 = h1 - h0;
    }
  }
  p5 = tmpw + p1 + p2;
  if (fExpanded) {
    p6 = h1;
  }
  else {
    p6 = h0;
  }
  if (p3 < 0) {
    p3 = 0;
  }
  if (p5 + p3 > dw) {
    p5 = dw - p3;
  }
  if ((fOrientation & 1) == 1) {
    p6++;
    mp.fillRect(TQRect(p4, p3, p6, p5), TQt::white);
  }
  else {
    mp.fillRect(TQRect(p3, p4, p5, p6), TQt::white);
  }
  if ((fOrientation & 2) == 2) {
    mp.fillRect(TQRect(rw - 1, rh - 1, 1, 1), TQt::black);
  }
  else {
    if ((fOrientation & 1) == 1) {
      mp.fillRect(TQRect(0, rh - 1, 1, 1), TQt::black);
    }
    else {
      mp.fillRect(TQRect(rw - 1, 0, 1, 1), TQt::black);
    }
  }
  if (initialization) {
    mp.fillRect(rect(), TQt::black);
    mp.fillRect(TQRect(0, 0, 1, 1), TQt::white);
  }
  mp.end();
  setMask(bm);
}

void KoolDock::unhighlight()
{
  iOnClick = -1;
  paintEvent(NULL);;
}

void KoolDock::mousePressEvent(TQMouseEvent *e)
{
  mPress(e->x(), e->y(), e->button());
}

void KoolDock::mPress(int mx, int my, ButtonState srcButton)
{
  int i, j;
  int iClicked;
  Item *item;

  if ((fOrientation & 1) == 1) {
    std::swap(mx, my);
  }
  if ((fOrientation & 2) == 2) {
    my = h1 - my;
  }
  mx = mx - x1;

  mx = mx + Offset;
  iClicked = itemFromPoint(mx);

  if (srcButton == TQt::LeftButton) {
    i = iClicked;
    if ((my >= h1 - iy - iSize[i]) && (my <= h1 - iy)) {
      if ((i >= 0) && (i < (int) items.count())) {
        items.at(i)->anim(false);
        WId id = items.at(i)->getId();
        if (id == 0) {
          // If user clicked on a quick launcher, launch the app
          // Acknowledge on click
          iOnClick = i;
          paintEvent(NULL);

          // Run the app
          debug(TQString("clicked: %1").arg(items.at(i)->getName()));
          if (items.at(i)->getName() == "KMenu") {
            // Show K Menu
            run(items.at(i)->getCommand());
          }
          else {
            // Run the application with TDE feedback (loading icon)
            // We need to run the .desktop file, since the command
            // may be a url or another TDEIO stuff like 'system:/'
            if (items.at(i)->getFilename() != "") {
              run(items.at(i)->getFilename());
            }
            else {
              run(items.at(i)->getCommand());
            }
          }
        }
        else {
          KWin::WindowInfo info;
          KWin::WindowInfo winfo;
          info = KWin::windowInfo(id, 0, NET::WM2WindowClass);
          TQString name = info.visibleName();
          TQCString cls = info.windowClassClass();

          if (i >= ((int) items.count() - numSystray)) {
            KWin::deIconifyWindow(id);
            kdDebug(0) << "Systray: " << id << " Name: " << name << " Estado: " << info.state() << endl;
          }
          else {
            // If user clicked on a running task's icon, activate it
            cId = id;
            if (fGrouping) // Switch between windows when clicking on window group icon
            {
              // Find currently focused window in witems list
              int jl = -1, il;
              bool getNext = false;
              for (j = 0, item = witems.at(0); item; j++, item = witems.next()) {
                if (item->getId() == CurrentFocus) {
                  jl = j;
                  break;
                }
              }
              if (jl >= 0) {
                if (witems.at(jl)->getClass() == cls) {
                  getNext = true;
                }
              }
              else {
                getNext = true;
              }

              jl = -1;
              if (getNext) {
                il = witems.count();
                for (j = 0, item = witems.at(0); item; j++, item = witems.next()) {
                  if (item->getIndex() < il) {
                    if (item->getClass() == cls) {
                      winfo = item->info;
                      if ((fMinimizedOnly == 0 || winfo.isMinimized()) && (fCurrent == 0 || winfo.isOnDesktop(KWin::currentDesktop()))) {
                        jl = j;
                        il = item->getIndex();
                      }
                    }
                  }
                }
              }
              else {
                il = -1;
                for (j = 0, item = witems.at(0); item; j++, item = witems.next()) {
                  if (item->getIndex() > il) {
                    if (item->getClass() == cls) {
                      winfo = item->info;
                      if ((fMinimizedOnly == 0 || winfo.isMinimized()) && (fCurrent == 0 || winfo.isOnDesktop(KWin::currentDesktop()))) {
                        jl = j;
                        il = item->getIndex();
                      }
                    }
                  }
                }
              }
              if (jl >= 0) {
                cId = witems.at(jl)->getId();
              }
            }

            if (cId != CurrentFocus) {
              activateApp();
            }
            else {
              minApp();
              CurrentFocus = winId();
            }
          }
        }
      }
      if ((fHidden == 1) && (fHideOnClick == 1)) {
        onleaveEvent(NULL); // it's configurable
      }
    }
  }
  else if (srcButton == TQt::RightButton) {
    // Right button.
    i = iClicked;
    advMenu->clear();
    advMenu->insertItem(SmallIconSet("go-up"), i18n("Keep &Above Others"), this, TQ_SLOT(toggleAlwaysOnTop()), 0, 1);
    advMenu->insertItem(SmallIconSet("go-down"), i18n("Keep &Below Others"), this, TQ_SLOT(toggleKeptBelowOthers()), 0, 2);
    advMenu->insertItem(SmallIconSet("view-fullscreen"), i18n("&Fullscreen"), this, TQ_SLOT(toggleFullScreen()), 0, 3);

    // Main KoolDock popup menu
    popup->clear();
    popup->insertTitle(i18n("Main Menu"));
    popup->insertItem(SmallIcon("configure"), i18n("Edit Quick Launch &Menu"), this, TQ_SLOT(edit()));
    popup->insertItem(SmallIcon("pencil"), i18n("Edit &Preferences"), this, TQ_SLOT(editPref()));
    popup->insertItem(SmallIcon("edit-redo"), i18n("&Reload configuration"), this, TQ_SLOT(restart()));
    popup->insertSeparator();
    popup->insertItem(SmallIcon("about_kde"), i18n("&About"), this, TQ_SLOT(about()));
    popup->insertSeparator();
    popup->insertItem(SmallIcon("system-log-out"), i18n("E&xit"), this, TQ_SLOT(endProg()));
    // End Main KoolDock Menu

    if (fShowNav == 1) {
      // Menu to be appended to MainMenu
      godesk->clear();
      for (int index = 0; index < KWin::numberOfDesktops(); index++) {
        TQString tmp = i18n("Desktop &%1").arg(index + 1);
        int menustate = godesk->insertItem(SmallIcon("forward"), tmp, index + 1);
        if (KWin::currentDesktop() == (index + 1)) {
          godesk->setItemEnabled(menustate, false);
        }
      }
      // End godesk Menu

      // Append Navigation Menu (godesk+Time)
      TQDateTime timeEntry = TQDateTime::currentDateTime();
      TQString tmp = i18n("Navigation: Desktop %1").arg(KWin::currentDesktop());
      popup->insertTitle(tmp);
      popup->insertItem(SmallIcon("forward"), i18n("&Go to Desktop"), godesk);
      popup->insertItem(SmallIcon("forward"), i18n("&Task List"), tasklist);
      popup->insertSeparator();
      popup->insertItem(SmallIcon("clock"), timeEntry.toString());
      // End append Navigation Menu
    }

    if ((my >= h1 - iy - iSize[i]) && (my <= h1 - iy)) {
      if ((i >= 0) && (i < (int) items.count())) {
        WId id = items.at (i)->getId();
        if (id == 0) {
          // If user right clicked on a quick launch icon.
          if (items.at (i)->getCommand() != "") {
            // Edit the .desktop file
            if ((i == 0) && fShowKMenu) {
              // If user right clicked on the K menu, show the configuration menu.
              popup->exec(TQCursor::pos());
            }
            else {
              iGroup = false;
              appMenu->clear();
              appMenu->insertTitle(i18n("Item menu"));
              iFilename = items.at(i)->getFilename();
              appMenu->insertItem(SmallIcon("configure"), i18n("&Edit item"), this, TQ_SLOT(editItem()));
              appMenu->insertItem(SmallIcon("window-close"), i18n("&Delete item"), this, TQ_SLOT(removeItem()));
              appMenu->insertSeparator();
              appMenu->insertItem(SmallIcon("forward"), "&KoolDock", popup);
              appMenu->exec(TQCursor::pos());
            }
          }
        }
        else {
          // If user clicked on a running task icon, show the app menu.
          // Pop-up menu for right-clicking on a taskbar icon.
          cId = id;
          KWin::WindowInfo winfo = KWin::windowInfo(cId, 0, NET::WM2WindowClass | NET::WM2AllowedActions);

          // Begin Move to Desktop Menu
          deskpopup->clear();
          deskpopup->insertItem(SmallIcon("forward"), i18n("All desktops"), 0);
          TQString tmp = i18n("Current Desktop &%1").arg(KWin::currentDesktop());
          deskpopup->insertItem (SmallIcon ("forward"), tmp, KWin::currentDesktop());
          deskpopup->insertSeparator();
          for (int i = 0; i < KWin::numberOfDesktops(); i++) {
            if (winfo.isOnDesktop(KWin::currentDesktop()) && (i + 1) == KWin::currentDesktop()) {
              continue;
            }
            else {
              if ((i + 1) != KWin::currentDesktop()) {
                TQString tmpd = i18n("Desktop &%1").arg(i + 1);
                deskpopup->insertItem(SmallIcon("forward"), tmpd, i + 1);
              }
            }
          }
          dIndex = winfo.desktop();
          if (dIndex == -1) {
            dIndex = 0;
          }
          deskpopup->setItemChecked(dIndex, true);
          // End Move to Desktop Menu

          advMenu->setItemChecked(1, winfo.state() & NET::KeepAbove);
          advMenu->setItemChecked(2, winfo.state() & NET::KeepBelow);
          advMenu->setItemChecked(3, winfo.state() & NET::FullScreen);
          advMenu->setItemEnabled(3, winfo.actionSupported(NET::ActionFullScreen));

          appMenu->clear();
          if (fGrouping && (items.at(iClicked)->getCount() > 0)) {
            iGroup = true;
            TQCString cls = winfo.windowClassClass();
            popups.clear();
            for (j = 0, item = witems.at(0); item; j++, item = witems.next()) {
              if (item->getClass() == cls) {
                winfo = item->info;
                if ((fMinimizedOnly == 0 || winfo.isMinimized()) && (fCurrent == 0 || winfo.isOnDesktop(KWin::currentDesktop()))) {
                  TDEPopupMenu *tmpMenu = new TDEPopupMenu;
                  createMenu(tmpMenu, &winfo);
                  connect(tmpMenu, TQ_SIGNAL(aboutToShow()), TQ_SLOT(menuShow()));
                  popups.append(tmpMenu);
                  appMenu->setItemParameter(appMenu->insertItem(*item->getIcon(iwBig2), item->getName(), tmpMenu), item->getId());
                }
              }
            }
            appMenu->insertSeparator();
            appMenu->insertItem(SmallIcon("forward"), "&Move to Desktop", deskpopup);
            appMenu->insertItem(i18n("Mi&nimize all"), this, TQ_SLOT(minAllApps()));
            appMenu->insertItem(i18n("Ma&ximize all"), this, TQ_SLOT(maxAllApps()));
            appMenu->insertItem(i18n("&Restore all"), this, TQ_SLOT(restAllApps()));
            appMenu->insertItem(SmallIcon("window-close"), i18n("&Close all"), this, TQ_SLOT(closeAllApps()));
          }
          else {
            iGroup = false;
            createMenu(appMenu, &winfo);
          }
          appMenu->insertSeparator();
          appMenu->insertItem(SmallIcon("forward"), "KoolDock", popup);
          appMenu->exec(TQCursor::pos());
          iGroup = false;
        }
      }
    }
    else {
      // Show the configuration popup menu if the user clicked on another place.
      popup->exec(TQCursor::pos());
    }
    deskpopup->clear();
    godesk->clear();
    popup->clear();
    popups.clear();
    appMenu->clear();
  }
}

void KoolDock::mMoveEvent(int ex, int ey)
{
  if (!fExpanded) {
    return;
  }
  unsigned int i;
  int mx, dmx;
  int dx;
  unsigned int k;
  int cur_cx_desk;
  int p1 = 0, p2 = 0;

  if ((fOrientation & 1) == 1) {
    mx = ex;
    ex = ey;
    ey = mx;
  }
  if ((fOrientation & 2) == 2) {
    ey = h1-ey;
  }
  if (w0 > dw) {
    mx = w0 * ex / dw;
  }
  else {
    mx = ex - x0;
  }
  dmx = abs(mx - last_mx);
  last_mx = mx;
  if (w1 > dw) {
    Offset = (w1 - dw) * mx / w0;
    ex = ex + Offset;
  }
  else {
    Offset = 0;
  }

  if (fSteppy == 1) {
    last_ncx = mx = (int) (last_ncx * 0.7 + cx[(ex - x0 - iSpace) / iDist] * 0.3);
  }
  if (!mkbigTimer->isActive() && !mksmallTimer->isActive()) {
    Ybase = 0;
  }
  if ((dmx >= UPDATE_DIST && fExpanded) || mkbigTimer->isActive() || mksmallTimer->isActive()) {
    ii_first = 0;
    ii_last = items.count() - 1;
    for (i = 0; i < items.count(); i++) {
      dx = abs(cx[i] - mx);
      if (dx < funcW) {
        iSize[i] = func(dx);
      }
      else {
        iSize[i] = iwSmall;
        if (cx[i] < mx) {
          ii_first = std::min (i + 1, items.count() - 1);
        }
        else if (ii_last == (int) items.count() - 1) {
          ii_last = std::max ( (int) i - 1, 0);
        }
      }
    }

    cur_cx[0] = iSpace + iSize[0] / 2;

    for (i = 1; i < items.count() + 1; i++) {
      cur_cx[i] = cur_cx[i - 1] + (iSize[i] + iSize[i - 1]) / 2 + iSpace;
    }
    for (k = 0; (k < items.count() - 1) && (mx > cx[k]); k++);
    cur_cx_desk = ((int) ((iwBig2 - iwSmall) * 0.6 * fAmount) + iSpace * 2) / 2 +
                          cx[k] +
                          (int) ((cx[k] - mx) * (func(0) + func(iDist) - 2 * iwSmall) / (2 * iDist));
    adjust = cur_cx_desk - cur_cx[k];

    if ((w1 < dw) && (!mkbigTimer->isActive() || (zoomTicksB > 1 && mkbigTimer->isActive()))) {
      if (!initialization && (menuCount == 0)) {
        if (mx < 0) {
          onleaveEvent(NULL);
        }
        if ((lastX > 0) && (mx > tmpw + firstX - x1 - (w1 - w0) / 2)) {
          onleaveEvent(NULL);
        }
      }
    }
    if (ii_last < (int) items.count() - 1) {
      cur_cx[items.count() - 1] = w1 * zoomVal / fzoomSpeed + (eoffset - soffset + (w1 + w0) / 2) * (fzoomSpeed - zoomVal) / (fzoomSpeed) - iwSmall / 2 - iSpace - adjust;
      for (i = items.count() - 2; (int) i >= ii_last + 1; i--) {
        cur_cx[i] = cur_cx[i + 1] - iDist;
      }
      if (ii_last == 0) {
        cur_cx[0] = cur_cx[1] - iDist - (iSize[0] - iSize[1]) / 2;
      }
    }

    for (i = 0; (int) i < ii_first; i++) {
      cur_cx[i] += (int) ((soffset - eoffset + (w1 - w0) / 2) * (fzoomSpeed - zoomVal) / fzoomSpeed);
    }
    paintEvent(NULL);
  }

  mx = ex-x1;

  i = itemFromPoint(mx);
  mouseOnLauncher = ((int) i < numLaunchers);

  if ((showNames == 1) && (iwBig == iwBig2) && (dmx < 10)) {
    // Get the name of the item at the mouse position
    if (!mksmallTimer->isActive() && !mkbigTimer->isActive()) {
      if (i < MAX_ICONS + 1) {
        if (((int) i >= 0) && (i < items.count())) {
          nom = items.at(i)->getName();
        }
        else {
          nom = "";
        }
      }

      if (nom != aux) {
        xosd_st = 0;
      }
      if (xosd_st == 0) {
        xosdw->setText(nom);
        xosd_st = 1;
      }
      aux = nom;
      mx = mx-Offset;
      if (fOrientation == 0) {
        p1 = mx + x1 - (xosdw->w / 2);
        p2 = dh - h - xosdw->h;
      }
      if (fOrientation == 1) {
        p1 = dh - h1 - xosdw->w;
        p2 = mx- xosdw->h / 2 + x1;
      }
      if (fOrientation == 2) {
        p1 = mx + x1 - (xosdw->w / 2);
        p2 = h1;
      }
      if (fOrientation == 3) {
        p1 = h1;
        p2 = mx- xosdw->h / 2 + x1;
      }
      if ((fOrientation & 1) == 0) {
        if (p1 < 0) {
          p1 = 0;
        }
        if (p1 + xosdw->w > dw) {
          p1 = dw - xosdw->w;
        }
      }
      if (xinerama == 1) {
        p1 += XinPreviousWidth;
      }
      if (!initialization && ((xosdw->pos().x() != p1) || (xosdw->pos().y() != p2))) {
        xosdw->move2(p1, p2);
      }
    }
  }
  if (dmx >= 10) {
    xosdw->move2(0, rdh);
  }
}

// Mouse Wheel now switches desktops (away from user desktop+1, towards user desktop-1)
// -Francisco
void KoolDock::wheelEvent(TQWheelEvent* e)
{
  if ((e->delta() == 120) && (KWin::currentDesktop() < KWin::numberOfDesktops())) {
    KWin::setCurrentDesktop(KWin::currentDesktop() + 1);
  }
  if ((e->delta() == -120) && (KWin::currentDesktop() > 0)) {
    KWin::setCurrentDesktop(KWin::currentDesktop() - 1);
  }
}

void KoolDock::mkbigTimerDo()
{
  zoomTicksB++;
  iwBig = iwBig2 * zoomVal / fzoomSpeed + iwSmall * (fzoomSpeed - zoomVal) / fzoomSpeed;  // frames to grow up the dockbar
  if (iwBig < iwSmall) {
    iwBig = iwSmall;
  }
  zoomVal = zoomVal + zoomStepB;

  if (fzoomSpeed <= zoomVal) {
    zoomVal = fzoomSpeed;
    iwBig = iwBig2;
    mkbigTimer->stop();
    last_mx = -1;
    debug(TQString("Stopped mkbigTimer"));
    if ((zoomTicksB >= neededTicksB) && fSpeed) {
      // Performace check
      int timing = perf->elapsed();
      zoomStepB = zoomStepB * timing / fzoomSpeed;
      if (zoomStepB <= 0) {
        zoomStepB = 1;
      }
      if (zoomStepB > 200) {
        zoomStepB = 200;
      }
      neededTicksB = (int) ((fzoomSpeed / zoomStep) - 1) * zoomStep / zoomStepB;
    }
    zoomTicksB = 0;
    zoomTicksS = 0;
    if (initialization) {
      pTest();
    }
    else {
      if (fHidden == 1) {
        mTimer->start(fMouseTimer, false);
      }
      else {
        mTimer->changeInterval(fMouseTimer);
      }
    }
  }
  iy = (iDist - iwSmall) / 2;
  funcH = iwBig - iwSmall;
  if (fHidden == 1) {
    Ybase = iwBig2 * (fzoomSpeed - zoomVal) / fzoomSpeed;
  }
  mMoveEvent(TQWidget::mapFromGlobal(TQCursor::pos()).x(), TQWidget::mapFromGlobal(TQCursor::pos()).y());
  paintEvent(NULL);
}

void KoolDock::mksmallTimerDo()
{
  zoomTicksS++;
  iwBig = iwBig2 * zoomVal / fzoomSpeed + iwSmall * (fzoomSpeed - zoomVal) / fzoomSpeed;
  if (iwBig < iwSmall) {
    iwBig = iwSmall;
  }
  if (zoomVal < 0) {
    zoomVal = 0;
    mksmallTimerstop();
  }
  else {
    if (fHidden == 1) {
      Ybase = iwBig2 * (fzoomSpeed - zoomVal) / fzoomSpeed;
    }
    funcH = iwBig - iwSmall;
    iy = (iDist - iwSmall) / 2;
    mMoveEvent(lastXPos, lastYPos);
    paintEvent(NULL);
  }
  zoomVal = zoomVal - zoomStepS;
}

void KoolDock::mksmallTimerstop()
{
  zoomVal = 0;
  if ((fStayBelow == 1) && (fHidden == 0)) {
    setDockBelow();
  }
  int i;
  mksmallTimer->stop();
  xosdw->move2(0, rdh);
  fExpanded = false;
  debug(TQString("Stopped mksmallTimer"));
  if (!initialization) {
    if (fHidden == 0) {
      mTimer->changeInterval(250);
    }
    else {
      mTimer->stop();
    }
  }

  w = w0;
  x = x0;
  h = h0;

  // Normalize the dock
  for (i = 0; i < (int) items.count() + 1; i++) {
    iSize[i] = iwSmall;
    cur_cx[i] = cx[i];
  }
  ii_first = 0;
  ii_last = items.count() - 1;
  adjust = 0;
  iwBig = iwBig2;
  if (fHidden == 0) {
    move2(x, dh - h);
    resize2(w, h);
  }
  else {
    move(0, rdh);
    resize2(w, h);
  }
  oldfirstX = x;
  oldtmpw = w;
  paintEvent(NULL);
  if ((zoomTicksS >= neededTicksS) && fSpeed) {
    // Performace check
    int timing = perf->elapsed();
    zoomStepS = zoomStepS * timing / fzoomSpeed;
    if (zoomStepS <= 0) {
      zoomStepS = 1;
    }
    if (zoomStepS > 200) {
      zoomStepS = 200;
    }
    neededTicksS = (int) ((fzoomSpeed / zoomStep) - 1) * zoomStep / zoomStepS;
  }
  zoomTicksB = 0;
  zoomTicksS = 0;
  if (initialization) {
    pTest();
  }
}

void KoolDock::enterEvent (TQEvent *)
{
  if (((fExpanded == true) && !mksmallTimer->isActive()) || mkbigTimer->isActive()) {
    return;
  }
  if ((fStayBelow == 1) && (fHidden == 0)) {
    setDockAbove();
  }
  if (mksmallTimer->isActive() == true) {
    mksmallTimer->stop();
  }

  w = w1;
  x = x1;
  h = h1;

  if (!fExpanded) {
    getTopBG();
    if (dockOpacity > 0) {
      bitBlt(&bottomBgf, 0, 0, &bottomBg);
      KPixmapEffect::fade(bottomBgf, ((float) dockOpacity) * 0.01, bgColor);
    }
    adjust = x0 - x1;
    iwBig = iwSmall;
  }
  resize2(w, h);
  move2(x, rdh);

  funcH = iwBig - iwSmall;
  iy = (iDist - iwSmall) / 2;

  fExpanded = true;
  oldfirstX = x;
  oldtmpw = w;
  debug("enterEvent");
  zoomTicksB = 0;
  zoomTicksS = 0;
  perf->start();
  mkbigTimer->start(zoomStep, false);
  mkbigTimerDo();
  paintEvent(NULL);
  move2(x,dh-h);
}

void KoolDock::onleaveEvent(TQEvent *)
{
  if (menuCount > 0) {
    return;
  }
  if (mksmallTimer->isActive() == true) {
    return;
  }
  zoomTicksB = 0;
  zoomTicksS = 0;
  perf->start();
  debug("onleaveEvent");
  lastXPos = TQWidget::mapFromGlobal(TQCursor::pos()).x();
  lastYPos = TQWidget::mapFromGlobal(TQCursor::pos()).y();
  if (mkbigTimer->isActive()) {
    mkbigTimer->stop();
  }
  mksmallTimer->start(zoomStep, false);

  if (showNames == 1) {
    xosdw->move2(0, rdh);
    xosd_st = 0;
  }
  if (fHidden == 1) {
    trackTimer->start(250, false);
  }
}

void KoolDock::edit()
{
  editPref();
  setupdlg->tabWidget->setCurrentPage(3);
}

void KoolDock::run(const TQString& command)
{

  TQString exec;
  static TQString zz = TQString(0);
  static int ii = 0;
  static TQCString yy = "";

  kapp->propagateSessionManager();

  _filterData->setData(command.stripWhiteSpace());
  TQStringList filters;
  filters << "kurisearchfilter" << "tdeshorturifilter";
  KURIFilter::self()->filterURI(*(_filterData), filters);

  TQString cmd = (_filterData->uri().isLocalFile() ? _filterData->uri().path() :_filterData->uri().url());
  // Nothing interesting. Quit!
  if (cmd.isEmpty()) {
    KMessageBox::sorry(0L, i18n("You have to enter a command to execute or a URL to be opened first."));
    return;
  }
  else {
    switch (_filterData->uriType()) {
      case KURIFilterData::LOCAL_FILE:
      case KURIFilterData::LOCAL_DIR:
      case KURIFilterData::NET_PROTOCOL:
      case KURIFilterData::HELP: {
        if (useList) {
          TDEApplication::startServiceByDesktopPath(command, lstDrop, NULL , NULL , &ii , yy ,true);
        }
        else {
          (void) new KRun(_filterData->uri());
        }
        return;
      }
      case KURIFilterData::EXECUTABLE:
      case KURIFilterData::SHELL: {
        exec = cmd;
        if (_filterData->hasArgsAndOptions()) {
          cmd += _filterData->argsAndOptions();
        }
        break;
      }
      case KURIFilterData::UNKNOWN:
      case KURIFilterData::ERROR:
      default:
        KMessageBox::sorry(0, i18n("<qt>The program name or command <b>%1</b>\n"
                                   "cannot be found. Please correct the command\n"
                                   "or URL and try again</qt>").arg(cmd));
        return;
    }
  }
  if (KRun::runCommand(cmd, exec, "")) {
    return;
  }
  else {
    KMessageBox::sorry(0, i18n("<qt>Could not run <b>%1</b>.\nPlease correct"
                               " the command or URL and try again.</qt>").arg(cmd));
    return;
  }
}

// Parabolic function
int KoolDock::func(int x)
{
  int res = iwBig - (int) ((x * x * funcH) / (funcW * funcW));
  return res;
}

int KoolDock::func2(int x)
{
  int res;
  if (x < funcW) {
    res = iwBig - (int) ((x * x * funcH) / (funcW * funcW));
  }
  else {
    res = iwSmall;
  }
  return res;
}

// Here we add windows to the taskbar
void KoolDock::addWindows()
{
  // Show task bar
  int index;
  if (fShowTaskbar) {
    KWin::WindowInfo info;
    TQValueList<WId>::ConstIterator it;
    int i;
    Item *item;

    // First we removed every taskbar item
    int count = items.count() - numSystray;

    for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
      item->setCount(0);
    }
    for (i = count; i >= numLaunchers; i--) {
      items.remove(i);
    }

    // Lets go through all the windows
    if (firstTime) {
      for (it = wm->windows().begin(); it != wm->windows().end(); ++it) {
        addwTask(*it);
      }
      firstTime = false;
    }

    for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
      item->setId(item->getId());
      info = item->info;
      index = info.desktop();
      // If it belongs to the current desktop, lets add it
      if (info.valid()) {
        if ((fCurrent == 0) || (index == KWin::currentDesktop()) || (index == -1)) {
          addTask(item->getId(), i);
        }
      }
    }
    for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
      if (!item->info.valid()) {
        witems.remove(i);
      }
    }
    doUpdateGeometry();
  }
  CurrentFocus = wm->activeWindow();
  updTaskList();
}

void KoolDock::workAreaChanged()
{
  int mdw, mdh;
  if (xinerama == 0) {
    mdw = TQApplication::desktop()->width();
    mdh = TQApplication::desktop()->height();
  }
  else {
    mdw = leftRes;
    mdh = XinDesiredHeight;
  }
  if ((fOrientation & 1) == 1) {
    std::swap(mdw, mdh);
  }
  if ((dw != mdw) || (dh != mdh)) {
    reload();
  }
}

// What happens when we change desktops
void KoolDock::currentDesktopChanged(int)
{
  if (initialization) {
    return;
  }
  //funcH = iwBig2 - iwSmall;
  //iwBig = iwBig2;
  addWindows();
  doUpdateGeometry();
  move(0, rdh);
  getTopBG();
  if (fExpanded) {
    move2(x1, dh - h1);
  }
  if ((fHidden == 0) && (!fExpanded)) {
    move2(x0, dh - h0);
  }
  xosdw->move2(0, rdh);
  oldDesktop = KWin::currentDesktop();
}

void KoolDock::windowAdded(WId id)
{
  if (initialization) {
    return;
  }
  if (!fShowTaskbar && fShowNav) {
    addToTaskList(id);
  }
  if (!fShowTaskbar) {
    return;
  }
  KWin::WindowInfo info = KWin::windowInfo(id);
  TQString name = info.name();
  if (name == "kooldock xosd window") {
    debug("Not adding OSD window to taskbar.");
    return;
  }
  if (name == "kooldock") {
    debug("Not adding ourselves.");
    return;
  }

  debug(TQString("windowAdded(%1)").arg(name));

  if (addwTask(id) && fShowNav) {
    addToTaskList(id);
  }
  addTask(id);
  doUpdateGeometry();
  debug(TQString("windowAdded(%1)").arg(name));
}

void KoolDock::windowRemoved(WId id)
{
  if (initialization) {
    return;
  }
  if (fShowNav) {
    rmFromTaskList(id);
  }
  if (!fShowTaskbar) {
    return;
  }
  unsigned int i;
  Item *item;
  debug(TQString("windowRemoved(%1)").arg(id));

  KWin::WindowInfo info = KWin::windowInfo(id);
  TQString name = info.name();

  if (name == "kooldock xosd window") {
    debug("Not removing OSD window from taskbar.");
    return;
  }
  for (i = 0; i < witems.count(); i++) {
    item = witems.at(i);
    if (item->getId() == id) {
      rmTask(id,i);
      rmwTask(i);
      rmFromTaskList(id);
      break;
    }
  }
  doUpdateGeometry();
}

void KoolDock::numberOfDesktopsChanged(int /*num*/)
{
  if (initialization) return;
  if (fShowTaskbar || fShowNav) addWindows();
}

void KoolDock::windowChanged(WId id, unsigned int properties)
{
  if (initialization) {
    return;
  }
  if (fShowNav && !fShowTaskbar) {
    rmFromTaskList(id);
    addToTaskList(id);
  }
  if (!fShowTaskbar) {
    return;
  }
  Item *item;
  bool iconChanged, nameChanged;
  int i;
  bool toRepaint = false;
  bool hasfound = false;
  int iFound;

  KWin::WindowInfo winfo = KWin::windowInfo(id);

  iconChanged = (properties & NET::WMIcon);
  nameChanged = ((properties & NET::WMName) | (properties & NET::WMVisibleName));

  properties = 0;
  if (id != winId()) { // Do not add kooldock window
    if (ignored (winfo.name()) == false) {
      for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
        // Find item in witem (window item) list
        if (item->getId() == id) {
          hasfound = true; // Remember whether item was found and its index
          iFound = i;

          // Handle icon/name changes
          if (iconChanged) {
            item->setIcon(KWin::icon(id, iwBig2, iwBig2, true));
            toRepaint = true;
          }
          if (nameChanged) {
            item->setName(winfo.name());
          }
          if ((fShowNotification) && (id != wm->activeWindow())) {
            debug(TQString("windowChanged (inactive window changed)"));
            // An inactive window's title changed
            // notify user
            item->anim(true);
            if (onChangeTimer == NULL) {
              onChangeTimer = new TQTimer(this);
              connect(onChangeTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(onChangeTimerTicked()));
              onChangeTimer->start(ON_CHANGE_ANIM_INTERVAL, false);
            }
          }
          item->setId(id);
          break;
        }
      }
      // If window is on window list and user has not changed desktop recently...
      if (hasfound && (oldDesktop == KWin::currentDesktop())) {
        if (witems.at(iFound)->getCount() == 0) { // Window icon is not visible on kooldock
          //... check whether it can be added
          if (((fCurrent == 0) || winfo.isOnDesktop(KWin::currentDesktop())) && (fMinimizedOnly == 0 || winfo.isMinimized())) {
            toRepaint |= addTask(id);
          }
        }
        else {
          //... check whether it can be removed
          if (((fCurrent == 1) && (!winfo.isOnDesktop(KWin::currentDesktop()))) || ((fMinimizedOnly == 1) && (!winfo.isMinimized()))) {
            toRepaint |= rmTask(id, iFound);
          }
        }
        if (fShowNav) {
          rmFromTaskList(id);
          addToTaskList(id);
        }
      }
      if (toRepaint) {
        doUpdateGeometry();
        paintEvent(NULL);
      }
    }
  }
}

void KoolDock::systemTrayWindowAdded(WId id)
{
  if (initialization) {
    return;
  }
  if (fSystray == 1) {
    KWin::WindowInfo info = KWin::windowInfo(id);
    TQString name = info.visibleName();
    if (ignored(info.name()) == false) {
      TQPixmap pix = KWin::icon(id, iwBig2, iwBig2, true);
      numSystray++;
      items.append(new Item(pix, id, name, iwSmall, iwBig2));
      debug(TQString("addSystem Tray(%1)").arg(info.visibleName()));
      doUpdateGeometry();
    }
  }
}

void KoolDock::systemTrayWindowRemoved(WId id)
{
  if (initialization) {
    return;
  }
  if (fSystray == 1) {
    numSystray--;
    if (numSystray < 0) {
      numSystray = 0;
    }
    windowRemoved(id);
  }
}

void KoolDock::activeWindowChanged(WId id)
{
  if (initialization) {
    return;
  }
  if (id != winId()) {
    CurrentFocus = id;
  }

  // end notify animation
  unsigned int i;
  for (i = 0; i <= items.count() - 1; i++) {
    if (items.at(i)->getId() == id) {
      items.at(i)->anim(false);
    }
  }

  bool toDelete = true;
  for (i = 0; i <= items.count() - 1; i++) {
    if (items.at(i)->isAnimed()) {
      toDelete = false;
    }
  }

  if (toDelete && (onChangeTimer != NULL)) {
    delete onChangeTimer;
    onChangeTimer = NULL;
    debug("Deleted onChangeTimer");
  }
  if (fGrouping) {
    movetoback(id);
  }
  paintEvent(NULL);
}

void KoolDock::doUpdateGeometry()
{
  int dw1, dw0;
  unsigned int i;
  iwBig= iwBig2;
  for (i = 0; i < items.count(); i++) {
    cx[i] = iSpace + i * iDist + iwSmall / 2;
    iSize[i] = iwSmall;
    if (!fExpanded) {
      cur_cx[i] = cx[i];
    }
  }
  w0 = 2 * iSpace + (items.count() - 1) * iDist + iwSmall + soffset * 2 - eoffset * 2;
  w = w0;
  w1 = w0 + (int) ((iwBig - iwSmall) * 0.6 * fAmount) + iSpace * 2;
  x1 = (dw - w1) * fpercentPos / 100;
  if (w1 > dw) {
    x1 = 0;
  }
  if (w1 > dw) {
    dw1 = dw;
  }
  else {
    dw1 = w1;
  }
  if (w0 > dw) {
    dw0 = dw;
  }
  else {
    dw0 = w0;
  }
  x0 = (dw1 - dw0) / 2 + x1;
  x = x0;
  h0 = 2 * iy + iwSmall;
  h = h0;
  h1 = 2 * iy + iwBig;

  adjust = 0;

  if (fHidden == 0) {
    resize2(w, h);
    move2(x, dh - h);
  }

  ii_first = 0;
  ii_last = items.count() - 1;

  if (fExpanded == true) {
    w = w1;
    h = h1;
    x = x1;
    funcH = iwBig2 - iwSmall;
    iy = (iDist - iwSmall) / 2;
    if (fHidden == 1) {
      move(0, rdh);
      getBottomBG();
      getTopBG();
    }
    resize2(w, h);
    move2(x, dh - h);
  }
  else if (fHidden == 1) {
    move(0, rdh);
  }
  debug(TQString("w1: %1").arg(w1));
  debug(TQString("x1: %1").arg(x1));
  if (fExpanded) {
    last_mx = -10;
    mMoveEvent(lastXPos, lastYPos);
  }
  oldfirstX = x;
  oldtmpw = w;
  paintEvent(NULL);
  xosdw->move2(0, rdh);
}

bool KoolDock::rmTask(WId id, int iFound)
{
  Item *item, *witem, *fitem;
  int i, j;
  int miFound;
  bool hasfound;
  hasfound = false;
  miFound = iFound;
  TQCString cls;

  if (miFound == -1) {
    for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
      if (item->getId() == id) {
        hasfound = true;
        miFound = i;
        break;
      }
    }
  }
  else {
    hasfound = true;
  }
  if (hasfound) {
    fitem = witems.at(miFound);
    if (fitem->getId() == id) {
      if (fitem->getCount() == 1) {
        cls = fitem->getClass();
        // Remove item
        for (i = numLaunchers, item = items.at(numLaunchers); item; i++, item = items.next()) {
          if (fGrouping) {
            if (cls == item->getClass()) {
              int cnt = item->getCount();
              fitem->setCount(0);
              if (cnt == 0) {
                items.remove(i);
                return true;
              }
              else {
                int ir, il = -1, im = -1;
                int jl = -1, jm = -1;
                ir = fitem->getIndex();
                for (j = 0, witem = witems.at(0); witem; j++, witem = witems.next()) {
                  if (witem->getClass() == cls) {
                    if ((witem->getIndex() < ir) && (witem->getIndex() > il)) {
                      il = witem->getIndex();
                      jl = witem->getId();
                    }
                    if (witem->getIndex() > im) {
                      im = witem->getIndex();
                      jm = witem->getId();
                    }
                  }
                }
                item->setCount(cnt - 1);
                if (jl >= 0) {
                  item->setId(jl);
                  return true;
                }
                if (jm >= 0) {
                  item->setId(jm);
                }
                return true;
              }
            }
          }
          else {
            if (item->getId() == id) {
              items.remove(i);
              witems.at(miFound)->setCount(0);
              return true;
            }
          }
        }
      }
    }
  }
  return false;
}

void KoolDock::rmwTask(int iFound)
{
  Item* item;
  int i;
  int ind = witems.at(iFound)->getIndex();

  for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
    if (item->getIndex() > ind) {
      item->setIndex(item->getIndex() - 1);
    }
  }
  witems.remove(iFound);
}

bool KoolDock::addTask(WId id, int iFound)
{
  Item *item;
  int i ;
  bool hasfound = false;
  int miFound = iFound;
  KWin::WindowInfo info = KWin::windowInfo(id, 0, NET::WM2WindowClass);
  const int SUPPORTED_WINDOW_TYPES = NET::NormalMask | NET::DesktopMask | NET::DockMask |
                                     NET::ToolbarMask | NET::MenuMask | NET::DialogMask |
                                     NET::OverrideMask | NET::TopMenuMask |
                                     NET::UtilityMask | NET::SplashMask;
  TQString name = info.visibleName();
  TQCString cls = info.windowClassClass();
  if (info.windowType(SUPPORTED_WINDOW_TYPES) == NET::Normal ||
                                                 info.windowType(SUPPORTED_WINDOW_TYPES) == NET::Override ||
                                                 info.windowType(SUPPORTED_WINDOW_TYPES) == NET::Dialog ||
                                                 info.windowType(SUPPORTED_WINDOW_TYPES) == NET::Unknown) {
    if (info.isMinimized() || fMinimizedOnly==0) {
      if (fCurrent==0 || info.isOnDesktop (KWin::currentDesktop())) {
        if ((info.state() & NET::SkipTaskbar) == 0) {
          if (ignored (info.name()) == false) {
            if (miFound == -1) {
              for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
                if (item->getId() == id) {
                  hasfound = true;
                  miFound = i;
                  break;
                }
              }
            }
            else {
              hasfound=true;
            }

            if (hasfound) {
              if (witems.at(miFound)->getId() == id) {
                if (witems.at(miFound)->getCount() == 0) {
                  witems.at(miFound)->setCount(1);
                  if (fGrouping) {
                    hasfound = false;
                    for (i = numLaunchers, item = items.at(numLaunchers); item; i++, item = items.next()) {
                      if (item->getClass() == cls) {
                        item->setCount(item->getCount() + 1);
                        return true;
                      }
                    }
                  }
                  TQPixmap pix;
                  items.insert(items.count() - numSystray, new Item(pix, id, name, iwSmall, iwBig2, true));
                  items.at(items.count() - 1)->setClass(cls);
                  debug(TQString("addTask(%1)").arg(info.visibleName()));
                  return true;
                }
              }
            }
          }
        }
      }
    }
  }
  return false;
}

bool KoolDock::addwTask(WId id)
{
  KWin::WindowInfo info = KWin::windowInfo(id, 0, NET::WM2WindowClass);
  const int SUPPORTED_WINDOW_TYPES = NET::NormalMask | NET::DesktopMask | NET::DockMask |
                                     NET::ToolbarMask | NET::MenuMask | NET::DialogMask |
                                     NET::OverrideMask | NET::TopMenuMask |
                                     NET::UtilityMask | NET::SplashMask;
  TQString name = info.visibleName();
  TQCString cls = info.windowClassClass();

  if (info.windowType(SUPPORTED_WINDOW_TYPES) == NET::Normal ||
                                                 info.windowType(SUPPORTED_WINDOW_TYPES) == NET::Override ||
                                                 info.windowType(SUPPORTED_WINDOW_TYPES) == NET::Dialog ||
                                                 info.windowType(SUPPORTED_WINDOW_TYPES) == NET::Unknown) {
    if ((info.state() & NET::SkipTaskbar) == 0) {
      if (ignored(info.name()) == false) {
        TQPixmap pix = KWin::icon(id, iwBig2, iwBig2, true);
        witems.append(new Item(pix, id, name, iwSmall, iwBig2));
        witems.at(witems.count() - 1)->setClass(cls);
        witems.at(witems.count() - 1)->setIndex(witems.count() - 1);
        return true;
      }
    }
  }
  return false;
}

void KoolDock::loadConf()
{
  TDEConfig *config = TDEGlobal::config();

  config->setGroup("kooldock");
  fShowTaskbar = config->readNumEntry("ShowTaskbar", 0);
  fMinimizedOnly = config->readNumEntry("MinimizedOnly", 0);
  fShowNotification = config->readNumEntry("ShowNotification", 0);
  showNames = config->readNumEntry("showNames", 1);
  fCleaner = config->readNumEntry("Cleaner", 0);
  xosdFont = config->readEntry("xosdFont", "Tahoma");
  xosdColor = config->readEntry("xosdColor", "#f1f1f1");
  xosdShadowColor = config->readEntry("xosdShadowColor", "#000000");
  xosdSize = config->readNumEntry("xosdSize", 17);
  xosdShadowOffset = config->readNumEntry("xosdShadowOffset", 2);
  fShowBorders = config->readNumEntry("ShowBorders", 0);
  borderColor = TQColor(config->readEntry("BorderColor", "#b1c4de"));
  iwSmall = config->readNumEntry("SmallIconSize", 32);
  iwBig = config->readNumEntry("BigIconSize", 90);
  fAmount = config->readNumEntry("BigIconAmount", 5);
  if (fAmount > 10) {
    fAmount = 10;
  }
  if (fAmount < 4) {
    fAmount = 4;
  }
  fShowKMenu = config->readNumEntry("ShowKMenu", 0);
  fUseKBFX = config->readNumEntry("KBFX", 0);
  dockOpacity = config->readNumEntry("DockOpacity", 0);
  iSpace = config->readNumEntry("iSpace", 10);
  if (dockOpacity < 0) {
    dockOpacity = 0;
  }
  else if (dockOpacity > 100) {
    dockOpacity = 100;
  }
  bgColor = TQColor(config->readEntry("BackgroundColor", "#ccccff"));
  sepColor = TQColor(config->readEntry("SeparatorColor", "#000000"));
  fPriority = config->readNumEntry("Priority", 3);
  fMouseTimer = config->readNumEntry("MouseTimer", 25);
  fClipping = config->readNumEntry("Clipping", 0);
  fClipIcons = config->readNumEntry("ClipIconArea", 0);
  fpercentPos = config->readNumEntry("percentPos", 50);
  fOrientation = config->readNumEntry("fOrientation", 0);
  if ((fOrientation < 0) || (fOrientation > 3)) {
    fOrientation = 0;
  }
  fzoomSpeed = config->readNumEntry("zoomSpeed", 20);
  fSpeed = config->readNumEntry("speedControl", 0) == 1;
  if (fzoomSpeed > 10) {
    if (fzoomSpeed > 100) {
      zoomStep = 10;
    }
    else {
      zoomStep = fzoomSpeed / 10;
    }
  }
  else {
    zoomStep = 1;
  }
  if (fSpeed) {
    zoomStepB = 200;
    zoomStepS = 200;
    neededTicksB = 1;
    neededTicksS = 1;
  }
  else {
    zoomStepB = zoomStep;
    zoomStepS = zoomStep;
    neededTicksB = (int) (fzoomSpeed / zoomStep) - 1;
    neededTicksS = (int) (fzoomSpeed / zoomStep) - 1;
  }

  if (neededTicksB == 0) {
    neededTicksB = 1;
  }
  if (neededTicksS == 0) {
    neededTicksS = 1;
  }

  if (fpercentPos < 0) {
    fpercentPos = 0;
  }
  if (fpercentPos > 100) {
    fpercentPos = 100;
  }
  fHidden = config->readNumEntry("Hidden", 1);
  fHighLightTime = config->readNumEntry("HighLightTime", 2);
  fHideOnClick = config->readNumEntry("HideOnClick", 0);
  fStayBelow = config->readNumEntry("StayBelow", 0);
  fSteppy = config->readNumEntry("fSteppy", 0);
  fLeftImg = config->readEntry("LeftImg");
  fRightImg = config->readEntry("RightImg");
  fCenterImg = config->readEntry("CenterImg");
  fNWideBg = config->readBoolEntry("nWideBg", true);
  scaleMax = config->readBoolEntry("scaleMax", false);
  fFirstRun = config->readBoolEntry("FirstRun", true);
  xinerama = config->readNumEntry("Xinerama", 0);
  leftRes=config->readNumEntry("leftRes", TQApplication::desktop()->width());
  XinDesiredHeight=config->readNumEntry("XinDesiredHeight", TQApplication::desktop()->height());
  XinPreviousWidth=config->readNumEntry("XinPreviousWidth", 0);
  hideTimer = config->readNumEntry("hideTimer", 125);
  Solid = config->readNumEntry("Solid", 1);
  fShowShot = config->readBoolEntry("ShowSShot", false);
  fGrouping = config->readBoolEntry("iconGrouping", false);
  fShowNav = config->readNumEntry("Navigator", 1);
  fSystray = 0;//config->readNumEntry("Systray", 0);
  fCurrent = config->readNumEntry("currentDesktop", 0);
  curTheme = config->readEntry("Theme");

  if (config->readNumEntry ("xosdBold", 1) == 0) {
    xosdBold = false;
  }
  else {
    xosdBold = true;
  }

  if (config->readNumEntry ("xosdItalic", 1) == 0) {
    xosdItalic = false;
  }
  else {
    xosdItalic = true;
  }

  if (iwSmall > iwBig) {
    iwSmall = 32;
    iwBig = 90;
  }
  if (!fShowTaskbar) {
    fShowNotification = 0;
  }
  if ((fHidden != 1) && (fHidden != 0)) {
    fHidden = 1;
  }
  if ((fStayBelow != 1) && (fStayBelow != 0)) {
    fStayBelow = 0;
  }
}

void KoolDock::loadIgnore()
{
  TQString line;

  // Read the ignorelist into 'ignoreList'
  TQFile in(TQString(progPath + "/ignorelist.conf"));

  // Clear de ignoreList and the KEditListBox (ignoreBox)
  ignoreList.clear();
  setupdlg->ignoreBox->clear();
  if (in.open(IO_ReadOnly)) {
    while (in.readLine(line, MAX_LEN) != -1) {
      // Append the item and strip the last char (new line)
      ignoreList.append(line.mid(0, line.length() - 1));
    }
    in.close();
    if (!ignoreList.isEmpty()) {
      setupdlg->ignoreBox->insertStringList(ignoreList);
    }
  }
}

void KoolDock::saveConf()
{
  TDEConfig *config = TDEGlobal::config();

  config->setGroup("kooldock");
  config->writeEntry("ShowTaskbar", fShowTaskbar);
  config->writeEntry("MinimizedOnly", fMinimizedOnly);
  config->writeEntry("ShowNotification", fShowNotification);
  config->writeEntry("ShowBorders", fShowBorders);
  config->writeEntry("BorderColor", borderColor.name());
  config->writeEntry("SmallIconSize", iwSmall);
  config->writeEntry("BigIconSize", iwBig2);
  config->writeEntry("BigIconAmount", fAmount);
  config->writeEntry("DockOpacity", dockOpacity);
  config->writeEntry("BackgroundColor", bgColor.name());
  config->writeEntry("SeparatorColor", sepColor.name());
  config->writeEntry("ShowKMenu", fShowKMenu);
  config->writeEntry("KBFX", fUseKBFX);
  config->writeEntry("Priority", fPriority);
  config->writeEntry("MouseTimer", fMouseTimer);
  config->writeEntry("Clipping", fClipping);
  config->writeEntry("ClipIconArea", fClipIcons);
  config->writeEntry("percentPos", fpercentPos);
  config->writeEntry("zoomSpeed", fzoomSpeed);
  config->writeEntry("speedControl", fSpeed);
  config->writeEntry("Hidden", fHidden);
  config->writeEntry("StayBelow", fStayBelow);
  config->writeEntry("fOrientation", fOrientation);
  config->writeEntry("showNames", showNames);
  config->writeEntry("Cleaner", fCleaner);
  config->writeEntry("xosdFont", xosdFont);
  config->writeEntry("xosdColor", xosdColor);
  config->writeEntry("xosdShadowColor", xosdShadowColor);
  config->writeEntry("xosdSize", xosdSize);
  config->writeEntry("HideOnClick", fHideOnClick);
  config->writeEntry("fSteppy", fSteppy);
  config->writeEntry("HighLightTime", fHighLightTime);
  config->writeEntry("iSpace", iSpace);
  config->writeEntry("FirstRun", false);
  config->writeEntry("Xinerama", xinerama);
  config->writeEntry("hideTimer", hideTimer);
  config->writeEntry("Solid", Solid);
  config->writeEntry("ShowSShot", fShowShot);
  config->writeEntry("iconGrouping", fGrouping);
  config->writeEntry("Navigator", fShowNav);
  config->writeEntry("Systray", fSystray);
  config->writeEntry("currentDesktop", fCurrent);

  if (xosdBold == true) {
    config->writeEntry("xosdBold", 1);
  }
  else {
    config->writeEntry("xosdBold", 0);
  }

  if (xosdItalic == true) {
    config->writeEntry("xosdItalic", 1);
  }
  else {
    config->writeEntry("xosdItalic", 0);
  }
  config->sync();
}

void KoolDock::editPref()
{
  bool tmp; // To save some code

  // Open up the configuration dialog

  // Fill dialog with values from configuration
  tmp = (fHidden == 1);
  setupdlg->chk1->setChecked(tmp);
  setupdlg->hideTimer->setEnabled(tmp);
  setupdlg->hideOnClick->setEnabled(tmp);
  setupdlg->cbStayBelow->setEnabled(!tmp);
  setupdlg->cbStayBelow->setChecked(fStayBelow == 1);

  tmp = (fShowTaskbar == 1);
  setupdlg->chk6->setEnabled(tmp);
  setupdlg->cbMinimizedOnly->setEnabled(tmp);
  setupdlg->chkSshot->setEnabled(tmp);
  setupdlg->chkGrouping->setEnabled(tmp);
  setupdlg->currentDesk->setEnabled(tmp);

  setupdlg->systray->setChecked(fSystray == 1);

  setupdlg->currentDesk->setChecked(fCurrent == 1);

  // Even if start Hidden is disabled we load the stored value
  setupdlg->hideTimer->setValue(hideTimer);
  setupdlg->hideOnClick->setChecked(fHideOnClick == 1);
  setupdlg->Steppy->setChecked(fSteppy == 1);
  setupdlg->cbCleaner->setChecked(fCleaner == 1);

  tmp= (showNames == 1);
  setupdlg->chk2->setChecked(tmp);
  setupdlg->xosdBold->setEnabled(tmp);
  setupdlg->xosdItalic->setEnabled(tmp);
  setupdlg->xosdSize->setEnabled(tmp);
  setupdlg->spinBox2->setEnabled(tmp);
  setupdlg->kColorCombo1->setEnabled(tmp);
  setupdlg->kColorCombo_shadow->setEnabled(tmp);
  setupdlg->xosdFont->setEnabled(tmp);
  setupdlg->cbCleaner->setEnabled(tmp);

  if (Solid == 1) {
    setupdlg->chkSolid->setChecked(true);
    setupdlg->chkSolidSlot();
  }
  else {
    if (!curTheme.isEmpty()) {
      setupdlg->theme->setCurrentText(curTheme);
    }
    setupdlg->chkImg->setChecked(true);
    setupdlg->chkSolidSlot();
  }
  setupdlg->chk4->setChecked(fShowBorders == 1);
  setupdlg->kColorCombo1->setColor(xosdColor);
  setupdlg->kColorCombo_shadow->setColor(xosdShadowColor);
  setupdlg->xosdFont->setCurrentFont(xosdFont);
  setupdlg->kColorCombo2->setColor(bgColor.name());
  setupdlg->kColorCombo3->setColor(borderColor.name());
  setupdlg->kColorCombo4->setColor(sepColor.name());
  setupdlg->spinBox1->setValue(dockOpacity);
  setupdlg->xosdSize->setValue(xosdSize);
  setupdlg->spinBox2->setValue(xosdShadowOffset);
  setupdlg->chk5->setChecked(fShowTaskbar == 1);
  setupdlg->cbMinimizedOnly->setChecked(fMinimizedOnly == 1);
  setupdlg->chk6->setChecked(fShowNotification == 1);
  setupdlg->chk7->setChecked(fShowKMenu == 1);
  setupdlg->chkUseKBFX->setChecked(fUseKBFX == 1);
  setupdlg->iwSmall->setValue(iwSmall);
  setupdlg->iwBig->setValue(iwBig2);
  setupdlg->fAmount->setValue(fAmount);
  setupdlg->sbSpace->setValue(iSpace);
  setupdlg->nWideBg->setChecked(fNWideBg);
  if (scaleMax) {
    setupdlg->opScale2->setChecked(true);
  }
  else {
    setupdlg->opScale1->setChecked(true);
  }
  setupdlg->xosdBold->setChecked(xosdBold);
  setupdlg->xosdItalic->setChecked(xosdItalic);
  if (xinerama == 1) {
    setupdlg->xrma->setChecked(true);
    setupdlg->SleftRes->setEnabled(true);
    setupdlg->SHeight->setEnabled(true);
    setupdlg->PWidth->setEnabled(true);
    setupdlg->SleftRes->setValue(leftRes);
    setupdlg->SHeight->setValue(XinDesiredHeight);
    setupdlg->PWidth->setValue(XinPreviousWidth);
  }
  else {
    setupdlg->SleftRes->setEnabled(false);
    setupdlg->SHeight->setEnabled(false);
    setupdlg->PWidth->setEnabled(false);
    setupdlg->xrma->setChecked(false);
    setupdlg->SleftRes->setValue(TQApplication::desktop()->width());
    setupdlg->SHeight->setValue(TQApplication::desktop()->height());
  }
  setupdlg->nav->setChecked(fShowNav==1);
  setupdlg->chkSshot->setChecked(fShowShot);
  setupdlg->chkGrouping->setChecked(fGrouping);
  setupdlg->Priority->setValue(fPriority);
  setupdlg->chClipping->setChecked(fClipping == 1);
  setupdlg->chClipIcons->setChecked(fClipIcons == 1);
  setupdlg->zoomSpeed->setValue(fzoomSpeed);
  setupdlg->chkSpeed->setChecked(fSpeed);
  setupdlg->percentPos->setValue(fpercentPos);
  if (fOrientation == 0) {
    setupdlg->op0->setChecked(true);
  }
  if (fOrientation == 1) {
    setupdlg->op1->setChecked(true);
  }
  if (fOrientation == 2) {
    setupdlg->op2->setChecked(true);
  }
  if (fOrientation == 3) {
    setupdlg->op3->setChecked(true);
  }
  loadIgnore(); // Load Ignore List

  if (!setupdlg->isVisible() && !lockSetTab) {
    setupdlg->tabWidget->setCurrentPage(0);
  }
  setupdlg->toReloadIcons->setChecked(false);

  setupdlg->show();
  KWin::WindowInfo winfo = KWin::windowInfo(setupdlg->winId());

  if (winfo.desktop() !=-1) {
    KWin::setOnDesktop(setupdlg->winId(), KWin::currentDesktop());
  }
  KWin::activateWindow(setupdlg->winId());
}

void KoolDock::loadMenu()
{
  TQDir homeDir = TQDir::home();
  if (homeDir.exists(menuPath)) {
    TQDir dir(menuPath);
    // First make sure every index is correct!
    // Update the launchers index
    TQString preffix;
    TQStringList fileListRemove = dir.entryList("*.desktop");
    TQStringList fileListRemove2 = fileListRemove;

    for (unsigned int i = 0; i < fileListRemove2.count(); i++) {
      fileListRemove2[i].remove(0,2);
    }

    // Rename the files so they reflect their new position
    for (unsigned int i = 0; i < fileListRemove.count(); i++) {
      if (i < 10) {
        preffix = TQString("0%1").arg(i);
      }
      if (i >= 10) {
        preffix = TQString("%1").arg(i);
      }
      dir.rename(fileListRemove[i], TQString("%1%2").arg(preffix).arg(fileListRemove2[i]));
    }
    // End updating launchers index

    TQStringList fileList = dir.entryList("*.desktop");
    if (!fileList.isEmpty()) {
      for (TQStringList::Iterator it = fileList.begin(); it != fileList.end(); ++it) {
        if (((*it) != ".") && ((*it) != "..")) {
          items.append(new Item(menuPath + (*it), iwSmall, iwBig2));
        }
      }
    }
  }
  else {
    debug("Config directory doesn't exits");
    TQDir progPathDir(progPath);
    progPathDir.mkdir(progPath);
    TQDir menuPathDir(menuPath);
    menuPathDir.mkdir(menuPath);
    debug("Created item directory");

    // create initial entries.
    addFile(TQString("00_konqueror.desktop"),
            TQString("konqueror"),
            TQString("kfmclient openProfile webbrowsing"),
            TQString("Konqueror Web Browser"));
    addFile(TQString("01_home.desktop"),
            TQString("kfm_home"),
            TQString("kfmclient openProfile filemanagement"),
            TQString("Home directory"));
    addFile(TQString("02_kmail.desktop"),
            TQString("kmail"),
            TQString("kmail"),
            TQString("KMail"));
    addFile(TQString("03_kate.desktop"),
            TQString("kate"),
            TQString("kate"),
            TQString("Kate"));
    addFile(TQString("04_konsole.desktop"),
            TQString("konsole"),
            TQString("konsole"),
            TQString("Konsole"));
    addFile(TQString("05_kcontrol.desktop"),
            TQString("kcontrol"),
            TQString("kcontrol"),
            TQString("Control Center"));
    loadMenu();
  }
  numLaunchers = items.count();
}

void KoolDock::about()
{
  TDEAboutApplication about(this, 0, false);
  about.exec();
}

void KoolDock::onChangeTimerTicked()
{
  if (animValue > 70) {
    animState = false;
  }
  if (animValue < 5) {
    animState = true;
  }

  if (animState == true) {
    animValue = animValue + 5;
  }
  else {
    animValue = animValue - 5;
  }
  paintEvent(NULL);
}

void KoolDock::updateBackground(const TQPixmap& pix)
{
  if ((pix.width() == 1) && (pix.height() == 1)) {
    if (fHidden == 0) {
      if ((fOrientation & 1) == 1) {
        bottomBg = TQPixmap(h1, dw);
      }
      else {
        bottomBg = TQPixmap(dw, h1);
      }
      bottomBg.fill(pix.convertToImage().pixel(0,0));
    }
    if (dockOpacity > 0) {
      bitBlt(&bottomBgf, 0, 0, &bottomBg);
      KPixmapEffect::fade(bottomBgf, ((float) dockOpacity) * 0.01, bgColor);
    }
  }
  else {
    if (fHidden == 0) {
      bottomBg = TQPixmap(pix);
    }
    if (dockOpacity > 0) {
      bitBlt(&bottomBgf, 0, 0, &bottomBg);
      KPixmapEffect::fade(bottomBgf, ((float) dockOpacity) * 0.01, bgColor);
    }
  }
  uw = w;
  paintEvent(NULL);
}

void KoolDock::toggleAlwaysOnTop()
{
  KWin::WindowInfo info= KWin::windowInfo(cId);

  if (info.state() & NET::KeepAbove) {
    KWin::clearState(cId,NET::KeepAbove);
  }
  else {
    KWin::setState(cId,NET::KeepAbove);
    KWin::raiseWindow(cId);
  }
}

void KoolDock::toggleKeptBelowOthers()
{
  KWin::WindowInfo info = KWin::windowInfo(cId);

  if (info.state() & NET::KeepBelow) {
    KWin::clearState(cId,NET::KeepBelow);
  }
  else {
    KWin::setState(cId,NET::KeepBelow);
    KWin::lowerWindow(cId);
  }
}

void KoolDock::toggleFullScreen()
{
  KWin::WindowInfo info = KWin::windowInfo(cId);

  if (info.state() & NET::FullScreen) {
    KWin::clearState(cId,NET::FullScreen);
  }
  else {
    KWin::setState(cId,NET::FullScreen);
  }
}

void KoolDock::moveApp()
{
  KWin::WindowInfo info = KWin::windowInfo(cId);
  activateApp();

  TQCursor::setPos(info.geometry().center());

  NETRootInfo ri(tqt_xdisplay(), NET::WMMoveResize);
  ri.moveResizeRequest(cId, info.geometry().center().x(), info.geometry().center().y(), NET::Move);
}

void KoolDock::resizeApp()
{
  KWin::WindowInfo info = KWin::windowInfo(cId);
  activateApp();

  TQCursor::setPos(info.geometry().bottomRight());

  NETRootInfo ri(tqt_xdisplay(), NET::WMMoveResize);
  ri.moveResizeRequest(cId, info.geometry().bottomRight().x(),
                       info.geometry().bottomRight().y(), NET::BottomRight);
}

void KoolDock::minApp()
{
  Item *item;
  int i;
  TQPixmap shot;
  TQImage tmpImg;
  KWin::WindowInfo info= KWin::windowInfo(cId);

  if (info.isMinimized()) {
    for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
      if (item->getId() == cId) {
        // Set default's item icon
        item->setIcon(KWin::icon(cId, iwBig2, iwBig2, true));
      }
    }
    KWin::deIconifyWindow(cId, true);
    KWin::activateWindow(cId);
  }
  else {
    if (fShowShot == true) {
      for (i=0, item = witems.at(0); item; i++, item = witems.next()) {
        if (item->getId() == cId) {
          // Take the screenshot
          shot = TQPixmap::grabWindow(cId);
          // Scale the screenshot
          tmpImg = shot.convertToImage();
          tmpImg.scale(iwBig2, iwBig2);
          shot.convertFromImage(tmpImg);
          // Set the new item's icon
          item->setIcon(shot);
        }
      }
      paintEvent(NULL);
    }
    KWin::iconifyWindow(cId, true);
  }
  hide();
  TQTimer::singleShot(100, this, TQ_SLOT(refreshBackground()));
}

void KoolDock::maxApp()
{
  Item *item;
  int i;
  KWin::WindowInfo info = KWin::windowInfo(cId);

  if (fShowShot == true) {
    for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
      if (item->getId() == cId) {
        // Set default's item icon
        item->setIcon(KWin::icon(cId, iwBig2, iwBig2, true));
      }
    }
  }
  if (info.isMinimized()) {
    KWin::deIconifyWindow(cId, true);
  }
  else {
    if (info.state() & NET::Max) {
      KWin::clearState(cId, NET::Max);
    }
    else {
      KWin::setState(cId, NET::Max);
    }
  }
  KWin::activateWindow(cId);
  hide();
  TQTimer::singleShot(100, this, TQ_SLOT(refreshBackground()));
}

void KoolDock::restApp()
{
  Item *item;
  int i;
  KWin::WindowInfo info = KWin::windowInfo(cId);

  if (fShowShot == true) {
    for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
      if (item->getId() == cId) {
        // Set default's item icon
        item->setIcon(KWin::icon(cId, iwBig2, iwBig2, true));
      }
    }
  }

  KWin::clearState(cId, NET::MaxVert + NET::MaxHoriz);
  KWin::deIconifyWindow(cId, true);
  KWin::activateWindow(cId);
  hide();
  TQTimer::singleShot(100, this, TQ_SLOT(refreshBackground()));
}

void KoolDock::minAllApps()
{
  int i;
  Item *item;
  KWin::WindowInfo info = KWin::windowInfo(cId, 0, NET::WM2WindowClass);
  TQCString cls = info.windowClassClass();
  for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
    if (!item->info.isMinimized()) {
      if (((fMinimizedOnly == 0) || (item->info.isMinimized())) || ((fCurrent == 0) || item->info.isOnDesktop(info.desktop()))) {
        if (cls == item->getClass()) {
          KWin::iconifyWindow(item->getId(), true);
        }
      }
    }
  }
}

void KoolDock::maxAllApps()
{
  int i;
  Item *item;
  KWin::WindowInfo info = KWin::windowInfo(cId, 0, NET::WM2WindowClass);
  TQCString cls = info.windowClassClass();
  for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
    if (!(item->info.state() & NET::Max) || item->info.isMinimized()) {
      if (((fMinimizedOnly == 0) || item->info.isMinimized()) || ((fCurrent == 0) || item->info.isOnDesktop(info.desktop()))) {
        if (cls == item->getClass()) {
          if (item->info.isMinimized()) {
            KWin::deIconifyWindow(item->getId(), true);
          }
          KWin::setState(item->getId(), NET::Max);
        }
      }
    }
  }
}

void KoolDock::restAllApps()
{
  int i;
  Item *item;
  KWin::WindowInfo info = KWin::windowInfo(cId, 0, NET::WM2WindowClass);
  TQCString cls = info.windowClassClass();
  for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
    if (item->info.state() & NET::Max || item->info.isMinimized()) {
      if (((fMinimizedOnly == 0) || item->info.isMinimized()) || ((fCurrent == 0) || item->info.isOnDesktop(info.desktop()))) {
        if (cls == item->getClass()) {
          if (item->info.isMinimized()) {
            KWin::deIconifyWindow(item->getId(), true);
          }
          else {
            KWin::clearState(item->getId(), NET::Max);
          }
        }
      }
    }
  }
}

void KoolDock::closeAllApps()
{
  int i;
  Item *item;
  KWin::WindowInfo info = KWin::windowInfo(cId, 0, NET::WM2WindowClass);
  TQCString cls = info.windowClassClass();
  for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
    if (((fMinimizedOnly == 0) || item->info.isMinimized()) || ((fCurrent == 0) || item->info.isOnDesktop(info.desktop()))) {
      if (cls == item->getClass()) {
        NETRootInfo app(tqt_xdisplay(), NET::CloseWindow);
        app.closeWindowRequest(item->getId());
      }
    }
  }
}

void KoolDock::shadeApp()
{
  KWin::WindowInfo info = KWin::windowInfo(cId);

  if (info.state() & NET::Shaded) {
    KWin::clearState(cId, NET::Shaded);
  }
  else {
    KWin::setState(cId, NET::Shaded);
  }
  hide();
  TQTimer::singleShot(100, this, TQ_SLOT(refreshBackground()));
}

void KoolDock::activateApp()
{
  Item *item;
  int i;
  KWin::WindowInfo info = KWin::windowInfo(cId);

  if (fShowShot == true) {
    for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
      if (item->getId() == cId) {
        // Set default's item icon
        item->setIcon(KWin::icon(cId, iwBig2, iwBig2, true));
      }
    }
  }

  if ((info.desktop() != -1) && (info.desktop() != KWin::currentDesktop())) {
    goToDesktop(info.desktop());
  }
  if (info.isMinimized()) {
    KWin::deIconifyWindow(cId, true);
  }
  KWin::activateWindow(cId);
  hide();
  TQTimer::singleShot(100, this, TQ_SLOT(refreshBackground()));
}

void KoolDock::closeApp()
{
  NETRootInfo app(tqt_xdisplay(), NET::CloseWindow);
  app.closeWindowRequest(cId);
  debug(TQString("Closed: %1").arg(cId));
}

void KoolDock::editItem()
{
  run(TQString("kfmclient openProperties ") + iFilename);
}

void KoolDock::sendToDesktop(int desktop)
{
  if (desktop == 0) {
    desktop = -1;
  }
  if (iGroup && allApps) {
    int i;
    Item *item;
    KWin::WindowInfo info = KWin::windowInfo(cId, 0, NET::WM2WindowClass);
    TQCString cls = info.windowClassClass();
    for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
      if (((fMinimizedOnly == 0) || item->info.isMinimized()) || ((fCurrent == 0) || item->info.isOnDesktop(info.desktop()))) {
        if (cls == item->getClass()) {
          KWin::setOnDesktop(item->getId(), desktop);
        }
      }
    }
    return;
  }
  KWin::setOnDesktop(cId, desktop);
}

void KoolDock::goToDesktop(int desktop)
{
  KWin::setCurrentDesktop(desktop);
}

void KoolDock::goToWindow(int win)
{
  cId = (WId) win;
  activateApp();
}

void KoolDock::removeItem()
{
  TQFile::remove(iFilename);
  restart();
}

void KoolDock::addFile(const TQString& filename,
                       const TQString& iconname,
                       const TQString& execname,
                       const TQString& name,
                       bool notify,
                       bool terminal,
                       bool tclose,
                       bool cuser,
                       TQString puser)
{
  TQString progPath = locateLocal("data", "kooldock");
  TQString menuPath = progPath + TQString("/menu/");
  TQString confFile = locateLocal("config", "kooldockrc");

  TQFile out(TQString(menuPath + filename));
  if (out.open (IO_WriteOnly)) {
    TQTextStream out_s(&out);
    out_s << "[Desktop Entry]" << endl;
    out_s << "Comment=" << endl;
    out_s << "Encoding=UTF-8" << endl;
    out_s << "Exec=" << execname << endl;
    out_s << "GenericName=" << endl;
    out_s << "Icon=" << iconname << endl;
    out_s << "MimeType=" << endl;
    out_s << "Name=" << name << endl;
    out_s << "Path=" << endl;
    out_s << "ServiceTypes=" << endl;
    out_s << "SwallowExec=" << endl;
    out_s << "SwallowTitle=" << endl;
    out_s << "Terminal=false" << endl;
    out_s << "TerminalOptions=" << endl;
    out_s << "Type=Application" << endl;
    if (notify == true) {
      out_s << "X-TDE-StartupNotify=true" << endl;
    }
    else {
      out_s << "X-TDE-StartupNotify=false" << endl;
    }
    if (cuser == true) {
      out_s << "X-TDE-SubstituteUID=true" << endl;
      out_s << "X-TDE-Username=" << puser << endl;
    }
    else {
      out_s << "X-TDE-SubstituteUID=false" << endl;
      out_s << "X-TDE-Username=" << endl;
    }
    if (terminal == true) {
      out_s << "Terminal=true" << endl;
    }
    else {
      out_s << "Terminal=false" << endl;
    }
    if (tclose == true) {
      out_s << "TerminalOptions=\\s--noclose" << endl;
    }
    else {
      out_s << "TerminalOptions=" << endl;
    }
    out.close();
  }
}

bool KoolDock::ignored(const TQString& appname)
{
  if (ignoreList.count() > 0) {
    for (unsigned int i = 0; i < ignoreList.count(); i++) {
      if (ignoreList[i] == appname) {
        return true;
      }
    }
  }
  return false;
}


#ifdef _ENABLE_DEBUG
void KoolDock::debug(TQString message)
{
  // Debugging function (show messages to stdout)
  kdDebug (0) << "DEBUG: " << message << endl;
}
#endif
#ifndef _ENABLE_DEBUG
void KoolDock::debug (TQString)
{
}
#endif

void KoolDock::endProg()
{
  if ((fHidden == 0) && (fClipping == 1)) {
    if ((fOrientation & 1) == 1) {
      setDesktopIconsArea(0, 0, dh, dw);
    }
    else {
      setDesktopIconsArea(0, 0, dw, dh);
    }
  }
  debug("Clean exit.");
  exit(0);
}

void KoolDock::restart()
{
  TQString cmd;
  cmd = mainPath + " &";
  kdDebug(0) << "mainPath: " << mainPath << endl;
  debug("Restarting...");
  int status = system(cmd.latin1());
  debug(TQString("Status: %1").arg(status));
  endProg();
}

void KoolDock::reload()
{
  setupdlg->setEnabled(false);

  hide();
  if (wm) {
    delete wm;
  }
  trackTimer->stop();
  mkbigTimer->stop();
  mksmallTimer->stop();
  mTimer->stop();
  if (onChangeTimer != NULL) {
    onChangeTimer->stop();
  }
  if (trackTimer) {
    delete trackTimer;
  }
  if (mTimer) {
    delete mTimer;
  }
  if (mkbigTimer) {
    delete mkbigTimer;
  }
  if (mksmallTimer) {
    delete mksmallTimer;
  }
  if (onChangeTimer != NULL) {
    delete onChangeTimer;
  }
  if (_filterData) {
    delete _filterData;
  }
  if (rootpix) {
    delete rootpix;
  }
  if (xosdw) {
    delete xosdw;
  }
  if (clipw) {
    delete clipw;
  }
  if (info) {
    delete info;
  }

  if (reloadIcons) {
    items.clear();
    witems.clear();
  }
  init();
  if (setupdlg->isVisible()) {
    lockSetTab=true;
    editPref();
    if (reloadIcons) {
      setupdlg->appClear();
      setupdlg->appFill();
    }
    lockSetTab=false;
  }
}

void KoolDock::chkRestart()
{
  if (initialization) {
    return;
  }
  if (!setupdlg) {
    return;
  }
  // this function is called by a timer to check if the dock should be restarted
  // or not, depending on what was done in the configuration dialog.
  reloadIcons = setupdlg->toReloadIcons->isChecked();
  reload();
  reloadIcons = false;
  setupdlg->toReloadIcons->setChecked(false);
}

void KoolDock::setMainPath(const TQString& path)
{
  mainPath = path;
}

void KoolDock::setArgs(const TQString& params)
{
  args = params;
  if ((args == "-options") || (args == "-o")) {
    editPref();
  }
}

void KoolDock::move2(int nx, int ny)
{
  int cx, cy, xn=0;
  if (xinerama == 1) {
    xn = XinPreviousWidth;
  }

  cx = 0;
  if ((fOrientation & 2) == 2) {
    ny = 0;
    cy = 0;
  }
  else {
    ny = dh - h1;
    cy = dh - h0;
  }
  if ((fOrientation & 1) == 1)
  {
    rx=ny;
    ry=nx;
    std::swap(cx, cy);
  }
  else {
    rx = nx;
    ry = ny;
  }
  if ((rx == x0) && (ry == dh - h0) && (fExpanded == false) && (w1 > dw)) {
    if (w0 > dw) {
      Offset = (w1 - dw) * lastXPos/ dw - rx;
      if ((fOrientation & 1) == 1) {
        ry = 0;
      }
      move(xn, ry);
    }
    else {
      Offset = 0;
      if ((fOrientation & 1) == 1) {
        ry = 0;
      }
      else {
        rx = 0;
      }
      move(rx + xn, ry);
    }
  }
  else {
    if ((fOrientation & 1) == 1) {
      ry = 0;
    }
    else {
      rx = 0;
    }
    move(rx + xn, ry);
  }
  rx += xn;
}

void KoolDock::resize2(int nw, int nh)
{
  nw = dw;
  nh = h1;
  if ((fOrientation & 1) == 1) {
    rw = nh;
    rh = nw;
  }
  else {
    rw = nw;
    rh = nh;
  }
  if (w1 < dw) {
    Offset = 0;
  }
  resize(rw, rh);
  nw = dw;
  nh = h0;
}

void KoolDock::getBottomBG()
{
  if (fHidden == 0) {
    return;
  }
  int p1, p2, p3, p4;
  p1 = 0;
  if ((fOrientation & 2) ==2) {
    p2 = 0;
  }
  else {
    p2 = dh - h1;
  }
  p3 = dw;
  p4 = h1;
  if ((fOrientation & 1) == 1) {
    std::swap(p1, p2);
    std::swap(p3, p4);
  }
  if (xinerama == 1) {
    p1 += XinPreviousWidth;
  }
  bottomBg = TQPixmap::grabWindow(tqt_xrootwin(), p1, p2, p3, p4);
}

void KoolDock::getTopBG()
{
  int p1, p2, p3, p4;
  p1 = 0;
  if ((fOrientation & 2) ==2) {
    p2 = h0;
  }
  else {
    p2 = dh - h1;
  }
  p3 = dw;
  p4 = h1 - h0;
  if ((fOrientation & 1) ==1) {
    std::swap(p1, p2);
    std::swap(p3, p4);
  }
  if (xinerama == 1) {
    p1 += XinPreviousWidth;
  }
  topBg = TQPixmap::grabWindow(tqt_xrootwin(), p1, p2, p3, p4);
}

void KoolDock::setDesktopIconsArea(int left, int top, int width, int height)
{
  if (fClipIcons == 0) {
    return;
  }
  DCOPClient* client = TDEApplication::dcopClient();
  if (!client->isAttached()) {
    client->attach();
    client->registerAs("KoolDock");
  }
  for (int i = 0; i < KWin::numberOfDesktops(); i++) {
    TQByteArray data;
    TQDataStream args(data, IO_WriteOnly);
    args << left << top << width << height << i;
    client->send("kdesktop", "KDesktopIface", "desktopIconsAreaChanged(TQRect, int)", data);
  }
}

void KoolDock::setDockAbove()
{
  KWin::setState(winId(), NET::KeepAbove);
  raise();
}

void KoolDock::setDockBelow()
{
  KWin::setState(winId(), NET::KeepBelow);
  lower();
}

void KoolDock::menuShow()
{
  allApps = false;

  if (iGroup && (menuCount != 0)) {
    int tcId = appMenu->itemParameter(currMenu);
    if ((tcId == currMenu) && (menuCount == 1)) {
      allApps = true;
      deskpopup->setItemChecked(dIndex, false);
      return;
    }
    cId = tcId;
    KWin::WindowInfo info = KWin::windowInfo(cId, 0, NET::WM2AllowedActions);
    deskpopup->setItemChecked(dIndex, false);
    dIndex = info.desktop();
    if (dIndex == -1) {
      dIndex = 0;
    }
    deskpopup->setItemChecked(dIndex, true);
    advMenu->setItemChecked(1, info.state() & NET::KeepAbove);
    advMenu->setItemChecked(2, info.state() & NET::KeepBelow);
    advMenu->setItemChecked(3, info.state() & NET::FullScreen);
    advMenu->setItemEnabled(3, info.actionSupported(NET::ActionFullScreen));
  }
}

void KoolDock::menuX(int num)
{
  if (iGroup && (menuCount != 0)) {
    currMenu = num;
  }
}

void KoolDock::init()
{
  initialization = true;
  nDesks=-2;
  ptPart = 5;
  // Load the configuration
  loadConf();

  if ((fStayBelow == 0) || (fHidden == 1)) {
    reparent(0, getWFlags() | WX11BypassWM, pos(), false);
  }
  else {
    reparent(0, getWFlags() & ~WX11BypassWM, pos(), false);
  }
  hide();

  // Initialize the systray counter
  if (reloadIcons) {
    numSystray = 0;
  }

  // First, set our "nice" priority
  if (fPriority > 19) {
    fPriority = DEF_PRIORITY;
  }
  if (fPriority < 0) {
    fPriority = DEF_PRIORITY;
  }
  setpriority(0, 0, fPriority);
  debug(TQString("Priority: %1").arg(fPriority));

  iwBig2 = iwBig;

  lastX = 0;

  iDist = iwSmall + iSpace;
  funcW = (int) (iDist * fAmount / 2);
  funcH = iwBig - iwSmall;
  iy = iSpace / 2;

  KWin::setOnAllDesktops(winId(), true);
  KWin::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
  KWin::setType(winId(), NET::Dock);

  items.setAutoDelete(true);
  popups.setAutoDelete(true);
  desks.setAutoDelete(true);

  if (fShowKMenu == 1) {
    if (fUseKBFX == 1) {
      if (reloadIcons) {
        items.append(new Item("kmenu", "dcop kicker KBFXInterface showMenu", "KMenu", iwSmall, iwBig2));
      }
    }
    else {
      if (reloadIcons) {
        items.append(new Item("kmenu", "dcop kicker kicker popupKMenu 0", "KMenu", iwSmall, iwBig2));
      }
    }
  }

  //Lets load the menu entries
  if (reloadIcons) {
    loadMenu();
  }
  if (items.count() == 0) {
    items.append(new Item("kooldock", "kooldock -k; kooldock -o" , "K", iwSmall, iwBig2));
  }
  // Create the "xosd" widget
  xosdw = new xosd();
  rdh = TQApplication::desktop()->height();
  xosdw->move(0, rdh);

  wm = new KWinModule();

  info = new NETWinInfo(tqt_xdisplay(), winId(), tqt_xrootwin(), NET::WMState);
  info->setDesktop(NETWinInfo::OnAllDesktops);
  info->setState(NETWinInfo::SkipTaskbar | NETWinInfo::SkipPager, NETWinInfo::SkipTaskbar | NETWinInfo::SkipPager);
  setBackgroundMode(NoBackground);

  // Load the ignore List
  loadIgnore();

  xosd_st = 0;
  xosdw->setFont(xosdFont);
  if (xosdItalic == true) {
    xosdw->setItalic();
  }
  if (xosdBold == true) {
    xosdw->setBold();
  }
  xosdw->setSize(xosdSize);
  xosdw->setShadowOffset(xosdShadowOffset);
  xosdw->setColor(xosdColor);
  xosdw->setShadowColor(xosdShadowColor);

  // Show task bar
  if (fShowTaskbar) {
    connect(wm, TQ_SIGNAL(activeWindowChanged(WId)), TQ_SLOT(activeWindowChanged(WId)));
  }
  connect(wm, TQ_SIGNAL(windowAdded(WId)), TQ_SLOT(windowAdded(WId)));
  connect(wm, TQ_SIGNAL(windowRemoved(WId)), TQ_SLOT(windowRemoved(WId)));
  connect(wm, TQ_SIGNAL(windowChanged(WId, unsigned int)), TQ_SLOT(windowChanged(WId, unsigned int)));
  if (fSystray) {
    /* System Tray implementation (hope this works - Francisco) */
    connect(wm, TQ_SIGNAL(systemTrayWindowAdded(WId)), TQ_SLOT(systemTrayWindowAdded(WId)));
    connect(wm, TQ_SIGNAL(systemTrayWindowRemoved(WId)), TQ_SLOT(systemTrayWindowRemoved(WId)));

    TQCString screenstr;
    screenstr.setNum(tqt_xscreen());
    TQCString trayatom = "_NET_SYSTEM_TRAY_S" + screenstr;

    Display *display = tqt_xdisplay();

    net_system_tray_selection = XInternAtom(display, trayatom, false);
    net_system_tray_opcode = XInternAtom(display, "_NET_SYSTEM_TRAY_OPCODE", false);

    // Acquire system tray
    XSetSelectionOwner(display, net_system_tray_selection, winId(), CurrentTime);
  }
  connect(wm, TQ_SIGNAL(numberOfDesktopsChanged(int)), TQ_SLOT(numberOfDesktopsChanged(int)));
  connect(wm, TQ_SIGNAL(currentDesktopChanged(int)), TQ_SLOT(currentDesktopChanged(int)));
  connect(wm, TQ_SIGNAL(workAreaChanged()), TQ_SLOT(workAreaChanged()));

  // Pseudo-Transparency code
  rootpix = new KRootPixmap(this);
  rootpix->setCustomPainting(true);
  connect(rootpix, TQ_SIGNAL(backgroundUpdated(const TQPixmap &)), TQ_SLOT(updateBackground(const TQPixmap &)));
  rootpix->start();

  debug(TQString("Items loaded: %1").arg(items.count()));

  // Simple work around to support xinerama (user defined)
  if (xinerama == 0) {
    dw = TQApplication::desktop()->width();
    dh = TQApplication::desktop()->height();
  }
  else {
    dw = leftRes;
    dh = XinDesiredHeight;
  }

  xosdw->setClear(fCleaner);
  xosdw->setOrientation(fOrientation & 1, dw, rdh);

  // All icons to small size
  unsigned int i;
  for (i = 0; i < items.count() + 1; i++) {
    iSize[i] = iwSmall;
  }
  for (i = 0; i < items.count() + 1; i++) {
    cx[i] = iSpace + i * iDist + iwSmall / 2;
    cur_cx[i] = cx[i];
  }
  if ((fOrientation & 1) == 1) {
    std::swap(dw, dh);
  }
  if ((fOrientation == 2) || (fOrientation == 1)) {
    TQString tmpstr;
    tmpstr = fLeftImg;
    fLeftImg = fRightImg;
    fRightImg = tmpstr;
  }

  Offset = 0;
  xosdw->move2(0, rdh);
  xosdw->show();
  fExpanded = false;
  // Timer to track the mouse position
  // When the mouse pointer reaches the bottom of the screen, the bar should popup in a userdefined time (int hideTimer)
  track2active = false;
  trackTimer = new TQTimer(this);
  connect(trackTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(trackTimerEnd()));

  ii_first = 0;
  ii_last = items.count() - 1;
  iOnClick = -1;
  onChangeTimer = NULL;

  Ybase = 0;
  soffset = 0;
  eoffset = 0;
  last_ncx = 0;

  // For the the onscreen text (icon names)
  nom = "";
  aux = "";

  mTimer = new TQTimer(this);
  connect(mTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(mTimerEnd()));

  _filterData = new KURIFilterData();

  mkbigTimer = new TQTimer(this);
  connect(mkbigTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(mkbigTimerDo()));

  mksmallTimer = new TQTimer(this);
  connect(mksmallTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(mksmallTimerDo()));

  TQWMatrix m;
  m.rotate(-90 * fOrientation);
  if (!fLeftImg.isEmpty()) {
    LeftImg.load(fLeftImg);
    LeftImg = LeftImg.xForm(m);
  }
  if (!fRightImg.isEmpty()) {
    RightImg.load(fRightImg);
    RightImg = RightImg.xForm(m);
  }
  if (!fCenterImg.isEmpty()) {
    CenterImg.load(fCenterImg);
    CenterImg = CenterImg.xForm(m);
  }

  if (fHidden == 1) {
    move(0, rdh);
  }

  //Lets add the necesary windows
  if (reloadIcons && fShowTaskbar) {firstTime=true;addWindows();}

  debug("Kooldock has started");

  doUpdateGeometry();
  if ((fOrientation & 1) == 1) {
    offscr = TQPixmap(h1, dw);
    bottomBgf = TQPixmap(h1, dw);
  }
  else {
    offscr = TQPixmap(dw, h1);
    bottomBgf = TQPixmap(dw, h1);
  }

  soffset = iwSmall / 2 + func2(abs(1 - funcW)) +
            func2(abs(iDist + 1 - funcW)) +
            func2(abs(2 * iDist + 1 - funcW)) +
            func2(abs(3 * iDist + 1 -funcW)) / 2 - ((int) ((iwBig - iwSmall) * 0.6 * fAmount) +
            iSpace * 2) / 2 - 4 * iwSmall - (int) ((3 * iDist + 1 - funcW) * (func(0) + func (iDist) - 2 * iwSmall) / (2 * iDist)) + 1;
  eoffset= (int) ((iwBig2 - iwSmall) * fAmount / 100);
  doUpdateGeometry();
  if (fFirstRun)
  {
    fFirstRun=false;
    // Show welcome dialog.
    const char* welcomeMsg =
              I18N_NOOP("<center><B>Welcome</B></center>It appears to be the first time you run KoolDock.<br>"
                    "By default the dock is hidden at the botton of the screen, move your mouse"
                    " to the bottom edge of the screen and the dock will appear.<br>"
                    "Right click on the dock for a menu that allows you to configure it<br>"
                    "or run with <I>-o</I> parameter to have preferences window at start.<br>"
                    "We hope this software is usefull for you<br>-- The KoolDock Team");
    KMessageBox::information(0L, i18n(welcomeMsg));
    saveConf();	// create initial configuration.
  }

  clipw = new clip();

  if (fHidden == 1) {
    clipw->resize(0, 0);
    clipw->move(-10, -10);
  }
  else {
    int cx, cy;
    cx = 0;
    if ((fOrientation & 2) == 2) {
      cy = 0;
    }
    else {
      cy = dh - h0;
    }
    if ((fOrientation & 1) == 1) {
      clipw->move(cy, cx);
      clipw->resize(h0, dw);
    }
    else {
      clipw->move(cx, cy);
      clipw->resize(dw, h0);
    }
  }
  KWin::setOnAllDesktops(clipw->winId(), true);
  KWin::setState(clipw->winId(), NET::KeepBelow);
  clipw->lower();
  clipw->show();

  animValue = 0;
  animState = true;

  if (fHidden == 0) {
    resize2(w0, h0);
    rootpix->repaint(true);
  }
  // Create desktop clipper widget
  if ((fHidden == 0) && (fClipping == 1)) {
    // Clipping desktop
    if (fOrientation == 0) {
      clipw->clipDesktop(0, 0, 0, 0, 0, 0, 0, 0, 0, h0, 0, dh);
      setDesktopIconsArea(0, 0, dw, dh - h0);
    }
    if (fOrientation == 1) {
      clipw->clipDesktop(0, 0, 0, h0, 0, dh, 0, 0, 0, 0, 0, 0);
      setDesktopIconsArea(0, 0, dh - h0, dw);
    }
    if (fOrientation == 2) {
      clipw->clipDesktop(0, 0, 0, 0, 0, 0, h0, 0, dh, 0, 0, 0);
      setDesktopIconsArea(0, h0, dw, dh);
    }
    if (fOrientation == 3) {
      clipw->clipDesktop(h0, 0, dh, 0, 0, 0, 0, 0, 0, 0, 0, 0);
      setDesktopIconsArea(h0, 0, dh, dw);
    }
  }
  if ((fStayBelow == 1) && (fHidden == 0)) {
    setDockBelow();
  }
  setAcceptDrops(true);
  useList = false;
  if (fSpeed) {
    ptPart = 0;
  }
  else {
    ptPart = 1;
  }
  if (fHidden == 0) {
    paintEvent(NULL);
  }
  if (ptPart == 0) {
    enterEvent(NULL);
  }
  else {
    pTest();

  }
}

void KoolDock::pTest()
{
  if (ptPart == 0) {
    onleaveEvent(NULL);
    ptPart = 1;
    return;
  }

  // Finalize initialization
  if (fHidden == 1) {
    trackTimer->start(250, false);
  }
  else {
    mTimer->start(250, false);
  }
  oldDesktop = KWin::currentDesktop();
  initialization = false;
  if (fShowTaskbar) {
    addWindows();
  }
  show();
  if (fHidden == 0) {
    paintEvent(NULL);
  }
  setupdlg->setEnabled(true);
  if (fFirstRun) {
    editPref();
  }
  updTaskList();
}

void KoolDock::refreshBackground()
{
  getBottomBG();
  getTopBG();
  if (dockOpacity > 0) {
    bitBlt(&bottomBgf, 0, 0, &bottomBg);
    KPixmapEffect::fade(bottomBgf, ((float) dockOpacity) * 0.01, bgColor);
  }
  show();
  KWin::setOnAllDesktops(winId(),true);
  paintEvent(NULL);
}

void KoolDock::dragMoveEvent(TQDragMoveEvent* event)
{
  if (mouseOnLauncher && TQTextDrag::canDecode(event)) {
    event->accept();
  }
  else {
    event->ignore();
  }
}

void KoolDock::dropEvent(TQDropEvent* event)
{
  TQString strDrop;
  TQPoint pointer = TQCursor::pos();
  int px, py;

  px = pointer.x() - pos().x();
  py = pointer.y() - pos().y();

  TQTextDrag::decode(event, strDrop);
  lstDrop = TQStringList::split(TQString("\n"), strDrop, false);

  useList = true;
  mPress(px, py, TQt::LeftButton);
  useList = false;
}

//Funtion used in window grouping
void KoolDock::movetoback(WId id)
{
  int i;
  Item* item;
  int ic = -1, jc;
  TQCString cls;

  //find clicked item in witems list
  for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
    if (item->getId() == id) {
      ic = i;
      break;
    }
  }

  if (ic >= 0) {
    jc = witems.at(ic)->getIndex(); // Get item stack index
    for (i = 0, item = witems.at(0); item; i++, item = witems.next()) {
      if (item->getIndex() > jc) {
        item->setIndex(item->getIndex() - 1);
      }
    }
    // Move clicked item to last position in the stack
    witems.at(ic)->setIndex(witems.count() - 1);
    cls = witems.at(ic)->getClass();
    for (i= numLaunchers, item = items.at(numLaunchers); item; i++, item = items.next()) {
      if (item->getClass() == cls) {
        item->setId(witems.at(ic)->getId());
        item->setName(witems.at(ic)->getName());
        break;
      }
    }
  }
}

//Gets index of an incon by position
int KoolDock::itemFromPoint(int x)
{
  int i, Xpos = -1;
  for (i = 0; i < (int) items.count(); i++) {
    Xpos = xFromIndex(i);
    if (((x + iSpace / 2) > Xpos) && ((x-iSpace) < (Xpos+iSize[i]))) {
      break;
    }
  }
  return i;
}

//Gets position of an icon by its index
int KoolDock::xFromIndex(int i)
{
  int Xpos;
  if (i < ii_first) {
    Xpos = cur_cx[i] - iwSmall / 2 + SPACE_W;
  }
  else if ((i >= ii_first) && (i <= ii_last)) {
    Xpos = cur_cx[i] - iSize[i] / 2 + adjust + soffset;
  }
  else {  // if (i > ii_last)
    Xpos = cur_cx[i] - iwSmall / 2 + adjust + SPACE_W - 3 + soffset * 0;
  }
  return Xpos;
}

void KoolDock::aboutToShow()
{
  menuCount++;
}

void KoolDock::aboutToHide()
{
  menuCount--;
}

void KoolDock::createMenu(TDEPopupMenu* tmpMenu, KWin::WindowInfo* info)
{
  TQString appTitle;
  int menustate;
  appTitle = info->visibleName();
  appTitle.truncate(30);

  tmpMenu->insertTitle(appTitle);
  tmpMenu->insertItem(i18n("Ad&vanced"), advMenu);

  menustate = tmpMenu->insertItem(SmallIcon("move"), i18n("&Move"), this, TQ_SLOT(moveApp()));
  tmpMenu->setItemEnabled(menustate, info->actionSupported(NET::ActionMove));

  menustate = tmpMenu->insertItem(i18n("Re&size"), this, TQ_SLOT(resizeApp()));
  tmpMenu->setItemEnabled(menustate, info->actionSupported(NET::ActionMove));

  menustate = tmpMenu->insertItem(i18n("Mi&nimize"), this, TQ_SLOT(minApp()));
  if (info->isMinimized()) {
    tmpMenu->setItemChecked(menustate, true);
  }
  tmpMenu->setItemEnabled(menustate, info->actionSupported(NET::ActionMinimize));

  menustate = tmpMenu->insertItem(i18n("Ma&ximize"), this, TQ_SLOT(maxApp()));
  if ((info->state() & NET::Max) && !info->isMinimized()) {
    tmpMenu->setItemChecked(menustate, true);
  }
  tmpMenu->setItemEnabled(menustate, info->actionSupported(NET::ActionMax));

  menustate = tmpMenu->insertItem(i18n("&Shade"), this, TQ_SLOT(shadeApp()));
  if (info->state() & NET::Shaded) {
    tmpMenu->setItemChecked(menustate, true);
  }
  tmpMenu->setItemEnabled(menustate, info->actionSupported(NET::ActionShade));
  tmpMenu->insertItem(SmallIcon("forward"), i18n("&Move to Desktop"), deskpopup);
  tmpMenu->insertSeparator();
  tmpMenu->insertItem(SmallIcon("window-close"), i18n("&Close"), this, TQ_SLOT(closeApp()));
}

void KoolDock::updTaskList()
{
  if (!fShowNav) {
    return;
  }

  desks.setAutoDelete(true);

  //tasklist; menu to access every window throught navigation menu
  int j, index, incr;
  KWin::WindowInfo tmpinfo;

  nDesks = KWin::numberOfDesktops();

  tasklist->clear();
  desks.clear();

  for (index = 0; index <= nDesks; index++) {
    desks.append(new dInfo);
  }

  KWin::WindowInfo info;
  TQValueList<WId>::ConstIterator it;
  for (it = wm->windows().begin(); it != wm->windows().end(); ++it) {
    tmpinfo = KWin::windowInfo(*it);

    const int SUPPORTED_WINDOW_TYPES = NET::NormalMask | NET::DesktopMask | NET::DockMask |
                                       NET::ToolbarMask | NET::MenuMask | NET::DialogMask |
                                       NET::OverrideMask | NET::TopMenuMask |
                                       NET::UtilityMask | NET::SplashMask;
    TQString name = tmpinfo.visibleName();

    if (tmpinfo.windowType(SUPPORTED_WINDOW_TYPES) == NET::Normal ||
                                                      tmpinfo.windowType(SUPPORTED_WINDOW_TYPES) == NET::Override ||
                                                      tmpinfo.windowType(SUPPORTED_WINDOW_TYPES) == NET::Dialog ||
                                                      tmpinfo.windowType(SUPPORTED_WINDOW_TYPES) == NET::Unknown) {
      if ((tmpinfo.state() & NET::SkipTaskbar) == 0) {
        if (ignored (tmpinfo.name()) == false) {
          index = tmpinfo.desktop();
          if (index == -1) {
            index = 0;
          }
          incr = 0;
          if (!desks.at(index)->gBool()) {
            desks.current()->sBool(true);
            if (index == 0) {
              tasklist->insertTitle(i18n("All desktops"), -1, desks.current()->gInt());
            }
            else {
              tasklist->insertTitle(i18n("Desktop %1").arg(index), -1, desks.current()->gInt());
            }
            incr++;
          }
          tasklist->insertItem(KWin::icon(*it), tmpinfo.visibleName(), *it, desks.current()->gInt() +incr);
          incr++;
          for (j = index; j <= nDesks; j++) {
            desks.at(j)->inc(incr);
          }
        }
      }
    }
  }
}

void KoolDock::addToTaskList(WId id)
{
  if (!fShowNav || nDesks<0) return;
  int i;
  Item* item;
  int index, rIndex, j, incr = 0, decr = 0;
  KWin::WindowInfo tmpinfo = KWin::windowInfo(id);
  rIndex = tmpinfo.desktop();

  const int SUPPORTED_WINDOW_TYPES = NET::NormalMask | NET::DesktopMask | NET::DockMask |
                                     NET::ToolbarMask | NET::MenuMask | NET::DialogMask |
                                     NET::OverrideMask | NET::TopMenuMask |
                                     NET::UtilityMask | NET::SplashMask;
  TQString name = tmpinfo.visibleName();

  if (tmpinfo.windowType(SUPPORTED_WINDOW_TYPES) == NET::Normal ||
                                                    tmpinfo.windowType(SUPPORTED_WINDOW_TYPES) == NET::Override ||
                                                    tmpinfo.windowType(SUPPORTED_WINDOW_TYPES) == NET::Dialog ||
                                                    tmpinfo.windowType(SUPPORTED_WINDOW_TYPES) == NET::Unknown) {
    if ((tmpinfo.state() & NET::SkipTaskbar) == 0) {
      if (ignored(tmpinfo.name()) == false) {
        if (rIndex == 0) {
          return;
        }
        index = rIndex;
        if (index == -1) {
          index = 0;
        }
        if (!desks.at(index)->gBool()) {
          desks.at(index)->sBool(true);
          if (index == 0) {
            tasklist->insertTitle(i18n("All desktops"), -1, desks.at(index)->gInt());
          }
          else {
            tasklist->insertTitle(i18n("Desktop %1").arg(index), -1, desks.at(index)->gInt());
          }
          incr++;
        }
        else {
          if (fShowTaskbar) {
            for (i = witems.count(), item = witems.at(i); item; i--, item = witems.prev()) {
              if (item->getId() == id) {
                break;
              }
              if (item->info.desktop() == rIndex) {
                decr++;
              }
            }
          }
        }
        tasklist->insertItem(KWin::icon(id), tmpinfo.visibleName(), id, desks.at(index)->gInt() + incr - decr);
        incr++;
        for (j = index; j <= nDesks; j++) {
          desks.at(j)->inc(incr);
        }
      }
    }
  }
}

void KoolDock::rmFromTaskList(WId id)
{
  if (!fShowNav || nDesks<0) {
    return;
  }
  int i, j, k, dec=0;
  unsigned int index = 0;
  i = tasklist->indexOf(id);
  index = tasklist->idAt(i);
  if (index == id) {
    tasklist->removeItem(id);
    dec--;
    for (j = 0; j <= nDesks; j++) {
      if (desks.at(j)->gBool() && (desks.at(j)->gInt() >= i + 1)) {
        if (desks.at(j)->gInt() == i + 1) {
          if (tasklist->text(tasklist->idAt(i - 1)).isNull() && tasklist->text(tasklist->idAt(i)).isNull()) {
            dec--;
            desks.at(j)->sBool(false);
            tasklist->removeItemAt(i - 1);
          }
        }
        for (k = j; k <= nDesks; k++) {
          desks.at(k)->inc(dec);
        }
        break;
      }
    }
  }
}
#include "kooldock.moc"
