#ifndef __SPELL_CHECK_ENGINE_INTERFACE__
#define __SPELL_CHECK_ENGINE_INTERFACE__

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include <wx/hashmap.h>
#include <wx/arrimpl.cpp> // this is a magic incantation which must be done!
#include <wx/string.h>

#include "SpellCheckEngineOption.h"

// Get rid of the warning about identifiers being truncated in the debugger.  Using the STL collections
// will produce this everywhere.  Must disable at beginning of stdafx.h because it doesn't work if
// placed elsewhere.
#ifdef __VISUALC__
	#pragma warning(disable:4786)
#endif

WX_DECLARE_STRING_HASH_MAP(wxString, StringToStringMap);
WX_DECLARE_STRING_HASH_MAP(SpellCheckEngineOption, OptionsMap);

class wxSpellCheckUserInterface;

class wxSpellCheckEngineInterface
{
public:
  wxSpellCheckEngineInterface();
  virtual ~wxSpellCheckEngineInterface();

protected:
  StringToStringMap m_AlwaysReplaceMap;	// We need a map here to store the misspelled word and its replacement
  wxArrayString m_AlwaysIgnoreList;
	bool m_bPersonalDictionaryModified;
  bool m_bEngineInitialized;

  // Create a pointer to the dialog to present.
  // The main reason that this is here rather than created only if needed, is that I wanted repeat appearances
  //  of this dialog to remember if the user moved the dialog.
  wxSpellCheckUserInterface* m_pSpellUserInterface;
  OptionsMap m_Options;

public:
  // Base class administration functions
  void SetSpellCheckUserInterface(wxSpellCheckUserInterface* pDlg);
  wxSpellCheckUserInterface* GetSpellCheckUserInterface() const { return m_pSpellUserInterface; }

	// Spell Checker functions

  // Spell Checker Engine Administration functions
  virtual wxString GetSpellCheckEngineName() = 0;
  virtual int InitializeSpellCheckEngine() = 0;
  virtual int UninitializeSpellCheckEngine() = 0;
  virtual int SetOption(SpellCheckEngineOption& Option) = 0;
  virtual bool AddOptionToMap(SpellCheckEngineOption& option);
  virtual void ApplyOptions();  // Go through all the options in the options map and apply them to the spell check engine
  OptionsMap* GetOptions() { return &m_Options; }
  virtual void UpdatePossibleValues(SpellCheckEngineOption& WXUNUSED(OptionDependency), SpellCheckEngineOption& WXUNUSED(OptionToUpdate)) { wxASSERT(false); }
  bool IsInitialized() { return m_bEngineInitialized; }

  // Spell Checker Search/Suggestion functions
	virtual bool IsWordInDictionary(const wxString& strWord) = 0;
  virtual wxString CheckSpelling(wxString strText) = 0;
  virtual wxArrayString GetSuggestions(const wxString& strMisspelledWord) = 0;

  // Spell Checker Dictionary Manipulation functions (the above functions work on a read-only dictionary
  //  but these functions require write-access or usage of a personal dictionary
  virtual int AddWordToDictionary(const wxString& strWord) = 0;
  virtual int RemoveWordFromDictionary(const wxString& strWord) = 0;
  virtual wxArrayString GetWordListAsArray() = 0;
  bool IsPersonalDictionaryModified() { return m_bPersonalDictionaryModified; }
  virtual int GetUserCorrection(const wxString& strMisspelling);
  virtual void DefineContext(const wxString& strText, long nOffset, long nLength);
  void ShowOption(const wxString& strOption, bool bShow = true);

  // Helper functions for Unicode compatibility
  const wxCharBuffer ConvertToUnicode(const wxString& inputString);
  wxString ConvertFromUnicode(const char* inputBuffer);

  virtual wxString GetCharacterEncoding() = 0;

  class MisspellingContext
  {
  protected:
    wxString m_strContext;  // fragment of the document containing word prior to and following the misspelled word
    long m_nOffset;         // zero based offset into the strContext where the misspell word begins
    long m_nLength;         // length of the misspelled word within strContext

  public:
    MisspellingContext()
    {
      m_strContext = _T("");
      m_nOffset = 0;
      m_nLength = 0;
    }
    wxString GetContext() { return m_strContext; }
    long GetOffset() { return m_nOffset; }
    long GetLength() { return m_nLength; }
    void SetContext(const wxString& strContext) { m_strContext = strContext; }
    void SetOffset(long nOffset) { m_nOffset = nOffset; }
    void SetLength(long nLength) { m_nLength = nLength; }
  };

    virtual MisspellingContext GetCurrentMisspellingContext() { return m_Context; }

  protected:
    MisspellingContext m_Context;
};

#endif  // __SPELL_CHECK_ENGINE_INTERFACE__
