#include "xosd.h"

#include <tqpainter.h>
#include <tqbitmap.h>
#include <tqstring.h>
#include <tqfont.h>
#include <tqfontmetrics.h>

#include <tqwidget.h>
#include <tdelocale.h>
#include <netwm.h>
#include <netwm_def.h>
#include <twin.h>

#include <kdebug.h>
#include <stdlib.h>

xosd::xosd(TQWidget *parent, const char *name) :
  TQWidget(parent, name, WStyle_Customize |  WRepaintNoErase | WStyle_NoBorder |
           WDestructiveClose | WStyle_StaysOnTop | WX11BypassWM)
{
  info = new NETWinInfo(tqt_xdisplay(), winId(), tqt_xrootwin(), NET::WMState);
  info->setDesktop(NETWinInfo::OnAllDesktops);
  hide();
  KWin::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
  setCaption("kooldock xosd window");
  w=0;
  h=0;
  yOffset=0;
  fCleaner=0;
}

xosd::~xosd()
{
}

void xosd::setColor(const TQString& color)
{
  fontColor = color;
}

void xosd::setShadowColor(const TQString& color)
{
  shadowColor = color;
}

void xosd::setOrientation(int orientation, int w, int mh)
{
  fOrientation = orientation;
  dw = w;
  rdh = mh;
  if (fCleaner == 1) {
    //font is set, so program can get its height to prepare background buffer
    TQFontMetrics* metrics = new TQFontMetrics(f);
    h = metrics->height();
  
    bgBuffer = TQPixmap(dw, h);
    maskBuffer = TQPixmap(dw, h, true);
    bgBuffer = TQPixmap::grabWindow(tqt_xrootwin(), 0, 0, dw, h);
    lastX = 0;
    lastY = 0;
  }
}

// Enable/disable dynamic background
void xosd::setClear(int nClean)
{
  fCleaner = nClean;
}

void xosd::setShadowOffset(int off)
{
  shadowOffset = off;
}

void xosd::setText(const TQString& t)
{
  resize(0, 0);
  text = t;
  TQFontMetrics* metrics = new TQFontMetrics(f);
  w = metrics->width(text);
  w = w + shadowOffset + 5; // 5 pixels more
  h = metrics->height();
  yOffset = metrics->height()-metrics->descent();
  update();
}

void xosd::setFont(const TQString& font)
{
  f.setFamily(font);
}

void xosd::setItalic()
{
  f.setItalic(true);
}

void xosd::setBold()
{
  f.setBold(true);
}

void xosd::setSize(int size)
{
  f.setPointSize(size);
  fontSize = size;
}

void xosd::paintEvent(TQPaintEvent*)
{
  int i, j;

  resize(w, h);
  TQPixmap pm(size());
  TQBitmap bm(size());
  TQPainter p;

  // Drawing text
  p.begin(&pm, this);
  if (fCleaner == 1) {
    // Dynamic background - look cleaner
    bitBlt(&pm, 0, 0, &bgBuffer, lastX, 0, w, h);
  }
  else {
    // One colour background - work faster
    p.fillRect(rect(), TQColor(shadowColor));
  }
   
  p.setPen(TQColor(shadowColor));
  p.setFont(f);
  p.drawText(shadowOffset, yOffset + shadowOffset, text, AlignCenter);	// draw shadow text
  
  // Draw normal text
  p.setPen(TQColor(fontColor));
   
  p.drawText(1, yOffset, text, AlignCenter);	// draw front text
	
  p.end();
  
  // Drawing mask
  p.begin(&bm, this);
  // Draw the text with black color for making the mask
  p.setPen(TQt::white);
  p.fillRect(rect(), TQt::black);
  p.setFont(f);
  for (i = -fCleaner; i <= fCleaner; i++) {
    for (j = -fCleaner; j <= fCleaner; j++) {
      p.drawText(shadowOffset + i, yOffset + shadowOffset + j, text, AlignCenter);	// shadow
      p.drawText(1 + i, yOffset + j, text, AlignCenter);	// front
    }
  }
  p.end();
  bitBlt(this, 0, 0, &pm);	// update the widget
  if (fCleaner == 1) {
    bitBlt(&maskBuffer, 0, 0, &bm);
  }
  info->setState(NETWinInfo::SkipTaskbar | NETWinInfo::SkipPager, NETWinInfo::SkipTaskbar | NETWinInfo::SkipPager);
  setMask(bm);
}

void xosd::move2(int x, int y)
{
  // Bit block transfer don't work propertly with too less cursor position changes
  if (abs(lastY - y) > 2 || abs(lastX - x) > 2) {
    if (fCleaner == 1) {
      TQPixmap tmpBuffer;
      // Window is not hidden
      if (y != rdh) {
        tmpBuffer = TQPixmap::grabWindow(tqt_xrootwin(), 0, y, dw, h);
        if (lastY != rdh) {
          // Fill background covered with the text with cached version
          if (fOrientation == 0) { // horizontal
            bitBlt(&tmpBuffer, lastX, 0, &maskBuffer, 0, 0, w, h, TQt::AndROP);//copying part, which hides only the text
            bitBlt(&bgBuffer, lastX, 0, &maskBuffer, 0, 0, w, h, TQt::NotAndROP);//so the background won't be covered by
            bitBlt(&tmpBuffer, lastX, 0, &bgBuffer, lastX, 0, w, h, TQt::OrROP);//currently visible text.
          }
          if (fOrientation==1) { //vertical
            if ((y < lastY) && ((y + h) > lastY)) {
              bitBlt(&tmpBuffer, lastX, lastY-y, &maskBuffer, 0, 0, w, h, TQt::AndROP);
              bitBlt(&bgBuffer, lastX, 0, &maskBuffer, 0, 0, w, h, TQt::NotAndROP);
              bitBlt(&tmpBuffer, lastX, lastY-y, &bgBuffer, lastX, 0, w, h, TQt::OrROP);
            }
            if ((y > lastY) && ((y - lastY) < h)) {
              bitBlt(&tmpBuffer, lastX, 0, &maskBuffer, 0, 0, w, h, TQt::AndROP);
              bitBlt(&bgBuffer, lastX, y-lastY, &maskBuffer, 0, 0, w, h, TQt::NotAndROP);
              bitBlt(&tmpBuffer, lastX, 0, &bgBuffer, lastX, y-lastY, w, h, TQt::OrROP);
            }
          }
        }
      }
      bitBlt(&bgBuffer, 0, 0, &tmpBuffer);
      lastX = x;
      paintEvent(NULL);
    }
    move(x, y);
    lastX = x;
    lastY = y;
  }
}
#include "xosd.moc"
