/*
 * OpenMRCP - Open Source Media Resource Control Protocol Stack
 * Copyright (C) 2007, Cepstral LLC
 *
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Author(s):
 * Arsen Chaloyan <achaloyan@yahoo.com>
 *
 * Contributor(s):
 *
 */

#ifndef __MRCP_SYNTHESIZER_H__
#define __MRCP_SYNTHESIZER_H__

/**
 * @file mrcp_synthesizer.h
 * @brief MRCP Synthesizer Resource Definition
 */ 

#include "mrcp_resource.h"

MRCP_BEGIN_EXTERN_C

/** MRCP synthesizer methods */
typedef enum {
	SYNTHESIZER_SET_PARAMS,
	SYNTHESIZER_GET_PARAMS,
	SYNTHESIZER_SPEAK,
	SYNTHESIZER_STOP,
	SYNTHESIZER_PAUSE,
	SYNTHESIZER_RESUME,
	SYNTHESIZER_BARGE_IN_OCCURRED,
	SYNTHESIZER_CONTROL,
	SYNTHESIZER_DEFINE_LEXICON,

	SYNTHESIZER_METHOD_COUNT
} mrcp_synthesizer_method_id;

/** MRCP synthesizer events */
typedef enum {
	SYNTHESIZER_SPEECH_MARKER,
	SYNTHESIZER_SPEAK_COMPLETE,

	SYNTHESIZER_EVENT_COUNT
} mrcp_synthesizer_event_id;

/** MRCP synthesizer headers */
typedef enum {
	SYNTHESIZER_HEADER_JUMP_SIZE,
	SYNTHESIZER_HEADER_KILL_ON_BARGE_IN,
	SYNTHESIZER_HEADER_SPEAKER_PROFILE,
	SYNTHESIZER_HEADER_COMPLETION_CAUSE,
	SYNTHESIZER_HEADER_COMPLETION_REASON,
	SYNTHESIZER_HEADER_VOICE_GENDER,
	SYNTHESIZER_HEADER_VOICE_AGE,
	SYNTHESIZER_HEADER_VOICE_VARIANT,
	SYNTHESIZER_HEADER_VOICE_NAME,
	SYNTHESIZER_HEADER_PROSODY_VOLUME,
	SYNTHESIZER_HEADER_PROSODY_RATE,
	SYNTHESIZER_HEADER_SPEECH_MARKER,
	SYNTHESIZER_HEADER_SPEECH_LANGUAGE,
	SYNTHESIZER_HEADER_FETCH_HINT,
	SYNTHESIZER_HEADER_FETCH_TIMEOUT,
	SYNTHESIZER_HEADER_AUDIO_FETCH_HINT,
	SYNTHESIZER_HEADER_FAILED_URI,
	SYNTHESIZER_HEADER_FAILED_URI_CAUSE,
	SYNTHESIZER_HEADER_SPEAK_RESTART,
	SYNTHESIZER_HEADER_SPEAK_LENGTH,
	SYNTHESIZER_HEADER_LOAD_LEXICON,
	SYNTHESIZER_HEADER_LEXICON_SEARCH_ORDER,

	SYNTHESIZER_HEADER_COUNT
} mrcp_synthesizer_header_id;


/** Speech-units */
typedef enum {
	SPEECH_UNIT_SECOND,
	SPEECH_UNIT_WORD,
	SPEECH_UNIT_SENTENCE,
	SPEECH_UNIT_PARAGRAPH,

	SPEECH_UNIT_COUNT
} mrcp_speech_unit_t;

/** Speech-length types */
typedef enum {
	SPEECH_LENGTH_TYPE_TEXT,
	SPEECH_LENGTH_TYPE_NUMERIC_POSITIVE,
	SPEECH_LENGTH_TYPE_NUMERIC_NEGATIVE,

	SPEECH_LENGTH_TYPE_UNKNOWN
} mrcp_speech_length_type;

typedef struct mrcp_numeric_speech_length_t mrcp_numeric_speech_length_t;
/** Numeric speech-length */
struct mrcp_numeric_speech_length_t {
	size_t             length;
	mrcp_speech_unit_t unit;
};

#define MAX_TEXT_SPEECH_TAG_LENGTH 10

typedef struct mrcp_speech_length_value_t mrcp_speech_length_value_t;
/** Definition of speech-length value */
struct mrcp_speech_length_value_t {
	mrcp_speech_length_type type;
	union {
		char                         tag[MAX_TEXT_SPEECH_TAG_LENGTH];
		mrcp_numeric_speech_length_t numeric;
	} value;
};


/** MRCP voice-gender */
typedef enum {
	VOICE_GENDER_MALE,
	VOICE_GENDER_FEMALE,
	VOICE_GENDER_NEUTRAL,
	
	VOICE_GENDER_COUNT,
	VOICE_GENDER_UNKNOWN = VOICE_GENDER_COUNT
} mrcp_voice_gender_t;

typedef struct mrcp_voice_param_t mrcp_voice_param_t;
/** MRCP voice-param */
struct mrcp_voice_param_t {
	mrcp_voice_gender_t gender;
	size_t              age;
	size_t              variant;
	char               *name;
};


/** Prosody-volume */
typedef enum {
	PROSODY_VOLUME_SILENT,
	PROSODY_VOLUME_XSOFT,
	PROSODY_VOLUME_SOFT,
	PROSODY_VOLUME_MEDIUM,
	PROSODY_VOLUME_LOUD,
	PROSODY_VOLUME_XLOUD,
	PROSODY_VOLUME_DEFAULT,

	PROSODY_VOLUME_COUNT,
	PROSODY_VOLUME_UNKNOWN = PROSODY_VOLUME_COUNT
} mrcp_prosody_volume_t;

/** Prosody-rate */
typedef enum {
	PROSODY_RATE_XSLOW,
	PROSODY_RATE_SLOW,
	PROSODY_RATE_MEDIUM,
	PROSODY_RATE_FAST,
	PROSODY_RATE_XFAST,
	PROSODY_RATE_DEFAULT,

	PROSODY_RATE_COUNT,
	PROSODY_RATE_UNKNOWN = PROSODY_RATE_COUNT
} mrcp_prosody_rate_t;

typedef struct mrcp_prosody_param_t mrcp_prosody_param_t;
/** MRCP prosody-param */
struct mrcp_prosody_param_t {
	mrcp_prosody_volume_t volume;
	mrcp_prosody_rate_t   rate;
};


/** Synthesizer completion-cause specified in SPEAK-COMPLETE event */
typedef enum {
	SYNTHESIZER_COMPLETION_CAUSE_NORMAL               = 0,
	SYNTHESIZER_COMPLETION_CAUSE_BARGE_IN             = 1,
	SYNTHESIZER_COMPLETION_CAUSE_PARSE_FAILURE        = 2,
	SYNTHESIZER_COMPLETION_CAUSE_URI_FAILURE          = 3,
	SYNTHESIZER_COMPLETION_CAUSE_ERROR                = 4,
	SYNTHESIZER_COMPLETION_CAUSE_LANGUAGE_UNSUPPORTED = 5,
	SYNTHESIZER_COMPLETION_CAUSE_LEXICON_LOAD_FAILURE = 7,
	SYNTHESIZER_COMPLETION_CAUSE_CANCELLED            = 8,

	SYNTHESIZER_COMPLETION_CAUSE_COUNT                = 9,
	SYNTHESIZER_COMPLETION_CAUSE_UNKNOWN              = SYNTHESIZER_COMPLETION_CAUSE_COUNT
} mrcp_synthesizer_completion_cause_t;


typedef struct mrcp_synthesizer_header_t mrcp_synthesizer_header_t;

/** MRCP synthesizer-header */
struct mrcp_synthesizer_header_t {
	mrcp_speech_length_value_t          jump_size;
	apt_bool_t                          kill_on_barge_in;
	char                               *speaker_profile;
	mrcp_synthesizer_completion_cause_t completion_cause;
	char                               *completion_reason;
	mrcp_voice_param_t                  voice_param;
	mrcp_prosody_param_t                prosody_param;
	char                               *speech_marker;
	char                               *speech_language;
	char                               *fetch_hint;
	char                               *audio_fetch_hint;
	size_t                              fetch_timeout;
	char                               *failed_uri;
	char                               *failed_uri_cause;
	apt_bool_t                          speak_restart;
	mrcp_speech_length_value_t          speak_length;
	apt_bool_t                          load_lexicon;
	char                               *lexicon_search_order;
};

/** Initialize synthesizer header */
void mrcp_synthesizer_header_init(mrcp_synthesizer_header_t *synthesizer_header);

/** Destroy synthesizer header */
void mrcp_synthesizer_header_destroy(mrcp_synthesizer_header_t *synthesizer_header);

/** Initialize MRCP synthesizer resource */
mrcp_status_t mrcp_synthesizer_init(mrcp_resource_t *resource, mrcp_version_t version);

MRCP_END_EXTERN_C

#endif /*__MRCP_SYNTHESIZER_H__*/
