// 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_message_filter.h"

#include "base/bind.h"
#include "base/logging.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/speech/tts_controller.h"
#include "chrome/browser/speech/tts_message_filter.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/render_process_host.h"

using content::BrowserThread;

TtsMessageFilter::TtsMessageFilter(int render_process_id, Profile* profile)
    : render_process_id_(render_process_id),
      profile_(profile) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  TtsController::GetInstance()->AddVoicesChangedDelegate(this);
}

void TtsMessageFilter::OverrideThreadForMessage(
    const IPC::Message& message, BrowserThread::ID* thread) {
  switch (message.type()) {
  case TtsHostMsg_InitializeVoiceList::ID:
  case TtsHostMsg_Speak::ID:
  case TtsHostMsg_Pause::ID:
  case TtsHostMsg_Resume::ID:
  case TtsHostMsg_Cancel::ID:
    *thread = BrowserThread::UI;
    break;
  }
}

bool TtsMessageFilter::OnMessageReceived(const IPC::Message& message,
                                         bool* message_was_ok) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_EX(TtsMessageFilter, message, *message_was_ok)
    IPC_MESSAGE_HANDLER(TtsHostMsg_InitializeVoiceList, OnInitializeVoiceList)
    IPC_MESSAGE_HANDLER(TtsHostMsg_Speak, OnSpeak)
    IPC_MESSAGE_HANDLER(TtsHostMsg_Pause, OnPause)
    IPC_MESSAGE_HANDLER(TtsHostMsg_Resume, OnResume)
    IPC_MESSAGE_HANDLER(TtsHostMsg_Cancel, OnCancel)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void TtsMessageFilter::OnChannelClosing() {
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&TtsMessageFilter::OnChannelClosingInUIThread, this));
}

void TtsMessageFilter::OnInitializeVoiceList() {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  TtsController* tts_controller = TtsController::GetInstance();
  std::vector<VoiceData> voices;
  tts_controller->GetVoices(profile_, &voices);

  std::vector<TtsVoice> out_voices;
  out_voices.resize(voices.size());
  for (size_t i = 0; i < voices.size(); ++i) {
    TtsVoice& out_voice = out_voices[i];
    out_voice.voice_uri = voices[i].name;
    out_voice.name = voices[i].name;
    out_voice.lang = voices[i].lang;
    out_voice.local_service = true;
    out_voice.is_default = (i == 0);
  }
  Send(new TtsMsg_SetVoiceList(out_voices));
}

void TtsMessageFilter::OnSpeak(const TtsUtteranceRequest& request) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  scoped_ptr<Utterance> utterance(new Utterance(profile_));
  utterance->set_src_id(request.id);
  utterance->set_text(request.text);
  utterance->set_lang(request.lang);
  utterance->set_voice_name(request.voice);
  utterance->set_can_enqueue(true);

  UtteranceContinuousParameters params;
  params.rate = request.rate;
  params.pitch = request.pitch;
  params.volume = request.volume;
  utterance->set_continuous_parameters(params);

  utterance->set_event_delegate(this);

  TtsController::GetInstance()->SpeakOrEnqueue(utterance.release());
}

void TtsMessageFilter::OnPause() {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  TtsController::GetInstance()->Pause();
}

void TtsMessageFilter::OnResume() {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  TtsController::GetInstance()->Resume();
}

void TtsMessageFilter::OnCancel() {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  TtsController::GetInstance()->Stop();
}

void TtsMessageFilter::OnTtsEvent(Utterance* utterance,
                                  TtsEventType event_type,
                                  int char_index,
                                  const std::string& error_message) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  switch (event_type) {
    case TTS_EVENT_START:
      Send(new TtsMsg_DidStartSpeaking(utterance->src_id()));
      break;
    case TTS_EVENT_END:
      Send(new TtsMsg_DidFinishSpeaking(utterance->src_id()));
      break;
    case TTS_EVENT_WORD:
      Send(new TtsMsg_WordBoundary(utterance->src_id(), char_index));
      break;
    case TTS_EVENT_SENTENCE:
      Send(new TtsMsg_SentenceBoundary(utterance->src_id(), char_index));
      break;
    case TTS_EVENT_MARKER:
      Send(new TtsMsg_MarkerEvent(utterance->src_id(), char_index));
      break;
    case TTS_EVENT_INTERRUPTED:
      Send(new TtsMsg_WasInterrupted(utterance->src_id()));
      break;
    case TTS_EVENT_CANCELLED:
      Send(new TtsMsg_WasCancelled(utterance->src_id()));
      break;
    case TTS_EVENT_ERROR:
      Send(new TtsMsg_SpeakingErrorOccurred(
          utterance->src_id(), error_message));
      break;
    case TTS_EVENT_PAUSE:
      Send(new TtsMsg_DidPauseSpeaking(utterance->src_id()));
      break;
    case TTS_EVENT_RESUME:
      Send(new TtsMsg_DidResumeSpeaking(utterance->src_id()));
      break;
  }
}

void TtsMessageFilter::OnVoicesChanged() {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  OnInitializeVoiceList();
}

void TtsMessageFilter::OnChannelClosingInUIThread() {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
}

TtsMessageFilter::~TtsMessageFilter() {
}
