#include "baghira.h"

#include <qbitmap.h>
#include <qimage.h>
#include <qcolor.h>
#include <qpalette.h>
#include <qrect.h>
#include <qpoint.h>
#include <qapplication.h>
#include <qpainter.h>
#include <qpen.h>

#include <kwordwrap.h>

#define CLAMP(x,l,u) x < l ? l :\
		     x > u ? u :\
		     x
		     

#define ALPHA_COLOR(A,R,G,B) \
    destR = ((A * destR) + (255 - A) * R) / 255; \
    destG = ((A * destG) + (255 - A) * G) / 255; \
    destB = ((A * destB) + (255 - A) * B) / 255; \
    A = 255;
    
#define DELTA_COLOR(D,R,G,B) \
    delta = (255 - qRed(D))/2; \
    destR = srcR - delta; \
    destG = srcG - delta; \
    destB = srcB - delta;
    
#define SATURATION_COLOR(R,G,B) \
    grey = (299 * R + 587 * G + 114 * B) / 1000; \
    delta = 255 - grey; \
    grey = (grey *(10 - 5)) / 10; \
    iGrey = 255 - grey;\
    destR = (iGrey * (srcR - delta) + grey * R) / 255; \
    destG = (iGrey * (srcG - delta) + grey * G) / 255; \
    destB = (iGrey * (srcB - delta) + grey * B) / 255; 
    
#define SATURATION_COLOR2(S,R,G,B) \
   int max = 255+(int)(0.65*(100-S)); \
   destR = CLAMP((srcR + R - 128), 0, max); \
   destG = CLAMP((srcG + G - 128), 0, max); \
   destB = CLAMP((srcB + B - 128), 0, max); \
   destR = (S*destR + (100-S)*R)/100; \
   destG = (S*destG + (100-S)*G)/100; \
   destB = (S*destB + (100-S)*B)/100;
   
   
#define SATURATION_COLOR3(S,R,G,B) \
   destR = (S*(srcR + R - 128)/100 + R)/2; \
   destG = (S*(srcG + G - 128)/100 + G)/2; \
   destB = (S*(srcB + B - 128)/100 + B)/2; 
    
#define GM_COLOR(R,G,B)\
    destR = CLAMP(destR + R - 128, 0, 255);\
    destG = CLAMP(destG + G - 128, 0, 255);\
    destB = CLAMP(destB + B - 128, 0, 255);

    
#define COLOR_SPACE(R,G,B) \
    if ( R < 0 ) R = 0; else if ( R > 255 ) R = 255; \
    if ( G < 0 ) G = 0; else if ( G > 255 ) G = 255; \
    if ( B < 0 ) B = 0; else if ( B > 255 ) B = 255;
    

    
int LiquidStyle::getBrightness(unsigned int rgb) const {
	int red = qRed( rgb );
	int green = qGreen( rgb );
	int blue = qBlue( rgb );
	int V = red;
	if (green > V)  V = green;
	if (blue > V)  V = blue;
	return V;
}

QPixmap* LiquidStyle::adjustHSV( QImage &img, const QColor &c,
                                 bool blend, const QColor *bg ) const 
{
    QImage * tmp = adjustHSVImage( img, c, blend, bg );

    QPixmap *pix = new QPixmap;
    pix->convertFromImage( *tmp );
    delete tmp;
    return ( pix );
}


ButtonTile* LiquidStyle::createRoundFrameTile(QImage &img, const QColor &color, const QColor *bg, const QColor &baseColor ) const
{
    QColor bgColor( optionHandler->BrushMe() ? optionHandler->brushedMetalColor : bg ? *bg : qApp->palette().active().background() );

    if ( img.depth() != 32 )
    	img = img.convertDepth( 32 );
    QImage *dest = new QImage( img.width(), img.height(), 32, 0, _ENDIAN_ );
    dest->setAlphaBuffer( true );
    unsigned int *data = ( unsigned int * ) img.bits();
    unsigned int *destData = ( unsigned int* ) dest->bits();
    int total = img.width() * img.height();
    int current;
    int delta;
    int red, green, blue, grey, iGrey;
    int destR, destG, destB, alpha;
    int x,y;
  
    int srcR = color.red();
    int srcG = color.green();
    int srcB = color.blue();

    if (!optionHandler->IcyButtons()){
    	srcR += 20;
    	srcG += 20;
    	srcB += 20;    
    COLOR_SPACE(srcR, srcG, srcB);
    }

    for ( current = 0 ; current < total ; ++current ) {
    	alpha = qAlpha( data[ current ] );
	if (optionHandler->IcyButtons()) {
    	    red = qRed( data[ current ] );
    	    green = qGreen( data[ current ] );
	    blue = qBlue( data[ current ] );
	    SATURATION_COLOR(red, green, blue);
	}
	else {
	    // the coloring itself
	    DELTA_COLOR(data[ current ], srcR, srcG, srcB);
	}
	if ( alpha && alpha != 255 ) {
	   // only on translucent pixels - alphablending
	   y = (int)(current/img.width());
           x = current - y*img.width();
           if (red < 180 || x < 2 || y < 2 || y > img.height() - 2 || x > img.width() - 3){
               ALPHA_COLOR(alpha, bgColor.red(), bgColor.green(), bgColor.blue());
           }
           else{
               ALPHA_COLOR(alpha, baseColor.red(), baseColor.green(), baseColor.blue());
           }
	}
	// force back to valid colorspace !
	COLOR_SPACE(destR, destG, destB);
	destData[ current ] = qRgba( destR, destG, destB, alpha );
    }
    QPixmap destPix;
    destPix = *dest;
    ButtonTile *ret = separateTiles( &destPix, 11, 10, 6, 1, 0, false, true );
    delete dest;
    return ret;
}

QImage* LiquidStyle::adjustHSVImage( QImage &img, const QColor &c,
                                     bool blend, const QColor *bg ) const
{
    QColor bgColor( optionHandler->BrushMe() ? optionHandler->brushedMetalColor : bg ? *bg : qApp->palette().active().background() );

    if ( img.depth() != 32 )
    	img = img.convertDepth( 32 );
    QImage *dest = new QImage( img.width(), img.height(), 32, 0, _ENDIAN_ );
    dest->setAlphaBuffer( true );
    unsigned int *data = ( unsigned int * ) img.bits();
    unsigned int *destData = ( unsigned int* ) dest->bits();
    int total = img.width() * img.height();
    int current;
    int delta;
    int red, green, blue;
    int destR, destG, destB, alpha;
  
    int srcR = c.red();
    int srcG = c.green();
    int srcB = c.blue();
    
    int hue, s, v;
    c.getHsv( &hue, &s, &v );
    int sq = CLAMP((int)((45.0/128.0)*s+55),0,100);


    if (!optionHandler->IcyButtons()){
    	srcR += 20;
    	srcG += 20;
    	srcB += 20;    
    COLOR_SPACE(srcR, srcG, srcB);
    }

    // float srcPercent, destPercent;
    for ( current = 0 ; current < total ; ++current ) {
    	alpha = qAlpha( data[ current ] );
	if (optionHandler->IcyButtons()) {
    	    red = qRed( data[ current ] );
    	    green = qGreen( data[ current ] );
	    blue = qBlue( data[ current ] );
//	    SATURATION_COLOR(optionHandler->Saturation(), red, green, blue);
	    SATURATION_COLOR2(sq, red, green, blue);
	}
	else {
	    // the coloring itself
	    DELTA_COLOR(data[ current ], srcR, srcG, srcB);
	}
	if ( blend && alpha && alpha != 255 ) {
	   // only on translucent pixels - alphablending
	   ALPHA_COLOR(alpha, bgColor.red(), bgColor.green(), bgColor.blue());
	}
	// force back to valid colorspace !
	COLOR_SPACE(destR, destG, destB);
	destData[ current ] = qRgba( destR, destG, destB, alpha );
    }
    return ( dest );
}

QImage* LiquidStyle::tintBrush( const QImage &img, const QColor &c ) const
{

//     if ( img.depth() != 32 )
//     	img = img.convertDepth( 32 );
    QImage *dest = new QImage( img.width(), img.height(), 32, 0, _ENDIAN_ );
    unsigned int *data = ( unsigned int * ) img.bits();
    unsigned int *destData = ( unsigned int* ) dest->bits();
    int total = img.width() * img.height();
    int current;
    int delta;
    int red, green, blue, grey, iGrey;
    int destR, destG, destB, alpha;
 
    int srcR = c.red();
    int srcG = c.green();
    int srcB = c.blue();
    
    SATURATION_COLOR(200, 200, 200);
    COLOR_SPACE(destR, destG, destB);
    optionHandler->brushedMetalColor = QColor(destR, destG, destB);
    
    // float srcPercent, destPercent;
    for ( current = 0 ; current < total ; ++current ) {
    	alpha = qAlpha( data[ current ] );
    	red = qRed( data[ current ] );
    	green = qGreen( data[ current ] );
	blue = qBlue( data[ current ] );
	SATURATION_COLOR(red, green, blue);
	// force back to valid colorspace !
	COLOR_SPACE(destR, destG, destB);
	destData[ current ] = qRgba( destR, destG, destB, alpha );
    }
    return ( dest );
}




void LiquidStyle::clearImage( QImage &img ) const
{
    int x, y;
    int w = img.width();
    int h = img.height();
    unsigned int pixel = qRgba( 0, 0, 0, 0 );
    unsigned int *data;

    for ( y = 0 ; y < h ; ++y ) 
    	for ( data = (unsigned int *) img.scanLine( y ), x = 0 ; x < w ; data[ x++ ] = pixel ) ;
    // img.fill( pixel );
}

void LiquidStyle::adjustHSV( QPixmap &pix, const QColor &c ) const
{
    QImage img = pix.convertToImage();
    QPixmap *result = adjustHSV( img, c, false );
    pix = *result;
    delete result;
}


/* buttons are fractioned to 9 parts.
w, h are width and height of the whole button.
xOff  (yOff) is the distance of the central fraction from left (upper) button side.
centerW (centerH) is the width (height) of the central button fraction.
shadowH is the height of the buttons shadow*/
ButtonTile* LiquidStyle::createButtonTile( const QColor &c, 
					   const QColor &obgColor, 
                                           QImage *buttonImage, 
					   QImage *shadowImage, 
					   QImage *glowImage, 
					   QIntDict<ButtonTile>*buttonDict, 
					   QIntDict<ButtonTile>*shadowDict, 
					   QIntDict<ButtonTile>*glowDict, 
					   int w, int h, int xOff, int yOff, 
					   int centerW, int centerH, 
					   int shadowH, int glowWH, 
					   bool sunken, bool hover ) const
{
    QColor bgColor = optionHandler->BrushMe() ? optionHandler->brushedMetalColor : obgColor;
    int x, y, delta;
    int red, green, blue, grey;
    int destR, destG, destB, alpha;
//    float srcPercent, destPercent;
    unsigned int bgPixel = bgColor.rgb();
    
    int hue, s, v;
    c.getHsv( &hue, &s, &v );
    int sq = CLAMP((int)((45.0/128.0)*s+55),0,100);
    
    int srcR = c.red();
    int srcG = c.green();
    int srcB = c.blue();

    if (!optionHandler->IcyButtons()){
    srcR += 20;
    srcG += 20;
    srcB += 20;

    COLOR_SPACE(srcR, srcG, srcB);
    }
    
    unsigned int *data, *destData;
    ButtonTile *tile;

    int shadowOverhead;
    shadowH > glowWH ? shadowOverhead = shadowH - glowWH : shadowOverhead = 0;
    QImage img( w + 2*glowWH + shadowOverhead, h + 2*glowWH + shadowOverhead, 32, 0, _ENDIAN_  );
    img.setAlphaBuffer( !isPlain() || optionHandler->drawGroupBoxShadow() ? true : false);
    clearImage( img );

    // For unpressed buttons things are a little more complex. First
    // we color adjust the shadow with the background color then we
    // adjust the button to the button color. Finally we overlay the
    // button on the shadow, (in the same loop as color adjusting).
    // Technically we probably could of gotten away
    // with just adjusting both the shadow and the button to the button
    // color since the shadow is quite dark, but this is more correct and
    // would allow configurable shadow brightness. If the shadow was
    // just the button color, if someone configured it to be a rather
    // light brightness, and they had a dark background color it wouldn't
    // look right if based off the button color.
    //
    // Luckily this is only done once when the button is created for any
    // given color ;-)

    // first do the shadow
    if (!sunken && (shadowImage/* != NULL*/))
	for ( y = 0 ; y < h + shadowH ; ++y ) {
    	    data = ( unsigned int * ) shadowImage->scanLine( y );
	    destData = ( unsigned int * ) img.scanLine( y + glowWH ); // glowWH is the yOffset -> distance of visable button to top of complete button
    	    for ( x = 0 ; x < w ; ++x )
    		if ((alpha = qAlpha( data[ x ] ))) {
		    DELTA_COLOR(data[ x ], srcR, srcG, srcB);
		    if (alpha != 255) {
			ALPHA_COLOR(alpha, bgColor.red(), bgColor.green(), bgColor.blue());
		    }
		    COLOR_SPACE(destR, destG, destB);
		    destData[ x + glowWH ] = qRgba( destR, destG, destB, alpha );
		}
	}
    // ... or the glow
    else if (glowImage/* != NULL */)
	for ( y = 0 ; y < h + 2*glowWH ; ++y ) {
	    data = ( unsigned int * ) glowImage->scanLine( y );
	    destData = ( unsigned int * ) img.scanLine( y );
	    for ( x = 0 ; x < w + 2*glowWH ; ++x )
    		if ((alpha = qAlpha( data[ x ] ))) {
		    DELTA_COLOR(data[ x ], srcR, srcG, srcB);
		    if (alpha != 255) {
			ALPHA_COLOR(alpha, bgColor.red(), bgColor.green(), bgColor.blue());
		    }
		    COLOR_SPACE(destR, destG, destB);
		    destData[ x ] = qRgba( destR, destG, destB, alpha );
		}
	}
    
    // then the button and overlay
    for ( y = 0 ; y < h ; ++y ) {
	data = ( unsigned int * ) buttonImage->scanLine( y );
	destData = ( unsigned int * ) img.scanLine( y + glowWH );
	for ( x = 0 ; x < w ; ++x )
	    if ((alpha = qAlpha( data[ x ] ))) {
		if (optionHandler->IcyButtons()) {
	    	    red = qRed( data[ x ] );
	    	    green = qGreen( data[ x ] );
	    	    blue = qBlue( data[ x ] );
//	    	    SATURATION_COLOR(optionHandler->Saturation(), red, green, blue);
	    	    SATURATION_COLOR2(sq, red, green, blue);
		}
		else {
		    DELTA_COLOR(data[ x ], srcR, srcG, srcB);
		}
		if (alpha != 255) {
	    	    if ( qAlpha( destData[ x + glowWH ] ) ) {
	    		ALPHA_COLOR(alpha, qRed( destData[ x + glowWH ]), qGreen( destData[ x + glowWH ]), qBlue( destData[ x + glowWH ]));
		    }
		    else {
			ALPHA_COLOR(alpha, bgColor.red(), bgColor.green(), bgColor.blue());
		    }
		    alpha = 255;
		}
		COLOR_SPACE(destR, destG, destB);
		destData[ x + glowWH ] = qRgba( destR, destG, destB, alpha );
	    }
    }

    // Are we plain? If so fill in transparent pixels (must be after overlay)
    if ( isPlain() && !optionHandler->drawGroupBoxShadow() ) {
	delta = h + glowWH + ((shadowH > glowWH) ? shadowH : glowWH);
	grey = w + 2 * glowWH;
	for ( y = 0 ; y < delta ; ++y )
	    for (destData = (unsigned int *) img.scanLine( y ), x = 0 ; x < grey ; ++x )
		if ( qAlpha( destData[ x ] ) == 0 ) destData[ x ] = bgPixel;
    }
    QPixmap *pix = new QPixmap;
    pix->convertFromImage( img );
    tile = separateTiles( pix, xOff, yOff, centerW, centerH, shadowH, sunken, optionHandler->drawGroupBoxShadow() );
    if ( sunken && glowDict /*!= NULL*/)
    	glowDict->insert(c.rgb(),tile);
    else if (!sunken && shadowDict /*!= NULL*/)
	shadowDict->insert( c.rgb(), tile );
    else
	buttonDict->insert( c.rgb(), tile );
    delete pix;
    return ( tile );
}

QPixmap* LiquidStyle::createSliderEnd( const QColor &c, const QColor &bgColor, bool top) const
{

    int x, y, delta;
    int red, green, blue;
    int destR, destG, destB, alpha;
    
    int h, s, v;
    c.getHsv( &h, &s, &v );
    int sq = CLAMP((int)((45.0/128.0)*s+55),0,100);
    
    int srcR = c.red();
    int srcG = c.green();
    int srcB = c.blue();

    if (!optionHandler->IcyButtons()){
    srcR +=20;
    srcG += 20;
    srcB += 20;

    COLOR_SPACE(srcR, srcG, srcB);
    }

    unsigned int *data, *destData;

    QImage img( 13, 9, 32, 0, _ENDIAN_  );
    img.setAlphaBuffer( true ); // we need this always, as the slider groove is nevernever plain!
    clearImage( img );

    // just stole that from above...
    // first do the shadow
    for ( y = 0 ; y < 9 ; ++y ) {
	top ? data = ( unsigned int * ) slider_top_shd->scanLine( y ) : data = ( unsigned int * ) slider_btm_shd->scanLine( y );
	destData = ( unsigned int * ) img.scanLine( y );
	for ( x = 0; x < 13; ++x )
	    if ((alpha = qAlpha( data[ x ] ))) {
		DELTA_COLOR(data[ x ], srcR, srcG, srcB);
		if (alpha != 255 ) {
		    ALPHA_COLOR(alpha, bgColor.red(), bgColor.green(), bgColor.blue());
		}
		COLOR_SPACE(destR, destG, destB);
		destData[ x ] = qRgba( destR, destG, destB, alpha );
	    }
    }
    // then the button and overlay
    for ( y = 0 ; y < 7 ; ++y ) {
	top ? data = ( unsigned int * ) slider_top->scanLine( y ) : data = ( unsigned int * ) slider_btm->scanLine( y );
	destData = ( unsigned int * ) img.scanLine( top ? y + 2 : y );
	for ( x = 0 ; x < 13 ; ++x )
	    if ((alpha = qAlpha( data[ x ] ))) {
		if (optionHandler->IcyButtons()) {
	    	    red = qRed( data[ x ] );
	    	    green = qGreen( data[ x] );
	    	    blue = qBlue( data[ x] );
//		    SATURATION_COLOR(optionHandler->Saturation(), red, green, blue);
		    SATURATION_COLOR2(sq, red, green, blue);
		}
		else {
	    	    DELTA_COLOR(data[ x ], srcR, srcG, srcB);
		}
		if (alpha != 255) {
		    if ( qAlpha( destData[ x ] ) ) {
			ALPHA_COLOR(alpha, qRed( destData[ x ]), qGreen( destData[ x ]), qBlue( destData[ x ]));
		    }
		    else {
			ALPHA_COLOR(alpha, bgColor.red(), bgColor.green(), bgColor.blue());
		    }
		}
		COLOR_SPACE(destR, destG, destB);
		destData[ x ] = qRgba( destR, destG, destB, alpha );
	    }
    }
    QPixmap *pix = new QPixmap;
    pix->convertFromImage( img );
    return ( pix );
}



//   0     /  xO  /  xO + w
// -------------------------------------
// | xO   | w   | width()-xO-w | : yO 			/   0
// -------------------------------------
// | xO   | w   | width()-xO-w | : h 				/   yO
// -------------------------------------
// | xO   | w   | width()-xO-w | : height()-yO-h  	/  yO+h
// -------------------------------------
// Overload of mosfet's original function, takes 6 more parameters to use the funktion on variable bitmaps (mosfet's function does only work for very special bitmaps)
// by giving position and dimension of the central tile + the shadow height (panther doesn't seem to have a right shadow-offset)
ButtonTile* LiquidStyle::separateTiles( QPixmap *pix, 
					int xO, int yO, int w, int h, 
					int sh, bool sunken, bool forceAlpha ) const
{
    ButtonTile * tile = new ButtonTile();
    QPixmap *tmp;
    QBitmap *tmpMask;

    int w1 = xO;
    int w2 = w;
    int w3 = pix->width() - xO - w;
    int h1 = yO;
    int h2 = h;
    int h3 = pix->height() - yO - h;

    int xO1 = 0;
    int xO2 = xO;
    int xO3 = xO + w;
    int yO1 = 0;
    int yO2 = yO;
    int yO3 = yO + h;

    if ( !sunken ) {
	// Top tiles
	tmp = new QPixmap( w1, h1 );
	// bitBlt(...,x,y,width,height)
	bitBlt( tmp, 0, 0, pix, xO1, yO1, w1, h1 );
	tile->setPixmap( TileTopLeft, tmp );
	tmp = new QPixmap( w2, h1 );
	bitBlt( tmp, 0, 0, pix, xO2, yO1, w2, h1 );
	tile->setPixmap( TileTop, tmp );
	tmp = new QPixmap( w3, h1 );
	bitBlt( tmp, 0, 0, pix, xO3, yO1, w3, h1 );
	tile->setPixmap( TileTopRight, tmp );

	// Middle tiles
	tmp = new QPixmap( w1, h2 );
	bitBlt( tmp, 0, 0, pix, xO1, yO2, w1, h2 );
	tile->setPixmap( TileLeft, tmp );
	tmp = new QPixmap( w2, h2 );
	bitBlt( tmp, 0, 0, pix, xO2, yO2, w2, h2 );
	tile->setPixmap( TileMiddle, tmp );
	tmp = new QPixmap( w3, h2 );
	bitBlt( tmp, 0, 0, pix, xO3, yO2, w3, h2 );
	tile->setPixmap( TileRight, tmp );

	// Bottom tiles
	tmp = new QPixmap( w1, h3 );
	bitBlt( tmp, 0, 0, pix, xO1, yO3, w1, h3 );
	tile->setPixmap( TileBtmLeft, tmp );
	tmp = new QPixmap( w2, h3 );
	bitBlt( tmp, 0, 0, pix, xO2, yO3, w2, h3 );
	tile->setPixmap( TileBtm, tmp );
	tmp = new QPixmap( w3, h3 );
	bitBlt( tmp, 0, 0, pix, xO3, yO3, w3, h3 );
	tile->setPixmap( TileBtmRight, tmp );

	if ( !isPlain() || forceAlpha ) {
    	    tmpMask = new QBitmap( w1, h1 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO1, yO1, w1, h1 );
	    tile->pixmap( TileTopLeft ) ->setMask( *tmpMask );
	    delete tmpMask;
	    tmpMask = new QBitmap( w2, h1 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO2, yO1, w2, h1 );
	    tile->pixmap( TileTop ) ->setMask( *tmpMask );
	    delete tmpMask;
	    tmpMask = new QBitmap( w3, h1 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO3, yO1, w3, h1 );
	    tile->pixmap( TileTopRight ) ->setMask( *tmpMask );
	    delete tmpMask;

	    tmpMask = new QBitmap( w1, h2 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO1, yO2, w1, h2 );
	    tile->pixmap( TileLeft ) ->setMask( *tmpMask );
	    delete tmpMask;
	    tmpMask = new QBitmap( w2, h2 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO2, yO2, w2, h2 );
	    tile->pixmap( TileMiddle ) ->setMask( *tmpMask );
	    delete tmpMask;
	    
	    tmpMask = new QBitmap( w3, h2 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO3, yO2, w3, h2 );
	    tile->pixmap( TileRight ) ->setMask( *tmpMask );
	    delete tmpMask;

	    tmpMask = new QBitmap( w1, h3 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO1, yO3, w1, h3 );
	    tile->pixmap( TileBtmLeft ) ->setMask( *tmpMask );
	    delete tmpMask;
	    
	    tmpMask = new QBitmap( w2, h3 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO2, yO3, w2, h3 );
	    tile->pixmap( TileBtm ) ->setMask( *tmpMask );
	    delete tmpMask;
	    tmpMask = new QBitmap( w3, h3 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO3, yO3, w3, h3 );
	    tile->pixmap( TileBtmRight ) ->setMask( *tmpMask );
	    delete tmpMask;
	}
    } 
    else {
	// Top tiles
	tmp = new QPixmap( w1, h3 );
	// bitBlt(...,x,y,width,height)
	bitBlt( tmp, 0, 0, pix, xO1, yO1, w1, h3 );
	tile->setPixmap( TileTopLeft, tmp );
	tmp = new QPixmap( w2, h3 );
	bitBlt( tmp, 0, 0, pix, xO2, yO1, w2, h3 );
	tile->setPixmap( TileTop, tmp );
	tmp = new QPixmap( w3, h3 );
	bitBlt( tmp, 0, 0, pix, xO3, yO1, w3, h3 );
	tile->setPixmap( TileTopRight, tmp );

	// Middle tiles
	tmp = new QPixmap( w1, h2 );
	bitBlt( tmp, 0, 0, pix, xO1, yO2 + h3 - h1, w1, h2 );
	tile->setPixmap( TileLeft, tmp );
	tmp = new QPixmap( w2, h2 );
	bitBlt( tmp, 0, 0, pix, xO2, yO2 + h3 - h1, w2, h2 );
	tile->setPixmap( TileMiddle, tmp );
	tmp = new QPixmap( w3, h2 );
	bitBlt( tmp, 0, 0, pix, xO3, yO2 + h3 - h1, w3, h2 );
	tile->setPixmap( TileRight, tmp );

	// Bottom tiles
	tmp = new QPixmap( w1, h1 );
	bitBlt( tmp, 0, 0, pix, xO1, yO3 + h3 - h1, w1, h1 );
	tile->setPixmap( TileBtmLeft, tmp );
	tmp = new QPixmap( w2, h1 );
	bitBlt( tmp, 0, 0, pix, xO2, yO3 + h3 - h1, w2, h1 );
	tile->setPixmap( TileBtm, tmp );
	tmp = new QPixmap( w3, h1 );
	bitBlt( tmp, 0, 0, pix, xO3, yO3 + h3 - h1, w3, h1 );
	tile->setPixmap( TileBtmRight, tmp );

	if ( !isPlain() || forceAlpha ) {
	    tmpMask = new QBitmap( w1, h3 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO1, yO1, w1, h3 );
	    tile->pixmap( TileTopLeft ) ->setMask( *tmpMask );
	    delete tmpMask;
	    tmpMask = new QBitmap( w2, h3 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO2, yO1, w2, h3 );
	    tile->pixmap( TileTop ) ->setMask( *tmpMask );
	    delete tmpMask;
	    tmpMask = new QBitmap( w3, h3 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO3, yO1, w3, h3 );
	    tile->pixmap( TileTopRight ) ->setMask( *tmpMask );
	    delete tmpMask;
	    
	    tmpMask = new QBitmap( w1, h2 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO1, yO2 + h3 - h1, w1, h2 );
	    tile->pixmap( TileLeft ) ->setMask( *tmpMask );
	    delete tmpMask;
	    tmpMask = new QBitmap( w2, h2 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO2, yO2 + h3 - h1, w2, h2 );
	    tile->pixmap( TileMiddle ) ->setMask( *tmpMask );
	    delete tmpMask;
	    tmpMask = new QBitmap( w3, h2 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO3, yO2 + h3 - h1, w3, h2 );
	    tile->pixmap( TileRight ) ->setMask( *tmpMask );
	    delete tmpMask;

	    tmpMask = new QBitmap( w1, h1 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO1, yO3 + h3 - h1, w1, h1 );
	    tile->pixmap( TileBtmLeft ) ->setMask( *tmpMask );
	    delete tmpMask;
	    tmpMask = new QBitmap( w2, h1 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO2, yO3 + h3 - h1, w2, h1 );
	    tile->pixmap( TileBtm ) ->setMask( *tmpMask );
	    delete tmpMask;
	    tmpMask = new QBitmap( w3, h1 );
	    bitBlt( tmpMask, 0, 0, pix->mask(), xO3, yO3 + h3 - h1, w3, h1 );
	    tile->pixmap( TileBtmRight ) ->setMask( *tmpMask );
	    delete tmpMask;
	}
    }
    return ( tile );
}

void LiquidStyle::drawClearBevel( QPainter *p, 
				  int x, int y, int w, int h, 
				  const QColor &c, const QColor &obg ) const
{
    QColor bg = optionHandler->BrushMe() ? optionHandler->brushedMetalColor : obg;
    LiquidStyle * ptr = const_cast<LiquidStyle*>( this );
    QPen oldPen = p->pen(); // headers need this
    int x2 = x + w - 1;
    int y2 = y + h - 1;

    // outer dark rect
    p->setPen( c.dark( 115 ) );
    p->drawLine( x + 2, y, x2 - 2, y ); // t
    p->drawLine( x, y + 2, x, y2 - 2 ); // l
    p->drawPoint( x + 1, y + 1 ); // tl
    p->setPen( c.dark( 150 ) );
    p->drawLine( x + 2, y2, x2 - 2, y2 ); // b
    p->drawLine( x2, y + 2, x2, y2 - 2 ); // r
    p->drawPoint( x2 - 1, y2 - 1 ); // br
    p->setPen( c.dark( 132 ) );
    p->drawPoint( x2 - 1, y + 1 ); // tr
    p->drawPoint( x + 1, y2 - 1 ); // bl

    // inner top light lines
    p->setPen( c.light( 105 ) );
    p->drawLine( x + 2, y + 1, x2 - 2, y + 1 );
    p->drawLine( x + 1, y + 2, x2 - 1, y + 2 );
    p->drawLine( x + 1, y + 3, x + 2, y + 3 );
    p->drawLine( x2 - 2, y + 3, x2 - 1, y + 3 );
    p->drawPoint( x + 1, y + 4 );
    p->drawPoint( x2 - 1, y + 4 );

    // inner bottom light lines
    p->setPen( c.light( 110 ) );
    p->drawLine( x + 2, y2 - 1, x2 - 2, y2 - 1 );
    p->drawLine( x + 1, y2 - 2, x2 - 1, y2 - 2 );
    p->drawLine( x + 1, y2 - 3, x + 2, y2 - 3 );
    p->drawLine( x2 - 2, y2 - 3, x2 - 1, y2 - 3 );
    p->drawPoint( x + 1, y2 - 4 );
    p->drawPoint( x2 - 1, y2 - 4 );

    // inner left mid lines
    //p->setPen(c.light(105));
    p->setPen( c );
    p->drawLine( x + 1, y + 5, x + 1, y2 - 5 );
    p->drawLine( x + 2, y + 4, x + 2, y2 - 4 );

    // inner right mid lines
    p->drawLine( x2 - 1, y + 5, x2 - 1, y2 - 5 );
    p->drawLine( x2 - 2, y + 4, x2 - 2, y2 - 4 );
    
    // fill
    QPixmap *pix;
    if ( h >= 32 ) {
    	pix = bevelFillDict.find( c.rgb() );
	if ( !pix ) {
	    pix = new QPixmap( *bevelFillPix );
	    adjustHSV( *pix, c );
	    ptr->bevelFillDict.insert( c.rgb(), pix );
	}
    }
    else {
	pix = smallBevelFillDict.find( c.rgb() );
	if ( !pix ) {
	    pix = new QPixmap( *smallBevelFillPix );
	    adjustHSV( *pix, c );
	    ptr->smallBevelFillDict.insert( c.rgb(), pix );
	}
    }
    p->drawTiledPixmap( x + 3, y + 3, w - 6, h - 6, *pix );
    // blend
    int red, green, blue;
    QColor btnColor( c.dark( 130 ) );
    red = ( btnColor.red() >> 1 ) + ( bg.red() >> 1 );
    green = ( btnColor.green() >> 1 ) + ( bg.green() >> 1 );
    blue = ( btnColor.blue() >> 1 ) + ( bg.blue() >> 1 );
    btnColor.setRgb( red, green, blue );

    p->setPen( btnColor );
    p->drawPoint( x + 1, y );
    p->drawPoint( x, y + 1 );
    p->drawPoint( x + 1, y2 );
    p->drawPoint( x, y2 - 1 );

    p->drawPoint( x2 - 1, y );
    p->drawPoint( x2, y + 1 );
    p->drawPoint( x2 - 1, y2 );
    p->drawPoint( x2, y2 - 1 );

    p->setPen( oldPen );
}

void LiquidStyle::drawRoundButton( QPainter *painter, 
				   const QColorGroup &cg, 
				   const QColor &c, 
				   const QColor &oback, 
				   int x, int y, int w, int h, 
				   bool supportPushDown, 
				   bool pushedDown, bool hover, 
				   bool autoDefault, bool isHTML, 
				   int bgX, int bgY ) const
{
    QColor back = optionHandler->BrushMe() ? optionHandler->brushedMetalColor : oback;

    if ( ( w < 21 || h < 25 )/* && !autoDefault*/ ) {
        drawCombo( painter, cg, c, x, y, w, h+2, pushedDown, hover, false, center );
	QPen oldpen(painter->pen());
        painter->setPen( c.dark(150));
	painter->drawRect(x,y,w,h);
        if (pushedDown) {
    	    painter->setPen(c.dark(180));
	    painter->drawRect(x+1,y+1,w-2,h-2);
	}
	painter->setPen(oldpen);
	return ;
    }
    LiquidStyle *ptr = const_cast<LiquidStyle*>( this );
    ButtonTile *tile = pushedDown ? btnDict.find( c.rgb() ) : btnShadowedDict.find( c.rgb() );

    if ( !tile )
	tile = createButtonTile( c, cg.background(), ptr->btnBorderImg, ptr->btnShadowImg, ptr->buttonGlow, &(ptr->btnDict), &(ptr->btnShadowedDict), &(ptr->buttonGlowDict), 37, 21, 12, 11, 17, 1, 2, 2, pushedDown, hover );

    if ( !tile ) {
	qWarning( "Button tile is NULL!" );
	return ;
    }
    if ( !tmpBtnPix )
	ptr->tmpBtnPix = new QPixmap( w, h );
    else if ( w > tmpBtnPix->width() || h > tmpBtnPix->height() ) {
	// make temp pixmap size == largest button
	delete tmpBtnPix;
	ptr->tmpBtnPix = new QPixmap( w, h );
    }

    QPainter p;
    p.begin( tmpBtnPix );
    
    QPixmap *stipple = cg.brush( QColorGroup::Background ).pixmap();
    stipple ? p.drawTiledPixmap( 0, 0, w, h, *stipple, bgX, bgY ) : p.fillRect(0,0,w,h,cg.brush( QColorGroup::Background ));
    
    if ( !pushedDown ) {
	// corners
	// tiled fills
	if ( w > 22 ) {
    	    p.drawTiledPixmap( 12, 0, w - 24, 11, *tile->pixmap( TileTop ) );
	    p.drawTiledPixmap( 12, h - 13, w - 24, 13, *tile->pixmap( TileBtm ) );
	}
	if ( h > 24 ) {
	    p.drawTiledPixmap( 0, 11, 12, h - 24, *tile->pixmap( TileLeft ) );
	    p.drawTiledPixmap( w - 12, 11, 12, h - 24, *tile->pixmap( TileRight ) );
	}
	if ( w > 22 && h > 24 )
	    p.drawTiledPixmap( 12, 11, w - 24, h - 24, *tile->pixmap( TileMiddle ) );
	    
	p.drawPixmap( 0, 0, *tile->pixmap( TileTopLeft ) );
	p.drawPixmap( w - 12, 0, *tile->pixmap( TileTopRight ) );
	p.drawPixmap( 0, h - 13, *tile->pixmap( TileBtmLeft ) );
	p.drawPixmap( w - 12, h - 13, *tile->pixmap( TileBtmRight ) );
    }
    else {
	if ( w > 22 ) {
	    p.drawTiledPixmap( 12, 0, w - 24, 13, *tile->pixmap( TileTop ) );
	    p.drawTiledPixmap( 12, h - 11, w - 24, 13-2, *tile->pixmap( TileBtm ) );
	}
	if ( h > 24 ) {
	    p.drawTiledPixmap( 0, 13, 12, h - 24, *tile->pixmap( TileLeft ) );
	    p.drawTiledPixmap( w - 12, 13, 12, h - 24, *tile->pixmap( TileRight ) );
	}
	if ( w > 22 && h > 24 )
	    p.drawTiledPixmap( 12, 13, w - 24, h - 24, *tile->pixmap( TileMiddle ) );
	    
	p.drawPixmap( 0, 0, *tile->pixmap( TileTopLeft ) );
	p.drawPixmap( w - 12, 0, *tile->pixmap( TileTopRight ) );
	p.drawTiledPixmap( 0, h - 11,12,13-2, *tile->pixmap( TileBtmLeft ) );
	p.drawTiledPixmap( w - 12, h - 11,12,13-2, *tile->pixmap( TileBtmRight ) );
    }
    p.end();
    painter->drawPixmap( x, y, *tmpBtnPix, 0, 0, w, h );
}


void LiquidStyle::drawRectangularButton( QPainter *painter, 
					 const QColorGroup &cg, const QColor &c,
					 int x, int y, int w, int h, 
					 bool sunken, bool hover, bool isCombo, int position, bool isHtml) const
{
    LiquidStyle *ptr = const_cast<LiquidStyle*>( this );

    QColor bgColor = optionHandler->BrushMe() ? optionHandler->brushedMetalColor : cg.background();
    QColor tmpColor;
    tmpColor = isCombo && !(hover || sunken) ? optionHandler->InactiveButtonColor() : c;

    int xOffset, width;
    int r = x + w; // warning: != Qrect.right(), but Qrect.right() + 1!!!
    int bottom = y + h;

    if (position == left) {
	xOffset = x+10;
	width = w - 10;
    }
    else if (position == center) {
	xOffset = x;
	width = w;
    }
    else if (position == right) {
	xOffset = x;
	width = w - 10;
    }
    else if (position == full) {
	xOffset = x + 10;
	width = w - 20;
    }

    ButtonTile *tile = rectBtnDict.find( tmpColor.rgb() );
    if ( !tile )
	tile = createButtonTile( tmpColor, bgColor, ptr->rectbutton, ((QImage*)NULL), ((QImage*)NULL), &(ptr->rectBtnDict), (QIntDict<ButtonTile>*)NULL, (QIntDict<ButtonTile>*)NULL, 33, 25, 10, 5, 13, 15, 0, 0, sunken, false);

    if ( !tile ) {
	qWarning( "Button tile is NULL!" );
	return ;
    }
   
   if (!(isHtml || position == center )){
 	painter->fillRect( 0, 0, w, h, bgColor );
   }

    int tileH = 0;
    QPixmap tmpPix(10, 1);
    
    bool split = isCombo && !(hover || sunken);
    if ( split ) { // unsunken or unhovered combos a splitted
	// corners
	// tiled fills
	if ( w > 20 ) {
    	    painter->drawTiledPixmap( xOffset, y, width, 5, *tile->pixmap( TileTop ) );
	    painter->drawTiledPixmap( xOffset, bottom - 5, width, 5, *tile->pixmap( TileBtm ) );
	}
	QPixmap tmpPix(10, 1);
	if ( h > 10 ) {
	    tileH = (int)((h-25)/2);
	    if (position == left || position == full){
			if (h > 20){
				painter->drawPixmap(x, y+5+tileH, *tile->pixmap( TileLeft ));
				bitBlt( &tmpPix, 0, 0, tile->pixmap(TileLeft), 0, 0, 10, 1 );
				painter->drawTiledPixmap(x,y+5,10,tileH,tmpPix);
				bitBlt( &tmpPix, 0, 0, tile->pixmap(TileLeft), 0, 14, 10, 1 );
				painter->drawTiledPixmap(x,y+5+tileH+15,10,h-25-tileH,tmpPix);
			}
			else
				painter->drawPixmap( x, y+5, *tile->pixmap( TileLeft ),0,-tileH,10,15+2*tileH+1 /*tileH is negative in this case*/ );
		}
	}
	if ( w > 20 && h > 10 )
		if (h > 25){
			painter->drawTiledPixmap(xOffset, y+5+tileH, width, 15, *tile->pixmap(TileMiddle));
			bitBlt( &tmpPix, 0, 0, tile->pixmap(TileMiddle), 0, 0, 10, 1 );
			painter->drawTiledPixmap(xOffset,y+5,width,tileH,tmpPix);
			bitBlt( &tmpPix, 0, 0, tile->pixmap(TileMiddle), 0, 14, 10, 1 );
			painter->drawTiledPixmap(xOffset,y+5+tileH+15,width,h-25-tileH,tmpPix);
		}
		else
			painter->drawTiledPixmap( xOffset, y+5, width, h-10, *tile->pixmap(TileMiddle),0,-tileH /*tileH is negative in this case*/);
	
	if (position == left || position == full) {
	    painter->drawPixmap( x, y, *tile->pixmap( TileTopLeft ) );
    	    painter->drawPixmap( x, bottom - 5, *tile->pixmap( TileBtmLeft ) );
	}
	    
	    
    }
    else { // for sunken or hovered we have just one color - one button
	if ( w > 20 ) {
    	    painter->drawTiledPixmap( xOffset, y, width, 5, *tile->pixmap( TileTop ) );
	    painter->drawTiledPixmap( xOffset, bottom - 5, width, 5, *tile->pixmap( TileBtm ) );
	}
	if ( h > 10 ) {
	    tileH = (int)((h-25)/2);
	    if (position == left || position == full){
			if (h > 25){
				painter->drawPixmap(x, y+5+tileH, *tile->pixmap( TileLeft ));
				bitBlt( &tmpPix, 0, 0, tile->pixmap(TileLeft), 0, 0, 10, 1 );
				painter->drawTiledPixmap(x,y+5,10,tileH,tmpPix);
				bitBlt( &tmpPix, 0, 0, tile->pixmap(TileLeft), 0, 14, 10, 1 );
				painter->drawTiledPixmap(x,y+5+tileH+15,10,h-25-tileH,tmpPix);
			}
			else
				painter->drawPixmap( x, y+5, *tile->pixmap( TileLeft ),0,-tileH,10,15+2*tileH+1 /*tileH is negative in this case*/ );
		}
	    if (position == right || position == full){
			if (h > 25){
				painter->drawPixmap(r-10, y+5+tileH, *tile->pixmap( TileRight ));
				bitBlt( &tmpPix, 0, 0, tile->pixmap(TileRight), 0, 0, 10, 1 );
				painter->drawTiledPixmap(r-10,y+5,10,tileH,tmpPix);
				bitBlt( &tmpPix, 0, 0, tile->pixmap(TileRight), 0, 14, 10, 1 );
				painter->drawTiledPixmap(r-10,y+5+tileH+15,10,h-25-tileH,tmpPix);
			}
			else
				painter->drawPixmap( r-10, y+5, *tile->pixmap(TileRight),0,-tileH,10,15+2*tileH+1 /*tileH is negative in this case*/ );
		}
	}
	if ( w > 20 && h > 10 )
		if (h > 25){
			painter->drawTiledPixmap(xOffset, y+5+tileH, width, 15, *tile->pixmap(TileMiddle));
			bitBlt( &tmpPix, 0, 0, tile->pixmap(TileMiddle), 0, 0, 10, 1 );
			painter->drawTiledPixmap(xOffset,y+5,width,tileH,tmpPix);
			bitBlt( &tmpPix, 0, 0, tile->pixmap(TileMiddle), 0, 14, 10, 1 );
			painter->drawTiledPixmap(xOffset,y+5+tileH+15,width,h-25-tileH,tmpPix);
		}
		else
			painter->drawTiledPixmap( xOffset, y+5, width, h-10, *tile->pixmap(TileMiddle),0,-tileH /*tileH is negative in this case*/);
	
	if (position == left || position == full) {
	    painter->drawPixmap( x, y, *tile->pixmap( TileTopLeft ) );
    	    painter->drawPixmap( x, bottom - 5, *tile->pixmap( TileBtmLeft ) );
	}
	if (position == right || position == full) {
	    painter->drawPixmap( r - 10, y, *tile->pixmap( TileTopRight ) );
	    painter->drawPixmap( r - 10, bottom - 5, *tile->pixmap( TileBtmRight ) );
	}

    }

    if (position == center){
	painter->setPen(c.dark(130));
	if (sunken || hover) painter->drawLine(x,y+1,x,bottom-2);
	painter->drawLine(r-1,y+2,r-1,bottom-2);
    }
     else if (position == left){
 	painter->setPen(c.dark(130));
 	painter->drawLine(r-1,y+2,r-1,bottom-2);
     }
   else if (position == right && (sunken || hover)){
	painter->setPen(c.dark(130));
	painter->drawLine(x,y+2,x,bottom-2);
   }
    

    if (split) { // second part of combos if needed
	tile = rectBtnDict.find( c.rgb() );
	if ( !tile )
	    tile = createButtonTile( c, bgColor, ptr->rectbutton, ((QImage*)NULL), ((QImage*)NULL), &(ptr->rectBtnDict), (QIntDict<ButtonTile>*)NULL, (QIntDict<ButtonTile>*)NULL, 33, 25, 10, 5, 13, 15, 0, 0, sunken, hover );
	if ( !tile ) {
    	    qWarning( "Button tile is NULL!" );
	    return ;
	}
	// corners
	// tiled fills
	if ( w > 20 ) {
	    painter->drawTiledPixmap( r-24, y, (position == center || position == left) ? 24 : 14, 5, *tile->pixmap( TileTop ) );
	    painter->drawTiledPixmap( r-24, bottom - 5, (position == center || position == left) ? 24 : 14, 5, *tile->pixmap( TileBtm ) );
	}
	if ( h > 10 ) {
	    if (position == right || position == full){
			if (h > 25){
				painter->drawPixmap(r-10, y+5+tileH, *tile->pixmap( TileRight ));
				bitBlt( &tmpPix, 0, 0, tile->pixmap(TileRight), 0, 0, 10, 1 );
				painter->drawTiledPixmap(r-10,y+5,10,tileH,tmpPix);
				bitBlt( &tmpPix, 0, 0, tile->pixmap(TileRight), 0, 14, 10, 1 );
				painter->drawTiledPixmap(r-10,y+5+tileH+15,10,h-25-tileH,tmpPix);
			}
			else
				painter->drawPixmap( r-10, y+5, *tile->pixmap(TileRight),0,-tileH,10,15+2*tileH+1 /*tileH is negative in this case*/ );
		}
	}
	if ( w > 20 && h > 10 ){
		if (h > 25){
			painter->drawTiledPixmap(r-24, y+5+tileH, (position == center || position == left) ? 24 : 14, 15, *tile->pixmap(TileMiddle));
			bitBlt( &tmpPix, 0, 0, tile->pixmap(TileMiddle), 0, 0, 10, 1 );
			painter->drawTiledPixmap(r-24,y+5,(position == center || position == left) ? 24 : 14,tileH,tmpPix);
			bitBlt( &tmpPix, 0, 0, tile->pixmap(TileMiddle), 0, 14, 10, 1 );
			painter->drawTiledPixmap(r-24,y+5+tileH+15,(position == center || position == left) ? 24 : 14,h-25-tileH,tmpPix);
		}
		else
			painter->drawTiledPixmap( r-24, y+5, (position == center || position == left) ? 24 : 14, h-10, *tile->pixmap(TileMiddle),0,-tileH /*tileH is negative in this case*/);
	}
	if (position == right || position == full) {
	    painter->drawPixmap( r - 10, y, *tile->pixmap( TileTopRight ) );
	    painter->drawPixmap( r - 10, bottom - 5, *tile->pixmap( TileBtmRight ) );
        }
    }

    if (isCombo) {
	painter->setPen(c);
	painter->drawLine(r-24,y+2,r-24,bottom-2);

	SFlags flags = Style_Default;
	int ax = r - 15;
	int ay = h/3 - 1;

	painter->setPen(cg.text());
	painter->setBrush( cg.text() );
	painter->drawPixmap(ax, ay-1, *sbUp, 1, 0, 5, 4);
	painter->drawPixmap(ax, ay+6, *sbDown, 1, 2, 5, 4);
    }
}


void LiquidStyle::drawCombo( QPainter *painter, 
			    const QColorGroup &cg, 
			    const QColor &c, 
			    int x, int y, int w, int h, 
			    bool sunken, bool hover, bool isCombo, 
			    int position ) const
{

    LiquidStyle *ptr = const_cast<LiquidStyle*>( this );

    QColor bgColor = cg.background();
    QColor tmpColor;
    tmpColor = isCombo && !(hover || sunken) ? optionHandler->InactiveButtonColor() : c;

    int xOffset, width;
    int r = x + w; // warining: != Qrect.right(), but Qrect.right() + 1!!!
    int bottom = y + h;

    if (position == left) {
	xOffset = x+7;
	width = w - 7;
    }
    else if (position == center) {
	xOffset = x;
	width = w;
    }
    else if (position == right) {
	xOffset = x;
	width = w - 7;
    }
    else if (position == full) {
	xOffset = x+7;
	width = w - 14;
    }

    ButtonTile *tile = sunken ? comboDict.find( tmpColor.rgb() ) : comboShadowedDict.find( tmpColor.rgb() );
    if ( !tile )
	tile = createButtonTile( tmpColor, bgColor, ptr->combo, ptr->comboShadow, ((QImage*)NULL), &(ptr->comboDict), &(ptr->comboShadowedDict), (QIntDict<ButtonTile>*)NULL, 44, 21, 7, 9, 30, 1, 2, 0, sunken, false);

    if ( !tile ) {
	qWarning( "Button tile is NULL!" );
	return ;
    }
//     if ( !tmpBtnPix )
// 	ptr->tmpBtnPix = new QPixmap( w, h );
//     else if ( w > tmpBtnPix->width() || h > tmpBtnPix->height() ) {
// 	// make temp pixmap size == largest button
// 	delete tmpBtnPix;
// 	ptr->tmpBtnPix = new QPixmap( w, h );
//     }

//    QPainter p;
//    p.begin( tmpBtnPix );

//    QPixmap *stipple = cg.brush( QColorGroup::Background ).pixmap();
//    if ( !stipple )  // button may have custom colorgroup
//    	stipple = qApp->palette().active().brush( QColorGroup::Background ).pixmap();
//     if ( !isPlain()/* && bgX != -1 && bgY != -1 */&& stipple )
//  	painter->drawTiledPixmap( 0, 0, w, h, *stipple/*, bgX, bgY */);
//     else
//  	painter->fillRect( 0, 0, w, h, bgColor );

    if ( !sunken ) { // unsunken or unhovered combos a splitted
	// corners
	// tiled fills
	if ( w > 14 ) {
	    painter->drawTiledPixmap( xOffset, y, width, 9, *tile->pixmap( TileTop ) );
	    painter->drawTiledPixmap( xOffset, bottom - 13, width, 13, *tile->pixmap( TileBtm ) );
	}
	if ( h > 22 ) {
	    if (position == left || position == full)
		painter->drawTiledPixmap( x, y+9, 7, h - 22, *tile->pixmap( TileLeft ) );
	    if ((!isCombo || hover) && (position == right || position == full))
		painter->drawTiledPixmap( r - 7, y+9, 7, bottom - 22, *tile->pixmap( TileRight ) );
	}
	if ( w > 14 && h > 22 )
	    painter->drawTiledPixmap( xOffset, y+9, width, h - 22, *tile->pixmap( TileMiddle ) );
	if (position == left || position == full){
	    painter->drawPixmap( x, y, *tile->pixmap( TileTopLeft ) );
	    painter->drawPixmap( x, bottom - 13, *tile->pixmap( TileBtmLeft ) );
	}
	if ((!isCombo || hover) && (position == right || position == full)){
	    painter->drawPixmap( r - 7, y, *tile->pixmap( TileTopRight ) );
	    painter->drawPixmap( r - 7, bottom - 13, *tile->pixmap( TileBtmRight ) );
	}
	    
	    
    }
    else { // for sunken or hovered we have just one color - one button
	if ( w > 14 ) {
    	    painter->drawTiledPixmap( xOffset, y, width, 13, *tile->pixmap( TileTop ) );
	    painter->drawTiledPixmap( xOffset, bottom - 9, width, 11, *tile->pixmap( TileBtm ) );
	}
	if ( h > 22 ) {
	    if (position == left || position == full)
		painter->drawTiledPixmap( x, y+13, 7, h - 22, *tile->pixmap( TileLeft ) );
	    //if (!isCombo)
	    if (position == right || position == full)
		painter->drawTiledPixmap( r - 7, y+13, 7, h - 22, *tile->pixmap( TileRight ) );
	}
	if ( w > 14 && h > 22 )
    	    painter->drawTiledPixmap( xOffset, y+13, width, h - 22, *tile->pixmap( TileMiddle ) );
	if (position == left || position == full) {
	    painter->drawPixmap( x, y, *tile->pixmap( TileTopLeft ) );
    	    painter->drawPixmap( x, bottom - 9, *tile->pixmap( TileBtmLeft ) );
	}
	if (position == right || position == full) {
	    painter->drawPixmap( r - 7, y, *tile->pixmap( TileTopRight ) );
	    painter->drawPixmap( r - 7, bottom - 9, *tile->pixmap( TileBtmRight ) );
	}

    }

    if (position == center){
	painter->setPen(optionHandler->InactiveButtonColor().dark(130));
	if (sunken || hover) painter->drawLine(x,y+1,x,bottom-2);
	painter->drawLine(r-1,y+1,r-1,bottom-2);
    }
     else if (position == left){
 	painter->setPen(optionHandler->InactiveButtonColor().dark(130));
 	painter->drawLine(r-1,y+1,r-1,bottom-2);
     }
   else if (position == right && (sunken || hover)){
	painter->setPen(optionHandler->InactiveButtonColor().dark(130));
	painter->drawLine(x,y+1,x,bottom-2);
   }
    

    if (isCombo && !(hover || sunken)) { // second part of combos if needed
	tile = comboShadowedDict.find( c.rgb() );
	if ( !tile )
	    tile = createButtonTile( c, bgColor, ptr->combo, ptr->comboShadow, (QImage*)NULL, &(ptr->comboDict), &(ptr->comboShadowedDict), (QIntDict<ButtonTile>*)NULL, 44, 21, 7, 9, 30, 1, 2,0, sunken, hover );
	if ( !tile ) {
    	    qWarning( "Button tile is NULL!" );
	    return ;
	}
	// corners
	// tiled fills
	if ( w > 14 ) {
	    painter->drawTiledPixmap( r-24, y, (position == center || position == left) ? 24 : 17, 9, *tile->pixmap( TileTop ) );
	    painter->drawTiledPixmap( r-24, bottom - 13, (position == center || position == left) ? 24 : 17, 13, *tile->pixmap( TileBtm ) );
	}
	if ( h > 22 )
	    painter->drawTiledPixmap( r - 7, y+9, 7, h - 22, *tile->pixmap( TileRight ) );
	if ( w > 14 && h > 22 )
	    painter->drawTiledPixmap( r-24, y+9, (position == center || position == left) ? 24 : 17, h - 22, *tile->pixmap( TileMiddle ) );
	if (position == right || position == full) {
		painter->drawPixmap( r - 7, y, *tile->pixmap( TileTopRight ) );
		painter->drawPixmap( r - 7, bottom - 13, *tile->pixmap( TileBtmRight ) );
	}
    }

    if (isCombo) {
	painter->setPen(c);
	painter->drawLine(r-24,y+1,r-24,bottom-4);

	SFlags flags = Style_Default;
	int ax = r - 15;
	int ay = h/3 - 1;

	painter->setPen(cg.text());
	painter->setBrush( cg.text() );
	painter->drawPixmap(ax, ay-1, *sbUp, 1, 0, 5, 4);
	painter->drawPixmap(ax, ay+6, *sbDown, 1, 2, 5, 4);
    }
}

void LiquidStyle::drawRoundFrame( QPainter *p, const QRect &r,
                                 const QColorGroup &cg, bool focused, QPoint offset ) const
{
    ButtonTile *tile = focused ? activeRoundFrame : inactiveRoundFrame;
    if (!tile) tile = createRoundFrameTile(*roundFrame, focused ? cg.button() : optionHandler->InactiveButtonColor(), &cg.background(), cg.base() );
    
    // first: fill background (tiled)
    // outer
    QPixmap *stipple = cg.brush( QColorGroup::Background ).pixmap();
    if (stipple){
        p->drawTiledPixmap( r.x(),r.y(), 7, 8, *stipple, offset.x(), offset.y());
        p->drawTiledPixmap( r.right() - 7, r.y(), 8, 8, *stipple, offset.x()+r.width()-6, offset.y());
        p->drawTiledPixmap( r.x(), r.bottom()-7, 8, 8, *stipple, offset.x(), offset.y() + r.height()-6);
        p->drawTiledPixmap( r.right() - 7, r.bottom()-7, 8, 8, *stipple, offset.x() + r.width() - 6, offset.y() + r.height()-6);
    }
    else{
        p->fillRect(r.x(),r.y(), 7, 8, optionHandler->BrushMe() ? optionHandler->brushedMetalColor : cg.background());
        p->fillRect(r.right() - 7, r.y(), 8, 8, optionHandler->BrushMe() ? optionHandler->brushedMetalColor : cg.background());
        p->fillRect(r.x(), r.bottom()-7, 8, 8, optionHandler->BrushMe() ? optionHandler->brushedMetalColor : cg.background());
        p->fillRect(r.right() - 7, r.bottom()-7, 8, 8, optionHandler->BrushMe() ? optionHandler->brushedMetalColor : cg.background());
    }
    // inner
    p->fillRect(r.x()+3,r.y()+4,r.width()-6,r.height()-7,cg.base());
    
    
    // now draw frame
    p->drawPixmap(0,0, *tile->pixmap( TileTopLeft ));
    p->drawPixmap(r.right()-10,0, *tile->pixmap( TileTopRight ));
    p->drawPixmap(0,r.bottom()-10, *tile->pixmap( TileBtmLeft ));
    p->drawPixmap(r.right()-10,r.bottom()-10, *tile->pixmap( TileBtmRight ));
    if (r.width() > 22){
        p->drawTiledPixmap(11,0,r.width()-22,10, *tile->pixmap( TileTop ));
        p->drawTiledPixmap(11,r.bottom()-10,r.width()-22,11, *tile->pixmap( TileBtm ));
    }
    if (r.height() > 21){
        p->drawTiledPixmap(0,10,11,r.height()-21, *tile->pixmap( TileLeft ));
        p->drawTiledPixmap(r.right()-10,10,11,r.height()-21, *tile->pixmap( TileRight ));
    }
    if (focused){
        p->setPen(cg.button());
        p->drawLine(r.x()+8,r.bottom()-1,r.right()-8,r.bottom()-1);
    }
}

void LiquidStyle::drawEditFrame( QPainter *p, const QRect &r,
                                 const QColorGroup &cg, bool isHTML, bool focused, bool inverse/*, bool round*/ ) const
{
    QColor fill( cg.background().dark( 105 ) );
    QColor tmp(0,0,0);
    QColor light1( 0, 0, 0 );
    QColor light2( 0, 0, 0 );

    QColor dark1( 0, 0, 0 );
    QColor dark2( 0, 0, 0 );
    QColor dark3( 0, 0, 0 );

    if ( !focused ) {
	light1 = cg.background().dark( 115 );
	light2 = cg.background().dark( 120 );

	dark1 = cg.background().dark( 140 );
	dark2 = cg.background().dark( 160 );
	dark3 = cg.background().dark( 200 );
    } 
    else {
    	int h,s,v;
	cg.button().getHsv( &h, &s, &v );
    	tmp.setHsv(h, (int)(s/1.5) ,v);
	light1 = tmp;
	light2 = tmp.light( 120 );
	
	dark1 = tmp.dark( 110 );
	dark2 = tmp.dark( 120 );
	dark3 = tmp.dark( 140 );
    }
    
    int x = r.x();
    int y = inverse ? r.bottom() - 1: r.y();
    int right = r.right();
    int bottom = inverse ? r.y() + 1 : r.bottom();


    if ( !isHTML ) {
	p->setPen( fill );
	p->drawPoint( x, y );
	p->drawPoint( x, bottom );
	p->drawPoint( right, y );
	p->drawPoint( right, bottom );

	// outer rect
	// top
	p->setPen( light1 );
	p->drawPoint( x + 1, y );
	p->drawPoint( right - 1, y );
	p->drawPoint( x, y + 1 );
	p->drawPoint( right, y + 1 );
	// bottom
	p->drawPoint( x, bottom - 1 );
	p->drawPoint( right, bottom - 1 );
	p->drawPoint( x + 1, bottom );
	p->drawPoint( right - 1, bottom );
	// top
	focused ? p->setPen( light2 ) : p->setPen( dark3 );
	p->drawLine( x + 2, y, right - 2, y );
	// bottom, left and right
	if (!focused) p->setPen( cg.background() );
        p->drawLine( x + 2, bottom, right - 2, bottom );
        p->drawLine( x, y + 2, x, bottom - 2 );
        p->drawLine( right, y + 2, right, bottom - 2 );
    } 
    else {
        p->setPen( light2 );
        p->drawLine( x, y, right, y );
        p->drawLine( x, y, x, bottom );
        p->setPen( dark1 );
        p->drawLine( x, bottom, right, bottom );
        p->drawLine( right, y, right, bottom );
    }
    // inner rect
    p->setPen( dark1 );
    p->drawPoint( x + 1, y + 1 );
    p->drawPoint( x + 1, bottom - 1 );
    p->drawPoint( right - 1, y + 1 );
    p->drawPoint( right - 1, bottom - 1 );
    p->setPen( dark2 );
    p->drawLine( x + 2, y + 1, right - 2, y + 1 );
    p->setPen( dark2 );
    p->drawLine( x + 2, bottom - 1, right - 2, bottom - 1 );
    p->drawLine( x + 1, y + 2, x + 1, bottom - 2 );
    p->drawLine( right - 1, y + 2, right - 1, bottom - 2 );
//     }
}

bool LiquidStyle::isHTMLWidget( const QWidget *widget ) const
{
    const QObject * w = widget->parent();
    if ( w ) {
    	if ( !w->inherits( "QClipperWidget" ) )
    	    return ( false );
	w = w->parent();
	if ( w ) {
	    w = w->parent();
	    if ( w && w->inherits( "KHTMLView" ) )
		return ( true );
	}
    }
    return ( false );
}

void LiquidStyle::drawHTMLCBBorder( const QPixmap &pix, const QColor &c ) const
{
    QPainter p;
    p.begin( &pix );
    p.setPen( c.dark( 200 ) );
    p.drawRect( 0, 0, 16, 16 );
    p.end();
}
