/*
 * Copyright (C) 2007 Gustavo Pichorim Boiko <boiko@mandriva.com>
 * Copyright (C) 2006 Laurent Montel<lmontel@mandriva.com>
 *
 * renderGradient() code adapted from the Plastik stype
 * Copyright (C) 2003 Sandro Giessl <ceebx@users.sourceforge.net>
 *
 * based on KDE3 HighColor Style (version 1.0)
 * 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>
 *
 * 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.
 */


#ifndef __MANDRIVASTYLE_H
#define __MANDRIVASTYLE_H

#include <tqbitmap.h>
#include <tqintdict.h>
#include <kdrawutil.h>
#include <kpixmap.h>
#include <tdestyle.h>
#include <tqintcache.h>

class TQPopupMenu;


class MandrivaStyle : public TDEStyle
{
    TQ_OBJECT

public:
    MandrivaStyle();
    virtual ~MandrivaStyle();

    void polish(const TQStyleControlElementData &ceData, ControlElementFlags elementFlags, void *);
    void unPolish(const TQStyleControlElementData &ceData, ControlElementFlags elementFlags, void *);
    void applicationPolish(const TQStyleControlElementData &ceData, ControlElementFlags elementFlags, void *);
    void renderMenuBlendPixmap( KPixmap& pix, const TQColorGroup &cg,
                                const TQPopupMenu* popup ) const;

    void drawTDEStylePrimitive( TDEStylePrimitive kpe,
                              TQPainter* p,
                              const TQStyleControlElementData &ceData,
                              ControlElementFlags elementFlags,
                              const TQRect &r,
                              const TQColorGroup &cg,
                              SFlags flags = Style_Default,
                              const TQStyleOption& = TQStyleOption::Default,
                              const TQWidget* widget = 0 ) const;

    void drawPrimitive( PrimitiveElement pe,
                        TQPainter* p,
                        const TQStyleControlElementData &ceData,
                        ControlElementFlags elementFlags,
                        const TQRect &r,
                        const TQColorGroup &cg,
                        SFlags flags = Style_Default,
                        const TQStyleOption& = TQStyleOption::Default ) const;

    void drawControl( ControlElement element,
                      TQPainter *p,
                      const TQStyleControlElementData &ceData,
                      ControlElementFlags elementFlags,
                      const TQRect &r,
                      const TQColorGroup &cg,
                      SFlags flags = Style_Default,
                      const TQStyleOption& = TQStyleOption::Default,
                      const TQWidget *widget = 0 ) const;

    void drawControlMask( ControlElement element,
                          TQPainter *p,
                          const TQStyleControlElementData &ceData,
                          ControlElementFlags elementFlags,
                          const TQRect &r,
                          const TQStyleOption& = TQStyleOption::Default,
                          const TQWidget *widget = 0 ) const;

    void drawComplexControl( ComplexControl control,
                             TQPainter *p,
                             const TQStyleControlElementData &ceData,
                             ControlElementFlags elementFlags,
                             const TQRect &r,
                             const TQColorGroup &cg,
                             SFlags flags = Style_Default,
                             SCFlags controls = SC_All,
                             SCFlags active = SC_None,
                             const TQStyleOption& = TQStyleOption::Default ,
                             const TQWidget *widget = 0 ) const;

    void drawComplexControlMask( ComplexControl control,
                                 TQPainter *p,
                                 const TQStyleControlElementData &ceData,
                                 ControlElementFlags elementFlags,
                                 const TQRect &r,
                                 const TQStyleOption& = TQStyleOption::Default,
                                 const TQWidget *widget = 0 ) const;

    int pixelMetric( PixelMetric m,
                     const TQStyleControlElementData &ceData,
                     ControlElementFlags elementFlags,
                     const TQWidget *widget = 0 ) const;

    TQSize sizeFromContents( ContentsType contents,
                             const TQStyleControlElementData &ceData,
                             ControlElementFlags elementFlags,
                             const TQSize &contentSize,
                             const TQStyleOption& opt,
                             const TQWidget *widget = 0 ) const;

    TQRect subRect( SubRect r,
                    const TQStyleControlElementData &ceData,
                    const ControlElementFlags elementFlags,
                    const TQWidget *widget ) const;

    // Fix TQt3's wacky image positions
    TQPixmap stylePixmap( StylePixmap stylepixmap,
                          const TQStyleControlElementData &ceData,
                          ControlElementFlags elementFlags,
                          const TQStyleOption& = TQStyleOption::Default,
                          const TQWidget *widget = 0 ) const;

    TQRect querySubControlMetrics( ComplexControl control,
                                   const TQStyleControlElementData &ceData,
                                   ControlElementFlags elementFlags,
                                   SubControl subcontrol,
                                   const TQStyleOption& opt = TQStyleOption::Default,
                                   const TQWidget* widget = 0 ) const;

protected:
    enum Hover
    {
        HoverNone = 0,
        // scrollbar
        HoverScrollBarSlider,
        HoverScrollBarAddLine,
        HoverScrollBarSubLine,
        HoverScrollBarAddPage,
        HoverScrollBarSubPage,
        HoverScrollBarFirst,
        HoverScrollBarLast,
        // combobox
        HoverComboBoxArrow,
        HoverComboBoxEdit
    };


    virtual bool objectEventHandler( const TQStyleControlElementData &ceData, ControlElementFlags elementFlags, void* source, TQEvent *e );

    void renderGradient(TQPainter* p,
                        const TQRect& r,
                        const TQColor& ca,
                        const TQColor& cb ,
                        bool horizontal) const;

    TQWidget    *hoverWidget;
    enum Hover hoverControl;

    struct MandrivaColorData 
    {
        ~MandrivaColorData();
        TQRgb spotColor;

        // gradient color
        //rename to grey
        TQColor shades[7];
        
        // five blue color
        TQColor blueMdkColor[5];

        // button gradients 
        TQColor buttonColor[7];
        
        
        TQColor radioColor;

        bool isGroup (const TQColorGroup &cg) 
        {
            return cg.button() == buttonColor[0] && cg.highlight().rgb() == spotColor;
        }
    };

private:
    enum TabPosition {Single = 0,First,Last, Middle};

    // Disable copy constructor and = operator
    MandrivaStyle( const MandrivaStyle & );
    MandrivaStyle& operator=( const MandrivaStyle & );

    void drawButton( const MandrivaColorData *cdata, 
                     const TQRect & r, TQPainter *p,
                     const TQColorGroup &cg, 
                     SFlags flags) const;

    void drawHandlePoint ( const MandrivaColorData *cdata,
                           TQPainter *p, 
                           int x, 
                           int y) const;

    void drawHandle( const MandrivaColorData *cdata, 
                     TQPainter *p,
                     const TQRect &r,
                     const TQColorGroup &cg,
                     SFlags flags, 
                     const TQStyleOption& opt, 
                     bool drawBorderAndGradient, 
                     bool drawGradient = false ) const;

    void drawGroupBox(const MandrivaColorData *cdata, 
                      const TQColorGroup & cg, 
                      TQPainter *p, 
                      const TQRect & r, 
                      bool active, 
                      bool sunken )const;

    void drawLineSeparator(const MandrivaColorData *cdata, 
                           const TQColorGroup & cg, 
                           TQPainter *p, 
                           const TQRect & r, 
                           bool horiziontal,
                           bool active, 
                           bool sunken,
                           bool skipOffset = true) const;

    void drawFrame( const MandrivaColorData *cdata, 
                    const TQColorGroup & cg, 
                    TQPainter *p, 
                    const TQRect & r, 
                    bool active) const;

    void drawComboboxArrow( TQPainter *p,
                            const TQStyleControlElementData &ceData,
                            ControlElementFlags elementFlags,
                            const TQRect &r,
                            const TQColorGroup &cg,
                            SFlags flags,
                            SCFlags active,
                            const TQWidget *widget)const;

    void drawMandrivaArrow( TQPointArray a, TQPainter *p,
                            const TQRect &r,
                            const TQColorGroup &cg,
                            SFlags flags,
                            const TQStyleOption& opt ) const;


    MandrivaColorData *realizeData (const TQColorGroup &cg) const;
    const MandrivaColorData *lookupData (const TQColorGroup &cg) const;
    bool isFormWidget(const TQWidget* widget) const;
    bool excludeColor(const TQColor &col, bool active) const;
    void getShade (const TQColorGroup &cg, int shadenr, TQColor &res) const;
    void updateHoverControl(const TQPoint &pos, const TQStyleControlElementData &ceData, ControlElementFlags elementFlags);
    TQIntCache<MandrivaColorData> m_dataCache;
    static const double shading[8];
    mutable bool formMode;
    bool kickerMode;
    // For KPE_ListViewBranch
    mutable TQBitmap *verticalLine;
    mutable TQBitmap *horizontalLine;

    // pixmap cache.
    enum CacheEntryType 
    {
        cSurface,
        cGradientTile,
        cAlphaDot
    };
    struct CacheEntry
    {
        CacheEntryType type;
        int width;
        int height;
        TQRgb c1Rgb;
        TQRgb c2Rgb;
        bool horizontal;

        TQPixmap* pixmap;

        CacheEntry(CacheEntryType t, int w, int h, TQRgb c1, TQRgb c2 = 0,
                   bool hor = false, TQPixmap* p = 0 ):
            type(t), width(w), height(h), c1Rgb(c1), c2Rgb(c2), horizontal(hor), pixmap(p)
        {}

        ~CacheEntry()
        {
            delete pixmap;
        }

        int key()
        {
            // create an int key from the properties which is used to refer to entries in the TQIntCache.
            // the result may not be 100% correct as we don't have so much space in one integer -- use
            // == operator after find to make sure we got the right one. :)
            return horizontal ^ (type<<1) ^ (width<<5) ^ (height<<10) ^ (c1Rgb<<19) ^ (c2Rgb<<22);
        }

        bool operator == (const CacheEntry& other)
        {
            bool match = (type == other.type) &&
                        (width   == other.width) &&
                        (height == other.height) &&
                        (c1Rgb == other.c1Rgb) &&
                        (c1Rgb == other.c1Rgb) &&
                        (horizontal == other.horizontal);
            return match;
        }
    };
    TQIntCache<CacheEntry> *pixmapCache;

};

#endif
