/*
 * SuSE window decoration for SuSE 9.1
 * written by Adrian Schroeter <adrian@suse.de>
 *
 * copyright 2002 SuSE AG, GPL License
 *
 */

#include "MachBunt.h"
#include <kpixmapeffect.h>
#include <kimageeffect.h>
#include <kiconeffect.h>
#include <kdrawutil.h>
#include <tdelocale.h>
#include <tdeconfig.h>
#include <kstandarddirs.h>

#include <tqlabel.h>
#include <tqlayout.h>
#include <tqdrawutil.h>
#include <tqdatetime.h>
#include <tqcursor.h>
#include <tqbitmap.h>
#include <tqimage.h>

extern "C"
{
  TDE_EXPORT KDecorationFactory *create_factory()
  {
    return new SuSEMachBunt::BuntFactory();
  }
}

namespace SuSEMachBunt {

#include "pixmaps.h"

// [button number][inactive/active][std/mouseOver/buttonPressed][miniIcon]
KPixmap buttonPixmap[BtnCount][2][3][2];
bool    titlebarResize, titlebarPlain,
        titlebarLogo, titlebarSidebar,
        titlebarNoPlainButtons;
double  titlebarLenseButtonFlare;

static bool    pixmaps_created = false;
static TQImage  left_img[2][2];
static TQImage  middle_img[2][2];
static TQImage  right_img[2][2];
static TQImage  text_img[2][2];
static TQImage  bar_img[2][2];
static TQImage  kroete_img[2][2];
static TQImage  button_img[2][2];
static TQImage  button_l_img[2][2];
static TQImage  button_r_img[2][2];

extern TQColor  *btnForeground;
extern TQPixmap *defaultPixmap;

static TQImage colorize(TQImage img, const TQColor &col1, const TQColor &col2, float bright, float contrast )
{
	int rval, gval, bval, val, val2, i;
	int pixels = (img.depth() > 8) ? img.width()*img.height()
				: img.numColors();
	unsigned int *data = img.depth() > 8 ? (unsigned int *) img.bits()
				: (unsigned int *) img.colorTable();

	for (i=0; i<pixels; i++)
	{
	    val  = static_cast<int>(tqBlue(data[i]) * contrast);
	    val2 = static_cast<int>(tqGreen(data[i]) * contrast);

	    rval = static_cast<int>( (val2*255*3  + (255-val2)*col2.red())/255   );
	    gval = static_cast<int>( (val2*255*3  + (255-val2)*col2.green())/255 );
	    bval = static_cast<int>( (val2*255*3  + (255-val2)*col2.blue())/255  );
	    rval = static_cast<int>( (val *rval + (255-val)*col1.red())/255   );
	    gval = static_cast<int>( (val *gval + (255-val)*col1.green())/255 );
	    bval = static_cast<int>( (val *bval + (255-val)*col1.blue())/255  );

		if ( 255 < rval+tqRed(data[i]) ) rval = 255;
			else rval += tqRed(data[i]);
		if ( 255 < gval+tqRed(data[i]) ) gval = 255;
			else gval += tqRed(data[i]);
		if ( 255 < bval+tqRed(data[i]) ) bval = 255;
			else bval += tqRed(data[i]);

	    if (bright != 1.0)
	    {
			rval = static_cast<int>(bright*rval);
			gval = static_cast<int>(bright*gval);
			bval = static_cast<int>(bright*bval);
	    }

	    data[i] = tqRgba(rval, gval, bval, tqAlpha(data[i]));
	}

	return img;
}

KPixmap create_buttonPixmap( int x, int y, TQPixmap _pix, TQPixmap bg, int active, int mouse )
{
	TQImage   i;
	KPixmap  _p(TQPixmap(x,y));
	TQPixmap  t, pix;
	TQPainter p;

	if ( _pix.isNull() )
		pix = TQPixmap(kdelogo);
	else
		pix = _pix;

	p.begin(&_p);

	if ( x != pix.width() || y != pix.height() ){
		p.drawImage( 0, 0, bg.convertToImage().smoothScale(x,y) );
		p.drawPixmap((x-pix.width())/2, (y-pix.height())/2, pix );
	}else{
	    	p.drawTiledPixmap(0, 0, x, y, bg );
		p.drawPixmap(0, (y-pix.height())/2, pix );
	}

	p.end();

	if ( !(mouse == 1 && titlebarPlain) && !(mouse == 0 && !titlebarPlain) ){ // not standard
		i=_p;
		if ( (mouse == 0 && titlebarPlain) || (mouse == 1 && !titlebarPlain) ){ // mouse over
			_p.convertFromImage(KImageEffect::blend(TQt::white, i, 0.25 ));
		}else{	// pressed
			_p.convertFromImage(KImageEffect::blend(TQt::black, i, 0.25 ));
		}

		if ( mouse == 2 ) { // pressed
			i=_p;
			p.begin(&_p);
			p.drawImage( 0, 2, i, 0, 0, i.width(), i.height()-2 );
			p.end();
		}
	}

	return _p;
}

TQImage image_convert( const char **b, int h){
    TQPixmap p(b);
	TQImage i;
	i = p.convertToImage();
    if ( p.height()!=h )
       i = i.smoothScale((p.width()*h)/p.height(),h);
    return i;
}

static void create_pixmaps( )
{
    if(pixmaps_created)
        return;

    pixmaps_created = true;

	for ( int m=0; m<2; m++ )
	  for ( int i=0; i<2; i++){
		TQColor ctb = KDecoration::options()->color(KDecoration::ColorTitleBar,i);
		TQColor ctbB = KDecoration::options()->color(KDecoration::ColorTitleBlend,i);
		left_img[i][m]    = colorize(image_convert(left_xpm, m ? 12 : PIX_HEIGHT)  , ctb,
								  ctbB, 0.75 , 0.75 );
		right_img[i][m]   = colorize(image_convert(right_xpm, m ? 12 : PIX_HEIGHT) , ctb,
								  ctbB, 1.0  , 1.0  );
		middle_img[i][m]  = colorize(image_convert(middle_xpm, m ? 12 : PIX_HEIGHT), ctb,
								  ctbB, 1.0  , 1.0  );
		text_img[i][m]    = colorize(image_convert(middle_xpm, m ? 12 : PIX_HEIGHT), ctb,
								  ctbB, 0.75 , 0.75 );
		kroete_img[i][m]  = colorize(image_convert(kroete_xpm, m ? 12 : PIX_HEIGHT), ctb,
								  ctbB, 1.0  , 1.0  );
		bar_img[i][m]       = colorize(image_convert(bar_xpm, m ? 12 : PIX_HEIGHT), ctb,
								  ctbB, 1.0  , 1.0  );
		button_img[i][m]    = colorize(image_convert(middle_button_xpm, m ? 12 : PIX_HEIGHT), ctb,
								  ctbB, 1.0  , 1.0  );
		button_l_img[i][m]  = colorize(image_convert(middle_button_left_xpm, m ? 12 : PIX_HEIGHT), ctb,
								  ctbB, 1.0  , 1.0  );
		button_r_img[i][m]  = colorize(image_convert(middle_button_right_xpm, m ? 12 : PIX_HEIGHT), ctb,
								  ctbB, 1.0  , 1.0  );
	  }

	for ( int m=0; m<2; m++ )
	 for ( int M=0; M<3; M++ )
	  for ( int a=0; a<2; a++ ){
		buttonPixmap[0][a][M][m] = create_buttonPixmap( m ? 12 : PIX_HEIGHT, m ? 12 : PIX_HEIGHT, TQPixmap(kdelogo), button_img[a][m], a, M );
		buttonPixmap[1][a][M][m] = create_buttonPixmap( m ? 12 : PIX_HEIGHT, m ? 12 : PIX_HEIGHT, TQPixmap(sticky_xpm), button_img[a][m], a, M );
		buttonPixmap[2][a][M][m] = create_buttonPixmap( m ? 12 : PIX_HEIGHT, m ? 12 : PIX_HEIGHT, TQPixmap(question_xpm), button_img[a][m], a, M );
		buttonPixmap[3][a][M][m] = create_buttonPixmap( m ? 12 : PIX_HEIGHT, m ? 12 : PIX_HEIGHT, TQPixmap(iconify_xpm), button_img[a][m], a, M );
		buttonPixmap[4][a][M][m] = create_buttonPixmap( m ? 12 : PIX_HEIGHT, m ? 12 : PIX_HEIGHT, TQPixmap(maximze_xpm), button_img[a][m], a, M );
		TQPixmap i(button_img[a][m]);
		TQPainter p(&i);
		p.drawPixmap(button_img[a][m].width()-right_img[a][m].width()+BORDER_RIGHT, 0, right_img[a][m]);
		p.end();
		buttonPixmap[5][a][M][m] = create_buttonPixmap( m ? 12 : PIX_HEIGHT, m ? 12 : PIX_HEIGHT, TQPixmap(close_xpm), i, a, M );
	  }

    // Make sure button pixmaps contrast with the current colour scheme.
    if(tqGray(KDecoration::options()->color(KDecoration::ColorTitleBar,true).rgb()) > 127)
        btnForeground = new TQColor(TQt::black);
    else
        btnForeground = new TQColor(TQt::white);
}

void delete_pixmaps()
{
    delete btnForeground;

    pixmaps_created = false;
}

MachBunt::MachBunt(KDecorationBridge* bridge, KDecorationFactory* factory)
	: KDecoration(bridge, factory), windowLayout(0)
{
    TDEGlobal::locale()->insertCatalogue("twin_clients");
    TDEGlobal::locale()->insertCatalogue("twin-style-machbunt");

    lastButtonWidth = 0;
    buttonPressedPosition.setX( -1 );
    for ( int i=0; i < BtnCount; i++ )
	button[i]=0;

    hiddenItems = false;
}

MachBunt::~MachBunt()
{
}

void MachBunt::init()
{
	if ( isTool() ) {
	   titleHeight = 12;
	   smallButtons = true;
	} else {
	   titleHeight = PIX_HEIGHT;
	   smallButtons = false;
	}

	createMainWidget(WNoAutoErase);
	widget()->installEventFilter( this );
	widget()->setBackgroundMode(NoBackground);

	TDEConfig c("twinMachBuntrc");
	c.setGroup("General");
	titlebarResize  		 = c.readBoolEntry("TitleBarResize", true);
	titlebarLogo    		 = c.readBoolEntry("TitleBarLogo", true);
	titlebarPlain   		 = c.readBoolEntry("TitleBarPlain", true);
	titlebarNoPlainButtons 	 = c.readBoolEntry("TitleBarNoPlainButtons", false);
	titlebarSidebar 		 = c.readBoolEntry("TitleBarSideBar", false);
	titlebarLenseButtonFlare = c.readDoubleNumEntry("titlebarLenseButtonFlare", 1.7);
	defaultPixmap			 = new TQPixmap(kdelogo);
	create_pixmaps();
	createButtons();

	doLayout();
}

void MachBunt::createButtons()
{
	if ( !button[BtnMenu] )
		button[BtnMenu] = new MachBuntButton(this, "menu", BtnMenu, text_img[0][smallButtons], text_img[1][smallButtons], smallButtons, i18n("Menu"));
	//if ( !button[BtnSticky] )
	//  button[BtnSticky] = new MachBuntButton(this, "sticky", BtnSticky, middle_img[0][smallButtons], middle_img[1][smallButtons], smallButtons, i18n("Sticky"));
	if ( !button[BtnHelp] )
		button[BtnHelp]= new MachBuntButton(this, "help", BtnHelp, middle_img[0][smallButtons], middle_img[1][smallButtons], smallButtons, i18n("Help"));
	if ( !button[BtnIconify] )
		button[BtnIconify] = new MachBuntButton(this, "iconify", BtnIconify, middle_img[0][smallButtons], middle_img[1][smallButtons], smallButtons, i18n("Minimize"));
	if ( !button[BtnMax] )
		button[BtnMax]     = new MachBuntButton(this, "maximize", BtnMax, middle_img[0][smallButtons], middle_img[1][smallButtons], smallButtons, i18n("Maximize"));
	if ( !button[BtnClose] )
		button[BtnClose]   = new MachBuntButton(this, "close", BtnClose, middle_img[0][smallButtons], middle_img[1][smallButtons], smallButtons, i18n("Close"));

    // Connect required stuff together
    connect( button[BtnMenu],    TQ_SIGNAL(pressed()),      this, TQ_SLOT( menuButtonPressed() ));
    connect( button[BtnClose],   TQ_SIGNAL( clicked() ),    this, TQ_SLOT( closeWindow() ));
    connect( button[BtnIconify], TQ_SIGNAL( clicked() ),    this, TQ_SLOT( minimize() ));
    connect( button[BtnMax],     TQ_SIGNAL( clicked() ),    this, TQ_SLOT( slotMaximize() ));
    for ( int i=0; i < BtnCount; i++ )
    	if ( button[i] ){
    		connect( button[i], TQ_SIGNAL(shapeMe(int)),this, TQ_SLOT(doShape(int)));
    		connect( button[i], TQ_SIGNAL(pressed()),this, TQ_SLOT(buttonPressed()));
    		connect( button[i], TQ_SIGNAL(released()),this, TQ_SLOT(buttonReleased()));
    		connect( button[i], TQ_SIGNAL(mousePressedMove(TQMouseEvent*)),this, TQ_SLOT(mouseMoveOnButtonPressed(TQMouseEvent*)));
	}

     connect( button[BtnHelp], TQ_SIGNAL( clicked() ), this, TQ_SLOT( showContextHelp() ));

    // Hide buttons which are not required
    // We can un-hide them if required later
    if ( !isMinimizable() )
        button[BtnIconify]->hide();
    if ( !isMaximizable() )
        button[BtnMax]->hide();
    if ( !providesContextHelp())
        button[BtnHelp]->hide();

    // Make sure that the menu button uses the correct mini-icon
    iconChange();
    maximizeChange();
    desktopChange();
}

void MachBunt::reset( unsigned long changed )
{
    for(int i = 0; i < BtnCount; i++)
       if(button[i])
          button[i]->reset( changed );
    widget()->repaint();
}

int MachBunt::mapButton( const TQChar &c)
{
   if (c.isNull()) return -1;
   switch (c.latin1())
   {
      case 'M':
        return BtnMenu;
      //case 'S':
      //  return BtnSticky;
      case 'H': // Help
        return BtnHelp;
      case 'I': // Minimize
        return BtnIconify;
      case 'A': // Maximize
        return BtnMax;
      case 'X': // Close
        return BtnClose;
   }
   // something went wrong
   tqDebug("unknown Button to map: %c\n", c.latin1() );
   return -1;
}

void MachBunt::doLayout()
{
    delete windowLayout;

    windowLayout = new TQVBoxLayout(widget(), 0, 0);
    titlebar     = new TQSpacerItem ( 0, titleHeight, TQSizePolicy::Expanding, TQSizePolicy::Fixed);
    TQBoxLayout *topLayout = new TQBoxLayout(windowLayout, TQBoxLayout::LeftToRight, 0, 0);

    TQString leftButtons(options()->customButtonPositions() ? options()->titleButtonsLeft() : "M");
    TQString rightButtons(options()->customButtonPositions() ? options()->titleButtonsRight() : "HIAX");

    bool first_left = true;
    for ( unsigned int i = 0; i < leftButtons.length(); i++)
    {
       int b = mapButton(leftButtons[i]);
       if (b >= 0)
       {
          topLayout->addWidget(button[b], TQt::AlignVCenter);
          topLayout->setStretchFactor(button[b], 0);
          button[b]->setFixedSize(titleHeight, titleHeight);
          if( first_left )
          {
              first_left = false;
              button[b]->setPosition( ButtonLeft );
          }
       }
    }

    topLayout->addItem(titlebar);

    MachBuntButton* last_right = NULL;
    for ( unsigned int i = 0; i < rightButtons.length(); i++)
    {
       int b = mapButton(rightButtons[i]);
       if ( b>=0 ){
          topLayout->addWidget(button[b], TQt::AlignVCenter);
	  topLayout->setStretchFactor(button[b], 0);
	  button[b]->setFixedSize(titleHeight, titleHeight);
          last_right = button[b];
       }
    }
    if( last_right )
        last_right->setPosition( ButtonRight );

    TQHBoxLayout * midLayout   = new TQHBoxLayout(windowLayout, 0, 0);
    midLayout->addSpacing(BORDER_LEFT);
    if( isPreview())
        midLayout->addWidget(new TQLabel( i18n( "<center><b>MachBunt</b></center>" ), widget()));
    else
        midLayout->addItem( new TQSpacerItem( 0, 0 )); // no widget in the middle
    midLayout->addSpacing(BORDER_RIGHT);

    windowLayout->addSpacing(BORDER_BOTTOM);
    windowLayout->setStretchFactor(topLayout, 0);
    windowLayout->setStretchFactor(midLayout, 1);
}

void MachBunt::borders(int& left, int& right, int& top, int& bottom) const
{
    left = BORDER_LEFT;
    right = BORDER_RIGHT;
    top =  titleHeight;
    bottom = BORDER_BOTTOM;
}

void MachBunt::mouseMoveOnButtonPressed( TQMouseEvent *e )
{
#if 0
    if ( buttonPressedPosition.x() >= 0 ){
	TQPoint p( buttonPressedPosition.x() - geometry().x(),
	          buttonPressedPosition.y() - geometry().y());

	if ( mousePosition(p) == KDecoration::TopLeft ||
	     mousePosition(p) == KDecoration::TopRight )
	    	performMouseCommand(Options::MouseResize, TQCursor::pos());
	else if ( mousePosition(p) == KDecoration::Top ){
	    	TQPoint m(geometry().x()+geometry().width()/2, geometry().y());
	    	performMouseCommand(Options::MouseResize, m );
	}
	buttonPressedPosition.setX( -1 );
    }

    KDecoration::mouseMoveEvent(e);
#endif
}

void MachBunt::buttonPressed()
{
    TQPoint p( TQCursor::pos().x() - geometry().x(),
              TQCursor::pos().y() - geometry().y());

    if ( mousePosition(p) == KDecorationDefines::PositionTopLeft  ||
         mousePosition(p) == KDecorationDefines::PositionTopRight ||
         mousePosition(p) == KDecorationDefines::PositionTop )
        	buttonPressedPosition = TQCursor::pos();
}

void MachBunt::buttonReleased()
{
    buttonPressedPosition.setX( -1 );
//    keyPressEvent( Key_Escape );
}

  KDecoration::Position
MachBunt::mousePosition(const TQPoint & p) const
{
	int x = p.x();
	int y = p.y();

	if ( y < titleHeight ){
		if ( x < BUTTON_RESIZE_SIZE )
			return KDecorationDefines::PositionTopLeft;
		if ( x > width() - 1 - BUTTON_RESIZE_SIZE )
			return KDecorationDefines::PositionTopRight;
	}

	if ( titlebarResize ){
		if ( ( ! (x < BUTTON_RESIZE_SIZE || x > width() - 1 - BUTTON_RESIZE_SIZE) )
		    && (y < TOP_RESIZE_HEIGHT ))
		{
			if ( titlebarResize==true )
				return KDecorationDefines::PositionTop;
			else
				return KDecorationDefines::PositionCenter;
		}
	}
  return KDecoration::mousePosition(p);
}

void MachBunt::slotMaximize()
{
    if ( button[BtnMax]->last_button == MidButton )
       maximize(maximizeMode() ^ MaximizeVertical );
    else if ( button[BtnMax]->last_button == RightButton )
       maximize(maximizeMode() ^ MaximizeHorizontal );
    else
       maximize(maximizeMode() == MaximizeFull ? MaximizeRestore : MaximizeFull);
}

void MachBunt::resize( const TQSize& s )
{
    widget()->resize( s );
}

TQSize MachBunt::minimumSize() const
{
   return TQSize( 200, 50 );
}

const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
    | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask
    | NET::UtilityMask | NET::SplashMask;

bool MachBunt::isTool()
{
  NET::WindowType type = windowType( SUPPORTED_WINDOW_TYPES_MASK );
  return ((type==NET::Toolbar)||(type==NET::NET::Utility)||(type==NET::Menu));
}

bool MachBunt::eventFilter( TQObject* o, TQEvent* e )
{
    if( o != widget())
    return false;
    switch( e->type())
    {
    case TQEvent::Resize:
        resizeEvent(static_cast< TQResizeEvent* >( e ) );
        return true;
    case TQEvent::Paint:
        paintEvent(static_cast< TQPaintEvent* >( e ) );
        return true;
    case TQEvent::MouseButtonDblClick:
        mouseDoubleClickEvent(static_cast< TQMouseEvent* >( e ) );
        return true;
    case TQEvent::MouseButtonPress:
        processMousePressEvent(static_cast< TQMouseEvent* >( e ) );
        return true;
    default:
        break;
    }
    return false;
}

void MachBunt::desktopChange()
{
  emit(oadChange(isOnAllDesktops()));
}

KDecoration* BuntFactory::createDecoration( KDecorationBridge* b )
{
  return(new MachBunt(b, this));
}

bool BuntFactory::reset(unsigned long changed)
{
  // Do we need to "hit the wooden hammer" ?
  bool needHardReset = false;
  if (changed & (SettingDecoration | SettingFont | SettingButtons | SettingBorder))
  {
    needHardReset = true;
  }
  if( changed & SettingColors )
  { // pixmaps need to be recreated
    delete_pixmaps();
    create_pixmaps();
  }

  if (needHardReset) {
    return true;
  } else {
    resetDecorations(changed);
    return false;
  }
}

TQValueList< BuntFactory::BorderSize > BuntFactory::borderSizes() const
{ // the list must be sorted
  return TQValueList< BorderSize >() << BorderNormal;
  // TODO << BorderLarge << BorderVeryLarge <<  BorderHuge << BorderVeryHuge << BorderOversized;
}

void MachBunt::resizeEvent( TQResizeEvent*)
{
    doShape();

    calcHiddenButtons();
    widget()->repaint();
#if 0
    for ( int i=0; i < BtnCount; i++ )
 	if ( button[i] )
	     button[i]->reset(0);

    if (isVisibleToTLW())
    {
        update(rect());
        int dx = 0;
        int dy = 0;

	    if ( e->oldSize().width() != width() )
	       dx = 32 + TQABS( e->oldSize().width() -  width() );

	    if ( e->oldSize().height() != height() )
	       dy = 8 + TQABS( e->oldSize().height() -  height() );

	    if ( dy )
	       update( 0, height() - dy + 1, width(), dy );

        if ( dx )
        {
	       update( width() - dx + 1, 0, dx, height() );
	       update( TQRect( TQPoint(4,4), titlebar->geometry().bottomLeft() - TQPoint(1,0) ) );
	       update( TQRect( titlebar->geometry().topRight(), TQPoint( width() - 4, titlebar->geometry().bottom() ) ) );
           // Titlebar needs no paint event
	       TQApplication::postEvent( widget(), new TQPaintEvent( titlebar->geometry(), false ) );
	    }
    }
#endif
}


void MachBunt::captionChange()
{
    widget()->repaint( titlebar->geometry(), false );
}

void MachBunt::iconChange()
{
    button[BtnMenu]->setPixmap( icon().pixmap( TQIconSet::Small, TQIconSet::Normal ));

    if (button[BtnMenu]->isVisible())
       button[BtnMenu]->repaint(false);
}


void MachBunt::paintEvent( TQPaintEvent *pe )
{
//    bool hicolor = TQPixmap::defaultDepth() > 8;
	int fontoffset = 1;

	TQPainter p(widget());
	p.setClipRegion(pe->region());

	// Obtain widget bounds.
	TQRect r(widget()->rect());
	    int i;
	int x = r.x();
	int y = r.y();
	int x2 = r.width()-1;
	int y2 = r.height()-1;
	int w  = r.width();
	int ps = smallButtons ? PIX_SIDE/2 : PIX_SIDE;

	TQColorGroup g = options()->colorGroup(KDecorationDefines::ColorFrame, isActive());

	p.setPen( g.dark() );
	// the dark outer drawings
	p.drawLine(x,   y+PIX_CORNER_RADIUS+2*BORDER_LEFT, x,  y2);
	p.drawLine(x2,  y+PIX_CORNER_RADIUS+2*BORDER_LEFT, x2, y2);
	p.drawLine(x,   y2                               , x2, y2);
	// the dark diagonals beside titlebar
	p.drawLine(x,  y+PIX_CORNER_RADIUS+2*BORDER_LEFT, x+BORDER_LEFT,  y+PIX_CORNER_RADIUS+BORDER_LEFT);
	p.drawLine(x2, y+PIX_CORNER_RADIUS+2*BORDER_LEFT, x2-BORDER_LEFT, y+PIX_CORNER_RADIUS+BORDER_LEFT);
	p.setPen( g.light() );
	if ( titlebarSidebar ){
		for ( i=1; i<BORDER_LEFT; i++)
			p.drawLine(x+i,  y+PIX_CORNER_RADIUS+2*BORDER_LEFT-i+1, x+i,  y2-1);
		for ( i=1; i<BORDER_RIGHT; i++)
			p.drawLine(x2-i, y+PIX_CORNER_RADIUS+2*BORDER_LEFT-i+1, x2-i, y2-1);
	}else{
		for ( i=1; i<BORDER_LEFT; i++)
			p.drawLine(x+i,  titleHeight, x+i,  y2-1);
		for ( i=1; i<BORDER_RIGHT; i++)
			p.drawLine(x2-i, titleHeight, x2-i, y2-1);
	}
	for ( i=1; i<BORDER_BOTTOM; i++)
		p.drawLine(x+1,y2-i, w-2, y2-i);

	// draw the title bar.
	r = titlebar->geometry();
//	TQFontMetrics fm(options()->font(true));

	KPixmap titleBuffer;
	if ( titlebarSidebar )
		titleBuffer.resize(w-BORDER_LEFT-BORDER_RIGHT, titleHeight);
	else
		titleBuffer.resize(w, titleHeight);
	TDEIconEffect kie;

	TQPainter p2( &titleBuffer, widget());

	p2.drawTiledPixmap( ps, 0, titleBuffer.width()-2*ps, titleHeight, middle_img[isActive()][smallButtons]);
	p2.drawTiledPixmap( 0, 0, ps, titleHeight, left_img[isActive()][smallButtons]);
	p2.drawTiledPixmap( titleBuffer.width()-ps, 0, ps, titleHeight, right_img[isActive()][smallButtons]);

	int l;
	if ( button[BtnHelp] && button[BtnHelp]->isShown() )
		l=button[BtnHelp]->x();
	else if ( button[BtnIconify]->isShown() )
		l=button[BtnIconify]->x();
	else if ( button[BtnMax]->isShown() )
		l=button[BtnMax]->x();
	else if ( button[BtnClose]->isShown() )
		l=button[BtnClose]->x();
	else
		l=0;

	p2.drawTiledPixmap(l-titleHeight/2, 0, titleHeight-(titleHeight/2), titleHeight, button_img[isActive()][smallButtons], titleHeight/2, 0);

	// Reduce the font size and weight for toolwindows.
	TQFont font = options()->font(true);
	if ( smallButtons )
	{
	   font.setPointSize( font.pointSize() - 2 );
	   font.setWeight( TQFont::Normal );
	   fontoffset = 0;
	}
	p2.setFont( font );
	p2.setPen( options()->color(KDecorationDefines::ColorFont, isActive() ));
	w = p2.fontMetrics().width(caption())+2*TEXT_BORDER;
	if ( w > r.width()-3-button_l_img[0][smallButtons].width()-bar_img[0][smallButtons].width() ) w=r.width()-3-button_l_img[0][smallButtons].width()-bar_img[0][smallButtons].width();
	p2.drawTiledPixmap( r.x()-TEXT_BORDER-ps, 0, w+ps+2*TEXT_BORDER+3, titleHeight , text_img[isActive()][smallButtons]);
	p2.drawPixmap(r.x()+w+TEXT_BORDER, 0, bar_img[isActive()][smallButtons]);
	if ( titlebarLogo && isActive() && r.x()+w+kroete_img[0][smallButtons].width() < r.width()  )
	 	p2.drawTiledPixmap( r.x()+w+bar_img[0][smallButtons].width(), 0, kroete_img[0][smallButtons].width(), titleHeight, kroete_img[isActive()][smallButtons]);
	p2.drawText( r.x(), fontoffset, w+TEXT_BORDER, r.height()-1, AlignLeft | AlignVCenter, caption() );

	p2.end();

	if ( titlebarSidebar )
		p.drawPixmap( BORDER_LEFT, 0, titleBuffer );
	else
		p.drawPixmap( 0, 0, titleBuffer );
}

void MachBunt::showEvent(TQShowEvent *)
{
    doShape();
    widget()->repaint();
}

void MachBunt::mouseDoubleClickEvent( TQMouseEvent * e )
{
    if (titlebar->geometry().contains( e->pos() ) )
	titlebarDblClickOperation();
}


void MachBunt::maximizeChange()
{
//    button[BtnMax]->setBitmap(m ? minmax_bits : maximize_bits);
	button[BtnMax]->setTipText( (maximizeMode()==MaximizeFull) ? i18n("Restore") : i18n("Maximize"));
}


void MachBunt::activeChange()
{
    for(int i=0; i < BtnCount; i++)
    {
        if(button[i])
            button[i]->repaint();
    }

    widget()->repaint();
}


void MachBunt::calcHiddenButtons()
{
    // order of hiding is help, maximize, minimize, close, then menu;
    int minWidth = 32 + titleHeight*4 + (providesContextHelp() ? titleHeight*2 : titleHeight );

    if(lastButtonWidth > width())   // Shrinking
    {
        lastButtonWidth = width();
        if(width() < minWidth)
        {
            hiddenItems = true;

            for(int i = 0; i < BtnCount; i++)
            {
                if(button[i])
                {
                    if( !button[i]->isHidden() )
                    {
                        button[i]->hide();
                    }
                    minWidth -= button[i]->sizeHint().width();
                    if(width() >= minWidth)
                        return;
                }
            }
        }
    }
    else
    if(hiddenItems) // Expanding
    {
        lastButtonWidth = width();
        int totalSize = titleHeight*3;

        for(int i = BtnCount - 1; i >= 0; i--)
        {
            if(button[i])
            {
                if(button[i]->sizeHint().width() + totalSize <= width())
                {
                    totalSize += button[i]->sizeHint().width();
                    button[i]->resize(button[i]->sizeHint());
                    button[i]->show();
                }
                else
                    return;
            }
        }

        // all items shown now
        hiddenItems = false;
    }
    else
        lastButtonWidth = width();
}

void MachBunt::menuButtonPressed()
{
    // KS - move the menu left by 3 pixels, and down 2 pixels.
    TQPoint menupoint ( button[BtnMenu]->rect().bottomLeft().x()-3,
                       button[BtnMenu]->rect().bottomLeft().y()+2 );
    KDecorationFactory* f = factory();
    showWindowMenu( button[BtnMenu]->mapToGlobal( menupoint ));
    if( !f->exists( this )) // 'this' was destroyed
        return;
    button[BtnMenu]->setDown(false);
}

void MachBunt::doShape(int x)
{
	TQRegion mask(0, 0, width(), height());

	int bWidth = smallButtons ? 12 : PIX_HEIGHT;
	int i, bl=0, br=0, p=0;
	int r(width());
	if ( titlebarSidebar ){
		bl=BORDER_LEFT;
		br=BORDER_RIGHT;
	        // is the right button pressed ?
		if ( x >=  (r - br - bWidth) )
		   p=2;
	}

	mask -= TQRegion(0, 0, bl+3, 1);
	mask -= TQRegion(0, 1, bl+1, 1);

	// Remove top-right corner.
	if ( smallButtons ){
		mask -= TQRegion(r-3-br, 0, 3+br, 1+p);
		mask -= TQRegion(r-2-br, 1, 2+br, 1+p);
		mask -= TQRegion(r-1-br, 2, 1+br, 1+p);
	}else{
		mask -= TQRegion(r-7-br, 0, 7+br, 1+p);
		mask -= TQRegion(r-5-br, 1, 5+br, 1+p);
		mask -= TQRegion(r-4-br, 2, 4+br, 1+p);
		mask -= TQRegion(r-3-br, 3, 3+br, 1+p);
		mask -= TQRegion(r-2-br, 4, 2+br, 1+p);
		mask -= TQRegion(r-1-br, 5, 1+br, 2+p);
	}
	for ( i=0; i<br; i++)
		mask -= TQRegion(r-i-1, 0, 1, PIX_CORNER_RADIUS+bl+br-i);

	// the buttons
    	for ( i=0; i<BtnCount; i++){
		if ( button[i] && button[i]->isShown() ){
			// top left corner of this button and right part of the button before
			mask -= TQRegion( button[i]->x() - 3, 0, 4, 1 );
			mask -= TQRegion( button[i]->x() - 1, 0, 1, 2 );
		}
	}

        // the pressed button
	if ( x != 0 ){
		mask -= TQRegion( x, 0, bWidth, 2 );
		mask -= TQRegion( x, 0, 1, 3 );
		mask -= TQRegion( x + bWidth -3 , 0, 3, 3 );
		mask -= TQRegion( x + bWidth -1 , 0, 1, 4 );
        }

	setMask(mask);
}

}

#include "MachBunt.moc"
