// Copyright 2015 Google Inc. 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 "starboard/shared/starboard/application.h"

#include "starboard/atomic.h"
#include "starboard/condition_variable.h"
#include "starboard/event.h"
#include "starboard/log.h"

namespace starboard {
namespace shared {
namespace starboard {

namespace {

// Dispatches an event of |type| with |data| to the system event handler,
// calling |destructor| on |data| when finished dispatching. Does all
// appropriate NULL checks so you don't have to.
void Dispatch(SbEventType type, void* data, SbEventDataDestructor destructor) {
  SbEvent event;
  event.type = type;
  event.data = data;
  SbEventHandle(&event);
  if (destructor && event.data) {
    destructor(event.data);
  }
}

// Dispatches a Start event to the system event handler.
void DispatchStart(int argc, char** argv) {
  SbEventStartData start_data;
  start_data.argument_values = argv;
  start_data.argument_count = argc;
  start_data.link = NULL;
  Dispatch(kSbEventTypeStart, &start_data, NULL);
}

// The next event ID to use for Schedule().
volatile SbAtomic32 g_next_event_id = 0;

}  // namespace

Application* Application::g_instance = NULL;

Application::Application() : error_level_(0), thread_(SbThreadGetCurrent()) {
  Application* old_instance =
      reinterpret_cast<Application*>(SbAtomicAcquire_CompareAndSwapPtr(
          reinterpret_cast<SbAtomicPtr*>(&g_instance),
          reinterpret_cast<SbAtomicPtr>(NULL),
          reinterpret_cast<SbAtomicPtr>(this)));
  SB_DCHECK(!old_instance);
}

Application::~Application() {
  Application* old_instance =
      reinterpret_cast<Application*>(SbAtomicAcquire_CompareAndSwapPtr(
          reinterpret_cast<SbAtomicPtr*>(&g_instance),
          reinterpret_cast<SbAtomicPtr>(this),
          reinterpret_cast<SbAtomicPtr>(NULL)));
  SB_DCHECK(old_instance);
  SB_DCHECK(old_instance == this);
}

int Application::Run(int argc, char** argv) {
  Initialize();
  DispatchStart(argc, argv);

  for (;;) {
    if (!DispatchAndDelete(GetNextEvent())) {
      break;
    }
  }

  Teardown();
  return error_level_;
}

void Application::Stop(int error_level) {
  Event* event = new Event(kSbEventTypeStop, NULL, NULL);
  event->error_level = error_level;
  Inject(event);
}

SbEventId Application::Schedule(SbEventCallback callback,
                                void* context,
                                SbTimeMonotonic delay) {
  SbEventId id = SbAtomicNoBarrier_Increment(&g_next_event_id, 1);
  InjectTimedEvent(new TimedEvent(id, callback, context, delay));
  return id;
}

void Application::Cancel(SbEventId id) {
  CancelTimedEvent(id);
}

void Application::HandleFrame(const player::VideoFrame& frame) {
  AcceptFrame(frame);
}

bool Application::DispatchAndDelete(Application::Event* event) {
  if (!event) {
    return true;
  }

  bool should_continue = true;
  if (event->event->type == kSbEventTypeStop) {
    should_continue = false;
    error_level_ = event->error_level;
  }

  if (event->event->type == kSbEventTypeScheduled) {
    TimedEvent* timed_event = reinterpret_cast<TimedEvent*>(event->event->data);
    timed_event->callback(timed_event->context);
  } else {
    SbEventHandle(event->event);
  }
  delete event;
  return should_continue;
}

}  // namespace starboard
}  // namespace shared
}  // namespace starboard
