#ifndef __windows_utils_h__
#define __windows_utils_h__

#include <windows.h>

#include "cmt_std.h"
#include "cmt_string.h"
#include "cmt_vector.h"
#include "cmt_system.h"

//-------------------------------------------------------------------
class WWindow
{
public:
  WWindow ();

  void enable ();
  void disable ();

protected:
  HWND _window;
};
//-------------------------------------------------------------------

//-------------------------------------------------------------------
class WEdit : public WWindow
{
public:
  WEdit ();
  WEdit (HWND edit);
  WEdit (HWND container, int id);

  void init (HWND container, int id);
  WEdit& operator = (HWND edit);
  void set (const char* text);
  void set (const cmt_string& text);
  void clear ();
  cmt_string get () const;
  void copy (const WEdit& other);

private:
  HWND _edit;
};
//-------------------------------------------------------------------

//-------------------------------------------------------------------
class WList : public WWindow
{
public:
  WList ();
  WList (HWND list);
  WList (HWND container, int id);

  void init (HWND container, int id);
  WList& operator = (HWND list);
  void append (const char* text);
  void append (const cmt_string& text);
  void insert (int index, const cmt_string& text);
  void modify (int index, const cmt_string& text);
  void delete_item (int index);
  void clear ();
  void cancel_selection ();
  int get_selected_index ();
  void set_selected_index (int index);
  cmt_string get_selected ();
  int get_item_count () const;
  cmt_string get_item (int index) const;
  void get_item (int index, cmt_string& text) const;
  int get_item_length (int index) const;
  void copy (const WList& other);
  void set (const CmtSystem::cmt_string_vector& v, int first = 0);
  void set (const cmt_string& file_name);
  void get (CmtSystem::cmt_string_vector& v) const;
  void get (cmt_string& s) const;
  void set_extent ();
  int get_width () const;
  int get_extent () const;

private:
  HWND _list;
  int _selected_index;
  int _width;
};
//-------------------------------------------------------------------

/*---------------------------------------------------------------------*/
class mysb :public streambuf
{
public:
  mysb (WList& list);
  ~mysb ();

private:
  int_type overflow (int_type c);
  int underflow ();

  streambuf* _old;
  cmt_string* _buf;
  WList& _list;
};
/*---------------------------------------------------------------------*/

/*---------------------------------------------------------------------*/
class WDialog
{
public:
  WDialog ();

  virtual void action (UINT message_type,
                       WPARAM parameter1,
                       LPARAM parameter2);
  virtual void init_action ();
  virtual void menu_action (int menu_item,
                            WPARAM parameter1,
                            LPARAM parameter2);

protected:

  int run (HINSTANCE instance, HWND father, int id);

  HWND _dialog;

private:

  static LRESULT CALLBACK proc (HWND dialog,
                                UINT message_type,
                                WPARAM parameter1,
                                LPARAM parameter2);
};
/*---------------------------------------------------------------------*/

/*---------------------------------------------------------------------*/
class TextEditor : public WDialog
{
public:
  TextEditor (cmt_string& ref);

  int run (HINSTANCE instance, HWND father);
  virtual void action (UINT message_type,
                       WPARAM parameter1,
                       LPARAM parameter2);
  void init_action ();
  void menu_action (int menu_item, WPARAM parameter1, LPARAM parameter2);

private:
  cmt_string& _ref;
  WEdit _edit;
};
/*---------------------------------------------------------------------*/

/*---------------------------------------------------------------------*/
class ListEditor : public WDialog
{
public:
  ListEditor (WList& list);

  int run (HINSTANCE instance, HWND father);
  virtual void action (UINT message_type,
                       WPARAM parameter1,
                       LPARAM parameter2);
  void set_position (int index);
  void init_action ();
  void menu_action (int menu_item, WPARAM parameter1, LPARAM parameter2);

private:
  WList& _ref_list;
  WList _list;
  HINSTANCE _instance;
  int _selected_index;
  int _last_index;
  int _ref_selected_index;
};
/*---------------------------------------------------------------------*/

/*---------------------------------------------------------------------*/
class CmtMutex
{
public:
  CmtMutex ();
  ~CmtMutex ();

  void lock ();
  void unlock ();

private:
  CRITICAL_SECTION _section;
};
/*---------------------------------------------------------------------*/

/*---------------------------------------------------------------------*/
class CmtThread
{
public:
  CmtThread ();
  virtual ~CmtThread ();

  virtual void run ();
  bool is_running ();
  void set_running ();
  void reset_running ();
  bool start ();
  void stop ();

private:
  static void run_it (CmtThread* thread);

  HANDLE _thread;
  DWORD _id;
  CmtMutex _mutex;
  bool _shutdown;
  bool _running;
};
/*---------------------------------------------------------------------*/

#endif
