// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/speech/tts_android.h"

#include <string>

#include "base/android/jni_string.h"
#include "base/memory/singleton.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/speech/tts_controller.h"
#include "chrome/common/features.h"
#include "jni/TtsPlatformImpl_jni.h"

using base::android::AttachCurrentThread;
using base::android::JavaParamRef;

// static
TtsPlatformImpl* TtsPlatformImpl::GetInstance() {
  return TtsPlatformImplAndroid::GetInstance();
}

TtsPlatformImplAndroid::TtsPlatformImplAndroid()
    : utterance_id_(0) {
  JNIEnv* env = AttachCurrentThread();
  java_ref_.Reset(
      Java_TtsPlatformImpl_create(env, reinterpret_cast<intptr_t>(this)));
}

TtsPlatformImplAndroid::~TtsPlatformImplAndroid() {
  JNIEnv* env = AttachCurrentThread();
  Java_TtsPlatformImpl_destroy(env, java_ref_);
}

bool TtsPlatformImplAndroid::PlatformImplAvailable() {
  return true;
}

bool TtsPlatformImplAndroid::Speak(
    int utterance_id,
    const std::string& utterance,
    const std::string& lang,
    const VoiceData& voice,
    const UtteranceContinuousParameters& params) {
  JNIEnv* env = AttachCurrentThread();
  jboolean success = Java_TtsPlatformImpl_speak(
      env, java_ref_, utterance_id,
      base::android::ConvertUTF8ToJavaString(env, utterance),
      base::android::ConvertUTF8ToJavaString(env, lang), params.rate,
      params.pitch, params.volume);
  if (!success)
    return false;

  utterance_ = utterance;
  utterance_id_ = utterance_id;
  return true;
}

bool TtsPlatformImplAndroid::StopSpeaking() {
  JNIEnv* env = AttachCurrentThread();
  Java_TtsPlatformImpl_stop(env, java_ref_);
  utterance_id_ = 0;
  utterance_.clear();
  return true;
}

void TtsPlatformImplAndroid::Pause() {
  StopSpeaking();
}

void TtsPlatformImplAndroid::Resume() {
}

bool TtsPlatformImplAndroid::IsSpeaking() {
  return (utterance_id_ != 0);
}

void TtsPlatformImplAndroid::GetVoices(
    std::vector<VoiceData>* out_voices) {
  JNIEnv* env = AttachCurrentThread();
  if (!Java_TtsPlatformImpl_isInitialized(env, java_ref_))
    return;

  int count = Java_TtsPlatformImpl_getVoiceCount(env, java_ref_);
  for (int i = 0; i < count; ++i) {
    out_voices->push_back(VoiceData());
    VoiceData& data = out_voices->back();
    data.native = true;
    data.name = base::android::ConvertJavaStringToUTF8(
        Java_TtsPlatformImpl_getVoiceName(env, java_ref_, i));
    data.lang = base::android::ConvertJavaStringToUTF8(
        Java_TtsPlatformImpl_getVoiceLanguage(env, java_ref_, i));
    data.gender = TTS_GENDER_NONE;
    data.events.insert(TTS_EVENT_START);
    data.events.insert(TTS_EVENT_END);
    data.events.insert(TTS_EVENT_ERROR);
  }
}

void TtsPlatformImplAndroid::VoicesChanged(JNIEnv* env,
                                           const JavaParamRef<jobject>& obj) {
  TtsController::GetInstance()->VoicesChanged();
}

void TtsPlatformImplAndroid::OnEndEvent(JNIEnv* env,
                                        const JavaParamRef<jobject>& obj,
                                        jint utterance_id) {
  SendFinalTtsEvent(utterance_id, TTS_EVENT_END,
                    static_cast<int>(utterance_.size()));
}

void TtsPlatformImplAndroid::OnErrorEvent(JNIEnv* env,
                                          const JavaParamRef<jobject>& obj,
                                          jint utterance_id) {
  SendFinalTtsEvent(utterance_id, TTS_EVENT_ERROR, 0);
}

void TtsPlatformImplAndroid::OnStartEvent(JNIEnv* env,
                                          const JavaParamRef<jobject>& obj,
                                          jint utterance_id) {
  if (utterance_id != utterance_id_)
    return;

  TtsController::GetInstance()->OnTtsEvent(
      utterance_id_, TTS_EVENT_START, 0, std::string());
}

void TtsPlatformImplAndroid::SendFinalTtsEvent(
    int utterance_id, TtsEventType event_type, int char_index) {
  if (utterance_id != utterance_id_)
    return;

  TtsController::GetInstance()->OnTtsEvent(
      utterance_id_, event_type, char_index, std::string());
  utterance_id_ = 0;
  utterance_.clear();
}

// static
TtsPlatformImplAndroid* TtsPlatformImplAndroid::GetInstance() {
  return base::Singleton<
      TtsPlatformImplAndroid,
      base::LeakySingletonTraits<TtsPlatformImplAndroid>>::get();
}

// static
bool TtsPlatformImplAndroid::Register(JNIEnv* env) {
  return RegisterNativesImpl(env);
}
