// 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.

#ifndef COBALT_SPEECH_SPEECH_SYNTHESIS_UTTERANCE_H_
#define COBALT_SPEECH_SPEECH_SYNTHESIS_UTTERANCE_H_

#include <string>

#include "cobalt/script/environment_settings.h"
#include "cobalt/script/wrappable.h"
#include "cobalt/speech/speech_synthesis_error_event.h"
#include "cobalt/speech/speech_synthesis_voice.h"
#include "cobalt/web/event_target.h"

namespace cobalt {
namespace speech {

// The speech synthesis voice interface is the scripted web API for defining a
// speech synthesis voice.
//   https://dvcs.w3.org/hg/speech-api/raw-file/4f41ea1126bb/webspeechapi.html#speechsynthesisvoice
class SpeechSynthesisUtterance : public web::EventTarget {
 public:
  explicit SpeechSynthesisUtterance(script::EnvironmentSettings* settings);
  SpeechSynthesisUtterance(
      const scoped_refptr<SpeechSynthesisUtterance>& utterance);
  SpeechSynthesisUtterance(script::EnvironmentSettings* settings,
                           const std::string& text);

  // Web API: SpeechSynthesisUtterance
  //

  // Read+Write Attributes.
  std::string text() const { return text_; }
  void set_text(const std::string& text) { text_ = text; }

  std::string lang() const { return lang_; }
  void set_lang(const std::string& lang) { lang_ = lang; }

  scoped_refptr<SpeechSynthesisVoice> voice() const { return voice_; }
  void set_voice(const scoped_refptr<SpeechSynthesisVoice>& voice) {
    voice_ = voice;
  }

  float volume() const { return volume_; }
  void set_volume(const float volume) { volume_ = volume; }

  float rate() const { return rate_; }
  void set_rate(const float rate) { rate_ = rate; }

  float pitch() const { return pitch_; }
  void set_pitch(const float pitch) { pitch_ = pitch; }

  // EventHandlers.
  const EventListenerScriptValue* onstart() const {
    return GetAttributeEventListener(base::Tokens::start());
  }

  void set_onstart(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::start(), event_listener);
  }

  const EventListenerScriptValue* onend() const {
    return GetAttributeEventListener(base::Tokens::end());
  }

  void set_onend(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::end(), event_listener);
  }

  const EventListenerScriptValue* onerror() const {
    return GetAttributeEventListener(base::Tokens::error());
  }

  void set_onerror(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::error(), event_listener);
  }

  const EventListenerScriptValue* onpause() const {
    return GetAttributeEventListener(base::Tokens::pause());
  }

  void set_onpause(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::pause(), event_listener);
  }

  const EventListenerScriptValue* onresume() const {
    return GetAttributeEventListener(base::Tokens::resume());
  }

  void set_onresume(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::resume(), event_listener);
  }

  const EventListenerScriptValue* onmark() const {
    return GetAttributeEventListener(base::Tokens::mark());
  }

  void set_onmark(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::mark(), event_listener);
  }

  const EventListenerScriptValue* onboundary() const {
    return GetAttributeEventListener(base::Tokens::boundary());
  }

  void set_onboundary(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::boundary(), event_listener);
  }

  // Custom, not in any spec.
  //
  void SignalPendingSpeak();
  void DispatchErrorCancelledEvent();

  void DispatchStartEvent();
  void DispatchEndEvent();
  void DispatchErrorEvent(SpeechSynthesisErrorCode error_code);

  DEFINE_WRAPPABLE_TYPE(SpeechSynthesisUtterance);
  void TraceMembers(script::Tracer* tracer) override;

 private:
  ~SpeechSynthesisUtterance() override;

  script::EnvironmentSettings* settings_;

  std::string text_;
  std::string lang_;
  scoped_refptr<SpeechSynthesisVoice> voice_;

  float volume_;
  float rate_;
  float pitch_;

  bool pending_speak_;

  DISALLOW_COPY_AND_ASSIGN(SpeechSynthesisUtterance);
};

}  // namespace speech
}  // namespace cobalt

#endif  // COBALT_SPEECH_SPEECH_SYNTHESIS_UTTERANCE_H_
