/* Polyester widget style for KDE 4
   Copyright (C) 2006 Marco Martin <notmart@gmail.com>

   based on Plastik widget style for KDE 3
   Copyright (C) 2003 Sandro Giessl <ceebx@users.sourceforge.net>

   based on the KDE style "dotNET":

   Copyright (C) 2001-2002, Chris Lee <clee@kde.org>
                            Carsten Pfeiffer <pfeiffer@kde.org>
                            Karol Szwed <gallium@kde.org>
   Drawing routines completely reimplemented from KDE3 HighColor, which was
   originally based on some stuff from the KDE2 HighColor.

   based on drawing routines of the style "Keramik":

   Copyright (c) 2002 Malte Starostik <malte@kde.org>
             (c) 2002,2003 Maksim Orlovich <mo002j@mail.rochester.edu>
   based on the KDE3 HighColor Style
   Copyright (C) 2001-2002 Karol Szwed      <gallium@kde.org>
             (C) 2001-2002 Fredrik Höglund  <fredrik@kde.org>
   Drawing routines adapted from the KDE2 HCStyle,
   Copyright (C) 2000 Daniel M. Duley       <mosfet@kde.org>
             (C) 2000 Dirk Mueller          <mueller@kde.org>
             (C) 2001 Martijn Klingens      <klingens@kde.org>
   Progressbar code based on KStyle,
   Copyright (C) 2001-2002 Karol Szwed <gallium@kde.org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
 */



#include "polyester.h"
#include "moc_polyester.cpp"

#include <cmath>
#include <QDockWidget>


//bitmap for the slider handle
static const unsigned char slider_mask_bits[] = {
   0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe};


PolyesterStyle::PolyesterStyle() :
#ifdef NO_KDE
    QWindowsStyle(),
#else
    KStyle(),
#endif
    flatMode(false)
{

    horizontalDots = 0;
    verticalDots = 0;


    QSettings globalSettings;
    _contrast = globalSettings.value("/Qt/KDE/contrast", 6).toInt();

   QSettings settings("Polyester", "Style");
   settings.beginGroup("Style");
    _useLowerCaseText = settings.value("useLowerCaseText", false).toBool();
    _scrollBarLines = settings.value("scrollBarLines", false).toBool();
    _scrollBarStyle = settings.value("scrollBarStyle", "ThreeButtonScrollBar").toString();
    _scrollBarExtent = settings.value("scrollBarSize", 16).toInt();
    if(_scrollBarExtent < 8 || _scrollBarExtent > 48)
      _scrollBarExtent = 16;
    _animateProgressBar = settings.value("animateProgressBar", false).toBool();
    _animateButton = settings.value("animateButton", false).toBool();
    /*don't animate buttons in gtk-qt or openoffice, they aren't able to do so :-)*/
    if( ( qstrcmp( qApp->argv() [ 0 ], "unknown" ) == 0 ) ||
        ( qstrcmp( qApp->argv() [ 0 ], "soffice.bin" ) == 0 ))
        _animateButton = false;
    _animateButtonToDark = settings.value("animateButtonToDark", false).toBool();
    _buttonStyle = settings.value("buttonStyle", "glass").toString();
    _lightBorder= settings.value("lightBorder", true).toBool();
    _coloredScrollBar = settings.value("coloredScrollBar", true).toBool();
    _sunkenShadows = settings.value("sunkenShadows", true).toBool();
    _centeredTabBar = settings.value("centeredTabBar", false).toBool();
    _highLightTab = settings.value("highLightTab", true).toBool();
    _statusBarFrame = settings.value("statusBarFrame", true).toBool();
    _colorizeSortedHeader = settings.value("colorizeSortedHeader", true).toBool();
    _menuItemSpacing = settings.value("menuItemSpacing", 8).toInt();
    if( _menuItemSpacing > 12 || _menuItemSpacing < 0 )
      _menuItemSpacing = 8;
    _buttonMenuItem = settings.value("buttonMenuItem", true).toBool();
    _menuBarEmphasis = settings.value("menuBarEmphasis", false).toBool();
    _menuBarEmphasisBorder = settings.value("menuBarEmphasisBorder", true).toBool();
    if( _menuBarEmphasis )
        _customMenuBarEmphasisColor = settings.value("customMenuBarEmphasisColor", false).toBool();
    else
        _customMenuBarEmphasisColor = false;
    _menuBarEmphasisColor = settings.value("menuBarEmphasisColor", "black").toString();
    _menuStripe = settings.value("menuStripe", true).toBool();
    _shadowedMenuBarText = settings.value("shadowedMenuBarText", true).toBool();
    _shadowedButtonsText = settings.value("shadowedButtonsText", true).toBool();
    _drawToolBarSeparator = settings.value("drawToolBarSeparator", true).toBool();
    _drawToolBarItemSeparator = settings.value("drawToolBarItemSeparator", true).toBool();
    _drawFocusRect = settings.value("drawFocusRect", true).toBool();
    _drawTriangularExpander = settings.value("drawTriangularExpander", false).toBool();
    _inputFocusHighlight = settings.value("inputFocusHighlight", true).toBool();
    _customOverHighlightColor = settings.value("customOverHighlightColor", false).toBool();
    _overHighlightColor.setNamedColor( settings.value("overHighlightColor", "black").toString() );
    _customFocusHighlightColor = settings.value("customFocusHighlightColor", false).toBool();
    _focusHighlightColor.setNamedColor( settings.value("focusHighlightColor", "black").toString() );
    _customCheckMarkColor = settings.value("customCheckMarkColor", false).toBool();
    _checkMarkColor.setNamedColor( settings.value("checkMarkColor", "black").toString() );
    settings.endGroup();

    if( !_scrollBarStyle.compare( "ThreeButtonScrollBar" ) )
        _scrollBarType = ThreeButtonScrollBar;
    else if( !_scrollBarStyle.compare( "WindowsStyleScrollBar" ) )
        _scrollBarType = WindowsStyleScrollBar;
    else if( !_scrollBarStyle.compare( "PlatinumStyleScrollBar" ) )
        _scrollBarType = PlatinumStyleScrollBar;
    else if( !_scrollBarStyle.compare( "NextStyleScrollBar" ) )
        _scrollBarType = NextStyleScrollBar;
    else
       _scrollBarType = NoButtonsScrollBar;

    // setup pixmap cache...
   /* pixmapCache = new QIntCache<CacheEntry>(150000, 499);
    pixmapCache->setAutoDelete(true);*/
    // setup pixmap cache...
    pixmapCache = new QCache<int, CacheEntry>(327680);

#ifndef NO_KDE
    setWidgetLayoutProp(WT_MenuBar, MenuBar::ItemSpacing, 0);
    setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin,        0);
    setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin + Left,  0);
    setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin + Right, 0);
    setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin + Top, 0);
    setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin + Bot, 2);

    setWidgetLayoutProp(WT_MenuBarItem, MenuBarItem::Margin, 3);
    setWidgetLayoutProp(WT_MenuBarItem, MenuBarItem::Margin+Left, 8);
    setWidgetLayoutProp(WT_MenuBarItem, MenuBarItem::Margin+Right, 8);
    setWidgetLayoutProp(WT_MenuBarItem, MenuBarItem::Margin+Top, 0);
    setWidgetLayoutProp(WT_MenuBarItem, MenuBarItem::Margin+Bot, 0);
#endif

    //if ( _animateProgressBar )
    {
        animationTimer = new QTimer( this );
        connect( animationTimer, SIGNAL(timeout()), this, SLOT(updateProgressPos()) );
    }

    if ( _animateButton )
    {
        btnAnimTimer = new QTimer( this );
        connect( btnAnimTimer, SIGNAL(timeout()), this, SLOT(animate()) );
    }

}


void PolyesterStyle::updateProgressPos()
{
    QProgressBar* pb;
    //Update the registered progressbars.
    QMap<QWidget*, int>::iterator iter;
    bool visible = false;
    for (iter = progAnimWidgets.begin(); iter != progAnimWidgets.end(); iter++)
    {
        pb = dynamic_cast<QProgressBar*>(iter.key());

        if ( !pb )
         continue;

        if ( iter.key() -> isEnabled() &&
             pb -> value() != pb->maximum() )
        {
            // update animation Offset of the current Widget
            iter.value() = (iter.value() + 1) % 20;
            iter.key()->update();
        }
        if ((pb->minimum() == 0 && pb->maximum() == 0))
        {
          pb->setValue(pb->value()+1);
          pb->update();
        }
        if (iter.key()->isVisible())
            visible = true;
    }
    if (!visible)
        animationTimer->stop();
}

void PolyesterStyle::animate()
{

  btnAnimTimer->stop();

  int animationDelta = 1;
  if( _animateButtonToDark )
  animationDelta = -1;

  bool mustStop = true;

  for ( AnimWidgetMap::iterator it = animWidgets.begin(); it != animWidgets.end(); ++it) {
      QWidget *widget = it.key();

          if( animWidgets[widget].active == true ) {
            mustStop = false;
              if(abs(animWidgets[widget].animFrame) < ANIMATIONSTEPS) {
                  if ( _animateButton ) {
                      animWidgets[widget].animFrame += animationDelta;
                      widget->repaint();
                  } else {
                      animWidgets[widget].animFrame = ANIMATIONSTEPS;
                  }
              }
          } else {
              if(abs(animWidgets[widget].animFrame) > 0) {
                mustStop = false;
                  if ( _animateButton ) {
                      animWidgets[widget].animFrame -= animationDelta;
                      widget->repaint();
                  } else {
                      animWidgets[widget].animFrame = 0;
                  }
            //     btnAnimTimer->start(TIMERINTERVAL, true); // single-shot
              }
          }
  }

  if( !mustStop )
  {
    btnAnimTimer->setSingleShot( true );
    btnAnimTimer->start(TIMERINTERVAL);
  }
}


PolyesterStyle::~PolyesterStyle()
{
    delete pixmapCache;
    delete horizontalDots;
    delete verticalDots;
}

void PolyesterStyle::polish(QApplication* app)
{
#ifdef NO_KDE
          QWindowsStyle::polish(app);
#else
          KStyle::polish(app);
#endif
}

void PolyesterStyle::polish(QPalette& pal)
{
#ifdef NO_KDE
    QWindowsStyle::polish(pal);
#else
    KStyle::polish(pal);
#endif
}

void PolyesterStyle::polish(QWidget* widget)
{
    // use qobject_cast where possible to check if the widget inheits one of the classes. might improve
    // performance compared to QObject::inherits()
  //TODO:don't add to animwidgets non animated widgets :)
    if ( ::qobject_cast<QPushButton*>(widget) || ::qobject_cast<QComboBox*>(widget) ||
            ::qobject_cast<QAbstractSpinBox*>(widget) || ::qobject_cast<QSlider*>(widget) ||
            ::qobject_cast<QCheckBox*>(widget) || ::qobject_cast<QRadioButton*>(widget) ||
            ::qobject_cast<QToolButton*>(widget) || widget->inherits("QSplitterHandle") )
    {
//         widget->setBackgroundMode(PaletteBackground);
        widget->installEventFilter(this);

        if( _animateButton )
        {
          //TODO: discover if it's going to stay deleted...
            //if (!btnAnimTimer->isActive())
            //  btnAnimTimer->start( TIMERINTERVAL, false );

            animWidgets[widget].active = false;
                connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(animWidgetDestroyed(QObject*)));
        }
        widget->setAttribute(Qt::WA_Hover);
        /*QSlider *slider = ::qobject_cast<QSlider*>(widget);
        if(slider)
        {
          connect(slider, SIGNAL(sliderMoved(int)), this, SLOT(sliderThumbMoved(int)));
          connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sliderThumbMoved(int)));
        }*/
    }
    else if( qobject_cast<QTabBar *>(widget)
             || widget->inherits("QHeaderView"))
    {
      widget->setAttribute(Qt::WA_Hover);
      widget->installEventFilter(this);
    }
    else if( qobject_cast<QScrollBar *>(widget))
    {
     widget->setAttribute(Qt::WA_Hover);
     //widget->setAttribute(Qt::WA_OpaquePaintEvent, false);
    }
    else if (QFrame *frame = qobject_cast<QFrame *>(widget))
    {
      //never ugly panels(idea from bespin)...
     /* if( frame->frameShape() == QFrame::Box
          || frame->frameShape() == QFrame::Panel
          || frame->frameShape() == QFrame::WinPanel )
        frame->setFrameShape(QFrame::StyledPanel);*/

      // overwrite ugly lines
      if( frame->frameShape() == QFrame::HLine
          || frame->frameShape() == QFrame::VLine )
         widget->installEventFilter(this);
    }
    else if (qobject_cast<QMenuBar*>(widget)
             || widget->inherits("Q3ToolBar")
             || qobject_cast<QToolBar*>(widget)
             || (widget && qobject_cast<QToolBar *>(widget->parent())) )
    {
      widget->setBackgroundRole(QPalette::Background);
    }

    if( QAbstractScrollArea *area = qobject_cast<QAbstractScrollArea*>(widget))
    {
      //TODO:don't make shadow on QGraphicsViews
      //QGraphicsView *view = qobject_cast<QGraphicsView*>(widget);
      bool systemBackground = !(area->testAttribute(Qt::WA_NoSystemBackground));
      if( _sunkenShadows && systemBackground && area->frameStyle() == (QFrame::StyledPanel | QFrame::Sunken) )
      {
        widget->installEventFilter(this);
        QColor borderColor = getColor(widget->palette(), PanelContour);
        QColor highlightColor = getColor(widget->palette(), MouseOverHighlight);
        QWidget * borderLeft = new ScrollAreaBorder(ScrollAreaBorder::Left,
                                                    borderColor, highlightColor,
                                                    _contrast, true, area);
        QWidget * borderRight = new ScrollAreaBorder(ScrollAreaBorder::Right,
                                                      borderColor, highlightColor,
                                                      _contrast, true, area);
        QWidget * borderTop = new ScrollAreaBorder(ScrollAreaBorder::Top,
                                                    borderColor, highlightColor,
                                                    _contrast, true, area);
        QWidget * borderBottom = new ScrollAreaBorder(ScrollAreaBorder::Bottom,
                                                      borderColor, highlightColor,
                                                      _contrast, true, area);

        borderLeft->show();
        borderRight->show();
        borderTop->show();
        borderBottom->show();
      }
      else if( systemBackground && area->frameShape() == QFrame::StyledPanel  )
      {
        widget->installEventFilter(this);
        QColor borderColor = getColor(widget->palette(), PanelContour);
        QColor highlightColor = getColor(widget->palette(), MouseOverHighlight);

        QWidget * borderTop = new ScrollAreaBorder(ScrollAreaBorder::Top,
                                                    borderColor, highlightColor,
                                                    _contrast, false, area);
        QWidget * borderBottom = new ScrollAreaBorder(ScrollAreaBorder::Bottom,
                                                      borderColor, highlightColor,
                                                      _contrast, false, area);

        borderTop->show();
        borderBottom->show();
      }
    }

    //HACK: if the height of the parent widget is "not much", assuming we're in a statusbar,
    //this for not animating dolphin statusbar progressbar all the time (it's not a QStatusBar it seems)
    if( !widget->parentWidget() || widget->parentWidget()->height() > widget->height()*2 )
    {
        if( QProgressBar* pb = ::qobject_cast<QProgressBar*>(widget))
        {
        
            widget->installEventFilter(this);
            progAnimWidgets[widget] = 0;
            connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(progressBarDestroyed(QObject*)));
    
            if( !animationTimer->isActive() )
            {
            if( pb->minimum() == 0 && pb->maximum() == 0 )
                animationTimer->start( 25 );
            else if( _animateProgressBar )
                animationTimer->start( 50 );
            }
        }
    }


#ifdef NO_KDE
    QWindowsStyle::polish(widget);
#else
    KStyle::polish(widget);
#endif
}

void PolyesterStyle::unpolish(QWidget* widget)
{
    // use qobject_cast to check if the widget inheits one of the classes.
    if ( ::qobject_cast<QPushButton*>(widget) || ::qobject_cast<QComboBox*>(widget) ||
            ::qobject_cast<QSpinBox*>(widget) || ::qobject_cast<QSlider*>(widget) ||
            ::qobject_cast<QCheckBox*>(widget) || ::qobject_cast<QRadioButton*>(widget) ||
            ::qobject_cast<QToolButton*>(widget) || ::qobject_cast<QLineEdit*>(widget) ||
            widget->inherits("QSplitterHandle") )
    {
        widget->removeEventFilter(this);
        widget->setAttribute(Qt::WA_Hover, false);
        animWidgets.remove(widget);
    }
    if (qobject_cast<QMenuBar*>(widget)
        || widget->inherits("Q3ToolBar")
        || qobject_cast<QToolBar*>(widget)
        || (widget && qobject_cast<QToolBar *>(widget->parent())) )
    {
        widget->setBackgroundRole(QPalette::Button);
    }

    const QSlider *slider = ::qobject_cast<QSlider*>(widget);
    if(slider && sliderValues.contains(slider))
    sliderValues.remove(slider);

    if ( ::qobject_cast<QProgressBar*>(widget) )
    {
        progAnimWidgets.remove(widget);
    }


    if( QAbstractScrollArea *area = qobject_cast<QAbstractScrollArea*>(widget))
    {
      if( area->frameShape() == QFrame::StyledPanel  )
      {
        QList<ScrollAreaBorder *> borders = area->findChildren<ScrollAreaBorder *>();
        foreach (ScrollAreaBorder *border, borders)
        {
          border->hide();
          border->deleteLater();
        }
      }
    }
    if( QFrame *frame = qobject_cast<QFrame *>(widget) )
    {
      if( frame->frameShape() == QFrame::HLine ||
          frame->frameShape() == QFrame::VLine )
         widget->removeEventFilter(this);
    }

#ifdef NO_KDE
    QWindowsStyle::unpolish(widget);
#else
    KStyle::unpolish(widget);
#endif
}


void PolyesterStyle::unpolish(QApplication* app)
{
#ifdef NO_KDE
    QWindowsStyle::unpolish(app);
#else
    KStyle::unpolish(app);
#endif
}

void PolyesterStyle::progressBarDestroyed(QObject* obj)
{
    progAnimWidgets.remove(static_cast<QWidget*>(obj));
}

void PolyesterStyle::animWidgetDestroyed(QObject* obj)
{
    animWidgets.remove(static_cast<QWidget*>(obj));
}

void PolyesterStyle::renderContour(QPainter *p,
                                const QRect &r,
                                const QColor &backgroundColor,
                                const QColor &contour,
                                const uint flags) const
{
    if((r.width() <= 0)||(r.height() <= 0))
        return;

    const bool drawLeft = flags&Draw_Left;
    const bool drawRight = flags&Draw_Right;
    const bool drawTop = flags&Draw_Top;
    const bool drawBottom = flags&Draw_Bottom;
    const bool disabled = flags&Is_Disabled;

    const bool sharpTopLeft = flags&Sharp_UpperLeft;
    const bool sharpTopRight = flags&Sharp_UpperRight;
    const bool sharpBottomLeft = flags&Sharp_BottomLeft;
    const bool sharpBottomRight = flags&Sharp_BottomRight;

    QColor contourColor;
    if (disabled) {
        contourColor = backgroundColor.dark(150);
    } else {
        contourColor = contour;
    }

// sides
    p->setPen( alphaBlendColors(backgroundColor, contourColor, 50) );
    if(drawLeft)
        p->drawLine(r.left(), drawTop?r.top()+2:r.top(), r.left(), drawBottom?r.bottom()-2:r.bottom());
    if(drawRight)
        p->drawLine(r.right(), drawTop?r.top()+2:r.top(), r.right(), drawBottom?r.bottom()-2:r.bottom());
    if(drawTop)
        p->drawLine(drawLeft?r.left()+2:r.left(), r.top(), drawRight?r.right()-2:r.right(), r.top());
    if(drawBottom)
        p->drawLine(drawLeft?r.left()+2:r.left(), r.bottom(), drawRight?r.right()-2:r.right(), r.bottom());

// edges

    // first part...
    p->setPen(alphaBlendColors(backgroundColor, contourColor, 50) );
    if(drawLeft && drawTop) {
        switch(flags&Round_UpperLeft) {
            case false:
                p->drawPoint(r.left()+1, r.top());
                p->drawPoint(r.left(), r.top()+1);
                break;
            default:
                p->drawPoint(r.left()+1, r.top()+1);
        }
    }
    if(drawLeft && drawBottom) {
        switch(flags&Round_BottomLeft) {
            case false:
                p->drawPoint(r.left()+1, r.bottom());
                p->drawPoint(r.left(), r.bottom()-1);
                break;
            default:
                p->drawPoint(r.left()+1, r.bottom()-1);
        }
    }
    if(drawRight && drawTop) {
        switch(flags&Round_UpperRight) {
            case false:
                p->drawPoint(r.right()-1, r.top());
                p->drawPoint(r.right(), r.top()+1);
                break;
            default:
                p->drawPoint(r.right()-1, r.top()+1);
        }
    }
    if(drawRight && drawBottom) {
        switch(flags&Round_BottomRight) {
            case false:
                p->drawPoint(r.right()-1, r.bottom());
                p->drawPoint(r.right(), r.bottom()-1);
                break;
            default:
                p->drawPoint(r.right()-1, r.bottom()-1);
        }
    }

    // second part... fill edges in case we don't paint alpha-blended
   /* p->setPen( backgroundColor );
    if (!alphaBlend) {
        if(flags&Round_UpperLeft && drawLeft && drawTop) {
            p->drawPoint( r.x(), r.y() );
        }
        if(flags&Round_BottomLeft && drawLeft && drawBottom) {
            p->drawPoint( r.x(), r.bottom() );
        }
        if(flags&Round_UpperRight && drawRight && drawTop) {
            p->drawPoint( r.right(), r.y() );
        }
        if(flags&Round_BottomRight && drawRight && drawBottom) {
            p->drawPoint( r.right(), r.bottom() );
        }
    }*/

    qreal oldOpacity = p->opacity();
    qreal newOpacity = oldOpacity/3;
    // third part... anti-aliasing...
    if(drawLeft && drawTop)
    {
        switch(flags&Round_UpperLeft)
        {
            case false:
              p->setOpacity(newOpacity);
              p->drawPoint(r.left(),r.top());
              p->setOpacity(oldOpacity);
               //TODO: renderpixel.. renderPixel(p,QPoint(r.left(),r.top()),alphaAA,contourColor,backgroundColor,alphaBlend);
                break;
            default:
              p->setOpacity(newOpacity);
              p->drawPoint(r.left()+1,r.top());
              p->drawPoint(r.left(),r.top()+1);
              p->setOpacity(oldOpacity);
                /*renderPixel(p,QPoint(r.left()+1,r.top()),alphaAA,contourColor,backgroundColor,alphaBlend);
                renderPixel(p,QPoint(r.left(),r.top()+1),alphaAA,contourColor,backgroundColor,alphaBlend);*/
        }
    }
    if(drawLeft && drawBottom)
    {
        switch(flags&Round_BottomLeft) {
            case false:
                 p->setOpacity(newOpacity);
                 p->drawPoint(r.left(),r.bottom());
                 p->setOpacity(oldOpacity);
                //renderPixel(p,QPoint(r.left(),r.bottom()),alphaAA,contourColor,backgroundColor,alphaBlend);
                break;
            default:
              p->setOpacity(newOpacity);
              p->drawPoint(r.left()+1,r.bottom());
              p->drawPoint(r.left(),r.bottom()-1);
              p->setOpacity(oldOpacity);
                /*renderPixel(p,QPoint(r.left()+1,r.bottom()),alphaAA,contourColor,backgroundColor,alphaBlend);
                renderPixel(p,QPoint(r.left(),r.bottom()-1),alphaAA,contourColor,backgroundColor,alphaBlend);*/
        }
    }
    if(drawRight && drawTop) {
        switch(flags&Round_UpperRight) {
            case false:
              p->setOpacity(newOpacity);
              p->drawPoint(QPoint(r.right(),r.top()));
              p->setOpacity(oldOpacity);
                //renderPixel(p,QPoint(r.right(),r.top()),alphaAA,contourColor,backgroundColor,alphaBlend);
                break;
            default:
              p->setOpacity(newOpacity);
              p->drawPoint(QPoint(r.right()-1,r.top()));
              p->drawPoint(QPoint(r.right(),r.top()+1));
              p->setOpacity(oldOpacity);
                /*renderPixel(p,QPoint(r.right()-1,r.top()),alphaAA,contourColor,backgroundColor,alphaBlend);
                renderPixel(p,QPoint(r.right(),r.top()+1),alphaAA,contourColor,backgroundColor,alphaBlend);*/
        }
    }
    if(drawRight && drawBottom)
    {
        switch(flags&Round_BottomRight) {
            case false:
              p->setOpacity(newOpacity);
              p->drawPoint(QPoint(r.right(),r.bottom()));
              p->setOpacity(oldOpacity);
              //renderPixel(p,QPoint(r.right(),r.bottom()),alphaAA,contourColor,backgroundColor,alphaBlend);
              break;
            default:
              p->setOpacity(newOpacity);
              p->drawPoint(QPoint(r.right()-1,r.bottom()));
              p->drawPoint(QPoint(r.right(),r.bottom()-1));
              p->setOpacity(oldOpacity);
                /*renderPixel(p,QPoint(r.right()-1,r.bottom()),alphaAA,contourColor,backgroundColor,alphaBlend);
                renderPixel(p,QPoint(r.right(),r.bottom()-1),alphaAA,contourColor,backgroundColor,alphaBlend);*/
        }
    }


    //HACK: paint the sharp border over the rest, it's NoGooD(tm)
    p->setPen( alphaBlendColors(backgroundColor, contourColor, 50) );
    if( !(flags&Round_UpperLeft) && sharpTopLeft )
      p->drawPoint( r.left(), r.top() );
    if( !(flags&Round_UpperRight) && sharpTopRight )
      p->drawPoint( r.right(), r.top() );
    if( !(flags&Round_BottomLeft) && sharpBottomLeft )
      p->drawPoint( r.left(), r.bottom() );
    if( !(flags&Round_BottomRight) && sharpBottomRight )
      p->drawPoint( r.right(), r.bottom() );

}

void PolyesterStyle::renderMask(QPainter *p,
                              const QRect &r,
                              const QColor &color,
                              const uint flags) const
{
    if((r.width() <= 0)||(r.height() <= 0))
        return;

    const bool roundUpperLeft = flags&Round_UpperLeft;
    const bool roundUpperRight = flags&Round_UpperRight;
    const bool roundBottomLeft = flags&Round_BottomLeft;
    const bool roundBottomRight = flags&Round_BottomRight;


    p->fillRect (QRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2) , color);

    p->setPen(color);
    // sides
    p->drawLine(roundUpperLeft?r.x()+1:r.x(), r.y(),
                roundUpperRight?r.right()-1:r.right(), r.y() );
    p->drawLine(roundBottomLeft?r.x()+1:r.x(), r.bottom(),
                roundBottomRight?r.right()-1:r.right(), r.bottom() );
    p->drawLine(r.x(), roundUpperLeft?r.y()+1:r.y(),
                r.x(), roundBottomLeft?r.bottom()-1:r.bottom() );
    p->drawLine(r.right(), roundUpperLeft?r.y()+1:r.y(),
                r.right(), roundBottomLeft?r.bottom()-1:r.bottom() );
}

void PolyesterStyle::renderSurface(QPainter *p,
                                 const QRect &r,
                                 const QColor &backgroundColor,
                                 const QColor &buttonColor,
                                 const QColor &highlightColor,
                                 int intensity,
                                 const uint flags) const
{
    if((r.width() <= 0)||(r.height() <= 0))
        return;

    const bool disabled = flags&Is_Disabled;

    const bool drawLeft = flags&Draw_Left;
    const bool drawRight = flags&Draw_Right;
    const bool drawTop = flags&Draw_Top;
    const bool drawBottom = flags&Draw_Bottom;
    const bool roundUpperLeft = flags&Round_UpperLeft;
    const bool roundUpperRight = flags&Round_UpperRight;
    const bool roundBottomLeft = flags&Round_BottomLeft;
    const bool roundBottomRight = flags&Round_BottomRight;
    const bool sunken = flags&Is_Sunken;
    const bool horizontal = flags&Is_Horizontal;
    bool highlight = false,
        highlightLeft = false,
        highlightRight = false,
        highlightTop = false,
        highlightBottom = false;
    // only highlight if not sunken & not disabled...
    if(!sunken && !disabled) {
        highlight = (flags&Is_Highlight);
        highlightLeft = (flags&Highlight_Left);
        highlightRight = (flags&Highlight_Right);
        highlightTop = (flags&Highlight_Top);
        highlightBottom = (flags&Highlight_Bottom);
    }

    QColor baseColor = alphaBlendColors(backgroundColor, disabled?backgroundColor:buttonColor, 10);
    if (disabled) {
        intensity = 2;
    } else if (highlight) {
        // blend this _slightly_ with the background
        baseColor = alphaBlendColors(baseColor, highlightColor, 240);
        baseColor.setAlpha(255);
    } else if (sunken) {
        // enforce a common sunken-style...
        baseColor = baseColor.dark(100+intensity);
        //intensity = _contrast*2;
    }

// some often needed colors...
    // 1 more intensive than 2.
    const QColor colorTop1 = alphaBlendColors(baseColor,
                    sunken?baseColor.dark(100+intensity*2):baseColor.light(100+intensity*2), 80);
    const QColor colorTop2 = alphaBlendColors(baseColor,
                    sunken?baseColor.dark(100+intensity):baseColor.light(100+intensity), 80);
    const QColor colorBottom1 = alphaBlendColors(baseColor,
                        sunken?baseColor.light(100+intensity*2):baseColor.dark(100+intensity*2), 80);
    const QColor colorBottom2 = alphaBlendColors(baseColor,
                        sunken?baseColor.light(100+intensity):baseColor.dark(100+intensity), 80);

    const QColor colorBorder = colorTop1.light(100+_contrast);

// sides
    if (drawLeft) {
        if (horizontal && !_lightBorder) {
            int height = r.height();
            if (roundUpperLeft || !drawTop) height--;
            if (roundBottomLeft || !drawBottom) height--;
            renderGradient(p, QRect(r.left(), (roundUpperLeft&&drawTop)?r.top()+1:r.top(), 1, height),
                           colorBorder, baseColor);
        } else {
            p->setPen((sunken&&!_lightBorder)?colorTop1:colorBorder );
            p->drawLine(r.left(), (roundUpperLeft&&drawTop)?r.top()+1:r.top(),
                        r.left(), (roundBottomLeft&&drawBottom)?r.bottom()-1:r.bottom() );
        }
    }
    if (drawRight) {
        if (horizontal && !_lightBorder) {
            int height = r.height();
            // TODO: there's still a bogus in it: when edge4 is Thick
            //       and we don't whant to draw the Top, we have a unpainted area
            if (roundUpperRight || !drawTop) height--;
            if (roundBottomRight || !drawBottom) height--;
            renderGradient(p, QRect(r.right(), (roundUpperRight&&drawTop)?r.top()+1:r.top(), 1, height),
                           baseColor, _lightBorder&&!sunken?colorBorder:colorBottom1);
        } else {
            /*3d effect or light borders?*/
            p->setPen(_lightBorder&&!sunken?colorBorder:colorBottom1 );
            p->drawLine(r.right(), (roundUpperRight&&drawTop)?r.top()+1:r.top(),
                        r.right(), (roundBottomRight&&drawBottom)?r.bottom()-1:r.bottom() );
        }
    }
    if (drawTop) {
        if ( horizontal || _lightBorder ) {
            p->setPen((sunken&&!_lightBorder)?colorTop1:colorBorder );
            p->drawLine((roundUpperLeft&&drawLeft)?r.left()+1:r.left(), r.top(),
                        (roundUpperRight&&drawRight)?r.right()-1:r.right(), r.top() );
        } else {
            int width = r.width();
            if (roundUpperLeft || !drawLeft) width--;
            if (roundUpperRight || !drawRight) width--;
            renderGradient(p, QRect((roundUpperLeft&&drawLeft)?r.left()+1:r.left(), r.top(), width, 1),
                           colorTop2, colorBorder, false );
        }
    }
    if (drawBottom) {
        if ( horizontal|| _lightBorder ) {
            p->setPen(_lightBorder&&!sunken?colorBorder:colorBottom1 );
            p->drawLine((roundBottomLeft&&drawLeft)?r.left()+1:r.left(), r.bottom(),
                        (roundBottomRight&&drawRight)?r.right()-1:r.right(), r.bottom() );
        } else {
            int width = r.width();
            if (roundBottomLeft || !drawLeft) width--;
            if (roundBottomRight || !drawRight) width--;
            renderGradient(p, QRect((roundBottomLeft&&drawLeft)?r.left()+1:r.left(), r.bottom(), width, 1),
                           colorBottom2, _lightBorder&&!sunken?colorBorder:colorBottom1, false);
        }
    }

// button area...
    int width = r.width();
    int height = r.height();
    if (drawLeft) width--;
    if (drawRight) width--;
    if (drawTop) height--;
    if (drawBottom) height--;

    int left = r.left();
    int top = r.top();
    if (drawLeft) left++;
    if (drawTop) top++;
    QRect surfaceRect(drawLeft?r.left()+1:r.left(),
                      drawTop?r.top()+1:r.top(), width, height);


    QBrush brush;
    if( sunken )
    {
      if( _sunkenShadows )
        brush = getSurfaceBrush(surfaceRect.adjusted(0,0,
                                                     horizontal?0:3,
                                                     horizontal?3:0),
                                baseColor, horizontal);
      else
        brush = getShadowBrush(surfaceRect, baseColor, horizontal);
    }
    else
      brush = getSurfaceBrush(surfaceRect, baseColor, horizontal);
    p->fillRect(surfaceRect, brush);

    //sunken shadow, flags a little bit complicated :)
    if( _sunkenShadows && sunken )
    {
      uint shadowFlags = Draw_Top|Draw_Left;
      if( horizontal )
        shadowFlags |= Draw_Right;
      else
        shadowFlags |= Draw_Bottom;

      if( !(flags & Draw_Top) )
        shadowFlags |= Sharp_UpperLeft|Sharp_UpperRight;
      if( !(flags & Draw_Bottom) )
        shadowFlags |= Sharp_BottomLeft|Sharp_BottomRight;
      if( !(flags & Draw_Left) )
        shadowFlags |= Sharp_UpperLeft|Sharp_BottomLeft;
      if( !(flags & Draw_Right) )
        shadowFlags |= Sharp_BottomRight|Sharp_UpperRight;

      if( flags & Sharp_UpperLeft )
        shadowFlags |= Sharp_UpperLeft;
      if( flags & Sharp_UpperRight )
        shadowFlags |= Sharp_UpperRight;
      if( flags & Sharp_BottomLeft )
        shadowFlags |= Sharp_BottomLeft;
      if( flags & Sharp_BottomRight )
        shadowFlags |= Sharp_BottomRight;

      renderSunkenShadow(p, r, Qt::black, shadowFlags, horizontal);

    }

// highlighting...
    qreal opacity = p->opacity();
    p->setOpacity((double)highlightColor.alpha()/255.0);
    if(highlightTop)
    {
        p->setPen(alphaBlendColors(colorTop1 , highlightColor, 20) );
        p->drawLine((roundUpperLeft&&drawLeft)?r.left()+1:r.left(), r.top(),
                    (roundUpperRight&&drawRight)?r.right()-1:r.right(), r.top() );

        p->setPen(alphaBlendColors(colorTop2 , highlightColor, 90) );
        p->drawLine(highlightLeft?r.left()+1:r.left(), r.top()+1,
                    highlightRight?r.right()-1:r.right(), r.top()+1 );

        if( roundUpperLeft&&drawLeft&&!highlightLeft )
        {
          p->drawPoint(r.left(),r.top()+2);
          p->setPen(alphaBlendColors(colorTop1 , highlightColor, 20) );
          p->drawPoint(r.left(),r.top()+1);
        }
        if( roundUpperRight&&drawRight&&!highlightRight )
        {
          p->setPen(alphaBlendColors(colorTop1 , highlightColor, 20) );
          p->drawPoint(r.right(),r.top()+1);
          p->setPen(alphaBlendColors(colorTop2 , highlightColor, 90) );
          p->drawPoint(r.right(),r.top()+2);
        }
    }
    if(highlightBottom)
    {
        p->setPen(alphaBlendColors(colorBottom1 , highlightColor, 20) );
        p->drawLine((roundBottomLeft&&drawLeft)?r.left()+1:r.left(), r.bottom(),
                    (roundBottomRight&&drawRight)?r.right()-1:r.right(), r.bottom() );
        p->setPen(alphaBlendColors(colorBottom2 , highlightColor, 90) );
        p->drawLine(highlightLeft?r.left()+1:r.left(), r.bottom()-1,
                    highlightRight?r.right()-1:r.right(), r.bottom()-1 );

        if( roundBottomLeft&&drawLeft&&!highlightLeft )
        {
         p->drawPoint(r.left(),r.bottom()-2);
         p->setPen(alphaBlendColors(colorBottom1 , highlightColor, 20) );
         p->drawPoint(r.left(),r.bottom()-1);
        }
        if( roundBottomRight&&drawRight&&!highlightRight )
        {
         p->setPen(alphaBlendColors(colorBottom2 , highlightColor, 90) );
         p->drawPoint(r.right(),r.bottom()-2);
         p->setPen(alphaBlendColors(colorBottom1 , highlightColor, 20) );
         p->drawPoint(r.right(),r.bottom()-1);
        }
    }
    if(highlightLeft)
    {
        p->setPen(alphaBlendColors(colorTop1 , highlightColor, 20) );
        p->drawLine(r.left(), (roundUpperLeft&&drawTop)?r.top()+1:r.top(),
                    r.left(), (roundBottomLeft&&drawBottom)?r.bottom()-1:r.bottom() );
        p->setPen(alphaBlendColors(colorTop2 , highlightColor, 90) );
        p->drawLine(r.left()+1, highlightTop?r.top()+1:r.top(),
                    r.left()+1, highlightBottom?r.bottom()-1:r.bottom() );
    }
    if(highlightRight)
    {
        p->setPen(alphaBlendColors(colorBottom1 , highlightColor, 20) );
        p->drawLine(r.right(), (roundUpperRight&&drawTop)?r.top()+1:r.top(),
                    r.right(), (roundBottomRight&&drawBottom)?r.bottom()-1:r.bottom() );
        p->setPen(alphaBlendColors(colorBottom2 , highlightColor, 90) );
        p->drawLine(r.right()-1, highlightTop?r.top()+1:r.top(),
                    r.right()-1, highlightBottom?r.bottom()-1:r.bottom() );
    }
    p->setOpacity(opacity);
}

QBrush PolyesterStyle::getSurfaceBrush(const QRect &r, const QColor &backgroundColor, bool horizontal) const
{
  QLinearGradient gradient;
  if(horizontal)
    gradient = QLinearGradient(r.center().x(), r.top(), r.center().x(), r.bottom());
  else
    gradient = QLinearGradient(r.left(), r.center().y(), r.right(), r.center().y());

  if( !_buttonStyle.compare("glass" ) )
  {
    gradient.setColorAt(0, backgroundColor.lighter(100+_contrast));
    gradient.setColorAt(0.5, backgroundColor);
    gradient.setColorAt(0.501, backgroundColor.darker(100+_contrast));
    gradient.setColorAt(1, backgroundColor.lighter(100+_contrast));
  }
  else if( !_buttonStyle.compare("flat" ) )
  {
    return(QBrush(backgroundColor));
  }
  else if( !_buttonStyle.compare("gradients" ) )
  {
    gradient.setColorAt(0, backgroundColor.lighter(100+_contrast));
    gradient.setColorAt(1, backgroundColor.darker(100+_contrast));
  }
  else //reverseGradients
  {
    gradient.setColorAt(0, backgroundColor.darker(100+_contrast));
    gradient.setColorAt(1, backgroundColor.lighter(100+_contrast));
  }

  return QBrush(gradient);
}

//for sunken frames like in lineedits, scrollbars etc
QBrush PolyesterStyle::getShadowBrush(const QRect &r, const QColor &backgroundColor, bool horizontal) const
{
  /*if( !_sunkenShadows )
    return backgroundColor;*/

  QLinearGradient gradient;
  if(horizontal)
    gradient = QLinearGradient(r.center().x(), r.top(), r.center().x(), r.bottom());
  else
    gradient = QLinearGradient(r.left(), r.center().y(), r.right(), r.center().y());

  gradient.setColorAt(0, backgroundColor.darker(110+_contrast));
  gradient.setColorAt(0.5, backgroundColor);
  //gradient.setColorAt(0.65, backgroundColor);
  gradient.setColorAt(1, backgroundColor.light(110+_contrast));


  return QBrush(gradient);
}

//the previous method is for surfaces, this is for little retouches
QBrush PolyesterStyle::getTransparentShadowBrush(const QRect &r, QColor shadowColor,
                                                 bool horizontal, bool invert, int alpha) const
{
  QLinearGradient gradient;
  if(horizontal)
    gradient = QLinearGradient(r.center().x(),
                               (invert?r.bottom():r.top()),
                               r.center().x(),
                               (invert?r.top():r.bottom()));
  else
    gradient = QLinearGradient((invert?r.right():r.left()),
                               r.center().y(),
                               (invert?r.left():r.right()),
                               r.center().y());

  shadowColor.setAlpha(alpha);
  gradient.setColorAt(0, shadowColor);
  shadowColor.setAlpha(0);
  gradient.setColorAt(1, shadowColor);

  return QBrush(gradient);
}

void PolyesterStyle::renderSunkenShadow(QPainter *p, const QRect &r,
                                        const QColor &shadowColor,
                                        const uint flags, bool horizontal) const
{
  QRegion mask(r);
  if( !(flags&Sharp_UpperLeft) )
    mask -= QRegion( r.x(), r.y(), 1, 1 );
  if( !(flags&Sharp_BottomLeft) )
    mask -= QRegion( r.x(), r.bottom(), 1, 1 );
  if( !(flags&Sharp_UpperRight) )
    mask -= QRegion( r.right(), r.y(), 1, 1 );
  if( !(flags&Sharp_BottomRight) )
    mask -= QRegion( r.right(), r.bottom(), 1, 1 );
  p->save();
  p->setClipRegion(mask);

  QRect shadowRect;
  QBrush shadowBrush;

  //more the color is dark more is transparent
  int alpha = shadowColor.value()/4 + _contrast*5;

  //TOP
  if( flags&Draw_Top )
  {
    shadowRect = QRect(r.x(), r.y(), r.width(), horizontal?5:3);
    shadowBrush = QBrush(getTransparentShadowBrush(shadowRect,
                                                shadowColor,
                                                true, false, alpha));
    p->fillRect(shadowRect, shadowBrush);
  }

  //LEFT
  if( flags&Draw_Left )
  {
    shadowRect = QRect(r.x(), r.y(), horizontal?3:5, r.height());
    shadowBrush = QBrush(getTransparentShadowBrush(shadowRect,
                                                shadowColor,
                                                false, false, alpha));
    p->fillRect(shadowRect, shadowBrush);
  }

  //RIGHT
  if( flags&Draw_Right )
  {
    shadowRect = QRect(r.right()-(horizontal?2:3), r.y(), horizontal?3:4, r.height());
    shadowBrush = QBrush(getTransparentShadowBrush(shadowRect,
                                                (horizontal?shadowColor:Qt::white),
                                                false, true, horizontal?alpha:128));
    p->fillRect(shadowRect, shadowBrush);
  }

  //BOTTOM
  if( flags&Draw_Bottom )
  {
    shadowRect = QRect(r.x(), r.bottom()-(horizontal?3:2), r.width(), horizontal?4:3);
    shadowBrush = QBrush(getTransparentShadowBrush(shadowRect,
                                                (horizontal?Qt::white:shadowColor),
                                                true, true, horizontal?128:alpha));
    p->fillRect(shadowRect, shadowBrush);
  }

  p->restore();
}



void PolyesterStyle::renderRadioButton(QPainter *p,
                                        const QRect &r,
                                        const QColor &backgroundColor,
                                        const QColor &checkColor,
                                        const QColor &contourColor,
                                        const QColor &highlightColor,
                                        bool checked,
                                        const uint flags) const
{
  const bool highlight = (flags&Is_Highlight);
  const bool disabled = flags&Is_Disabled;

  p->save();

  if(disabled)
    p->setOpacity(0.6);

  p->setBrush(getSurfaceBrush(r, backgroundColor));
  p->setRenderHint(QPainter::Antialiasing);
  p->setPen(alphaBlendColors(backgroundColor, contourColor, 50) );
  p->drawEllipse(QRect(r.x()+1,r.y()+1,r.width()-2,r.height()-2));

  if( highlight )
  {
    p->setPen(QPen(highlightColor, 2) );
    p->drawEllipse(QRect(r.x()+2,r.y()+2,r.width()-4,r.height()-4));
  }

  if( checked )
  {
    p->setPen(QPen(Qt::NoPen) );
    p->setBrush(QBrush( checkColor, Qt::SolidPattern ));
    int dotSize = r.width()/3;
    p->drawEllipse(QRect(r.x()+dotSize,r.y()+dotSize,r.width()-dotSize*2,r.height()-dotSize*2));
  }

  p->restore();
}


void PolyesterStyle::renderButton(QPainter *p,
                               const QRect &r,
                               const QPalette &pal,
                               bool sunken,
                               bool mouseOver,
                               bool horizontal,
                               bool enabled,
                               int animFrame,
                               bool isDefault //TODO: move here all the default-button related code?
                              ) const
{
    // small fix for the kicker buttons...
//    if(kickerMode) enabled = true;


    const QPen oldPen( p->pen() );

    uint contourFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom;
    if(!enabled) contourFlags|=Is_Disabled;
//    if(khtmlMode) contourFlags|=Draw_AlphaBlend;

    uint surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom;
    if(horizontal) surfaceFlags|=Is_Horizontal;
    if(!enabled) surfaceFlags|=Is_Disabled;
    else
    {
        if(sunken)
          surfaceFlags|=Is_Sunken;
        else
        {
          if(((animFrame != 0) || mouseOver) &&
               (!_animateButton||!isDefault))
          {
                surfaceFlags|=Is_Highlight;
                if(horizontal)
                {
                    surfaceFlags|=Highlight_Top;
                    surfaceFlags|=Highlight_Bottom;
                }
                else
                {
                    surfaceFlags|=Highlight_Left;
                    surfaceFlags|=Highlight_Right;
                }
            }
        }
    }

    if (!flatMode) {
        contourFlags |= Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight;
        surfaceFlags |= Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight;

        renderContour(p, r, pal.color(QPalette::Background),
                      (isDefault?getColor(pal,ButtonContour).dark(100+_contrast*10):getColor(pal,ButtonContour)),
                      contourFlags);

        /*Colorize to mouseHover only the default button, the others will get lighter or darker*/
        if(!isDefault)
        {
          QColor higlight = pal.color(QPalette::Highlight);
          if( _animateButton )
          {
            higlight.setAlpha((int)(255*((double)animFrame/(double)ANIMATIONSTEPS)));
          }
           renderSurface(p, QRect(r.left()+1, r.top()+1, r.width()-2, r.height()-2),
                       pal.color(QPalette::Background), pal.color(QPalette::Button).light(100+animFrame),
                       higlight, _contrast, surfaceFlags);
        }
        else
        {
          //12.8 is the maximum amount of blending (256) / ANIMATIONSTEPS (20)
          QColor buttonColor = alphaBlendColors( pal.color(QPalette::Highlight), pal.color(QPalette::Button), (int)(12.8*animFrame)+50);

          renderSurface(p, QRect(r.left()+1, r.top()+1, r.width()-2, r.height()-2),
                        pal.color(QPalette::Background), buttonColor.light(100+animFrame), getColor(pal,MouseOverHighlight), _contrast+animFrame, surfaceFlags);
        }

    } else {
        renderContour(p, r, pal.color(QPalette::Background), pal.color(QPalette::Button).dark(105+_contrast*3),
                         contourFlags);

        renderSurface(p, QRect(r.left()+1, r.top()+1, r.width()-2, r.height()-2),
                      pal.color(QPalette::Background), pal.color(QPalette::Button), getColor(pal,MouseOverHighlight), _contrast/2, surfaceFlags);

        flatMode = false;
    }

    p->setPen(oldPen);


}



void PolyesterStyle::renderDot(QPainter *p,
                             const QPoint &point,
                             const QColor &baseColor,
                             const bool thick,
                             const bool sunken) const
{
    const QColor topColor = alphaBlendColors(baseColor, sunken?baseColor.dark(130):baseColor.light(150), 70);
    const QColor bottomColor = alphaBlendColors(baseColor, sunken?baseColor.light(150):baseColor.dark(130), 70);
    p->setPen(topColor );
    p->drawLine(point.x(), point.y(), point.x()+1, point.y());
    p->drawPoint(point.x(), point.y()+1);
    p->setPen(bottomColor );
    if(thick) {
        p->drawLine(point.x()+1, point.y()+2, point.x()+2, point.y()+2);
        p->drawPoint(point.x()+2, point.y()+1);
    } else {
        p->drawPoint(point.x()+1, point.y()+1);
    }
}

void PolyesterStyle::renderGradient(QPainter *painter,
                                  const QRect &rect,
                                  const QColor &c1,
                                  const QColor &c2,
                                  bool horizontal) const
{
    if((rect.width() <= 0)||(rect.height() <= 0))
        return;

    // generate a quite unique key for this surface.
    CacheEntry search(cGradientTile,
                      horizontal ? 0 : rect.width(),
                      horizontal ? rect.height() : 0,
                      c1.rgb(), c2.rgb(), horizontal );
    int key = search.key();

    CacheEntry *cacheEntry;
    if( (cacheEntry = pixmapCache->object(key)) ) {
        if( search == *cacheEntry ) { // match! we can draw now...
            if(cacheEntry->pixmap) {
                painter->drawTiledPixmap(rect, *(cacheEntry->pixmap) );
            }
            return;
        } else {
            // Remove old entry in case of a conflict!
            // This shouldn't happen very often, see comment in CacheEntry.
            pixmapCache->remove(key);
        }
    }

    // there wasn't anything matching in the cache, create the pixmap now...
    QPixmap *result = new QPixmap(horizontal ? 10 : rect.width(),
                                  horizontal ? rect.height() : 10);
    QPainter p(result);

    int r_w = result->rect().width();
    int r_h = result->rect().height();
    int r_x, r_y, r_x2, r_y2;
    result->rect().getCoords(&r_x, &r_y, &r_x2, &r_y2);

    int rDiff, gDiff, bDiff;
    int rc, gc, bc;

    register int x, y;

    rDiff = ( c2.red())   - (rc = c1.red());
    gDiff = ( c2.green()) - (gc = c1.green());
    bDiff = ( c2.blue())  - (bc = c1.blue());

    register int rl = rc << 16;
    register int gl = gc << 16;
    register int bl = bc << 16;

    int rdelta = ((1<<16) / (horizontal ? r_h : r_w)) * rDiff;
    int gdelta = ((1<<16) / (horizontal ? r_h : r_w)) * gDiff;
    int bdelta = ((1<<16) / (horizontal ? r_h : r_w)) * bDiff;

    // these for-loops could be merged, but the if's in the inner loop
    // would make it slow
    if(horizontal) {
        for ( y = 0; y < r_h; y++ ) {
            rl += rdelta;
            gl += gdelta;
            bl += bdelta;

            p.setPen(QColor(rl>>16, gl>>16, bl>>16));
            p.drawLine(r_x, r_y+y, r_x2, r_y+y);
        }
    } else {
        for( x = 0; x < r_w; x++) {
            rl += rdelta;
            gl += gdelta;
            bl += bdelta;

            p.setPen(QColor(rl>>16, gl>>16, bl>>16));
            p.drawLine(r_x+x, r_y, r_x+x, r_y2);
        }
    }

    p.end();

    // draw the result...
    painter->drawTiledPixmap(rect, *result);

    // insert into cache using the previously created key.
    CacheEntry *toAdd = new CacheEntry(search);
    toAdd->pixmap = result;
    bool insertOk = pixmapCache->insert( key, toAdd, result->width()*result->height()*result->depth()/8 );

    if(!insertOk)
        delete result;
}

void PolyesterStyle::renderPanel(QPainter *p,
                              const QRect &r,
                              const QPalette &pal,
                              const bool pseudo3d,
                              const bool sunken,
                              const bool focusHighlight) const
{
    int x, x2, y, y2, w, h;
    r.getRect(&x,&y,&w,&h);
    r.getCoords(&x, &y, &x2, &y2);

    if( focusHighlight )
    {
        renderContour(p, r, pal.color(QPalette::Background),
                      getColor(pal,FocusHighlight) );
    }
    else
    {
        renderContour(p, r, pal.color(QPalette::Background),
                      getColor(pal, PanelContour) );
    }

    if(pseudo3d)
    {
        if (sunken && !_lightBorder)
        {
            p->setPen(getColor(pal, PanelDark) );
        } else {
            p->setPen(getColor(pal, PanelLight) );
        }
        p->drawLine(r.left()+2, r.top()+1, r.right()-2, r.top()+1);
        p->drawLine(r.left()+1, r.top()+2, r.left()+1, r.bottom()-2);
        if (_lightBorder || sunken) {
            p->setPen(getColor(pal, PanelLight) );
        } else {
            p->setPen(getColor(pal, PanelDark) );
        }
        p->drawLine(r.left()+2, r.bottom()-1, r.right()-2, r.bottom()-1);
        p->drawLine(r.right()-1, r.top()+2, r.right()-1, r.bottom()-2);
        if( _sunkenShadows && sunken )
          renderSunkenShadow(p, r.adjusted(1,1,-1,-1));
    }
}


void PolyesterStyle::renderTab(QPainter *p,
                            const QRect &r,
                            const QPalette &pal,
                            bool mouseOver,
                            const SelectedTab selected,
                            const bool bottom,
                            const QStyleOptionTab::TabPosition pos,
                            const bool triangular,
                            bool cornerWidget,
                            const bool reverseLayout) const
{
    const bool isFirst = (pos == QStyleOptionTab::Beginning) || (pos == QStyleOptionTab::OnlyOneTab);
    const bool isLast = (pos == QStyleOptionTab::End);
    const bool isSingle = (pos == QStyleOptionTab::OnlyOneTab);


    /*if the tabbar is centered always render the left
      rounded connection of the first tab*/
    if( _centeredTabBar && !reverseLayout && isFirst )
     cornerWidget = true;

    if (selected == ThisTab)
    {
    // is selected

    // the top part of the tab which is nearly the same for all positions
        QRect Rc; // contour
        if (!bottom) {
            if (isFirst && !cornerWidget && !reverseLayout) {
                Rc = QRect(r.x(), r.y(), r.width()-1, r.height()-3);
            } else if (isFirst && !cornerWidget && reverseLayout) {
                Rc = QRect(r.x()+1, r.y(), r.width()-1, r.height()-3);
            } else {
                Rc = QRect(r.x()+1, r.y(), r.width()-2, r.height()-3);
            }
        } else {
            if (isFirst && !cornerWidget && !reverseLayout) {
                Rc = QRect(r.x(), r.y()+3, r.width()-1, r.height()-3);
            } else if (isFirst && !cornerWidget && reverseLayout) {
                Rc = QRect(r.x()+1, r.y()+3, r.width()-1, r.height()-3);
            } else {
                Rc = QRect(r.x()+1, r.y()+3, r.width()-2, r.height()-3);
            }
        }

        //const QRect Rs = Rc.adjusted(1,1,-1,0);
        QRect Rs(Rc.x()+1, bottom?Rc.y():Rc.y()+1, Rc.width()-2, Rc.height()-1); // the resulting surface
        // the area where the fake border shoudl appear
        const QRect Rb(r.x(), bottom?r.top():Rc.bottom()+1, r.width(), r.height()-Rc.height() );

        //if( p->viewTransformEnabled() )
          //Rs.adjust(0,0,-10,0);

        uint contourFlags = Draw_Left|Draw_Right;
        if(!bottom) {
            contourFlags |= Draw_Top|Round_UpperLeft|Round_UpperRight;
        } else {
            contourFlags |= Draw_Bottom|Round_BottomLeft|Round_BottomRight;
        }
        renderContour(p, Rc,
                      pal.color(QPalette::Background), getColor(pal,PanelContour),
                      contourFlags);

        // surface
        if(!bottom)
        {
            p->setPen(getColor(pal,PanelLight) );
            p->drawLine(Rs.x()+1, Rs.y(), Rs.right()-1, Rs.y() );
            renderGradient(p, QRect(Rs.x(), Rs.y()+1, 1, Rs.height()-1),
                           getColor(pal,PanelLight), getColor(pal,PanelLight2));
            renderGradient(p, QRect(Rs.right(), Rs.y()+1, 1, Rs.height()-1),
                            getColor(pal,PanelDark), getColor(pal,PanelDark2));

            if( !_buttonStyle.compare("glass" )  ){
                renderGradient(p, QRect(Rs.x()+1, Rs.y()+1, Rs.width()-2, Rs.height()/2),
                                pal.color(QPalette::Background).light(100+_contrast),
                                pal.color(QPalette::Background));
                renderGradient(p, QRect(Rs.x()+1, Rs.y()+Rs.height()/2, Rs.width()-2, Rs.height()/2),
                                pal.color(QPalette::Background).dark(100+_contrast),
                                pal.color(QPalette::Background));
            }else if( !_buttonStyle.compare("gradients" )  )
                renderGradient(p, QRect(Rs.x()+1, Rs.y()+1, Rs.width()-2, Rs.height()-1),
                                getColor(pal,PanelLight), pal.color(QPalette::Background));
            else if( !_buttonStyle.compare("reverseGradients" ) )
                renderGradient(p, QRect(Rs.x()+1, Rs.y()+1, Rs.width()-2,
                                Rs.height()-1),
                                pal.color(QPalette::Background).dark(100+_contrast), pal.color(QPalette::Background));
            else
                renderGradient(p, QRect(Rs.x()+1, Rs.y()+1, Rs.width()-2, 
                                Rs.height()-1),
                                pal.color(QPalette::Background), pal.color(QPalette::Background));

            if( _highLightTab )
            {
              p->fillRect( QRect(Rs.x()+1, Rs.y(), Rs.width()-2, 2),
                              pal.color(QPalette::Highlight));
              p->setPen( pal.color(QPalette::Highlight) );
              p->drawLine( Rs.x(), Rs.y()+1, Rs.x(), Rs.y()+2 );
              p->drawLine( Rs.right(), Rs.y()+1, Rs.right(), Rs.y()+2 );
            }
            /*renderSurface(p, Rs,
                          pal.color(QPalette::Background), pal.color(QPalette::Button), getColor(pal,MouseOverHighlight), _contrast,
                          Draw_Top|Draw_Bottom|Is_Horizontal);*/

            //hide the panel border
            p->fillRect( QRect(Rb.x()+1, Rb.bottom()-1, Rb.width()-1, 2), pal.color(QPalette::Background) );

        }
        else
        {
            p->setPen(pal.color(QPalette::Highlight));
            //p->drawLine(Rs.x()+1, Rs.bottom(), Rs.right()-1, Rs.bottom() );
            if( _highLightTab )
            {
              p->fillRect(Rs.x()+1, Rs.bottom()-1, Rs.width()-2, 2, pal.color(QPalette::Highlight) );
              p->drawLine(Rs.x(), Rs.bottom()-2, Rs.x(), Rs.bottom()-1 );
              p->drawLine(Rs.right(), Rs.bottom()-2, Rs.right(), Rs.bottom()-1 );
            }

            renderGradient(p, QRect(Rs.x(), Rs.y(), 1, Rs.height()-4),
                            getColor(pal,PanelLight), getColor(pal,PanelLight2));
            renderGradient(p, QRect(Rs.right(), Rs.y(), 1, Rs.height()-4),
                            getColor(pal,PanelDark), getColor(pal,PanelDark2));

            renderSurface(p, QRect(Rs.x()+1, Rs.y(), Rs.width()-2, Rs.height()-3), pal.color(QPalette::Background), pal.color(QPalette::Background), pal.color(QPalette::Highlight), _contrast, Is_Horizontal);
            //hide the panel border
            p->fillRect( QRect(Rb.x()+1, Rb.top(), Rb.width()-1, 2), pal.color(QPalette::Background) );

        }

    // some "position specific" paintings...

        // left connection from the panel border to the tab. :)
        if(isFirst && !reverseLayout && !cornerWidget) {
            p->setPen(alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 50) );
            p->drawLine(Rb.x(), Rb.y(), Rb.x(), Rb.bottom() );
            p->setPen(getColor(pal,PanelLight) );
            p->drawLine(Rb.x()+1, Rb.y(), Rb.x()+1, Rb.bottom() );
        } else if(isFirst && reverseLayout && !cornerWidget) {
            p->setPen(alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 50) );
            p->drawLine(Rb.right(), Rb.y(), Rb.right(), Rb.bottom() );
            p->setPen(getColor(pal,PanelDark) );
            p->drawLine(Rb.right()-1, Rb.y(), Rb.right()-1, Rb.bottom() );
        }
        // rounded connections to the panel...
        if(!bottom) {
            // left
            if( (!isFirst && !reverseLayout) || (reverseLayout) || (isFirst && !reverseLayout && cornerWidget) ) {
                p->setPen( alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 50) );
                p->drawPoint(Rb.x(), Rb.y());
                p->setPen( alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 150) );
                p->drawPoint(Rb.x(), Rb.y()+1);
                p->drawPoint(Rb.x()+1, Rb.y());
            }
            // right
            if( (!reverseLayout) || (!isFirst && reverseLayout) || (isFirst && reverseLayout) ) {
                p->setPen( alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 50) );
                p->drawPoint(Rb.right(), Rb.y());
                p->setPen( alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 150) );
                p->drawPoint(Rb.right(), Rb.y()+1);
                p->drawPoint(Rb.right()-1, Rb.y());
            }
        } else {
            // left
            if( (!isFirst && !reverseLayout) || (reverseLayout) || (isFirst && !reverseLayout && cornerWidget) ) {
                p->setPen( alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 50) );
                p->drawPoint(Rb.x(), Rb.bottom());
                p->setPen( alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 150) );
                p->drawPoint(Rb.x(), Rb.bottom()-1);
                p->drawPoint(Rb.x()+1, Rb.bottom());
            }
            // right
            if( (!reverseLayout) || (!isFirst && reverseLayout) || (isFirst && reverseLayout && cornerWidget) ) {
                p->setPen( alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 50) );
                p->drawPoint(Rb.right(), Rb.bottom());
                p->setPen( alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 150) );
                p->drawPoint(Rb.right(), Rb.bottom()-1);
                p->drawPoint(Rb.right()-1, Rb.bottom());
            }
        }

    }
    else
    {
    // inactive tabs

    // the top part of the tab which is nearly the same for all positions
        QRect Rc; // contour
        if (isFirst&&reverseLayout ) {
            Rc = QRect(r.x()+1, (bottom?r.y()+2:(triangular?r.y()+2:r.y()+3)), r.width()-2, (triangular?r.height()-4:r.height()-5) );
        } else {
            Rc = QRect(r.x()+1, (bottom?r.y()+2:(triangular?r.y()+2:r.y()+3)), r.width()-1, (triangular?r.height()-4:r.height()-5) );
        }

        if(pos == QStyleOptionTab::Middle
           || pos == QStyleOptionTab::Beginning)
        {
          Rc.adjust(0,0,1,0);
        }
        if( selected == PrevTab )
        {
          Rc.adjust(-2,0,0,0);
        }

        QRect Rs; // the resulting surface
        if ( (isFirst&&!reverseLayout) || (isLast&&reverseLayout) )
            Rs = QRect(Rc.x()+1,
                       bottom?Rc.y():Rc.y()+1,
                       Rc.width()-(selected == OtherTab?2:1),
                       Rc.height()-1);
        else if( reverseLayout ){
            Rs = QRect(Rc.x()-(selected == NextTab?1:0),
                       bottom?Rc.y():Rc.y()+1,
                       Rc.width()-(selected == OtherTab?1:0),
                       Rc.height()-1);
        }
        else{
            Rs = QRect(Rc.x()-(selected == PrevTab?1:0),
                       bottom?Rc.y():Rc.y()+1,
                       Rc.width()-(selected == OtherTab?1:0),
                       Rc.height()-1);
        }
        // the area where the fake border shoudl appear
        const QRect Rb(r.x(), bottom?r.y():Rc.bottom()+1, r.width(), 2 );

        uint contourFlags;
        if(!bottom) {
            if ( (isFirst&&!reverseLayout) || (isLast&&reverseLayout) ) {
                contourFlags = Draw_Left|Draw_Right|Draw_Top|Sharp_UpperRight|Round_UpperLeft;
            } else if ( (isLast&&!reverseLayout) || (isFirst&&reverseLayout) ) {
                contourFlags = Draw_Right|Draw_Top|Sharp_UpperLeft|Round_UpperRight;
            } else {
                contourFlags = Draw_Right|Draw_Top|Sharp_UpperLeft|Sharp_UpperRight;
            }
        } else {
            if ( (isFirst&&!reverseLayout) || (isLast&&reverseLayout) ) {
                contourFlags = Draw_Left|Draw_Right|Draw_Bottom|Sharp_BottomRight|Round_BottomLeft;
            } else if ( (isLast&&!reverseLayout) || (isFirst&&reverseLayout) ) {
                contourFlags = Draw_Right|Draw_Bottom|Sharp_BottomLeft|Round_BottomRight;
            } else {
                contourFlags = Draw_Right|Draw_Bottom|Sharp_BottomLeft|Sharp_BottomRight;
            }
        }
        renderContour(p, Rc,
                        pal.color(QPalette::Background), getColor(pal, ButtonContour),
                        contourFlags);

        uint surfaceFlags = Is_Horizontal;
        if(mouseOver) {
            surfaceFlags |= (bottom?Highlight_Bottom:Highlight_Top);
            surfaceFlags |= Is_Highlight;
        }
        if ( (isFirst&&!reverseLayout) || (isLast&&reverseLayout) ) {
            if(!bottom)
                surfaceFlags |= Draw_Left|Draw_Top|Round_UpperLeft;
            else
                surfaceFlags |= Draw_Left|Draw_Bottom|Round_BottomLeft;
        } else if ( (isLast&&!reverseLayout) || (isFirst&&reverseLayout) ) {
            if(!bottom)
                surfaceFlags |= Draw_Right|Draw_Top|Round_UpperRight;
            else
                surfaceFlags |= Draw_Right|Draw_Bottom|Round_BottomRight;
        } else {
            surfaceFlags |= (!bottom?Draw_Top:Draw_Bottom);
        }
        renderSurface(p, Rs,
                        pal.color(QPalette::Background), pal.color(QPalette::Button), getColor(pal,MouseOverHighlight), _contrast,
                        surfaceFlags);

    // some "position specific" paintings...
        // fake parts of the panel border
#if 0
        if(!bottom) {
            p->setPen(alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 50) );
            p->drawLine(Rb.x(), Rb.y(), ((isLast&&!reverseLayout)||(isFirst&&reverseLayout&&cornerWidget))?Rb.right():Rb.right()-1, Rb.y());
            p->setPen(getColor(pal,PanelLight) );
            //p->drawLine(Rb.x(), Rb.y()+1, ((isLast&&!reverseLayout)||(isFirst&&reverseLayout&&cornerWidget))?Rb.right():Rb.right()-1, Rb.y()+1 );
        } else {
            p->setPen(alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 50) );
            p->drawLine(Rb.x(), Rb.bottom(), ((isLast&&!reverseLayout)||(isFirst&&reverseLayout&&cornerWidget))?Rb.right():Rb.right()-1, Rb.bottom());
            p->setPen(getColor(pal,PanelDark) );
            p->drawLine(Rb.x(), Rb.bottom()-1, ((isLast&&!reverseLayout)||(isFirst&&reverseLayout&&cornerWidget))?Rb.right():Rb.right()-1, Rb.bottom()-1 );
        }
#endif
        // fake the panel border edge for tabs which are aligned left-most
        // (i.e. only if there is no widget in the corner of the tabwidget!)
        if(isFirst&&!reverseLayout&&!cornerWidget)
        // normal layout
        {
            if (!bottom) {
                p->setPen(alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 50) );
                p->drawPoint(Rb.x()+1, Rb.y()+1 );
                p->setPen(alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 150) );
                p->drawPoint(Rb.x(), Rb.y()+1 );
                p->setPen(pal.color(QPalette::Background) );
                p->drawPoint(Rb.x(), Rb.y() );
                p->setPen(alphaBlendColors( alphaBlendColors(pal.color(QPalette::Background), getColor(pal, ButtonContour), 50), getColor(pal,PanelContour), 150) );
                p->drawPoint(Rb.x()+1, Rb.y() );
            } else {
                p->setPen(alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 50) );
                p->drawPoint(Rb.x()+1, Rb.bottom()-1 );
                p->setPen(alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 150) );
                p->drawPoint(Rb.x(), Rb.bottom()-1 );
                p->setPen(pal.color(QPalette::Background) );
                p->drawPoint(Rb.x(), Rb.bottom() );
                p->setPen(alphaBlendColors( alphaBlendColors(pal.color(QPalette::Background), getColor(pal, ButtonContour), 50), getColor(pal,PanelContour), 150) );
                p->drawPoint(Rb.x()+1, Rb.bottom() );
            }
        } else if(isFirst&&reverseLayout&&!cornerWidget)
        // reverse layout
        {
            if (!bottom) {
                p->setPen(alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 50) );
                p->drawPoint(Rb.right()-1, Rb.y()+1 );
                p->setPen(alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 150) );
                p->drawPoint(Rb.right(), Rb.y()+1 );
                p->setPen(pal.color(QPalette::Background) );
                p->drawPoint(Rb.right(), Rb.y() );
                p->setPen(alphaBlendColors( alphaBlendColors(pal.color(QPalette::Background), getColor(pal, ButtonContour), 50), getColor(pal,PanelContour), 150) );
                p->drawPoint(Rb.right()-1, Rb.y() );
            } else {
                p->setPen(alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 50) );
                p->drawPoint(Rb.right()-1, Rb.bottom()-1 );
                p->setPen(alphaBlendColors(pal.color(QPalette::Background), getColor(pal,PanelContour), 150) );
                p->drawPoint(Rb.right(), Rb.bottom()-1 );
                p->setPen(pal.color(QPalette::Background) );
                p->drawPoint(Rb.right(), Rb.bottom() );
                p->setPen(alphaBlendColors( alphaBlendColors(pal.color(QPalette::Background), getColor(pal, ButtonContour), 50), getColor(pal,PanelContour), 150) );
                p->drawPoint(Rb.right()-1, Rb.bottom() );
            }
        }
    }
}


void PolyesterStyle::renderArrow( QPainter *p, const QRect &rect,
                                  const QColor color, Direction direction ) const
{
  int centerX = rect.center().x();
  int centerY = rect.center().y();
  int halfWidth = 3;
  int halfHeight = 2;

  QPointF points[3];

  switch(direction)
  {
    case Up:
      centerX++;
      points[0] = QPointF(centerX, centerY-halfHeight+1);
      points[1] = QPointF(centerX-halfWidth, centerY+halfHeight);
      points[2] = QPointF(centerX+halfWidth, centerY+halfHeight);
      break;
    case Down:
      centerX++;
      points[0] = QPointF(centerX-halfWidth, centerY-halfHeight+1);
      points[1] = QPointF(centerX+halfWidth, centerY-halfHeight+1);
      points[2] = QPointF(centerX, centerY+halfHeight);
      break;
    case Left:
      centerY++;
      points[0] = QPointF(centerX-halfHeight+1, centerY);
      points[1] = QPointF(centerX+halfHeight, centerY-halfWidth);
      points[2] = QPointF(centerX+halfHeight, centerY+halfWidth);
      break;
    //Default: Right
    default:
      centerY++;
      points[0] = QPointF(centerX-halfHeight+1, centerY-halfWidth);
      points[1] = QPointF(centerX-halfHeight+1, centerY+halfWidth);
      points[2] = QPointF(centerX+halfHeight, centerY);
      break;
  };
  p->save();
  p->setRenderHint(QPainter::Antialiasing, true);
  p->setBrush(color);
  p->setPen(QPen ( color, 1, Qt::SolidLine, Qt::RoundCap));
  p->drawPolygon(points, 3);
  p->restore();
}

void PolyesterStyle::drawPrimitive(PrimitiveElement pe,
                               const QStyleOption *option,
                               QPainter *p,
                               const QWidget *widget) const
{
    const bool reverseLayout = option->direction == Qt::RightToLeft;
    const State &flags = option->state;
    const QPalette &pal = option->palette;
    const QRect &r = option->rect;

    bool down   = flags & State_Sunken;
    bool on     = flags & State_On;
    bool sunken = down;
    bool horiz  = flags & State_Horizontal;
    const bool enabled = flags & State_Enabled;
    const bool mouseOver = flags & State_MouseOver;
    bool hasFocus = flags & State_HasFocus;

    int x = r.x();
    int y = r.y();
    int w = r.width();
    int h = r.height();

    int x2, y2;
    r.getCoords(&x, &y, &x2, &y2);

    switch(pe) {
    // BUTTONS
    // -------
        case PE_FrameFocusRect:
        {
          if(_drawFocusRect) //FIXME: it's necessary to be configurable? naaah :)
            {
              //Figuring out in what beast we are painting...
              //QWidget *widget = dynamic_cast<QWidget*>( p->device() );
              //rendercontour isn't able to draw with negative measures
              //rounded border in a listview/listbox is ugly
              //also if the background and the border color are equal the result is ugly
              if( r.width() < 0 || r.height() < 0 ||
                  /*(widget &&
                      (dynamic_cast<QScrollArea*>( widget->parent() ) ||
                      dynamic_cast<QListBox*>(  widget->parent()) )
                  ) ||*/
                  pal.color(QPalette::Background) == getColor(pal, ButtonContour)
                )
              {
                p->setPen( getColor(pal, ButtonContour) );
                p->drawRect( r );
                break;
              }

              QColor backgroundColor = pal.color(QPalette::Background);

              renderContour(p, r, backgroundColor, getColor(pal,ButtonContour),
                            Draw_Left| Draw_Right|Draw_Top|Draw_Bottom|
                              Round_UpperLeft|Round_UpperRight|
                              Round_BottomLeft|Round_BottomRight|Draw_AlphaBlend
                          );
            }
            break;
        }

        case PE_PanelButtonTool:
        {
            int animFrame = 0;

            QWidget* nonConstWidget = const_cast<QWidget*>(widget);
            if( _animateButton && animWidgets.contains(nonConstWidget) )
                animFrame = (int)animWidgets[nonConstWidget].animFrame;
            //const QStyleOptionButton* opt = qstyleoption_cast<const QStyleOptionButton*>(option);

            //vertical if the height is more than double the width
            if( on||down )
              renderButton(p, r, pal, true, mouseOver, ((qreal)r.width()/(qreal)r.height()) > 0.4, enabled,
                         animFrame, false );
            else
            {
              uint bflags = Draw_Right|Draw_Left|Draw_Top|Draw_Bottom|
                            Round_UpperRight|Round_BottomRight|
                            Round_UpperLeft|Round_BottomLeft;

              if( ((qreal)r.width()/(qreal)r.height()) > 0.4 )
                bflags |= Is_Horizontal;

              renderContour(p, r, pal.color(QPalette::Background),
                            getColor(pal, ButtonContour), bflags );
              renderSurface(p, r.adjusted(1,1,-1,-1),
                      pal.color(QPalette::Background), pal.color(QPalette::Background).light(100+animFrame), pal.color(QPalette::Background),
                      _contrast,
                      bflags);
            }

            break;
        }
        case PE_PanelButtonBevel:
        //case PE_PanelButtonTool:
        case PE_IndicatorButtonDropDown:
        case PE_PanelButtonCommand:
        {
            int animFrame = 0;

            QWidget* nonConstWidget = const_cast<QWidget*>(widget);
            if( _animateButton && animWidgets.contains(nonConstWidget) )
                animFrame = (int)animWidgets[nonConstWidget].animFrame;
            const QStyleOptionButton* opt = qstyleoption_cast<const QStyleOptionButton*>(option);
            bool isDefault = opt && (opt->features & QStyleOptionButton::DefaultButton);
            //vertical if the height is more than double the width
            renderButton(p, r, pal, (on||down), mouseOver, ((qreal)r.width()/(qreal)r.height()) > 0.4, enabled,
                         animFrame, isDefault );
            break;
        }

        case PE_FrameDefaultButton:
        {
            uint contourFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|
                    Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight;
            if(!enabled) contourFlags|=Is_Disabled;
            renderContour(p, r, pal.color(QPalette::Background), pal.color(QPalette::Background).dark(120),
                    contourFlags);
            break;
        }

        case PE_IndicatorSpinPlus:
        case PE_IndicatorSpinMinus: {
            p->setPen( pal.color(QPalette::ButtonText) );

            int l = qMin( w-2, h-2 );
            // make the length even so that we get a nice symmetric plus...
            if(l%2 != 0)
                --l;
            QPoint c = r.center();

            p->drawLine( c.x()-l/2, c.y(), c.x()+l/2, c.y() );
            if ( pe == PE_IndicatorSpinPlus ) {
                p->drawLine( c.x(), c.y()-l/2, c.x(), c.y()+l/2 );
            }
            break;
        }


    // CHECKBOXES
    // ----------
        case PE_IndicatorCheckBox:
        {
            QColor contentColor = enabled?pal.color(QPalette::Base):pal.color(QPalette::Background);

            uint contourFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom;
            if(!enabled) {
                contourFlags |= Is_Disabled;
            }
            renderContour(p, r, pal.color(QPalette::Background), getColor(pal, ButtonContour),
                    contourFlags);

            // surface
            uint surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Is_Horizontal;
            if(!enabled) {
                surfaceFlags |= Is_Disabled;
            } else if(mouseOver) {
                contentColor = alphaBlendColors(contentColor, getColor(pal,MouseOverHighlight), 240);
                surfaceFlags |= Is_Highlight;
                surfaceFlags |= Highlight_Left|Highlight_Right|
                        Highlight_Top|Highlight_Bottom;
            }
            renderSurface(p, QRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2),
                    pal.color(QPalette::Background), contentColor, getColor(pal,MouseOverHighlight), enabled?_contrast+3:(_contrast/2), surfaceFlags);

            drawPrimitive(PE_IndicatorMenuCheckMark, option, p, widget);

            break;
        }


    // RADIOBUTTONS
    // ------------
        case PE_IndicatorRadioButton:
        {
            const QColor contourColor = getColor(pal, ButtonContour, enabled);
            QColor contentColor = enabled?pal.color(QPalette::Base):pal.color(QPalette::Background);
            QColor checkmarkColor = enabled?getColor(pal,CheckMark):pal.color(QPalette::Background);

            uint renderFlags = 0;
            if(!enabled) renderFlags |= Is_Disabled;
            if(mouseOver) renderFlags |= Is_Highlight;
            bool checked = (flags & State_On || flags & State_Sunken);
            renderRadioButton(p, r, contentColor, checkmarkColor, contourColor,
                               getColor(pal,MouseOverHighlight),
                               checked, renderFlags);
            break;
        }

    // GENERAL PANELS
    // --------------


        case PE_FrameGroupBox:
        {
          //FIXME
            /*if ( option.isDefault() || option.lineWidth() <= 0 )
                break;*/
            renderPanel(p, r, pal, false);

            break;
        }

        case PE_FrameWindow:
        {
          p->setPen( pal.color(QPalette::Highlight).dark(130+_contrast));
          p->drawRect(r.adjusted(0,0,-1,-1));
          int bottom = r.bottom()-pixelMetric(PM_MDIFrameWidth, option, widget)+1;
          p->fillRect(QRect(r.x(),bottom, r.right(), bottom),
                      pal.color(QPalette::Highlight).dark(130+_contrast));

          break;
        }

        case PE_Frame:
        {
#ifdef NO_KDE
          //HACK: if we are in a qmenu render like a surface
          if( ::qobject_cast<QMenu*>(widget->parent()) )
          {
            const bool top = (widget->pos().y() <= 2);
            renderSurface(p,r.adjusted(top?0:1,0,-1,-1),
                          pal.color(QPalette::Background),
                          pal.color(QPalette::Button),
                          pal.color(QPalette::Highlight));
            p->setPen(getColor(pal, ButtonContour, true));
            if( !top )
              p->drawLine(r.left(),r.top(), r.right(), r.top());
            p->drawLine(r.left(),r.bottom(), r.right(), r.bottom());
            break;
          }
#endif

          //normal frame
          bool pseudo3d = false;
          bool sunken = false;

          if (option->state & State_Sunken)
          {
            pseudo3d = true;
            sunken = true;
          }
          else if(option->state & State_Raised)
            pseudo3d = true;

          renderPanel(p, r, pal, pseudo3d, sunken, (option->state & QStyle::State_HasFocus));
          break;
        }

        case PE_PanelLineEdit:
        {
            //Comboboxes and spinboxes draws the panel for their own
            if (widget)
            {
              if (qobject_cast<const QComboBox *>(widget->parentWidget()))
                    break;

              if (qobject_cast<const QAbstractSpinBox *>(widget->parentWidget()))
                    break;
            }

            bool isReadOnly = false;
            bool isEnabled = true;
            bool hasFrame = true;
            // panel is highlighted by default if it has focus, but if we have access to the
            // widget itself we can try to avoid highlighting in case it's readOnly or disabled.
            if (p->device() && dynamic_cast<QLineEdit*>(p->device()))
            {
                QLineEdit* lineEdit = dynamic_cast<QLineEdit*>(p->device());
                isReadOnly = lineEdit->isReadOnly();
                isEnabled = lineEdit->isEnabled();
                hasFrame = lineEdit->hasFrame();
            }

            //Render background
            QRect filledRect = r.adjusted(1, 1, -1, -1);
            p->fillRect(filledRect, pal.color(QPalette::Base) );

            if( !hasFrame )
              break;

            uint contourFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|
                    Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight;


            QColor shadowColor;
            if ( _inputFocusHighlight && hasFocus && !isReadOnly && isEnabled)
            {
                renderContour(p, r, pal.color(QPalette::Background),
                              getColor(pal,FocusHighlight,enabled), contourFlags );
                shadowColor = getColor(pal,FocusHighlight,enabled);
            }
            else
            {
                renderContour(p, r, pal.color(QPalette::Background),
                              getColor(pal, ButtonContour, enabled), contourFlags );
                shadowColor = Qt::black;
            }

            //shadow or contour lines
            if( _sunkenShadows )
            {
              renderSunkenShadow(p, r.adjusted(1,1,-1,-1), shadowColor);
            }
            else
            {
              const QColor contentColor = enabled?pal.color(QPalette::Base):pal.color(QPalette::Background);
              if (_inputFocusHighlight && hasFocus && !isReadOnly && isEnabled)
              {
                  p->setPen( getColor(pal,FocusHighlight).dark(130) );
              }
              else
              {
                // deciding if the 3d effect should be done or not
                p->setPen(contentColor.dark(100+(_lightBorder?-30:30)) );
              }
              p->drawLine(r.left()+1, r.top()+2, r.left()+1, r.bottom()-2 );
              p->drawLine(r.left()+2, r.top()+1, r.right()-2, r.top()+1 );
              if (_inputFocusHighlight && hasFocus && !isReadOnly && isEnabled)
              {
                  p->setPen( getColor(pal,FocusHighlight).light(130) );
              }
              else
              {
                p->setPen(contentColor.light(130) );
              }
              p->drawLine(r.left()+2, r.bottom()-1, r.right()-2, r.bottom()-1 );
              p->drawLine(r.right()-1, r.top()+2, r.right()-1, r.bottom()-2 );
            }

            break;
        }

        case PE_FrameStatusBar: {
            if(_statusBarFrame)
	    {
              renderContour(p, r, pal.color(QPalette::Background), pal.color(QPalette::Background).dark(160),
                            Draw_Left|Draw_Right|Draw_Top|Draw_Bottom);
            }
            break;
        }

        case PE_FrameTabBarBase:
        {
          if( !dynamic_cast<const QTabWidget *>(widget->parent()))
          {
            p->setPen( getColor(pal, PanelContour) );
            p->drawLine(r.left(), r.top(), r.right(), r.top());
          }
          break;
        }
        case PE_FrameTabWidget:
        {
            renderPanel(p, r, pal, true, sunken);
            break;
        }

        case PE_FrameMenu: {
          /*TODO: is there a way tho check if we are a menubar popup or a normal popup?
           so in the menubar popup 
          (QApplication::reverseLayout()?Sharp_UpperRight:Sharp_UpperLeft)|
          could be added
          */
            renderContour(p, r, pal.color(QPalette::Background), pal.color(QPalette::Background).dark(200),
                          Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Draw_AlphaBlend);
            break;
        }

    // MENU / TOOLBAR PANEL
    // --------------------
        case PE_PanelMenuBar:
        case PE_FrameDockWidget:
        case PE_PanelToolBar:
        {
            // fix for toolbar lag (from Mosfet Liquid) 
            QWidget* w = dynamic_cast<QWidget*>(p->device());
            if(w && w->backgroundRole() == QPalette::Button) 
                w->setBackgroundRole(QPalette::Background);
            p->fillRect(r, pal.color(QPalette::Background));

            if ( _drawToolBarSeparator &&
                 //don't draw the separator under the menubars if the emphasys with border is on
                 !( pe==PE_PanelMenuBar && _menuBarEmphasis && _menuBarEmphasisBorder )
               ) {
                if ( r.width() > r.height() ) {
                    // avoid drawing a double light line
                    if(!_lightBorder)
                    {
                      p->setPen( getColor(pal, PanelLight) );
                      p->drawLine( r.left(), r.top(), r.right(), r.top() );
                      p->setPen( getColor(pal, PanelDark) );
                      p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() );
                    }
                    else
                    {
                      p->setPen( pal.color(QPalette::Background).dark(100+_contrast*4) );
                      p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() );
                    }
                }
                else {
                    if(!_lightBorder)
                    {
                      p->setPen( getColor(pal, PanelLight) );
                      p->drawLine( r.left(), r.top(), r.left(), r.bottom() );
                      p->setPen( getColor(pal, PanelDark) );
                      p->drawLine( r.right(), r.top(), r.right(), r.bottom() );
                    }
                    else
                    {
                      p->setPen( pal.color(QPalette::Background).dark(100+_contrast*4) );
                      p->drawLine( r.left(), r.top(), r.left(), r.bottom() );
                    }
                }
            }

            break;
        }

    // TOOLBAR/DOCK WINDOW HANDLE
        case PE_IndicatorDockWidgetResizeHandle:
        case PE_IndicatorToolBarHandle:
        {

            int counter = 1;
            //how far form the center we start to draw dots
            int fromCenter = 6;

            int hCenter = r.left()+r.width()/2;
            int vCenter = r.top()+r.height()/2;

            if( pe == PE_IndicatorDockWidgetResizeHandle )
            {
              horiz = !horiz;
              fromCenter = 12;
            }

            qreal opacity = p->opacity();
            /*handles*/
            if(horiz)
            {
                for(int j = vCenter-fromCenter; j <= vCenter+fromCenter; j+=6)
                {
                    //opacity from 0.5 (borders) to 1 (center)
                    p->setOpacity( 1.5-((double)qAbs(j-vCenter)/(double)fromCenter) );
                    renderDot(p, QPoint(hCenter-1, j), pal.color(QPalette::Background), true, true);
                    counter++;
                }
            } else {
                for(int j = hCenter-fromCenter; j <= hCenter+fromCenter; j+=6)
                {
                    p->setOpacity( 1.5-((double)qAbs(j-hCenter)/(double)fromCenter) );
                    renderDot(p, QPoint(j, vCenter-1), pal.color(QPalette::Background), true, true);
                    counter++;
                }
            }

            p->setOpacity( opacity);

            break;
        }


    // TOOLBAR SEPARATOR
    // -----------------
        case PE_IndicatorToolBarSeparator:
        {
            p->fillRect(r, pal.color(QPalette::Background));

            if(_drawToolBarItemSeparator) {
                if(horiz) {
                    int center = r.left()+r.width()/2;
                    if(!_lightBorder)
                    {
                       p->setPen( getColor(pal, PanelDark) );
                       p->drawLine( center-1, r.top()+3, center-1, r.bottom()-3 );
                       p->setPen( getColor(pal, PanelLight) );
                       p->drawLine( center, r.top()+3, center, r.bottom()-3 );
                    }
                    else
                    {
                       p->setPen( pal.color(QPalette::Background).dark(100+_contrast*4) );
                       p->drawLine( center, r.top()+3, center, r.bottom()-3 );
                    }
                } else {
                    int center = r.top()+r.height()/2;
                    if(!_lightBorder)
                    {
                      p->setPen( getColor(pal, PanelDark) );
                      p->drawLine( r.x()+3, center-1, r.right()-3, center-1 );
                      p->setPen( getColor(pal, PanelLight) );
                      p->drawLine( r.x()+3, center, r.right()-3, center );
                   }
                   else
                   {
                      p->setPen( pal.color(QPalette::Background).dark(100+_contrast*4) );
                      p->drawLine( r.x()+3, center, r.right()-3, center );
                   }
                }
            }
            break;
        }

        case PE_IndicatorMenuCheckMark:
        {
          if ( flags & State_Off )
            break;

          const QColor contentColor = enabled?pal.color(QPalette::Base):pal.color(QPalette::Background);
          QColor checkmarkColor = enabled?getColor(pal,CheckMark):pal.color(QPalette::Background);
          if(flags & State_Sunken)
              checkmarkColor = alphaBlendColors(contentColor, checkmarkColor, 150);

          p->save();
          p->setRenderHint(QPainter::Antialiasing);
          p->setPen(QPen(checkmarkColor, qRound((double)r.width()/5), Qt::SolidLine, Qt::RoundCap) );
          p->drawLine(r.left()+4, r.top()+4, r.right()-3, r.bottom()-3);
          if( flags & State_On )
            p->drawLine(r.left()+4, r.bottom()-3, r.right()-3, r.top()+4);
          p->restore();

          break;

        }

        case PE_IndicatorSpinUp:
        case PE_IndicatorArrowUp:
        {
          renderArrow(p, r, pal.color(QPalette::ButtonText), Up);
          break;
        }
        case PE_IndicatorSpinDown:
        case PE_IndicatorArrowDown:
        {
          //HACK: otherwise the arrow is not positioned correctly in pushbuttons
          const QPushButton *b = dynamic_cast<const QPushButton *>(widget);
          renderArrow(p, (b?r.translated(-3,0):r), pal.color(QPalette::ButtonText), Down);
          break;
        }
        case PE_IndicatorHeaderArrow:
        {
          const QStyleOptionHeader *headerOpt = qstyleoption_cast<const QStyleOptionHeader *>(option);
          if( !headerOpt )
            break;
          if( headerOpt->sortIndicator == QStyleOptionHeader::SortUp)
            renderArrow(p, r, pal.color(QPalette::ButtonText), Up);
          else
            renderArrow(p, r, pal.color(QPalette::ButtonText), Down);
          break;
        }
        case PE_IndicatorArrowLeft:
        {
          renderArrow(p, r, pal.color(QPalette::ButtonText), Left);
          break;
        }
        case PE_IndicatorArrowRight:
        {
          renderArrow(p, r, pal.color(QPalette::ButtonText), Right);
          break;
        }

         // copied and slightly modified from QWindowsStyle.
        case PE_IndicatorBranch:
        {
            // Typical Windows style listview branch element (dotted line).

            int hCenter = r.center().x();
            int vCenter = r.center().y();

            QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
            //p->setBrush(brush);

            if( option->state & (State_Open | State_Children | State_Item | State_Sibling) )
            {
              int lineHeight;
              if( option->state & State_Sibling )
                lineHeight = r.height();
              else
                lineHeight = r.height()/2;

              p->fillRect(QRect(hCenter, r.y(), 1, lineHeight), brush);

              if(option->state & State_Item)
                if( !reverseLayout )
                  p->fillRect(QRect(hCenter, vCenter, r.width()/2, 1), brush);
                else
                  p->fillRect(QRect(r.x(), vCenter, r.width()/2, 1), brush);
            }

            if (option->state & State_Children)
            {
              QRect expanderRect(hCenter - 4, r.center().y() - 4, 9, 9);

              if(!_drawTriangularExpander)
              {
                renderContour(p, expanderRect,
                              pal.color(QPalette::Base), pal.color(QPalette::Dark),
                              Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|
                              Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight );
                renderSurface(p, expanderRect.adjusted(1,1,-1,-1),
                              pal.color(QPalette::Base), pal.color(QPalette::Base).dark(120),
                              pal.color(QPalette::Base) );

                  p->setPen( pal.color(QPalette::Text) );
                  // plus or minus
                  p->drawLine( hCenter - 2, vCenter, hCenter + 2, vCenter );
                  if ( !(flags & State_Open) ) // Collapsed = On
                      p->drawLine( hCenter, vCenter - 2, hCenter, vCenter + 2 );
              }
              else
              {
                if( flags & State_Open )
                  renderArrow( p, expanderRect,
                               pal.color(QPalette::Text), Down );
                else
                  renderArrow( p, expanderRect,
                               pal.color(QPalette::Text), Right );
              }
  
            }
            break;
        }

        default: {
#ifdef NO_KDE
           return QWindowsStyle::drawPrimitive(pe, option, p, widget);
#else
           return KStyle::drawPrimitive(pe, option, p, widget);
#endif
        }
    }
}




/*
void PolyesterStyle::drawControlMask(ControlElement element,
                                  QPainter *p,
                                  const QWidget *w,
                                  const QRect &r,
                                  const QStyleOption &opt) const
{
    switch (element) {
        case CE_PushButton: {
                    p->fillRect (r, color0);
                    renderMask(p, r, color1,
                            Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight);
                    break;
        }

        default: {
            QWindowsStyle::drawControlMask (element, p, w, r, opt);
        }
    }
}

void PolyesterStyle::drawComplexControlMask(ComplexControl c,
                                         QPainter *p,
                                         const QWidget *w,
                                         const QRect &r,
                                         const QStyleOption &o) const
{
    switch (c) {
        case CC_SpinBox:
        case CC_ListView:
        case CC_ComboBox: {
                p->fillRect (r, color0);
                renderMask(p, r, color1,
                        Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight);
            break;
        }
        default: {
            QWindowsStyle::drawComplexControlMask (c, p, w, r, o);
        }
    }
}
*/
void PolyesterStyle::drawComplexControl( ComplexControl control,
                                         const QStyleOptionComplex *opt,
                                         QPainter *p,
                                         const QWidget *widget) const
{
    const bool reverseLayout = opt->direction == Qt::RightToLeft;
    const State &flags = opt->state;
    const QPalette &pal = opt->palette;
    const QRect &r = opt->rect;
    const bool enabled = (flags & State_Enabled);

    switch(control)
    {
      //TODO:probably i won't do this, it's too huge :)
        /*case CC_Q3ListView:
        {
          const QStyleOptionQ3ListView *lvOpt = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt);
          if( !lvOpt )
            break;

          if( lvOpt->subControls & (SC_Q3ListViewBranch | SC_Q3ListViewExpand) )
          {
            QStyleOption branchOpt;
            branchOpt.QStyleOption::operator=(*opt);
            branchOpt.rect = QRect( r.center().x(), r.y(), 1, r.height() );
            branchOpt.state |= State_Children;
            drawPrimitive(PE_IndicatorBranch, &branchOpt, p, widget );
            p->setPen(Qt::red);
            p->drawRect( r.adjusted(1,1,1,1) );
          }
          break;
        }*/

    // COMBOBOX
    // --------
        case CC_ComboBox:
        {
            static const unsigned int handleWidth = 15;

            //const QComboBox *cb = dynamic_cast<const QComboBox *>(widget);
            QComboBox *cb = (QComboBox *)(widget); // **hack**: cast away const-ness for animation support!
            // at the moment cb is only needed to check if the combo box is editable or not.
            // if cb doesn't exist, just assume false and the app (gideon! ;) ) at least doesn't crash.

            const QStyleOptionComboBox *comboOpt;
            comboOpt = qstyleoption_cast<const QStyleOptionComboBox*>(opt);
            if (!comboOpt) break;

            bool editable = false;
            bool hasFocus = false;
            if (cb)
            {
                editable = cb->isEditable();
                hasFocus = cb->hasFocus();
            }

            int animFrame = 0;
            if( _animateButton && animWidgets.contains( cb ))
                animFrame = animWidgets[cb].animFrame;

            const QColor buttonColor = enabled?pal.color(QPalette::Button).light(100+animFrame):pal.color(QPalette::Background);
            QColor highlightColor = pal.color(QPalette::Highlight);
            if( _animateButton )
            {
              highlightColor.setAlpha((int)(255*((double)animFrame/(double)ANIMATIONSTEPS)));
            }
            const QColor inputColor = enabled?(editable?pal.color(QPalette::Base):pal.color(QPalette::Button))
                                              :pal.color(QPalette::Background);

            uint contourFlags = 0;
            if( khtmlWidgets.contains(cb) )
                contourFlags |= Draw_AlphaBlend;
            
            if (_inputFocusHighlight && hasFocus && editable && enabled)
            {
                QRect editField = subControlRect(CC_ComboBox, comboOpt, SC_ComboBoxEditField, widget);
                QRect editFrame = r;
                QRect buttonFrame = r;
                
                uint editFlags = contourFlags;
                uint buttonFlags = contourFlags;
                
                // Hightlight only the part of the contour next to the control button
                if (reverseLayout)
                {
                    // querySubControlMetrics doesn't work right for reverse Layout
                    int dx = r.right() - editField.right();
                    editFrame.setLeft(editFrame.left() + dx);
                    buttonFrame.setRight(editFrame.left() - 1);
                    editFlags |= Draw_Right|Draw_Top|Draw_Bottom|Round_UpperRight|Round_BottomRight;
                    buttonFlags |= Draw_Left|Draw_Top|Draw_Bottom|Round_UpperLeft|Round_BottomLeft;
                }
                else
                {
                    editFrame.setRight(editField.right());
                    buttonFrame.setLeft(editField.right() + 1);
                    
                    editFlags |= Draw_Left|Draw_Top|Draw_Bottom|Round_UpperLeft|Round_BottomLeft;
                    buttonFlags |= Draw_Right|Draw_Top|Draw_Bottom|Round_UpperRight|Round_BottomRight;
                }
                renderContour(p, editFrame, pal.color(QPalette::Background),  getColor(pal,FocusHighlight,enabled), editFlags);
                renderContour(p, buttonFrame, pal.color(QPalette::Background), 
                              getColor(pal, ButtonContour, enabled), buttonFlags);
            }
            else
            {
                contourFlags |= Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|
                    Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight;
                renderContour(p, r, pal.color(QPalette::Background), getColor(pal, ButtonContour, enabled), contourFlags);
            }
            //extend the contour: between input and handler...
            p->setPen(alphaBlendColors(pal.color(QPalette::Background), getColor(pal, ButtonContour, enabled), 50) );
            if(reverseLayout) {
                p->drawLine(r.left()+1+handleWidth, r.top()+1, r.left()+1+handleWidth, r.bottom()-1);
            } else {
                p->drawLine(r.right()-handleWidth-1, r.top()+1, r.right()-handleWidth-1, r.bottom()-1);
            }

            const QRect RbuttonSurface(reverseLayout?r.left()+1:r.right()-handleWidth, r.top()+1,
                                        handleWidth, r.height()-2);
            const QRect RcontentSurface(reverseLayout?r.left()+1+handleWidth+1:r.left()+1, r.top()+1,
                                         r.width()-handleWidth-3, r.height()-2);

            // handler

            uint surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Is_Horizontal;
            if(reverseLayout) {
                surfaceFlags |= Round_UpperLeft|Round_BottomLeft;
            } else {
                surfaceFlags |= Round_UpperRight|Round_BottomRight;
            }

            if ( (animFrame != 0) || (flags & State_MouseOver))
            {
                surfaceFlags |= Is_Highlight;
                if(editable) surfaceFlags |= Highlight_Left|Highlight_Right;
                surfaceFlags |= Highlight_Top|Highlight_Bottom;
            }
            renderSurface(p, RbuttonSurface,
                           pal.color(QPalette::Background), buttonColor, highlightColor, enabled?_contrast+3:(_contrast/2),
                           surfaceFlags);

            if(!editable)
            {
                surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Is_Horizontal;
                if(reverseLayout) {
                    surfaceFlags |= Round_UpperRight|Round_BottomRight;
                } else {
                    surfaceFlags |= Round_UpperLeft|Round_BottomLeft;
                }

                if ( (animFrame != 0) || (flags & State_MouseOver)) {
                    surfaceFlags |= Is_Highlight;
                    surfaceFlags |= Highlight_Top|Highlight_Bottom;
                }
                renderSurface(p, RcontentSurface,
                               pal.color(QPalette::Background), buttonColor, highlightColor, enabled?_contrast+3:(_contrast/2),
                               surfaceFlags);
                if (hasFocus)
                {
                  QStyleOptionFocusRect focusOpt;
                  focusOpt.QStyleOption::operator=(*comboOpt);
                  focusOpt.rect = subElementRect(SE_ComboBoxFocusRect,
                                              comboOpt, widget);
                    drawPrimitive(PE_FrameFocusRect, &focusOpt, p, widget );
                }
            }
            else
            {
              // input area
              QRect filledRect = RcontentSurface.adjusted(1, 1, -1, -1);
              p->fillRect(filledRect, inputColor );

              //shadow or border
              if( _sunkenShadows )
              {
                renderSunkenShadow(p, RcontentSurface,
                                   (_inputFocusHighlight && hasFocus && editable && enabled)
                                    ?getColor(pal,FocusHighlight):Qt::black,
                                   Draw_Top|Draw_Bottom|Draw_Left|Draw_Right|
                                     (reverseLayout?Sharp_UpperLeft|Sharp_BottomLeft
                                                   :Sharp_UpperRight|Sharp_BottomRight));
              }
              else
              {
                // thin frame around the input area
                if (_inputFocusHighlight && hasFocus && editable && enabled)
                {
                  p->setPen( getColor(pal,FocusHighlight).dark(130) );
                }
                else
                {
                  p->setPen(inputColor.dark(100+(_lightBorder?-30:30)) );
                }
                p->drawLine(RcontentSurface.x(), reverseLayout?RcontentSurface.y():RcontentSurface.y()+1,
                        RcontentSurface.x(), reverseLayout?RcontentSurface.bottom():RcontentSurface.bottom()-1);
                p->drawLine(RcontentSurface.x()+1, RcontentSurface.y(),
                        reverseLayout?RcontentSurface.right()-1:RcontentSurface.right(), RcontentSurface.y() );
                if (_inputFocusHighlight && hasFocus && editable && enabled)
                {
                  p->setPen( getColor(pal,FocusHighlight).light(130) );
                }
                else
                {
                  p->setPen(inputColor.light(130) );
                }
                p->drawLine(reverseLayout?RcontentSurface.x():RcontentSurface.x()+1, RcontentSurface.bottom(),
                        reverseLayout?RcontentSurface.right()-1:RcontentSurface.right(), RcontentSurface.bottom() );
                p->drawLine(RcontentSurface.right(), RcontentSurface.top()+1,
                        RcontentSurface.right(), RcontentSurface.bottom()-1 );
              }

            }

            p->setPen(pal.color(QPalette::Foreground));

            QStyleOption arrowOpt;
            arrowOpt.QStyleOption::operator=(*opt);
            arrowOpt.rect = RbuttonSurface;
            drawPrimitive(PE_IndicatorSpinDown, &arrowOpt, p, widget);/*p, RbuttonSurface, cg, Style_Default|Style_Enabled|State_Raised);*/

            // QComboBox draws the text using pal.color(QPalette::Text), we can override this
            // from here TODO: shadow here?
            /*p->setPen( pal.color(QPalette::ButtonText) );
            p->setBackgroundColor( pal.color(QPalette::Button) );*/
            break;
        }

        case CC_Slider: //The slider: at the moment it has many fixed sizes, maybe this is going to change...
        {
            //const QSlider* slider = (const QSlider*)widget;
            const QStyleOptionSlider *slidOpt = qstyleoption_cast<const QStyleOptionSlider*>(opt);
            if(!slidOpt) break;

            bool horizontal = slidOpt->orientation == Qt::Horizontal;

            QRect handleRect = QCommonStyle::subControlRect(CC_Slider, slidOpt, SC_SliderHandle, widget);

            int vCenter = r.center().y();
            int hCenter = r.center().x();

            //Giving the handleRect a fixed size...
            if (horizontal)
            {
              handleRect.setHeight(16);
              handleRect.moveCenter(QPoint(handleRect.center().x(), vCenter));
            }
            else
            {
              handleRect.setWidth(16);
              handleRect.moveCenter(QPoint(hCenter, handleRect.center().y()));
            }


            //SLIDER GROOVE
            if( (opt->subControls & SC_SliderGroove) )
            {

              if (horizontal)
              {
                  int coloredWidth = handleRect.center().x();

                  QRect coloredRect;
                  QRect emptyRect;
                  if(slidOpt->upsideDown)
                  {
                    emptyRect = QRect(r.left(), vCenter-3, handleRect.center().x(), 5);
                    coloredRect = QRect(coloredWidth, vCenter-3, r.width()-coloredWidth, 5);
                  }
                  else
                  {
                    emptyRect = QRect(coloredWidth, vCenter-3, r.width()-coloredWidth, 5);
                    coloredRect = QRect(r.left(), vCenter-3, handleRect.center().x(), 5);
                  }
  
                  //colored part
                  renderContour(p, coloredRect,
                                pal.color(QPalette::Background),
                                enabled && _coloredScrollBar?getColor(pal, DragButtonContour, IsEnabled)
                                        :pal.color(QPalette::Background).dark(130),
                                Draw_Left|Draw_Right|Draw_Top|Draw_Bottom);
                  renderGradient(p, QRect(coloredRect.x()+1, vCenter-2,
                                          coloredRect.width()-2, 3),
                                enabled && _coloredScrollBar?pal.color(QPalette::Highlight).light(100+_contrast*4)
                                        :pal.color(QPalette::Background).dark(120-_contrast),
                                enabled && _coloredScrollBar?pal.color(QPalette::Highlight)
                                        :pal.color(QPalette::Background).dark(120), true);
  
                  //empty part
                  renderContour(p, emptyRect,
                                pal.color(QPalette::Background), pal.color(QPalette::Background).dark(enabled?150:130),
                                Draw_Left|Draw_Right|Draw_Top|Draw_Bottom);
                  renderGradient(p, QRect(emptyRect.x()+1, vCenter-2,
                                          emptyRect.width()-2, 3),
                                pal.color(QPalette::Background).dark(100+_contrast*4),
                                pal.color(QPalette::Background).light(100+_contrast), true);
            }
            else
            {
                  int nonColoredHeight = handleRect.center().y();

                  QRect coloredRect;
                  QRect emptyRect;
                  if(!slidOpt->upsideDown)
                  {
                    emptyRect = QRect(hCenter-3, nonColoredHeight, 5, r.height()-nonColoredHeight);
                    coloredRect = QRect(hCenter-3, r.y(), 5, nonColoredHeight);
                  }
                  else
                  {
                    emptyRect = QRect(hCenter-3, r.y(), 5, nonColoredHeight);
                    coloredRect = QRect(hCenter-3, nonColoredHeight, 5, r.height()-nonColoredHeight);
                  }
  
                  //colored part
                  renderContour(p, coloredRect,
                                pal.color(QPalette::Background),
                                enabled && _coloredScrollBar?getColor(pal, DragButtonContour, IsEnabled)
                                        :pal.color(QPalette::Background).dark(130),
                                Draw_Left|Draw_Right|Draw_Top|Draw_Bottom);
                  renderGradient(p, QRect(hCenter-2, coloredRect.y()+1,
                                          3, coloredRect.height()-2),
                                enabled?pal.color(QPalette::Highlight).light(100+_contrast*4)
                                        :pal.color(QPalette::Background).dark(120-_contrast),
                                enabled?pal.color(QPalette::Highlight)
                                        :pal.color(QPalette::Background).dark(120), false);
  
                  //empty part
                  renderContour(p, emptyRect,
                                pal.color(QPalette::Background), pal.color(QPalette::Background).dark(enabled?150:130),
                                Draw_Left|Draw_Right|Draw_Top|Draw_Bottom);
                  renderGradient(p, QRect(hCenter-2, emptyRect.y()+1, 3,
                                          emptyRect.height()-2),
                                pal.color(QPalette::Background).dark(100+_contrast*4),
                                pal.color(QPalette::Background).light(100+_contrast), false);
              }
            }

            //SLIDER HANDLE
            if (slidOpt->subControls & SC_SliderHandle)
            {
              p->save();

              if( opt->subControls & SC_SliderTickmarks )
              {
                QRegion mask(handleRect);
                QBitmap bmp = QBitmap::fromData(QSize( 8, 13 ), slider_mask_bits);

                if(horizontal)
                {
                  if(slidOpt->tickPosition == QSlider::TicksBelow ||
                     slidOpt->tickPosition == QSlider::TicksBothSides)
                    bmp = bmp.transformed(QTransform().rotate(90));
                  else
                    bmp = bmp.transformed(QTransform().rotate(-90));
                }
                else if(slidOpt->tickPosition == QSlider::TicksLeft)
                  bmp = bmp.transformed(QTransform().rotate(180));


                QRegion triangle(bmp);
                if(horizontal && (slidOpt->tickPosition == QSlider::TicksBelow ||
                                  slidOpt->tickPosition == QSlider::TicksBothSides))
                  triangle.translate(handleRect.x()-2, handleRect.bottom()-7);
                else if(!horizontal && (slidOpt->tickPosition == QSlider::TicksRight ||
                                        slidOpt->tickPosition == QSlider::TicksBothSides))
                  triangle.translate(handleRect.right()-7, handleRect.top()-1);
                else if(horizontal && slidOpt->tickPosition == QSlider::TicksAbove)
                  triangle.translate(handleRect.x()-1, handleRect.top()-1);
                else if(!horizontal && slidOpt->tickPosition == QSlider::TicksLeft)
                  triangle.translate(handleRect.left()-1, handleRect.top()-2);

                mask -= triangle;
                p->setClipRegion(mask);

              }
              renderContour(p, handleRect,
                            pal.color(QPalette::Background),
                            enabled && _coloredScrollBar?getColor(pal, DragButtonContour, IsEnabled)
                                    :pal.color(QPalette::Background).dark(130),
                            Draw_Left|Draw_Right|Draw_Top|Draw_Bottom);
              renderSurface(p, QRect(handleRect.x()+1, handleRect.y()+1,
                                      handleRect.width()-2, handleRect.height()-2),
                            pal.color(QPalette::Background),
                            enabled && _coloredScrollBar?getColor(pal, DragButtonSurface, IsEnabled)
                                        :pal.color(QPalette::Button),
                            pal.color(QPalette::Highlight),
                            5, Draw_Left|Draw_Right|
                                Draw_Top|Draw_Bottom|Is_Horizontal);

              //two of the dots may be useless because could be off mask,
              //but not painting them would make the code even more complicate :)
              renderDot(p, QPoint(handleRect.left()+2, handleRect.top()+2),
                        enabled && _coloredScrollBar?getColor(pal, DragButtonSurface, IsEnabled)
                                        :pal.color(QPalette::Button),
                        false, true);
              renderDot(p, QPoint(handleRect.right()-3, handleRect.top()+2),
                        enabled && _coloredScrollBar?getColor(pal, DragButtonSurface, IsEnabled)
                                        :pal.color(QPalette::Button),
                        false, true);
              renderDot(p, QPoint(handleRect.left()+2, handleRect.bottom()-3),
                        enabled && _coloredScrollBar?getColor(pal, DragButtonSurface, IsEnabled)
                                        :pal.color(QPalette::Button),
                        false, true);
              renderDot(p, QPoint(handleRect.right()-3, handleRect.bottom()-3),
                        enabled && _coloredScrollBar?getColor(pal, DragButtonSurface, IsEnabled)
                                        :pal.color(QPalette::Button),
                        false, true);


              p->restore();

              if (opt->subControls & SC_SliderTickmarks)
              {
                p->setPen(enabled && _coloredScrollBar?getColor(pal, DragButtonContour, IsEnabled)
                                        :getColor(pal, ButtonContour, IsEnabled));
                if(horizontal)
                {
                  if( slidOpt->tickPosition != QSlider::TicksAbove )
                  {
                    p->drawLine(handleRect.left(), handleRect.bottom()-5,
                                handleRect.center().x(), handleRect.bottom());
                    p->drawLine(handleRect.right(), handleRect.bottom()-5,
                                handleRect.center().x(), handleRect.bottom());
                    p->setPen((enabled && _coloredScrollBar?getColor(pal, DragButtonSurface, IsEnabled)
                                        :pal.color(QPalette::Button)).light(110+_contrast));
                    p->drawLine(handleRect.left()+1, handleRect.bottom()-5,
                                handleRect.center().x(), handleRect.bottom()-1);
                    if( !_lightBorder )
                      p->setPen((enabled && _coloredScrollBar?getColor(pal, DragButtonSurface, IsEnabled)
                                        :pal.color(QPalette::Button)).dark(110+_contrast));
                    p->drawLine(handleRect.right()-1, handleRect.bottom()-5,
                                handleRect.center().x(), handleRect.bottom()-1);
                  }
                  else
                  {
                    p->drawLine(handleRect.left(), handleRect.top()+5,
                                handleRect.center().x(), handleRect.top());
                    p->drawLine(handleRect.right(), handleRect.top()+5,
                                handleRect.center().x(), handleRect.top());
                    p->setPen((enabled && _coloredScrollBar?getColor(pal, DragButtonSurface, IsEnabled)
                                        :pal.color(QPalette::Button)).light(110+_contrast));
                    p->drawLine(handleRect.left()+1, handleRect.top()+5,
                                handleRect.center().x(), handleRect.top()+1);
                    p->drawLine(handleRect.right()-1, handleRect.top()+5,
                                handleRect.center().x(), handleRect.top()+1);
                  }
                }
                else
                {
                  if( slidOpt->tickPosition != QSlider::TicksLeft )
                  {
                    p->drawLine(handleRect.right()-5, handleRect.top(),
                                handleRect.right(), handleRect.center().y());
                    p->drawLine(handleRect.right()-5, handleRect.bottom(),
                                handleRect.right(), handleRect.center().y());
                    p->setPen((enabled && _coloredScrollBar?getColor(pal, DragButtonSurface, IsEnabled)
                                        :pal.color(QPalette::Button)).light(110+_contrast));
                    p->drawLine(handleRect.right()-5, handleRect.top()+1,
                                handleRect.right()-1, handleRect.center().y());
                    if( !_lightBorder )
                      p->setPen((enabled && _coloredScrollBar?getColor(pal, DragButtonSurface, IsEnabled)
                                        :pal.color(QPalette::Button)).dark(110+_contrast));
                    p->drawLine(handleRect.right()-5, handleRect.bottom()-1,
                                handleRect.right()-1, handleRect.center().y());
                  }
                  else
                  {
                    p->drawLine(handleRect.left()+5, handleRect.top(),
                                handleRect.left(), handleRect.center().y());
                    p->drawLine(handleRect.left()+5, handleRect.bottom(),
                                handleRect.left(), handleRect.center().y());
                    p->setPen((enabled && _coloredScrollBar?getColor(pal, DragButtonSurface, IsEnabled)
                                        :pal.color(QPalette::Button)).light(110+_contrast));
                    p->drawLine(handleRect.left()+5, handleRect.top()+1,
                                handleRect.left()+1, handleRect.center().y());
                    p->drawLine(handleRect.left()+5, handleRect.bottom()-1,
                                handleRect.left()+1, handleRect.center().y());
                  }
                }
              }
            }

            //THICKMARKS
            if (slidOpt->subControls & SC_SliderTickmarks)
            {
              QStyleOptionSlider tmpSlidOpt = *slidOpt;
              tmpSlidOpt.subControls = SC_SliderTickmarks;
#ifdef NO_KDE
              QWindowsStyle::drawComplexControl(control, &tmpSlidOpt, p, widget);
#else
              KStyle::drawComplexControl(control, &tmpSlidOpt, p, widget);
#endif
            }
            break;
        }

    // TOOLBUTTON
    // ----------
      case CC_ToolButton:
        {
            QToolButton *tb = (QToolButton *) widget;// **hack**: cast away const-ness for animation support!

            const QStyleOptionToolButton *buttonOpt = qstyleoption_cast<const QStyleOptionToolButton *>(opt);
            if( !buttonOpt )
                break;
#ifndef NO_KDE
            //HACK: if we are in a qmenu we are a title
            bool menuTitle = false;
            if( ::qobject_cast<QMenu*>(widget->parent()) )
            {
                const bool top = (widget->pos().y() <= 2);
                renderSurface(p,r.adjusted(top?0:1,0,-1,-1),
                            pal.color(QPalette::Background),
                            pal.color(QPalette::Button),
                            pal.color(QPalette::Highlight));
                p->setPen(getColor(pal, ButtonContour, true));
                if( !top )
                p->drawLine(r.left(),r.top(), r.right(), r.top());
                p->drawLine(r.left(),r.bottom(), r.right(), r.bottom());
                
                // label in the toolbutton area
                QStyleOptionToolButton labelOpt = *buttonOpt;
                labelOpt.rect = r;
                labelOpt.state = QStyle::State_Active|QStyle::State_Enabled;
                drawControl(CE_ToolButtonLabel, &labelOpt, p, widget);
                break;
            }
#endif

            //QColorGroup g2 = cg;
            int animFrame = 0;
            if( _animateButton && animWidgets.contains( tb )){
                animFrame = animWidgets[tb].animFrame;
                /*g2.setColor( QColorGroup::Button, pal.color(QPalette::Button).light(100+animFrame) );*/
            }

            QRect button, menuarea;
            button   = subControlRect(control,
                                      buttonOpt,
                                      SC_ToolButton, widget);

            State bflags = buttonOpt->state,
                    mflags = buttonOpt->state;
            /*uint borderFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|
                    Round_UpperLeft|Round_UpperRight|Round_BottomLeft|Round_BottomRight;*/

            if ( animFrame == 0 && (bflags & State_AutoRaise) && !(bflags & State_MouseOver))
              bflags &= ~State_Raised;

            bflags &= ~State_MouseOver;


            if (buttonOpt->activeSubControls & SC_ToolButton)
                bflags |= State_Sunken;

            if (buttonOpt->activeSubControls & SC_ToolButtonMenu)
                mflags |= State_Sunken;

            //FIXME: special case for Tabbar
            if( ::qobject_cast<const QTabBar*>(widget->parent()) )
            {
              drawPrimitive(PE_PanelButtonTool, opt, p, widget);
            }
            else if( (buttonOpt->subControls & SC_ToolButton) &&
                (flags & State_Enabled) &&
                ((bflags & (State_Sunken| State_On | State_Raised)) || flags & State_MouseOver  ))
            {
              if( _animateButton && !(bflags & (State_Sunken| State_On )) )
              {
                qreal opacity = p->opacity();
                p->setOpacity((double)animFrame/(double)ANIMATIONSTEPS);
                drawPrimitive(PE_PanelButtonTool, opt, p, widget);
                p->setOpacity(opacity);
              }
              else
                drawPrimitive(PE_PanelButtonTool, opt, p, widget);
            }

            // Draw a toolbutton menu indicator if required
            if( buttonOpt->subControls & SC_ToolButtonMenu )
            {
              QRect menuarea = subControlRect(control,
                                              buttonOpt,
                                              SC_ToolButtonMenu, widget);

              renderArrow(p, menuarea, pal.color(QPalette::ButtonText), Down);

              p->save();
              if( _animateButton )
                p->setOpacity((double)animFrame/(double)ANIMATIONSTEPS);
              p->setPen(getColor(pal,ButtonContour));
              if(bflags & State_Raised )
                p->drawLine(menuarea.x()-2, menuarea.y(), menuarea.x()-2, menuarea.bottom());
              p->restore();
            }

            if (tb->hasFocus() && !tb->focusProxy()) {
                QRect fr = tb->rect();
                fr.adjusted(2, 2, -2, -2);
                drawPrimitive(PE_FrameFocusRect, opt, p, widget);
            }

            // label in the toolbutton area
            QStyleOptionToolButton labelOpt = *buttonOpt;
            labelOpt.rect = button;
            drawControl(CE_ToolButtonLabel, &labelOpt, p, widget);

            // Set the color for the ToolButton menu indicator
            //p->setPen(pal.color(QPalette::ButtonText) );

            break;
        }


      //Dial
      //-----------
      case CC_Dial:
      {
        const QStyleOptionSlider *sbOpt;
        sbOpt = qstyleoption_cast<const QStyleOptionSlider *>(opt);
        if (!sbOpt)
        {
#ifdef NO_KDE
          QWindowsStyle::drawComplexControl(QStyle::CC_Dial, opt, p, widget);
#else
          KStyle::drawComplexControl(QStyle::CC_Dial, opt, p, widget);
#endif
          break;
        }

        p->save();
        p->setRenderHint(QPainter::Antialiasing, true);

        const int margin = 5;
        const int width = qMin(r.width(),r.height())-2*margin;
        QRect dialRect(r.x()+margin, r.y()+margin, width, width);
        dialRect.moveCenter(QPoint(r.center().x(),r.center().y()));
        const int pinMargin = dialRect.width()/4;
        QRect pinRect(dialRect.adjusted(pinMargin,pinMargin,-pinMargin,-pinMargin));

        //border
        p->setPen(QPen(getColor(pal,ButtonContour),1));
        p->drawEllipse(dialRect);

        //light border and surface
        if( _sunkenShadows )
        {
          p->setPen(Qt::NoPen);
          QRadialGradient shadowGradient( dialRect.center().x()+1, dialRect.center().y()+3, (double)width/2.0 );
          QColor shadowColor = pal.color(QPalette::Base).dark(120+_contrast);
          shadowGradient.setColorAt(0,shadowColor);
          shadowGradient.setColorAt(0.5,shadowColor);
          shadowGradient.setColorAt(0.55,pal.color(QPalette::Base));
          shadowGradient.setColorAt(0.95,pal.color(QPalette::Base));
          shadowGradient.setColorAt(1,shadowColor);
          p->setBrush(shadowGradient);
        }
        else
        {
          //light border
          p->setPen(getColor(pal,PanelLight).light(110+_contrast));
          p->setBrush(getShadowBrush(dialRect, pal.color(QPalette::Button)));
        }
        p->drawEllipse(dialRect.adjusted(1,1,-1,-1));

        //central pin
        p->setPen(getColor(pal,ButtonContour));
        p->drawEllipse(pinRect);
        p->setPen(getColor(pal,PanelLight).light(110+_contrast));
        p->setBrush(getSurfaceBrush(pinRect, pal.color(QPalette::Button)));
        p->drawEllipse(pinRect.adjusted(1,1,-1,-1));

        if( _shadowedButtonsText )
        {
          p->setPen(pal.color(QPalette::Button).dark(120+_contrast));
          drawItemText(p, pinRect.adjusted(1,1,1,1),  Qt::AlignCenter, pal, enabled,
                      QString::number(sbOpt->sliderValue));
        }
        p->setPen(pal.color(QPalette::ButtonText));
        drawItemText(p, pinRect,  Qt::AlignCenter, pal, enabled,
                     QString::number(sbOpt->sliderValue));

        //p->drawText(pinRect.x(), pinRect.y(), sbOpt->sliderValue);



        // angle calculation from qcommonstyle.cpp (c) Trolltech 1992-2007.
        qreal angle;
        int sliderPosition = sbOpt->upsideDown ? sbOpt->sliderPosition : (sbOpt->maximum - sbOpt->sliderPosition);
        int range = sbOpt->maximum - sbOpt->minimum;
        if (!range)
          angle = PI / 2;
        else if (sbOpt->dialWrapping)
          angle = PI * 1.5 - (sliderPosition - sbOpt->minimum) * 2 * PI / range;
        else
          angle = (PI * 8 - (sliderPosition - sbOpt->minimum) * 10 * PI / range) / 6;


        const int pinSliderRatio = pinRect.width()/3;
        QRect sliderRect(pinRect.adjusted(pinSliderRatio,pinSliderRatio,-pinSliderRatio,-pinSliderRatio));
        const int r = (int)((double)dialRect.width()/2) - (int)((double)pinSliderRatio/1.4);
        sliderRect.translate(int(0.5 + r * cos(angle)), int(0.5 - r * sin(angle)));
        //p->setPen(QPen(Qt::NoBrush,0));
        p->setPen(getColor(pal,ButtonContour));
        p->drawEllipse(sliderRect);
        p->setBrush(getSurfaceBrush(sliderRect,
                                    sbOpt->state&QStyle::State_HasFocus
                                      ?pal.color(QPalette::Highlight)
                                      :pal.color(QPalette::Button)));
        p->setPen(getColor(pal,PanelLight).light(110+_contrast));
        p->drawEllipse(sliderRect.adjusted(1,1,-1,-1));

        p->restore();
        break;
      }

    //Titlebar
    //------------
      case CC_TitleBar:
      {
        const QStyleOptionTitleBar *titleBarOpt = qstyleoption_cast<const QStyleOptionTitleBar *>(opt);
        if( !titleBarOpt )
        {
#ifdef NO_KDE
          QWindowsStyle::drawComplexControl(QStyle::CC_TitleBar, opt, p, widget);
#else
          KStyle::drawComplexControl(QStyle::CC_TitleBar, opt, p, widget);
#endif
          break;
        }

        p->save();

        //TODO: use kwin settings
        renderGradient(p,r,pal.color(QPalette::Highlight).light(110+_contrast),
                       pal.color(QPalette::Highlight).dark(110+_contrast));

        //Dark border
        p->setPen(pal.color(QPalette::Highlight).dark(130+_contrast));
        p->drawLine(r.x(), r.y(), r.x(), r.bottom());
        p->drawLine(r.right(), r.y(), r.right(), r.bottom());
        p->drawLine(r.x(), r.y(), r.right(), r.y());
        //Light Border
        p->setPen(pal.color(QPalette::Highlight).light(130+_contrast));
        p->drawLine(r.x()+1, r.y()+1, r.right()-2, r.y()+1);
        renderGradient(p,QRect(r.x()+1, r.y()+1, 1, r.height()-1),
                       pal.color(QPalette::Highlight).light(130+_contrast),
                       pal.color(QPalette::Highlight).light(110+_contrast));
        renderGradient(p,QRect(r.right()-1, r.y()+1, 1, r.height()-1),
                       pal.color(QPalette::Highlight).light(130+_contrast),
                       pal.color(QPalette::Highlight).light(110+_contrast));

        //Text
        QFont font(p->font());
        font.setBold(true);
        font.setPixelSize((int)((double)r.height()/2));
        p->setFont(font);
        QRect textRect(subControlRect(CC_TitleBar, titleBarOpt, SC_TitleBarLabel, widget));
        //some calculations borrowed from qtcurve (c) Craig Drummond 2007
        bool tooWide((QFontMetrics(font).width(titleBarOpt->text) > textRect.width()));
        QTextOption textOpt((tooWide ? Qt::AlignLeft : Qt::AlignHCenter) | Qt::AlignVCenter);
        textOpt.setWrapMode(QTextOption::NoWrap);
        if( _shadowedButtonsText )
        {
          p->setPen(pal.color(QPalette::Highlight).dark(130+_contrast));
          p->drawText(textRect.adjusted(1,1,1,1), titleBarOpt->text, textOpt);
        }
        p->setPen(pal.color(QPalette::HighlightedText));
        p->drawText(textRect, titleBarOpt->text, textOpt);

        QPen indicatorsPen(pal.color(QPalette::HighlightedText), 2, Qt::SolidLine, Qt::RoundCap);

        //Min Button also this part is similar to qtcurve :)
        if( (titleBarOpt->subControls & SC_TitleBarMinButton)
             && (titleBarOpt->titleBarFlags & Qt::WindowMinimizeButtonHint)
             &&!(titleBarOpt->titleBarState& Qt::WindowMinimized))
        {
           QRect bRect(subControlRect(CC_TitleBar, titleBarOpt, SC_TitleBarMinButton, widget));

           if( bRect.isValid() )
           {
             bool sunken((titleBarOpt->activeSubControls & SC_TitleBarMinButton)
                          && (titleBarOpt->state & State_Sunken));
             renderSurface(p,bRect.adjusted(1,1,-1,-1),pal.color(QPalette::Highlight),
                           pal.color(QPalette::Highlight),
                           pal.color(QPalette::HighlightedText),
                           _contrast*2, defaultFlags|(sunken?Is_Sunken:0));
             renderContour(p,bRect,pal.color(QPalette::Highlight),
                           pal.color(QPalette::Highlight).dark(130+_contrast));

             if( sunken )
               bRect.adjust(1,1,1,1);
             p->setPen(indicatorsPen);
             p->setRenderHint(QPainter::Antialiasing);
             p->drawLine(bRect.center().x()-3, bRect.bottom()-4, bRect.center().x()+4, bRect.bottom()-4);
             p->setRenderHint(QPainter::Antialiasing, false);
           }
        }

        //Max Button
        if( (titleBarOpt->subControls & SC_TitleBarMaxButton)
             && (titleBarOpt->titleBarFlags & Qt::WindowMaximizeButtonHint)
             &&!(titleBarOpt->titleBarState & Qt::WindowMaximized))
        {
           QRect bRect(subControlRect(CC_TitleBar, titleBarOpt, SC_TitleBarMaxButton, widget));

           if( bRect.isValid() )
           {
             bool sunken((titleBarOpt->activeSubControls & SC_TitleBarMaxButton)
                          && (titleBarOpt->state & State_Sunken));
             renderSurface(p,bRect.adjusted(1,1,-1,-1),pal.color(QPalette::Highlight),
                           pal.color(QPalette::Highlight),
                           pal.color(QPalette::HighlightedText),
                           _contrast*2, defaultFlags|(sunken?Is_Sunken:0));
             renderContour(p,bRect,pal.color(QPalette::Highlight),
                           pal.color(QPalette::Highlight).dark(130+_contrast));

             if( sunken )
               bRect.adjust(1,1,1,1);
             p->setPen(indicatorsPen);
             p->setRenderHint(QPainter::Antialiasing);
             p->drawRect(bRect.center().x()-2, bRect.center().y()-2,
                         6, 6);
             p->setRenderHint(QPainter::Antialiasing, false);
           }
        }

        //Close Button
        if( (titleBarOpt->subControls & SC_TitleBarCloseButton)
             && (titleBarOpt->titleBarFlags & Qt::WindowSystemMenuHint))
        {
           QRect bRect(subControlRect(CC_TitleBar, titleBarOpt, SC_TitleBarCloseButton, widget));

           if( bRect.isValid() )
           {
             bool sunken((titleBarOpt->activeSubControls & SC_TitleBarCloseButton)
                          && (titleBarOpt->state & State_Sunken));
             renderSurface(p,bRect.adjusted(1,1,-1,-1),pal.color(QPalette::Highlight),
                           pal.color(QPalette::Highlight),
                           pal.color(QPalette::HighlightedText),
                           _contrast*2, defaultFlags|(sunken?Is_Sunken:0));
             renderContour(p,bRect,pal.color(QPalette::Highlight),
                           pal.color(QPalette::Highlight).dark(130+_contrast));

             if( sunken )
               bRect.adjust(1,1,1,1);
             p->setPen(indicatorsPen);
             p->setRenderHint(QPainter::Antialiasing);
             p->drawLine(bRect.center().x()-2, bRect.center().y()-2,
                         bRect.center().x()+4, bRect.center().y()+4);
             p->drawLine(bRect.center().x()+4, bRect.center().y()-2,
                         bRect.center().x()-2, bRect.center().y()+4);
             p->setRenderHint(QPainter::Antialiasing, false);
           }
        }

        //Normalize Button
        if( (titleBarOpt->subControls & SC_TitleBarNormalButton)
             && (((titleBarOpt->titleBarFlags & Qt::WindowMinimizeButtonHint)
             && (titleBarOpt->titleBarState & Qt::WindowMinimized))
             || ((titleBarOpt->titleBarFlags & Qt::WindowMaximizeButtonHint)
             && (titleBarOpt->titleBarState & Qt::WindowMaximized))) )
        {
           QRect bRect(subControlRect(CC_TitleBar, titleBarOpt, SC_TitleBarNormalButton, widget));

           if( bRect.isValid() )
           {
             bool sunken((titleBarOpt->activeSubControls & SC_TitleBarNormalButton)
                          && (titleBarOpt->state & State_Sunken));
             renderSurface(p,bRect.adjusted(1,1,-1,-1),pal.color(QPalette::Highlight),
                           pal.color(QPalette::Highlight),
                           pal.color(QPalette::HighlightedText),
                           _contrast*2, defaultFlags|(sunken?Is_Sunken:0));
             renderContour(p,bRect,pal.color(QPalette::Highlight),
                           pal.color(QPalette::Highlight).dark(130+_contrast));

             if( sunken )
               bRect.adjust(1,1,1,1);
             p->setPen(indicatorsPen);
             p->setRenderHint(QPainter::Antialiasing);
             p->drawRect(bRect.center().x()-3, bRect.center().y(),
                         6, 6);
             p->drawRect(bRect.center().x(), bRect.center().y()-3,
                         6, 6);
             p->setRenderHint(QPainter::Antialiasing, false);
           }
        }

        //Context help Button
        if( titleBarOpt->subControls & SC_TitleBarContextHelpButton
            && (titleBarOpt->titleBarFlags & Qt::WindowContextHelpButtonHint) )
        {
           QRect bRect(subControlRect(CC_TitleBar, titleBarOpt, SC_TitleBarContextHelpButton, widget));

           if( bRect.isValid() )
           {
             bool sunken((titleBarOpt->activeSubControls & SC_TitleBarContextHelpButton)
                          && (titleBarOpt->state & State_Sunken));
             renderSurface(p,bRect.adjusted(1,1,-1,-1),pal.color(QPalette::Highlight),
                           pal.color(QPalette::Highlight),
                           pal.color(QPalette::HighlightedText),
                           _contrast*2, defaultFlags|(sunken?Is_Sunken:0));
             renderContour(p,bRect,pal.color(QPalette::Highlight),
                           pal.color(QPalette::Highlight).dark(130+_contrast));

             if( sunken )
               bRect.adjust(1,1,1,1);
             p->setPen(indicatorsPen);

             p->drawText(bRect, Qt::AlignCenter, "?");
           }
        }

        //Shade Button
        if( titleBarOpt->subControls & SC_TitleBarShadeButton
             && (titleBarOpt->titleBarFlags & Qt::WindowShadeButtonHint) )
        {
           QRect bRect(subControlRect(CC_TitleBar, titleBarOpt, SC_TitleBarShadeButton, widget));

           if( bRect.isValid() )
           {
             bool sunken((titleBarOpt->activeSubControls & SC_TitleBarShadeButton)
                          && (titleBarOpt->state & State_Sunken));
             renderSurface(p,bRect.adjusted(1,1,-1,-1),pal.color(QPalette::Highlight),
                           pal.color(QPalette::Highlight),
                           pal.color(QPalette::HighlightedText),
                           _contrast*2, defaultFlags|(sunken?Is_Sunken:0));
             renderContour(p,bRect,pal.color(QPalette::Highlight),
                           pal.color(QPalette::Highlight).dark(130+_contrast));

             if( sunken )
               bRect.adjust(1,1,1,1);

             renderArrow(p, bRect, pal.color(QPalette::HighlightedText), Up);
           }
        }

        //Unshade Button
        if( titleBarOpt->subControls & SC_TitleBarUnshadeButton
            && (titleBarOpt->titleBarFlags & Qt::WindowShadeButtonHint) )
        {
           QRect bRect(subControlRect(CC_TitleBar, titleBarOpt, SC_TitleBarUnshadeButton, widget));

           if( bRect.isValid() )
           {
             bool sunken((titleBarOpt->activeSubControls & SC_TitleBarUnshadeButton)
                          && (titleBarOpt->state & State_Sunken));
             renderSurface(p,bRect.adjusted(1,1,-1,-1),pal.color(QPalette::Highlight),
                           pal.color(QPalette::Highlight),
                           pal.color(QPalette::HighlightedText),
                           _contrast*2, defaultFlags|(sunken?Is_Sunken:0));
             renderContour(p,bRect,pal.color(QPalette::Highlight),
                           pal.color(QPalette::Highlight).dark(130+_contrast));

             if( sunken )
               bRect.adjust(1,1,1,1);

             renderArrow(p, bRect, pal.color(QPalette::HighlightedText), Down);
           }
        }

        //System menu
        if( (titleBarOpt->subControls & SC_TitleBarSysMenu)
             && (titleBarOpt->titleBarFlags & Qt::WindowSystemMenuHint) )
        {
           QRect bRect(subControlRect(CC_TitleBar, titleBarOpt, SC_TitleBarSysMenu, widget));

           if( bRect.isValid() )
           {
             bool sunken((titleBarOpt->activeSubControls & SC_TitleBarSysMenu)
                          && (titleBarOpt->state & State_Sunken));
             if( titleBarOpt->icon.isNull() )
             {
               renderSurface(p,bRect.adjusted(1,1,-1,-1),pal.color(QPalette::Highlight),
                             pal.color(QPalette::Highlight),
                             pal.color(QPalette::HighlightedText),
                             _contrast*2, defaultFlags|(sunken?Is_Sunken:0));
               renderContour(p,bRect,pal.color(QPalette::Highlight),
                             pal.color(QPalette::Highlight).dark(130+_contrast));
             }
             else
             {
               if( sunken )
                 bRect.adjust(1,1,1,1);

               titleBarOpt->icon.paint(p, bRect);
             }
           }
        }

        p->restore();
        break;
      }

    // SpinBox
    // -----------
        case CC_SpinBox:
        {
            static const unsigned int handleWidth = 15;
            const QStyleOptionSpinBox *spinOpt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt);
            if( !spinOpt )
              break;
            QSpinBox *sw = (QSpinBox *)(widget);// **hack**: cast away const-ness for animation support!
            State sflags = flags;
            PrimitiveElement pe;

            bool upSunken = (spinOpt->activeSubControls & SC_SpinBoxUp) &&
                            (spinOpt->state & (State_Sunken | State_On));
            bool downSunken = (spinOpt->activeSubControls & SC_SpinBoxDown) &&
                              (spinOpt->state & (State_Sunken | State_On));

            bool hasFocus = false;
            if (sw)
                hasFocus = sw->hasFocus();

            int animFrame = 0;
            if( _animateButton && animWidgets.contains( sw )){
                animFrame = animWidgets[sw].animFrame;
            }

            const QColor buttonColor = enabled?pal.color(QPalette::Button).light(100+animFrame)
                                              :pal.color(QPalette::Background);
            const QColor inputColor = enabled?pal.color(QPalette::Base):pal.color(QPalette::Background);
            QColor highlightColor = pal.color(QPalette::Highlight);
            if( _animateButton )
            {
              highlightColor.setAlpha(qRound(255*((double)animFrame/(double)ANIMATIONSTEPS)));
            }
            // contour
            const bool heightDividable = ((r.height()%2) == 0);
            if (_inputFocusHighlight && hasFocus && enabled)
            {
                QRect editField = subControlRect(CC_SpinBox, qstyleoption_cast<const QStyleOptionComplex*>(opt), SC_SpinBoxEditField, widget);
                QRect editFrame = r;
                QRect buttonFrame = r;
                
                uint editFlags = 0;
                uint buttonFlags = 0;
                
                // Hightlight only the part of the contour next to the control buttons
                if (reverseLayout)
                {
                    // querySubControlMetrics doesn't work right for reverse Layout
                    int dx = r.right() - editField.right();
                    editFrame.setLeft(editFrame.left() + dx);
                    buttonFrame.setRight(editFrame.left() - 1);
                    editFlags |= Draw_Right|Draw_Top|Draw_Bottom|Round_UpperRight|Round_BottomRight;
                    buttonFlags |= Draw_Left|Draw_Top|Draw_Bottom|Round_UpperLeft|Round_BottomLeft;
                }
                else
                {
                    editFrame.setRight(editField.right());
                    buttonFrame.setLeft(editField.right() + 1);

                    editFlags |= Draw_Left|Draw_Top|Draw_Bottom|Round_UpperLeft|Round_BottomLeft;
                    buttonFlags |= Draw_Right|Draw_Top|Draw_Bottom|Round_UpperRight|Round_BottomRight;
                }
                renderContour(p, editFrame, pal.color(QPalette::Background),
                                 pal.color(QPalette::Highlight), editFlags);
                renderContour(p, buttonFrame, pal.color(QPalette::Background), 
                              getColor(pal, ButtonContour, enabled), buttonFlags);
            }
            else
            {
                renderContour(p,
                              subControlRect(CC_SpinBox,
                                     qstyleoption_cast<const QStyleOptionComplex*>(opt),
                                     SC_SpinBoxFrame, widget),
                              pal.color(QPalette::Background), getColor(pal, ButtonContour, enabled) );
            }
            p->setPen(alphaBlendColors(pal.color(QPalette::Background), getColor(pal, ButtonContour, enabled), 50) );
            p->drawLine(reverseLayout?r.left()+1+handleWidth:r.right()-handleWidth-1, r.top()+1,
                    reverseLayout?r.left()+1+handleWidth:r.right()-handleWidth-1, r.bottom()-1);
            p->drawLine(reverseLayout?r.left()+1:r.right()-handleWidth, r.top()+1+(r.height()-2)/2,
                    reverseLayout?r.left()+handleWidth:r.right()-1, r.top()+1+(r.height()-2)/2);

            //commented out because I always prefer that only one line is drawn
            /*if(heightDividable)
                p->drawLine(reverseLayout?r.left()+1:r.right()-handleWidth, r.top()+1+(r.height()-2)/2-1,
                        reverseLayout?r.left()+handleWidth:r.right()-1, r.top()+1+(r.height()-2)/2-1);*/

            // surface

            QRect upRect = QRect(reverseLayout?r.left()+1:r.right()-handleWidth, r.top()+1,
                    handleWidth, (r.height()-2)/2);
            QRect downRect = QRect(reverseLayout?r.left()+1:r.right()-handleWidth,
                    heightDividable?r.top()+1+((r.height()-2)/2):r.top()+1+((r.height()-2)/2)+1,
                    handleWidth, ((r.height()-2)/2) );
            if(heightDividable) {
                //upRect = QRect(upRect.left(), upRect.top(), upRect.width(), upRect.height()-1 );
                downRect = QRect(downRect.left(), downRect.top()+1, downRect.width(), downRect.height()-1 );
            }

            uint surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Is_Horizontal;
            if(reverseLayout)
            {
                surfaceFlags |= Round_UpperLeft;
            }
            else
            {
                surfaceFlags |= Round_UpperRight;
            }
            if ( (animFrame != 0) || (sflags & State_MouseOver))
            {
                surfaceFlags |= Is_Highlight;
                surfaceFlags |= Highlight_Top|Highlight_Left|Highlight_Right;
            }
            if( upSunken )
              surfaceFlags|=Is_Sunken;
            if(!enabled) surfaceFlags|=Is_Disabled;
            renderSurface(p, upRect, pal.color(QPalette::Background), buttonColor, highlightColor,
                           _contrast, surfaceFlags);
            surfaceFlags = Draw_Left|Draw_Right|Draw_Top|Draw_Bottom|Is_Horizontal;
            if(reverseLayout) {
                surfaceFlags |= Round_BottomLeft;
            } else {
                surfaceFlags |= Round_BottomRight;
            }
            if ( (animFrame != 0) || (sflags & State_MouseOver)) {
                surfaceFlags |= Is_Highlight;
                surfaceFlags |= Highlight_Bottom|Highlight_Left|Highlight_Right;
            }
            if( downSunken )
              surfaceFlags|=Is_Sunken;
            if(!enabled) surfaceFlags|=Is_Disabled;
            renderSurface(p, downRect, pal.color(QPalette::Background), buttonColor, highlightColor,
                           _contrast, surfaceFlags);

            // icons...
            sflags = State_Enabled;
            if (upSunken)
            {
                sflags |= State_On;
                sflags |= State_Sunken;
            } else
                sflags |= State_Raised;
            if (sw->buttonSymbols() == QSpinBox::PlusMinus)
                pe = PE_IndicatorSpinPlus;
            else
                pe = PE_IndicatorSpinUp;
            p->setPen(pal.color(QPalette::Foreground));
            QStyleOption upOpt;
            upOpt.QStyleOption::operator=(*opt);
            upOpt.rect = upRect;
            drawPrimitive(pe, &upOpt, p, widget);

            sflags = State_Enabled;
            if( downSunken )
            {
                sflags |= State_On;
                sflags |= State_Sunken;
            } else
                sflags |= State_Raised;
            if (sw->buttonSymbols() == QSpinBox::PlusMinus)
                pe = PE_IndicatorSpinMinus;
            else
                pe = PE_IndicatorSpinDown;
            p->setPen(pal.color(QPalette::Foreground));
            QStyleOption downOpt;
            downOpt.QStyleOption::operator=(*opt);
            downOpt.rect = downRect;
            drawPrimitive(pe, &downOpt, p, widget);



            // thin frame around the input area
            const QRect Rcontent = QRect(reverseLayout?r.left()+1+handleWidth+1:r.left()+1, r.top()+1,
                    r.width()-1-2-handleWidth, r.height()-2);

            //text input surface
            QRect filledRect = Rcontent.adjusted(1, 1, -1, -1);
            p->fillRect(filledRect, pal.color(QPalette::Base) );

            //shadows or border
            if( _sunkenShadows )
            {
              renderSunkenShadow(p, Rcontent,
                                 (_inputFocusHighlight && hasFocus && enabled)
                                    ?getColor(pal,FocusHighlight):Qt::black,
                                 Draw_Top|Draw_Bottom|Draw_Left|Draw_Right|
                                  (reverseLayout?Sharp_UpperLeft|Sharp_BottomLeft
                                   :Sharp_UpperRight|Sharp_BottomRight));
            }
            else
            {
              if (_inputFocusHighlight && hasFocus && enabled)
              {
                p->setPen( getColor(pal,FocusHighlight).dark(100+(_lightBorder?-30:30)) );
              }
              else
              {
                p->setPen(inputColor.dark(100+(_lightBorder?-30:30)) );
              }
              p->drawLine(Rcontent.left(), reverseLayout?Rcontent.top():Rcontent.top()+1,
                      Rcontent.left(), reverseLayout?Rcontent.bottom():Rcontent.bottom()-1 );
              p->drawLine(Rcontent.left()+1, Rcontent.top(),
                      reverseLayout?Rcontent.right()-1:Rcontent.right(), Rcontent.top() );
              if (_inputFocusHighlight && hasFocus && enabled)
              {
                p->setPen( getColor(pal,FocusHighlight).light(130) );
              }
              else
              {
                p->setPen(inputColor.light(130) );
              }
              p->drawLine(Rcontent.left()+1, Rcontent.bottom(), Rcontent.right()-1, Rcontent.bottom() );
              p->drawLine(Rcontent.right(), Rcontent.top()+1,
                      Rcontent.right(), reverseLayout?Rcontent.bottom()-1:Rcontent.bottom() );
            }

            break;
        }

        default:
#ifdef NO_KDE
           QWindowsStyle::drawComplexControl(control, opt, p, widget);
#else
           KStyle::drawComplexControl(control, opt, p, widget);
#endif
            break;
    }
}


QRect PolyesterStyle::subElementRect(SubElement se,
                                     const QStyleOption *option,
                                     const QWidget *widget) const
{
    switch (se)
    {
      /*case SE_ComboBoxFocusRect: {
          return querySubControlMetrics( CC_ComboBox, widget, SC_ComboBoxEditField );
      }*/

      // Don't use QWindowsStyles progressbar subrect
      // TODO:
      case SE_ProgressBarGroove: {
          return QRect(option->rect);
      }
      case SE_ProgressBarContents:
      case SE_ProgressBarLabel: {
          QRect rw = option->rect;
          if( _sunkenShadows )
            return rw;
          else
            return QRect(rw.left()+2, rw.top()+2, rw.width()-4, rw.height()-4 );
      }
      /*case SE_PushButtonContents:
        return widget->rect().adjusted(3,3,-3,-3);*/

      default: {
#ifdef NO_KDE
          return QWindowsStyle::subElementRect(se, option, widget);
#else
          return KStyle::subElementRect(se, option, widget);
#endif
      }
    }
}


QRect PolyesterStyle::subControlRect(ComplexControl control,
                                 const QStyleOptionComplex *opt,
                                 SubControl subcontrol,
                                 const QWidget *widget) const
{
  QRect r = opt->rect;
  QRect rect;
  int x, y, w, h, x2, y2;
  r.getRect(&x, &y, &w, &h);
  x2 = r.right(); y2 = r.bottom();

  switch (control)
  {
        //Scrollbar, more or less ripped off from Phase (c)2007 David Johnson
      case CC_ScrollBar:
      {
          // three button scrollbar
          const QStyleOptionSlider *sbOpt;
          sbOpt = qstyleoption_cast<const QStyleOptionSlider *>(opt);
          if (!sbOpt) break;

          bool horizontal = (sbOpt->orientation == Qt::Horizontal);
          int extent = pixelMetric(PM_ScrollBarExtent, sbOpt, widget);
          int slidermax = ((horizontal) ?  r.width() : r.height())
              - (extent * 3);
          int slidermin = pixelMetric(PM_ScrollBarSliderMin, sbOpt, widget);
          int sliderlen, sliderstart;

          if( _scrollBarType == NoButtonsScrollBar )
            slidermax += 3*extent;
          else if( _scrollBarType != ThreeButtonScrollBar )
            slidermax += extent;

          // calculate slider length
          if (sbOpt->maximum != sbOpt->minimum) {
              int range = sbOpt->maximum - sbOpt->minimum;
              sliderlen = (int)((double)(sbOpt->pageStep * slidermax) / (double)(range + sbOpt->pageStep));
              if ((sliderlen < slidermin) || (range > INT_MAX / 2))
                  sliderlen = slidermin;
              if (sliderlen > slidermax)
                  sliderlen = slidermax;
          } else {
              sliderlen = slidermax;
          }


          sliderstart = extent + sliderPositionFromValue(sbOpt->minimum,
                                                         sbOpt->maximum,
                                                         sbOpt->sliderPosition,
                                                         slidermax - sliderlen,
                                                         sbOpt->upsideDown);
          if( _scrollBarType == PlatinumStyleScrollBar
              || _scrollBarType == NoButtonsScrollBar )
            sliderstart -= extent;
          else if( _scrollBarType == NextStyleScrollBar )
            sliderstart += extent;

          switch (subcontrol)
          {
            case SC_ScrollBarAddLine:
            {
              if( _scrollBarType != NextStyleScrollBar
                  && _scrollBarType != NoButtonsScrollBar )
              {
                if( horizontal )
                  rect.setRect(x2 - extent + 1, y, extent, extent);
                else
                  rect.setRect(x, y2 - extent + 1, extent, extent);
              }
              else if( _scrollBarType == NextStyleScrollBar )
              {
                if( horizontal )
                  rect.setRect(x + extent /*+ 1*/, y, extent, extent);
                else
                  rect.setRect(x, y + extent /*+ 1*/, extent, extent);
              }
              else //NoButtonsScrollBar
                rect.setRect(0,0,0,0);

              break;
            }

            case SC_ScrollBarSubLine:
            {
              if( _scrollBarType == ThreeButtonScrollBar )
              {
                // rect that covers *both* subline buttons
                if( horizontal )
                  rect.setRect(x, y, w - extent + 1, extent);
                else
                  rect.setRect(x, y, extent, h - extent + 1);
              }
              else if( _scrollBarType == WindowsStyleScrollBar
                      || _scrollBarType == NextStyleScrollBar )
              {
                rect.setRect(x, y, extent, extent);
              }
              else if( _scrollBarType == PlatinumStyleScrollBar )
              {
                if( horizontal )
                  rect.setRect(x2-2*extent+2, y, extent, extent);
                else
                  rect.setRect(x, y2-2*extent+2, extent, extent);
              }
              else //NoButtonsScrollBar
              {
                rect.setRect(0,0,0,0);
              }
              break;
            }

            case SC_ScrollBarAddPage:
            {
              if( _scrollBarType == ThreeButtonScrollBar)
              {
                //3 buttons,platinum and windows the slider must not overwrite this
                sliderlen+=2;
                if (horizontal)
                    rect.setRect(sliderstart + sliderlen, y,
                                 slidermax - sliderstart - sliderlen + extent + 1,
                                 extent);
                else
                    rect.setRect(x, sliderstart + sliderlen, extent,
                                 slidermax - sliderstart - sliderlen + extent + 1);
              }
              else if( _scrollBarType == WindowsStyleScrollBar )
              {
                sliderlen+=2;
                if (horizontal)
                    rect.setRect(sliderstart + sliderlen, y,
                                 slidermax - sliderstart - sliderlen + extent,
                                 extent);
                else
                    rect.setRect(x, sliderstart + sliderlen, extent,
                                 slidermax - sliderstart - sliderlen + extent);
              }
              else if( _scrollBarType == PlatinumStyleScrollBar )
              {
                sliderlen+=2;
                if (horizontal)
                    rect.setRect(sliderstart + sliderlen, y,
                                 slidermax - sliderstart - sliderlen + 1,
                                 extent);
                else
                    rect.setRect(x, sliderstart + sliderlen, extent,
                                 slidermax - sliderstart - sliderlen + 1);
              }
              else if( _scrollBarType == NextStyleScrollBar )
              {
                if (horizontal)
                    rect.setRect(sliderstart + sliderlen, y,
                                slidermax - sliderstart - sliderlen + 2*extent,
                                extent);
                else
                    rect.setRect(x, sliderstart + sliderlen, extent,
                                 slidermax - sliderstart - sliderlen + 2*extent);
              }
              //NoButtonsScrollBar
              else
              {
                if (horizontal)
                    rect.setRect(sliderstart + sliderlen, y,
                                 slidermax - sliderstart - sliderlen,
                                 extent);
                else
                    rect.setRect(x, sliderstart + sliderlen, extent,
                                 slidermax - sliderstart - sliderlen);
              }
              break;
            }

            case SC_ScrollBarSubPage:
            {
              if( _scrollBarType == ThreeButtonScrollBar
                  || _scrollBarType == WindowsStyleScrollBar )
              {
                //3 buttons,next and windows the slider must not overwrite this
                sliderstart-=1;
                if( horizontal )
                    rect.setRect(x + extent, y,
                                 sliderstart - (x + extent), extent);
                else
                    rect.setRect(x, y + extent, extent,
                                 sliderstart - (x + extent));
              }
              else if( _scrollBarType == PlatinumStyleScrollBar
                       || _scrollBarType == NoButtonsScrollBar)
              {
                //platinum and nobuttons the slider must overwrite this
                sliderstart+=1;
                if( horizontal )
                    rect.setRect(x, y,
                                 sliderstart - x, extent);
                else
                    rect.setRect(x, y, extent,
                                 sliderstart - x);
              }
              //NextStyleScrollBar
              else //if( _scrollBarType == NextStyleScrollBar )
              {
                //3 buttons,next and windows the slider must not overwrite this
                sliderstart-=1;
                if( horizontal )
                    rect.setRect(x + 2*extent, y,
                                 sliderstart - (x + 2*extent), extent);
                else
                    rect.setRect(x, y + 2*extent, extent,
                                 sliderstart - (x + 2*extent));
              }

                break;
            }

            case SC_ScrollBarSlider:
            {
              if( horizontal )
                rect.setRect(qMax(sliderstart - 1,r.x()), y,
                             qMin(sliderlen + 2 + 1, r.width()-sliderstart+1),
                             extent);
              else
                rect.setRect(x, qMax(sliderstart - 1, r.y()), extent,
                             qMin(sliderlen + 2 + 1, r.height()-sliderstart+1));
              break;
            }

            case SC_ScrollBarGroove:
                if (horizontal) {
                    rect = r.adjusted(extent, 0, -(extent*2), 0);
                } else {
                    rect = r.adjusted(0, extent, 0, -(extent*2));
                }
                break;

            default:
                break;
          }
          rect = visualRect(sbOpt->direction, r, rect);
          break;
      }
      case CC_ToolButton:
      {
#ifdef NO_KDE
        rect = QWindowsStyle::subControlRect(control, opt,
                                             subcontrol, widget);
#else
        rect = KStyle::subControlRect(control, opt,
                                      subcontrol, widget);
#endif

        if( subcontrol == SC_ToolButtonMenu )
          rect.adjust(-2,0,-2,0);
        else if( subcontrol == SC_ToolButton )
          rect.adjust(0,0,-2,0);
        break;
      }
      default:
#ifdef NO_KDE
          rect = QWindowsStyle::subControlRect(control, opt,
                                               subcontrol, widget);
#else
          rect = KStyle::subControlRect(control, opt,
                                        subcontrol, widget);
#endif
  }
  return rect;

}


QStyle::SubControl PolyesterStyle::hitTestComplexControl(ComplexControl control,
                                             const QStyleOptionComplex *option,
                                             const QPoint &position,
                                             const QWidget *widget) const
{
    SubControl subcontrol = SC_None;
    QRect rect;

    switch(control)
    {
      case CC_ScrollBar:
      {
          const QStyleOptionSlider *sb;
          sb = qstyleoption_cast<const QStyleOptionSlider *>(option);
          if (!sb) break;

          // these cases are order dependent
          rect = subControlRect(control, sb, SC_ScrollBarSlider, widget);
          if (rect.contains(position)) {
              subcontrol = SC_ScrollBarSlider;
              break;
          }

          rect = subControlRect(control, sb, SC_ScrollBarAddPage, widget);
          if (rect.contains(position)) {
              subcontrol = SC_ScrollBarAddPage;
              break;
          }

          rect = subControlRect(control, sb, SC_ScrollBarSubPage, widget);
          if (rect.contains(position)) {
              subcontrol = SC_ScrollBarSubPage;
              break;
          }

          rect = subControlRect(control, sb, SC_ScrollBarAddLine, widget);
          if (rect.contains(position)) {
              subcontrol = SC_ScrollBarAddLine;
              break;
          }

          rect = subControlRect(control, sb, SC_ScrollBarSubLine, widget);
          if (rect.contains(position)) {
              subcontrol = SC_ScrollBarSubLine;
              break;
          }

          break;
      }

      default:
#ifdef NO_KDE
         subcontrol = QWindowsStyle::hitTestComplexControl(control, option,
                                                           position, widget);
#else
         subcontrol = KStyle::hitTestComplexControl(control, option,
                                                    position, widget);
#endif
          break;
    }

    return subcontrol;
}

#if 0
QRect PolyesterStyle::querySubControlMetrics(ComplexControl control,
                                          const QWidget *widget,
                                          SubControl subcontrol,
                                          const QStyleOption &opt) const
{
    if (!widget) {
        return QRect();
    }

    QRect r(widget->rect());
    switch (control) {
        case CC_ComboBox: {
            switch (subcontrol) {
                case SC_ComboBoxEditField: {
                    // TODO: is the handler width in pixelmetric?
                    return QRect(r.left()+2, r.top()+2, r.width()-4-15-1, r.height()-4);
                }
                default: {
                    return QWindowsStyle::querySubControlMetrics(control, widget, subcontrol, opt);
                }
            }
            break;
        }
        case CC_SpinBox: {
            const int fw = 2; // Frame width...

            const bool heightDividable = ((r.height()%2) == 0);

            QSize bs;
            if(heightDividable) {
                bs.setHeight(qMax(8, (r.height()-2)/2));
            } else {
                bs.setHeight(qMax(8, (r.height()-2-1)/2));
            }
            bs.setWidth(15);

            const int buttonsLeft = /*reverseLayout?r.left()+1:*/r.right()-bs.width();

            switch (subcontrol) {
                case SC_SpinBoxUp: {
                    return QRect(buttonsLeft, r.top()+1, bs.width(), bs.height() );
                }
                case SC_SpinBoxDown: {
                    if(heightDividable) {
                        return QRect(buttonsLeft, r.top()+1+bs.height(),
                                bs.width(), r.height()-(bs.height()+2) );
                    } else {
                        return QRect(buttonsLeft, r.top()+1+bs.height()+1,
                                bs.width(), r.height()-(bs.height()+2+1) );
                    }
                }
                case SC_SpinBoxFrame: {
                    return QRect(r.left(), r.top(), r.width(), r.height() );
                }
                case SC_SpinBoxEditField: {
                    return QRect(r.left()+fw, r.top()+fw,
                            r.width()-(bs.width()+1+2*fw), r.height()-2*fw);
                }
                case SC_SpinBoxButtonField: {
                    return QRect(buttonsLeft, r.top()+1, bs.width(), r.height()-2);
                }
                default: {
                    return QWindowsStyle::querySubControlMetrics(control, widget, subcontrol, opt);
                }
            }
            break;
        }
        default: {
            return QWindowsStyle::querySubControlMetrics(control, widget, subcontrol, opt);
        }
    }
}
#endif

QIcon PolyesterStyle::standardIconImplementation ( StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget ) const
{
  //Mostly from Oxygen
  // get button color (unfortunately option and widget might not be set)
  QColor iconColor;
  if (option)
      iconColor = option->palette.buttonText().color();
  else if (widget)
      iconColor = widget->palette().buttonText().color();
  else // black
      iconColor = Qt::black;

  switch (standardIcon)
  {
    case SP_TitleBarNormalButton:
    {
        QPixmap realpm(dockWidgetButtonSize, dockWidgetButtonSize);
        realpm.fill(QColor(0,0,0,0));
        QPainter painter(&realpm);
        painter.setRenderHints(QPainter::Antialiasing);
        painter.setBrush(Qt::NoBrush);
        painter.setPen(QPen(iconColor,1.0));
        painter.drawRect( QRectF(QPointF(4.5,3.5), QSizeF(5.0,5.0)) );

        return QIcon(realpm);
    }

    case SP_TitleBarCloseButton:
    case SP_DockWidgetCloseButton:
    {
        QPixmap realpm(dockWidgetButtonSize, dockWidgetButtonSize);
        realpm.fill(QColor(0,0,0,0));
        QPainter painter(&realpm);
        painter.setRenderHints(QPainter::Antialiasing);
        painter.setBrush(Qt::NoBrush);
        painter.setPen(QPen(iconColor,1.0));
        painter.drawLine( QPointF(4.5,3.5), QPointF(9.5,8.5) );
        painter.drawLine( QPointF(9.5,3.5), QPointF(4.5,8.5) );

        return QIcon(realpm);
    }
    default:
      break;
  }
#ifdef NO_KDE
  return QWindowsStyle::standardPixmap(standardIcon, option, widget);
#else
  return KStyle::standardPixmap(standardIcon, option, widget);
#endif
}

int PolyesterStyle::pixelMetric(PixelMetric m,
                                const QStyleOption *opt,
                                const QWidget *widget) const
{
    int ex = qMax(QApplication::fontMetrics().xHeight(), 15);

    switch(m)
    {
    // TABS
    // ----
        /*case PM_TabBarTabVSpace:
        {
            const QTabBar * tb = (const QTabBar *) widget;
            if (tb->shape() == QTabBar::RoundedNorth
                || tb->shape() == QTabBar::RoundedSouth
                || tb->shape() == QTabBar::RoundedEast
                || tb->shape() == QTabBar::RoundedWest)
                return 12;
            else
                return 4;
        }*/
        case PM_TabBarTabOverlap:
        {
            return 2;
        }

        case PM_DefaultLayoutSpacing:
        {
            return 4; // qcommon is 6
        }

        case PM_DefaultChildMargin:
            return 4; // qcommon is 9;

        case PM_DefaultTopLevelMargin:
            return 11;

    // extra space between menubar items
#ifdef NO_KDE
        case PM_MenuBarItemSpacing: {
            return 5;
        }
#endif
        case PM_MenuBarVMargin:{
          if( _menuBarEmphasis )
            return 2;
          else
            return 0;
        }
        case PM_MenuBarHMargin:{
          if( _menuBarEmphasis )
            return 2;
          else
            return 0;
        }

// #if (QT_VERSION >= 0x030300) // requires Qt 3.3
//     // extra space between toolbar items
//         case PM_ToolBarItemSpacing: {
//             return 4;
//         }
// #endif

    // SCROLL BAR
        case PM_ScrollBarSliderMin: {
            return 21;
        }
        case PM_ScrollBarExtent: {
            return _scrollBarExtent;
        }


    // SPLITTERS
    // ---------
        case PM_SplitterWidth: {
            return 6;
        }

    // PROGRESSBARS
    // ------------
        case PM_ProgressBarChunkWidth:
            return 10;

    // SLIDER
    // ------
        case PM_SliderLength:
            return 11;

    // MENU INDICATOR
    // --------------
        case PM_MenuButtonIndicator:
            return 8;

    // CHECKBOXES / RADIO BUTTONS
    // --------------------------
        case PM_ExclusiveIndicatorWidth:    // Radiobutton size
        case PM_ExclusiveIndicatorHeight:   // 13x13
        case PM_IndicatorWidth:             // Checkbox size
        case PM_IndicatorHeight:            // 13x13
            //return 13;
            return ex & 0xfffe;

    // FRAMES
    // ------
        case PM_SpinBoxFrameWidth:
            return 2;

        case PM_MenuBarPanelWidth:
        {
            if( _drawToolBarSeparator)
              return 1;
            else
              return 0;
        }

        case PM_DefaultFrameWidth:
        {
          if( const QAbstractScrollArea *area = ::qobject_cast<const QAbstractScrollArea*>(widget))
          {
            if( area->frameShape() == QFrame::StyledPanel  )
            {
              return 1;
            }
          }
          return 2;
        }

        case PM_ButtonDefaultIndicator: {
            return 1;
        }

      case PM_MenuPanelWidth: //menu framewidth
          return 1;

      case PM_TitleBarHeight:
          return qMax((int)(1.5*(double)QApplication::fontMetrics().lineSpacing()), 24);

      case PM_DockWidgetTitleMargin:
          return 2;

      case PM_DockWidgetFrameWidth:
          return 3;

        default:
#ifdef NO_KDE
           return QWindowsStyle::pixelMetric(m, opt, widget);
#else
           return KStyle::pixelMetric(m, opt, widget);
#endif
    }
}

QSize PolyesterStyle::sizeFromContents(ContentsType type, const QStyleOption* option, const QSize& contentsSize, const QWidget* widget) const
{
    switch(type)
    {
        //from Oxygen
        case CT_ToolButton:
        {
            // We want to avoid super-skiny buttons, for things like "up" when icons + text
            // For this, we would like to make width >= height.
            // However, once we get here, QToolButton may have already put in the menu area
            // (PM_MenuButtonIndicator) into the width. So we may have to take it out, fix things
            // up, and add it back in. So much for class-independent rendering...
            QSize size = contentsSize;

            if (const QStyleOptionToolButton* tbOpt = qstyleoption_cast<const QStyleOptionToolButton*>(option)) {
                if ((!tbOpt->icon.isNull()) && (!tbOpt->text.isEmpty()) && tbOpt->toolButtonStyle == Qt::ToolButtonTextUnderIcon)
                    size.setHeight(size.height()-9);
            }
            break;
        }

        //for some items only add a fixed margin
        case CT_MenuItem:
        case CT_ComboBox:
        //case CT_MenuBarItem:
        {
          QSize size = contentsSize;
          size.setHeight(size.height()+4);
          size.setWidth(size.width()+4);

          break;
        }
        case CT_PushButton:
        {
          QSize size = contentsSize;
          size.setWidth(size.width()+16);

          break;
        }

        default:
            break;
    }
#if NO_KDE
    return QWindowsStyle::sizeFromContents(type, option, contentsSize, widget);
#else
    return KStyle::sizeFromContents(type, option, contentsSize, widget);
#endif
}
/*
int PolyesterStyle::kPixelMetric(QWindowsStylePixelMetric kpm, const QWidget *widget) const
{
    switch(kpm)
    {
        case KPM_MenuItemSeparatorHeight:
            return 2;
        default:
            return QWindowsStyle::kPixelMetric(kpm, widget);
    }
}

QSize PolyesterStyle::sizeFromContents(ContentsType t,
                                    const QWidget *widget,
                                    const QSize &s,
                                    const QStyleOption &opt) const
{
    switch (t) {
        case CT_PopupMenuItem: {
            if (!widget || opt.isDefault())
                return s;

            const QPopupMenu *popup = dynamic_cast<const QPopupMenu *>(widget);
            QMenuItem *mi = opt.menuItem();
            int maxpmw = opt.maxIconWidth();
            int w = s.width(), h = s.height();
            bool checkable = popup->isCheckable();

            if (mi->custom()) {
                w = mi->custom()->sizeHint().width();
                h = mi->custom()->sizeHint().height();
                if (!mi->custom()->fullSpan() )
                    h += 4;
            } else if (mi->widget()) {
            // don't change the size in this case.
            } else if (mi->isSeparator()) {
                w = 20;
                h = 3;
            } else {
                if (mi->pixmap()) {
                    h = qMax(h, mi->pixmap()->height() + 2);
                } else {
                    h = qMax(h, 16 + 2 );
                    h = qMax(h, popup->fontMetrics().height() + _menuItemSpacing );
                }

                if (mi->iconSet()) {
                    h = qMax(h, mi->iconSet()->pixmap(QIconSet::Small, QIconSet::Normal).height() + 2);
                }
            }

            if (!mi->text().isNull() && (mi->text().find('\t') >= 0)) {
                w += itemHMargin + itemFrame*2 + 7;
            } else if (mi->popup()) {
                w += 2 * arrowHMargin;
            }

            if (maxpmw) {
                w += maxpmw + 6;
            }
            if (checkable && maxpmw < 20) {
                w += 20 - maxpmw;
            }
            if (checkable || maxpmw > 0) {
                w += 12;
            }

            w += rightBorder;

            return QSize(w, h);
        }

        case CT_PushButton:
        {
            const QPushButton* btn = static_cast<const QPushButton*>(widget);

            int w = s.width() + 2 * pixelMetric(PM_ButtonMargin, widget);
            int h = s.height() + 2 * pixelMetric(PM_ButtonMargin, widget);
            if ( btn->text().isEmpty() && s.width() < 32 ) return QSize(w, h);

            return QSize( w+25, h+5 );
        }

        case CT_ToolButton:
        {
            if(widget->parent() && ::qobject_cast<QToolBar*>(widget->parent()) )
                return QSize( s.width()+2*4, s.height()+2*4 );
            else
                return QWindowsStyle::sizeFromContents (t, widget, s, opt);
        }

        default:
            return QWindowsStyle::sizeFromContents (t, widget, s, opt);
    }

    return QWindowsStyle::sizeFromContents (t, widget, s, opt);
}
*/
int PolyesterStyle::styleHint(StyleHint stylehint, const QStyleOption * option,
                            const QWidget * widget, QStyleHintReturn * returnData) const
{
    switch (stylehint)
    {
        case SH_Menu_SubMenuPopupDelay:
            return 96; // Motif-like delay...
        case QStyle::SH_TabBar_Alignment:
        {
            if( _centeredTabBar )
              return Qt::AlignCenter;
            else
              return Qt::AlignLeft;
        }

        case SH_ItemView_ShowDecorationSelected:
#ifdef NO_KDE
          return true;
#else
          return false;
#endif

        case SH_TitleBar_NoBorder:
          return 1;

        case SH_DialogButtonLayout:
          return QDialogButtonBox::KdeLayout;

        //Suggestion by Daniel Molkentin,
        //algorithm from QT4 QWindowsXPStyle Copyright 2006 Trolltech
        case SH_LineEdit_PasswordCharacter:
        {
          if (widget)
          {
            const QFontMetrics &fm = widget->fontMetrics();
            if (fm.inFont(QChar(0x25CF)))
            {
              return 0x25CF;
            }
            else if (fm.inFont(QChar(0x2022)))
            {
              return 0x2022;
            }
          }
          else
          {
            return '*';
          }
        }
        case SH_ScrollView_FrameOnlyAroundContents:
          return false;

        case SH_MessageBox_CenterButtons:
          return true;

        default:
#ifdef NO_KDE
           return QWindowsStyle::styleHint(stylehint, option, widget, returnData);
#else
           return KStyle::styleHint(stylehint, option, widget, returnData);
#endif
    }
}

bool PolyesterStyle::eventFilter(QObject *obj, QEvent *ev)
{

    /*if (QWindowsStyle::eventFilter(obj, ev) )
        return true;*/

    if (!obj->isWidgetType() ) return false;

    //mostly from skandale (c)Christoph Feck
    QAbstractScrollArea *area;
    if( /*_sunkenShadows &&*/ ev->type() == QEvent::Paint
        && (area = qobject_cast<QAbstractScrollArea*>(obj)) )
    {
      int width = area->frameRect().width();//area->viewport()->rect().right()+3;
      int height = area->frameRect().height();

      bool sunken = ( area->frameStyle() == (QFrame::StyledPanel | QFrame::Sunken) );
      bool styled = ( area->frameShape() == QFrame::StyledPanel  );

      QList<QObject *> borders = area->children();
      foreach (QObject *child, borders)
      {
        if(ScrollAreaBorder *border = qobject_cast<ScrollAreaBorder *>(child))
        {

          switch( border->orientation() )
          {
            case ScrollAreaBorder::Left:
              border->setGeometry(1, 1, 3, height-2);
            break;
            case ScrollAreaBorder::Top:
              border->setGeometry(1, 1, width-2, (_sunkenShadows&&sunken?5:1) );
            break;
            case ScrollAreaBorder::Right:
              border->setGeometry(width - 4, 1, 3, height-2);
            break;
            case ScrollAreaBorder::Bottom:
              border->setGeometry(1, height - (_sunkenShadows&&sunken?5:2),
                                  width-2, (_sunkenShadows&&sunken?4:1));
            break;
          }
        }
      }
      return false;
    }
    else if( _sunkenShadows
            && (ev->type() == QEvent::FocusIn || ev->type() == QEvent::FocusOut)
            && (area = qobject_cast<QAbstractScrollArea*>(obj)) )
    {
      //repaint scrollbars for that one evil pixel on collapsed scrollbars
      if( area->verticalScrollBar() )
        area->verticalScrollBar()->repaint();
      if( area->horizontalScrollBar() )
        area->horizontalScrollBar()->repaint();

      QList<QObject *> borders = area->children();
      foreach (QObject *child, borders)
      {
        if(ScrollAreaBorder *border = qobject_cast<ScrollAreaBorder *>(child))
          border->repaint();
      }
    }
    //mostly from bespin...
    if( QFrame *frame = qobject_cast<QFrame*>(obj) )
    {
      if( ev->type() == QEvent::Paint
          && (frame->frameShape() == QFrame::HLine
              || frame->frameShape() == QFrame::VLine) )
      {
        QRect r(frame->rect());
        QPainter p(frame);
        QBrush brush = _lightBorder?frame->palette().color(QPalette::Background).dark(100+_contrast*4)
                       :getColor(frame->palette(),PanelDark);

        //for some strange reasons VLine and HLine seems to be swapped...
        if(  frame->frameShape() == QFrame::VLine )
        {
          p.fillRect(QRect(r.top(), r.left(), 1, r.height()),
                     brush);
          if( !_lightBorder )
            p.fillRect(QRect(r.top()+1, r.left(), 1, r.height()),
                       getColor(frame->palette(),PanelLight));
        }
        else
        {
          p.fillRect(QRect(r.top(), r.left(), r.width(), 1),
                     brush);
          if( !_lightBorder )
            p.fillRect(QRect(r.top(), r.left()+1, r.width(), 1),
                       getColor(frame->palette(),PanelLight));
        }
        p.end();
        return true;
      }
    }
    if( ::qobject_cast<QTabBar*>(obj) )
    {
      QWidget* widget = static_cast<QWidget*>(obj);
      if((ev->type() == QEvent::Leave || ev->type() == QEvent::HoverMove)
          && widget->isEnabled())
        //widget->repaint();
        //FIXME: This is butt-ugly, isn't it?
        QTimer::singleShot ( 20, widget, SLOT(repaint()) );
    }
    //header mouse over
    if ( ::qobject_cast<QHeaderView*>(obj) )
    {
        QWidget* widget = static_cast<QWidget*>(obj);
        if((ev->type() == QEvent::Leave)
            && widget->isEnabled())
        {
           widget->repaint();
        }
        /*else if ((ev->type() == QEvent::MouseMove) && static_cast<QWidget*>(obj)->isEnabled())
        {
           QMouseEvent * mEvent = ( QMouseEvent * ) ev;
           QHeaderView* header = static_cast<QHeaderView*>(widget);

        }*/
    }
    /*Scrollbar Mouse over*/
    if ( ::qobject_cast<QScrollBar*>(obj) )
    {
        QWidget* widget = static_cast<QWidget*>(obj);

        if ((ev->type() == QEvent::Enter) && static_cast<QWidget*>(obj)->isEnabled())
        {
           widget->repaint();
        }
        else if ((ev->type() == QEvent::Leave) && static_cast<QWidget*>(obj)->isEnabled())
        {
           widget->repaint();
        }
    }
    // focus highlight
    if ( ::qobject_cast<QLineEdit*>(obj) )
    {
        QWidget* widget = static_cast<QWidget*>(obj);

        if ( ::qobject_cast<QSpinBox*>(widget->parentWidget()) )
        {
            QWidget* spinbox = widget->parentWidget();
            if ((ev->type() == QEvent::FocusIn) || (ev->type() == QEvent::FocusOut))
            {
                spinbox->repaint();
            }
            return false;
        }

        if ((ev->type() == QEvent::FocusIn) || (ev->type() == QEvent::FocusOut))
        {
            widget->repaint();
        }
        return false;
    }
    
    //Hover highlight... use qobject_cast to check if the widget inheits one of the classes.
    if ( ::qobject_cast<QPushButton*>(obj) || ::qobject_cast<QComboBox*>(obj) ||
            ::qobject_cast<QSpinBox*>(obj) || ::qobject_cast<QCheckBox*>(obj) ||
            ::qobject_cast<QRadioButton*>(obj) || ::qobject_cast<QToolButton*>(obj) ||  obj->inherits("QSplitterHandle") )
    {
        if ((ev->type() == QEvent::Enter) && static_cast<QWidget*>(obj)->isEnabled())
        {
            QWidget* button = static_cast<QWidget*>(obj);

            //only animate widgets that support animation :-)
            if(_animateButton && !::qobject_cast<QRadioButton*>(obj)
               && !::qobject_cast<QCheckBox*>(obj)){
                animWidgets[button].active = true;
                // if timer isn't running, start it now for glow-in animation.
                if( !btnAnimTimer->isActive() )
                    btnAnimTimer->start( TIMERINTERVAL );
            }

            button->repaint();
        }
        else if ((ev->type() == QEvent::Leave) )
        {
            QWidget* button = static_cast<QWidget*>(obj);

            //only animate widgets that support animation :-)
            if(_animateButton && !::qobject_cast<QRadioButton*>(obj)
               && !::qobject_cast<QCheckBox*>(obj)){
                animWidgets[button].active = false;
                // if timer isn't running, start it now for glow-out animation.
                if( !btnAnimTimer->isActive() )
                    btnAnimTimer->start( TIMERINTERVAL );
            }

            button->repaint();
        }
        return false;
    }

    // Track show events for progress bars
    if ( QProgressBar* pb = ::qobject_cast<QProgressBar*>(obj) )
    {
        if( !animationTimer->isActive() )
        {
          if( pb->minimum() == 0 && pb->maximum() == 0)
            animationTimer->start( 25 );
          else if( _animateProgressBar )
            animationTimer->start( 50 );
        }
        //return false; FIXME: it is needed?
    }

#ifdef NO_KDE
    return QWindowsStyle::eventFilter(obj, ev);
#else
    return KStyle::eventFilter(obj, ev);
#endif
}

QColor PolyesterStyle::getColor(const QPalette &pal, const ColorType t, const bool enabled)const
{
    return getColor(pal, t, enabled?IsEnabled:IsDisabled);
}

QColor PolyesterStyle::getColor(const QPalette &pal, const ColorType t, const WidgetState s)const
{
    const bool enabled = (s != IsDisabled) &&
            ((s == IsEnabled) || (s == IsPressed) || (s == IsHighlighted));
    const bool pressed = (s == IsPressed);
    const bool highlighted = (s == IsHighlighted);

    switch(t) {
        case ButtonContour:
            return enabled ? pal.color(QPalette::Button).dark(130+_contrast*6)
                           : pal.color(QPalette::Background).dark(120+_contrast*6);
        case DragButtonContour: {
            if(enabled) {
                if(pressed)
                    return _coloredScrollBar?pal.color(QPalette::Highlight).dark(130+_contrast*5)
                                            :pal.color(QPalette::Background).dark(130+_contrast*5); // bright
                else if(highlighted)
                    return _coloredScrollBar?pal.color(QPalette::Highlight).dark(130+_contrast*9)
                                            :pal.color(QPalette::Background).dark(130+_contrast*9); // dark
                else
                    return _coloredScrollBar?pal.color(QPalette::Highlight).dark(130+_contrast*6)
                                            :pal.color(QPalette::Background).dark(130+_contrast*6); // normal
            } else {
                return pal.color(QPalette::Background).dark(120+_contrast*8);
            }
        }
        case DragButtonSurface: {
            if(enabled) {
                if(pressed)
                    return _coloredScrollBar?pal.color(QPalette::Highlight).dark(100-_contrast):pal.color(QPalette::Button).dark(100-_contrast);  // bright
                else if(highlighted)
                    return _coloredScrollBar?pal.color(QPalette::Highlight).light(100+_contrast):pal.color(QPalette::Button).light(100+_contrast); // dark
                else
                    return _coloredScrollBar?pal.color(QPalette::Highlight):pal.color(QPalette::Button);                      // normal
            } else {
                return pal.color(QPalette::Background);
            }
        }
        case PanelContour:
            return pal.color(QPalette::Background).dark(130+_contrast*6);
        case PanelDark:
           if( !_lightBorder )
            return alphaBlendColors(pal.color(QPalette::Background), pal.color(QPalette::Background).dark(120+_contrast*5), 110);
           else
            return alphaBlendColors(pal.color(QPalette::Background), pal.color(QPalette::Background).light(120+_contrast*5), 110);
        case PanelDark2:
           if( !_lightBorder )
            return alphaBlendColors(pal.color(QPalette::Background), pal.color(QPalette::Background).dark(110+_contrast*5), 110);
           else
            return alphaBlendColors(pal.color(QPalette::Background), pal.color(QPalette::Background).light(110+_contrast*5), 110);
        case PanelLight:
            return alphaBlendColors(pal.color(QPalette::Background), pal.color(QPalette::Background).light(120+_contrast*5), 110);
        case PanelLight2:
            return alphaBlendColors(pal.color(QPalette::Background), pal.color(QPalette::Background).light(110+_contrast*5), 110);
        case MouseOverHighlight:
            if( _customOverHighlightColor )
                return _overHighlightColor;
            else
                return pal.color(QPalette::Highlight);
        case FocusHighlight:
            if( _customFocusHighlightColor )
                return _focusHighlightColor;
            else
                return pal.color(QPalette::Highlight);
        case CheckMark:
            if( _customCheckMarkColor )
                return _checkMarkColor;
            else
                return pal.color(QPalette::Foreground);
        case MenuBarEmphasis:
            if( _customMenuBarEmphasisColor )
                return _menuBarEmphasisColor;
            else
                return pal.color(QPalette::Background);
        default:
            return pal.color(QPalette::Background);
    }
}

//////////////////////////////////////////////////////////////////////////////
// Plugin stuff                                                            //
//////////////////////////////////////////////////////////////////////////////

class PolyesterStylePlugin : public QStylePlugin
{
public:
    PolyesterStylePlugin() { ; }
    QStringList keys() const {
        return QStringList() << "Polyester";
    }
    QStyle *create(const QString &key)
    {
        if (key.toLower() == "polyester")
        {
            return new PolyesterStyle();
        }
        return 0;
    }
};

Q_EXPORT_PLUGIN2(PolyesterStyle, PolyesterStylePlugin)


