/* 
 * File:   JuliusServer.h
 * Author: hara
 *
 * Created on 2013/08/21, 10:12
 */

#ifndef JUNIUS_JULIUS_H
#define	JUNIUS_JULIUS_H

#include <string>
#include <map>

#include <boost/thread.hpp>
#include <boost/bind.hpp>

#include <julius/juliuslib.h>

#include "IJuliusOutput.h"

namespace Junius {

enum _japicode {
    JAPI_VERSION = 1,
    JAPI_STATUS,
    JAPI_DIE,
    JAPI_PAUSE,
    JAPI_TERMINATE,
    JAPI_RESUME,
    JAPI_DEBUG
};

typedef class CJulius {
public:
    static std::map<std::string, int> japi_table;
private:
    Recog *m_recog;
    boost::thread_group thread_manager;
    IJuliusOutput* m_outputInst;
public:
    CJulius();
    CJulius(const CJulius& orig);
    virtual ~CJulius();
    
    volatile bool bRequestStopThread;
    
    void setJuliusOutput(IJuliusOutput* outputInst){m_outputInst = outputInst;};
    
    bool init(int argc, char* argv[]);
    bool init(const char* jconf_filepath);
    
    // Input as "push"
    bool initPushInput();
    uint32_t beginPushInput();
    void addPushInput(SP16* data, int len);
    uint32_t endPushInput();

    // Input as "pull"
    bool startService();
    void stopService();
    
    void runForRealtimeStream(Recog *recog);
    void runForBatchStream(Recog *recog);

    static std::string CallbackReceiveMessage(char* msg, char* param, CJulius *self);

    std::string getVersion(void);
    std::string getEngineStatus(void);

    void requestEnginePause(void) {j_request_pause(m_recog);};
    void requestEngineResume(void) {j_request_resume(m_recog);};
    void requestEngineTerminate(void) {j_request_terminate(m_recog);};

    void debug(void);
    
    static void JAPISpeechReady(Recog *recog, void *data);
    static void JAPISpeechStart(Recog *recog, void *data);
    static void JAPISpeechEnd(Recog *recog, void *data);

    static void JAPIResult(Recog *recog, void *data);

    void cbApiSpeechReady(void);
    void cbApiSpeechStart(void);
    void cbApiSpeechEnd(void);

    void cbApiResult(Recog *recog);

private:
    bool _init(Jconf *jconf);

} CJulius;

} // namespace
#endif	/* JUNIUS_JULIUS_H */

