// 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)
    : 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 (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
