/*
 * Copyright 2016 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 "cobalt/browser/starboard/event_handler.h"

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "cobalt/base/deep_link_event.h"
#include "cobalt/network/network_event.h"
#include "cobalt/system_window/application_event.h"
#include "cobalt/system_window/starboard/system_window.h"

namespace cobalt {
namespace browser {

namespace {
EventHandler* g_the_event_handler = NULL;
}  // namespace

EventHandler::EventHandler(base::EventDispatcher* event_dispatcher)
    : event_dispatcher_(event_dispatcher) {
  DCHECK(!g_the_event_handler) << "There should be only one event handler.";
  g_the_event_handler = this;
}

// static
void EventHandler::HandleEvent(const SbEvent* starboard_event) {
  DCHECK(starboard_event);

  // Forward input events to |SystemWindow|.
  if (starboard_event->type == kSbEventTypeInput) {
    system_window::HandleInputEvent(starboard_event);
    return;
  }

  // Handle all other events internally.
  DCHECK(g_the_event_handler);
  g_the_event_handler->DispatchEvent(starboard_event);
}

void EventHandler::DispatchEvent(const SbEvent* starboard_event) const {
  // Create a Cobalt event from the Starboard event, if recognized.
  scoped_ptr<base::Event> cobalt_event;
  if (starboard_event->type == kSbEventTypePause) {
    cobalt_event.reset(new system_window::ApplicationEvent(
        system_window::ApplicationEvent::kPause));
  } else if (starboard_event->type == kSbEventTypeUnpause) {
    cobalt_event.reset(new system_window::ApplicationEvent(
        system_window::ApplicationEvent::kUnpause));
  } else if (starboard_event->type == kSbEventTypeSuspend) {
    cobalt_event.reset(new system_window::ApplicationEvent(
        system_window::ApplicationEvent::kSuspend));
  } else if (starboard_event->type == kSbEventTypeResume) {
    cobalt_event.reset(new system_window::ApplicationEvent(
        system_window::ApplicationEvent::kResume));
  } else if (starboard_event->type == kSbEventTypeNetworkConnect) {
    cobalt_event.reset(
        new network::NetworkEvent(network::NetworkEvent::kConnection));
  } else if (starboard_event->type == kSbEventTypeNetworkDisconnect) {
    cobalt_event.reset(
        new network::NetworkEvent(network::NetworkEvent::kDisconnection));
  } else if (starboard_event->type == kSbEventTypeLink) {
    const char* link = static_cast<const char*>(starboard_event->data);
    cobalt_event.reset(new base::DeepLinkEvent(link));
  }

  // Dispatch the Cobalt event, if created.
  if (cobalt_event) {
    event_dispatcher_->DispatchEvent(cobalt_event.Pass());
  } else {
    DLOG(WARNING) << "Unhandled Starboard event of type: "
                  << starboard_event->type;
  }
}

}  // namespace browser
}  // namespace cobalt
