#ifndef QRK_BUTTON_H
#define QRK_BUTTON_H

/*!
  \file
  \brief ボタン

  \author Satofumi KAMIMURA

  $Id: Button.h 883 2009-05-13 19:32:54Z satofumi $
*/

#include "Component.h"
#include <boost/signals.hpp>


namespace qrk
{
  typedef boost::signal<void (void)> ButtonCallback;


  class Surface;
  class CallbackEvent;


  /*!
    \brief ボタン
  */
  class Button : public Component
  {
    Button(void);
    Button(const Button& rhs);
    Button& operator = (const Button& rhs);

    struct pImpl;
    std::auto_ptr<pImpl> pimpl;

  public:
    typedef enum {
      Normal = 0,
      Focused,
      Pressed,
    } ButtonMode;

    explicit Button(Surface& normal_surface,
                    Surface& focused_surface,
                    Surface& pressed_surface);
    ~Button(void);

    Rect<long> rect(void) const;
    void setEventAcceptable(bool acceptable);
    void setAlpha(float alpha);
    void draw(const Rect<long>& area);

    void setSurface(Surface& surface, ButtonMode mode);

    void setEnabled(bool enable);

    /*!
      \brief ボタンをフォーカス状態にする
    */
    void setFocus(void);

    bool isFocused(void);
    bool isCursorInner(void);

    /*!
      \brief ボタンを押した状態にする

      release() が呼ばれるまで、押下状態を保持する
    */
    void click(void);


    /*!
      \brief ボタンを押せる状態にする

      押下状態を解除する
    */
    void release(void);


    /*!
      \brief 押されているか

      \retval true 押されている
      \retval false 押されていない
    */
    bool isClicked(void);


    // クリックを行うイベントの登録
    void setClickEvent(CallbackEvent* event);


    // クリック時のイベント
    void connectClickedEvent(const ButtonCallback::slot_type& slot);


    // フォーカス時のイベント
    void connectFocusedEvent(const ButtonCallback::slot_type& slot);
  };
}

#endif /* !QRK_BUTTON_H */
