
#ifndef _FOREIGN_MENU_H_INCLUDED_
#define _FOREIGN_MENU_H_INCLUDED_

#include <string>

#include <boost/thread/thread.hpp>

#ifndef WIN32
#define HANDLE int
#endif

struct FrgMenuMsg;

class ForeignMenuListener
{
public:
    virtual void on_menu_item_click(uint32_t id) = 0;
    virtual void on_menu_activate() = 0;
    virtual void on_menu_deactivate() = 0;
    virtual void on_connection_close() = 0;
};

class ForeignMenu
{
public:
    ForeignMenu(ForeignMenuListener& listener);
    ~ForeignMenu();

    bool open_connection(const std::string& pipe_name);
    void start();
    void stop();

	void init(const std::string& title);
    void set_title(const std::string& title);
    void add_item(uint32_t id, const std::string& name, uint32_t type);
    void modify_item();
    void remove_item();
    void remove_items();

private:
    void handle_foreign_menu_message(FrgMenuMsg *hdr);
    void wait_for_menu_events();
    void read_menu_events(unsigned long size);
    void write_to_client(const void *buf, uint32_t len);
#ifdef WIN32
    static void CALLBACK read_completion_routine(unsigned long err, unsigned long size, LPOVERLAPPED overlapped);
#else
    bool connect_foreign_menu(const std::string& pipe_name);
#endif

private:
    ForeignMenuListener& _listener;
    HANDLE _ipc_fd;
#ifdef WIN32
    OVERLAPPED _overlapped;
#endif
    boost::thread *_menu_events_thread;
    char *_tail_ptr;
    char _buffer[0x1000];
};

#endif // _FOREIGN_MENU_H_INCLUDED_
