// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/speech/speech_synthesis.h"

#include <string>

#include "cobalt/dom/navigator.h"
#include "starboard/speech_synthesis.h"

namespace cobalt {
namespace speech {

SpeechSynthesis::SpeechSynthesis(const scoped_refptr<dom::Navigator>& navigator,
                                 bool log_output)
    : log_output_(log_output), paused_(false), navigator_(navigator) {
#if SB_HAS(SPEECH_SYNTHESIS)
  const char* kVoiceName = "Cobalt";
  std::string voice_urn(kVoiceName);
  std::string voice_lang(navigator_->language());
  voice_urn.append(" ");
  voice_urn.append(voice_lang);
  voices_.push_back(
      new SpeechSynthesisVoice(voice_urn, kVoiceName, voice_lang, false, true));
#endif
}

SpeechSynthesis::~SpeechSynthesis() {}

void SpeechSynthesis::set_onvoiceschanged(
    const EventListenerScriptValue& event_listener) {
  base::Token event_name = base::Tokens::voiceschanged();
  SetAttributeEventListener(event_name, event_listener);
  DispatchEvent(new dom::Event(event_name));
}

void SpeechSynthesis::Cancel() {
  for (UtterancesList::iterator utterance_iterator = utterances_.begin();
       utterance_iterator != utterances_.end(); ++utterance_iterator) {
    (*utterance_iterator)->DispatchErrorCancelledEvent();
  }
  utterances_.clear();
#if SB_HAS(SPEECH_SYNTHESIS)
  SbSpeechSynthesisCancel();
#endif
}

void SpeechSynthesis::Resume() {
  if (paused_) {
    paused_ = false;
    for (UtterancesList::iterator utterance_iterator = utterances_.begin();
         utterance_iterator != utterances_.end(); ++utterance_iterator) {
      Speak(*utterance_iterator);
      if (utterances_.empty()) break;
    }
  }
}

void SpeechSynthesis::TraceMembers(script::Tracer* tracer) {
  dom::EventTarget::TraceMembers(tracer);

  tracer->TraceItems(utterances_);
  tracer->TraceItems(voices_);
  tracer->Trace(navigator_);
}

void SpeechSynthesis::DispatchErrorEvent(
    const scoped_refptr<SpeechSynthesisUtterance>& utterance,
    SpeechSynthesisErrorCode error_code) {
  utterance->DispatchErrorEvent(error_code);
  Cancel();
}

void SpeechSynthesis::Speak(
    const scoped_refptr<SpeechSynthesisUtterance>& utterance) {
  if (log_output_) {
    LOG(INFO) << "JavaScript Text-to-speech: " << utterance->text();
  }
  if (paused_) {
    // When the synthesis is paused, the utterance needs to be added to a queue
    // and preserved until synthesis is canceled or resumed.
    // A copy of the utterance needs to be made, so that the current state of
    // the object is preserved.
    SpeechSynthesisUtterance* copied_utterance =
        new SpeechSynthesisUtterance(utterance);
    copied_utterance->SignalPendingSpeak();
    utterances_.push_back(copied_utterance);
    return;
  }
  utterance->SignalPendingSpeak();
#if SB_HAS(SPEECH_SYNTHESIS)
  if (!utterance->lang().empty() &&
      utterance->lang() != navigator_->language()) {
    DispatchErrorEvent(utterance, kSpeechSynthesisErrorCodeLanguageUnavailable);
    return;
  }
  if ((utterance->volume() != 1.0f) || (utterance->rate() != 1.0f) ||
      (utterance->pitch() != 1.0f)) {
    DispatchErrorEvent(utterance, kSpeechSynthesisErrorCodeInvalidArgument);
    return;
  }

  SB_DLOG(INFO) << "Speaking: \"" << utterance->text() << "\" "
                << utterance->lang();
  SbSpeechSynthesisSpeak(utterance->text().c_str());
  utterance->DispatchStartEvent();
  utterance->DispatchEndEvent();
#else
  DispatchErrorEvent(utterance, kSpeechSynthesisErrorCodeSynthesisUnavailable);
#endif
}

}  // namespace speech
}  // namespace cobalt
