#ifndef TGLYPH_DIB_INCLUDED
#define TGLYPH_DIB_INCLUDED

// Macro defining class name (usable in resource definition)
#if !defined(OWL_GLYPHBTN_EX)
#define OWL_GLYPHBTN_EX  "OWL_GlyphBtn_Ex"
#endif

#if !defined(RC_INVOKED)
#include <owl/button.h>
#include <owl/uihelper.h>
#include <owl/bitset.h>
#include <winsys/color.h>
#include <services/preclass.h>

class TGlyphDib : public TButton  {
  public:
    TGlyphDib(TWindow*        parent,
                 int             id,
                 const char far* text,
                 int X, int Y, int W, int H,
                 bool            isDefault = false,
                 TModule*        module = 0);
    TGlyphDib(TWindow* parent, int resourceId, TModule* module = 0);
   ~TGlyphDib();

    // Enumeration describing the state when a particular bitmap should
    // be displayed. Used with the 'SetGlyph' method.
    // NOTE: If only a single 'up' bitmap is specified, TGltphBtn_Ex will
    //       automatically generate the bitmaps for the other states.
    //
    enum TGlyphType {
      gtUp       = TUIFace::Normal,   // Dib for when button is up
      gtDisabled = TUIFace::Disabled, // Dib for when button is disabled
      gtDown,                         // Dib for when button is depressed
      gtFocus                         // Dib for when button has focus
///added
      // gtNegative is for drived classes not actuall used by TGlyphDib
      ,gtNegative                     // Dib for when mouse is over the button
///
    };

    // Methods to specify the glyphs that should be used
    void    SetGlyph(TResId resId, TGlyphType = gtUp, TModule* module = 0);
    void    virtual SetGlyphDib(TDib* dib, TGlyphType type);
    ///called from SetGlyphDib
    void    virtual MapColors(TDib *dib,TGlyphType type);

    // Enumeration describing how to position the text and glyph
    // of the button.
    //
    enum  TLayoutStyle {
      lsNone,                   // Use specified coordinates

      // Horizontal layouts [center vertically]
      //
      lsH_SGST,                 // Space Glyph Space Text
      lsH_GST                   // Glyph Space Text
    };

    // Methods to specify how the glyph and/or text should be laid out
    void      SetLayoutStyle(TLayoutStyle style);
    void      SetTextOrigin(int x, int y);
    void      SetGlyphOrigin(int x, int y);

    // Set, clear, query flags about the state of the control
    int       Clear(int t);
    int       Set(int t);
    bool      IsSet(int t) const;

///added   .. these are needed to access private TFont & TDib from paint routine
    TDib*  dibOf(TGlyphType);
    TFont*    BtnFontOf();
///

  protected:
    // Helper functions
///changed these to virtual
    virtual  void SendNotificationEx();
    virtual  void PaintNow();
    virtual  void PaintButton(TDC& dc);
    virtual  void PaintFrame(TDC& dc, TRect& rect);
    virtual  void PaintDefaultRect(TDC& dc, TRect& rect);
    virtual  void PaintFace(TDC& dc, TRect& rect);
    virtual  void PaintFocusRect(TDC& dc, const TRect& faceRect);
    virtual  void ClearCapture();

    // Overriden TWindow virtuals
    void      SetupWindow();
    void      Paint(TDC& dc, bool erase, TRect& rect);
    void      GetWindowClass(WNDCLASS& wndClass);
    char far* GetClassName();

    // Routine which determines location of text and glyph
    virtual void LayoutTextGlyph(const TRect& faceRect, TRect& textRect,
                                 TRect& glyphRect);
    // Initialization routine
    void      InitVars();

    // Enumeration describing the current state of the button.
    enum  TButtonInfo {
      biPushed   = 0x0001,      // Button is currently depressed
      biFocus    = 0x0002,      // Button has focus
      biDefault  = 0x0004,      // Button is a 'DefaultPushButton'
      biDisabled = 0x0008,      // Button is disabled
      biShowText = 0x0010,      // Button should display its caption
      biShowGlyph= 0x0020       // Button should draw its glyph
    };

    // Event handlers
    void        EvPaint();
    bool        EvEraseBkgnd(HDC);
    void        EvSetFocus(THandle hWndLostFocus);
    void        EvKillFocus(THandle hWndGetFocus);
    HFONT       EvGetFont();
    void        EvSetFont(HFONT hFont, bool redraw);
    uint        EvGetDlgCode(MSG far* msg);
    void        EvLButtonDown(uint modKeys, TPoint& point);
    void        EvLButtonDblClk(uint modKeys, TPoint& point);
    void        EvLButtonUp(uint modKeys, TPoint& point);
    void        EvMouseMove(uint modKeys, TPoint& point);
    void        EvKeyDown(uint key, uint repeatCount, uint flags);
    void        EvKeyUp(uint key, uint repeatCount, uint flags);
    void        EvEnable(bool enabled);
    void        EvCancelMode();
    TResult     BmGetState(TParam1 param1, TParam2 param2);
    TResult     BmSetState(TParam1 param1, TParam2 param2);
    TResult     BmSetStyle(TParam1 param1, TParam2 param2);

  private:
    // Hidden to prevent accidental copying or assignment
    TGlyphDib(const TGlyphDib&);
    TGlyphDib& operator =(const TGlyphDib&);

    TDib*        dibUp;            // Pointer to 'normal' glyph
    TDib*        dibDisabled;       // Pointer to 'disabled' glyph
    TDib*        dibDown;          // Pointer to 'pushed' glyph
    TDib*        dibFocus;         // Pointer to 'focused' glyph
///added
    TDib*        dibNegative;      // Pointer to 'negative' glyph
///

    TFont*          BtnFont;        // Pointer to font used by button
    int             xGlyph;         // x (left) coordinate of glyph
    int             yGlyph;         // y (top ) coordinate of glyph
    int             xText;          // x (left) coordinate of text
    int             yText;          // y (top ) coordinate of text
    TLayoutStyle    LayStyle;       // How text & glyph should be laid out
    TBitFlags<int>  Flags;          // Status flags
  DECLARE_RESPONSE_TABLE(TGlyphDib);
};

// Generic definitions/compiler options (eg. alignment) following the
#include <services/posclass.h>

// Inline implementations

// Clear a flag
inline int
TGlyphDib::Clear(int t)
{
  return Flags.Clear(t);
}

// Set a flag
inline int
TGlyphDib::Set(int t)
{
  return Flags.Set(t);
}

// Test if a flag is set
inline bool
TGlyphDib::IsSet(int t) const
{
  return Flags.IsSet(t);
}

#endif  // !RC_INVOKED
#endif  // TGLYPH_DIB_INCLUDED