/*
  MeCab -- Yet Another Part-of-Speech and Morphological Analyzer

  $Id: mecab.h,v 1.23 2003/03/14 05:46:41 taku-ku Exp $;

  Copyright (C) 2001-2002  Taku Kudo <taku-ku@is.aist-nara.ac.jp>
  All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later verjsion.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the
  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.
*/
#ifndef _MECAB_MECAB_H
#define _MECAB_MECAB_H

/* C/C++ common data structures */

struct _mecab_token_t /* 16byte */
{
  unsigned short rcAttr2;
  unsigned short rcAttr1;
  unsigned short lcAttr;
  unsigned short posid;
  unsigned short length;
  unsigned short cost;
  unsigned int   feature;
};

struct _mecab_path_t
{
  struct _mecab_node_t* node;
  unsigned int  cost;
  struct _mecab_path_t* next;
}; 
   
struct _mecab_node_t
{
  struct _mecab_token_t *token;
  struct _mecab_node_t  *prev;
  struct _mecab_node_t  *next;
  struct _mecab_node_t  *lnext;
  struct _mecab_node_t  *rnext;
  struct _mecab_path_t  *path;
  char  *surface;
  char  *feature;
  unsigned int  length;
  unsigned int  end;
  unsigned int  cost;
  unsigned int  id;
}; 

/* C interface  */
#ifdef __cplusplus
#include <cstdio>
#else
#include <stdio.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

#ifdef _WIN32
#  ifdef DLL_EXPORT
#    define MECAB_DLL_EXTERN    __declspec(dllexport)
#  else
#    ifdef  MECAB_DLL_IMPORT
#      define MECAB_DLL_EXTERN  __declspec(dllimport)
#    endif
#  endif
#endif

#ifndef MECAB_DLL_EXTERN
#  define MECAB_DLL_EXTERN extern
#endif 

  typedef struct {
    int allocated;
    void *ptr;
  } mecab_t;
   
  typedef struct _mecab_node_t  mecab_node_t;
  typedef struct _mecab_path_t  mecab_path_t;
  typedef struct _mecab_token_t mecab_token_t;

  /* C interface */
  MECAB_DLL_EXTERN int           mecab_do                 (int, char**);
  MECAB_DLL_EXTERN int           mecab_make_dictionary    (char*, char*);
  MECAB_DLL_EXTERN mecab_t*      mecab_new                (int, char**);
  MECAB_DLL_EXTERN mecab_t*      mecab_new2               (char*);
  MECAB_DLL_EXTERN char*         mecab_strerror           (mecab_t*);
  MECAB_DLL_EXTERN void          mecab_destroy            (mecab_t*);
  MECAB_DLL_EXTERN int           mecab_lock               (mecab_t*);
  MECAB_DLL_EXTERN int           mecab_unlock             (mecab_t*);
  MECAB_DLL_EXTERN char*         mecab_sparse_tostr       (mecab_t*, char*);
  MECAB_DLL_EXTERN char*         mecab_sparse_tostr2      (mecab_t*, char*, unsigned int);
  MECAB_DLL_EXTERN char*         mecab_sparse_tostr3      (mecab_t*, char*, unsigned int, char*, unsigned int);
  MECAB_DLL_EXTERN mecab_node_t* mecab_sparse_tonode      (mecab_t*, char*);
  MECAB_DLL_EXTERN mecab_node_t* mecab_sparse_tonode2     (mecab_t*, char*, unsigned int);
  
#ifdef __cplusplus
}
#endif

/* C++ interface */
#ifdef __cplusplus
#include <iostream>
#include <string>
#include <strstream>

namespace MeCab
{
  class Tokenizer;
  class Viterbi;
  class Param;
  class Mutex;

  typedef struct _mecab_token_t Token;
  typedef struct _mecab_path_t  Path;
  typedef struct _mecab_node_t  Node;

  class Tagger 
  {
  private:
    char*        ibuf;
    unsigned int ibufsize;
    Tokenizer*   tokenizer;
    Viterbi*     viterbi;
    Mutex*       mutex;
    char*        node_format;
    char*        bos_format;
    char*        eos_format;
    std::ostrstream* ostrs;
    std::string  _what;

    std::istream& read              (std::istream&);
    std::istream& (Tagger::*_read)  (std::istream&);    
    std::istream& readLine          (std::istream&);
    std::istream& readLattice       (std::istream&);

    std::ostream& write             (std::ostream&, Node*);
    std::ostream& (Tagger::*_write) (std::ostream&, Node*);
    std::ostream& writeLattice      (std::ostream&, Node*);
    std::ostream& writeWakati       (std::ostream&, Node*);
    std::ostream& writeNone         (std::ostream&, Node*);
    std::ostream& writeUser         (std::ostream&, Node*);

    bool       open         (Param &); // this is private

  public:
    bool        open        (int, char**);
    bool        open        (const char*);
    bool        close       ();
    int         parse       (int, char**); 
    bool        parse       (std::istream&, std::ostream&);
    const char* parse       (std::istream&);
    const char* parse       (const char*, unsigned int = 0);
    const char* parse       (const char*, unsigned int, char*, unsigned int);
    Node*       parseToNode (const char*, unsigned int = 0);
    const char* what        ();
    bool        lock        ();
    bool        unlock      (); 

    Tagger ();
    Tagger  (int, char**);
    Tagger  (const char*);
    ~Tagger();     
  };
}

#endif
#endif
