#ifndef _aspell_i_data_hh_
#define _aspell_i_data_hh_

#include <vector>
#include <string>

#include "error.hh"
#include "iterator.hh"
#include "copy_ptr.hh"

class aspell;
class SC_Language;
class AspellConfig;

class WordList_Base : public aspell_object {
friend aspell;
private:
  copy_ptr<const SC_Language> lang_;
  int                         attach_count_;
private:
  void attach(const SC_Language &) ;
  void detach();
public:
  WordList_Base();
  virtual ~WordList_Base();
  void check_lang(const string& lang);
  void set_check_lang(const string & lang, const AspellConfig *);
  const SC_Language * lang() const {return lang_.ptr;};
  const char * lang_name() const;
  bool is_attached () const ;
};

class SavableWL_Base {
public:
  virtual void save() = 0;
};

class StandardWL_Base : public WordList_Base
{
public:
  typedef 
    virtual_forward_iterator_proxy<const char *, const char *> const_iterator;
  typedef const_iterator iterator;
  typedef begin_end_size<const_iterator>   WordList;
  typedef size_t         size_type;
  
  virtual const_iterator begin() const = 0;
  virtual const_iterator end() const = 0;
  virtual size_type size() const = 0;
  virtual bool empty() const = 0;
  
  //virtual ~StandardWL_Base() {}

  virtual void load(const string &, const AspellConfig * c = 0) = 0;
  virtual const char * file_name() const = 0;

  virtual bool operator [] (const char *word) const = 0;
  virtual bool operator [] (const string &word) const = 0;

  virtual const WordList words_w_soundslike(const char *word) const = 0;
};

class WritableWL_Base : public StandardWL_Base,
			public SavableWL_Base
{
public:
  virtual void merge(const string &) = 0;
  virtual void update() = 0;
  virtual void save() = 0;
  virtual void save_as(const string &) = 0;
  virtual void add(const string &w) = 0;
  virtual void add(const string &w, const string &s) = 0;
  virtual void clear() = 0;
};

class ReplacementsWL_Base : public WordList_Base, public SavableWL_Base
{
public:
  class Replacements {
    typedef 
      virtual_forward_iterator_proxy<const char *, const char *> 
      const_iterator;
    typedef const_iterator                 iterator;
    typedef unsigned int                   size_type;
  private:
    const char *   misspelled_word_;
    const_iterator begin_;
    const_iterator end_;
    size_type      size_;
  public:
    Replacements() : size_(0) {}
    Replacements(const char * mw, const_iterator b, const_iterator e, size_type s) 
      : misspelled_word_(mw), begin_(b), end_(e), size_(s) {}
    const char *   misspelled_word() 
                           const {return misspelled_word_;}
    const_iterator begin() const {return begin_;}
    const_iterator end()   const {return end_;}
    size_type      size()  const {return size_;}
    bool           empty() const {return !size_;}
  };

  typedef
    begin_end_size<virtual_forward_iterator_proxy<Replacements, Replacements> >
    WordList;
public:
  typedef size_t          size_type;
  typedef virtual_forward_iterator_proxy<Replacements, Replacements> 
          const_iterator;
  typedef const_iterator  iterator;

  virtual const_iterator begin() const = 0;
  virtual const_iterator end() const = 0;
  virtual size_type size() const = 0;
  virtual bool empty() const = 0;

  virtual void load(const string &, const AspellConfig *) = 0;
  virtual void merge(const string &) = 0;
  virtual void update() = 0;
  virtual void save() = 0;
  virtual void save_as(const string &) = 0;
  virtual void clear() = 0;
  virtual const char * file_name() = 0;
  virtual void add(const string &mis, const string &cor) = 0;
  virtual void add(const string &mis, const string &cor, const string &s) = 0;
  virtual const WordList words_w_soundslike(const char *word) const = 0;
};

typedef 
  const_multi_forward_container
   <
    vector
      <begin_end_size<virtual_forward_iterator_proxy<const char *, const char *> > >
   >
  SC_MWordList;

typedef 
  const_multi_forward_container
   <
    vector
      <begin_end_size<
         virtual_forward_iterator_proxy<ReplacementsWL_Base::Replacements,
                                        ReplacementsWL_Base::Replacements > > 
      >
   >
  SC_MReplList;

typedef ReplacementsWL_Base::Replacements SC_ReplList;
typedef ReplacementsWL_Base::WordList     SC_MMWordList;

#endif

