/*
 *  Copyright 2010 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include "webrtc/base/macwindowpicker.h"

#include <ApplicationServices/ApplicationServices.h>
#include <CoreFoundation/CoreFoundation.h>
#include <dlfcn.h>

#include "webrtc/base/logging.h"
#include "webrtc/base/macutils.h"

namespace rtc {

static const char* kCoreGraphicsName =
    "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/"
    "CoreGraphics.framework/CoreGraphics";

static const char* kWindowListCopyWindowInfo = "CGWindowListCopyWindowInfo";
static const char* kWindowListCreateDescriptionFromArray =
    "CGWindowListCreateDescriptionFromArray";

// Function pointer for holding the CGWindowListCopyWindowInfo function.
typedef CFArrayRef(*CGWindowListCopyWindowInfoProc)(CGWindowListOption,
                                                    CGWindowID);

// Function pointer for holding the CGWindowListCreateDescriptionFromArray
// function.
typedef CFArrayRef(*CGWindowListCreateDescriptionFromArrayProc)(CFArrayRef);

MacWindowPicker::MacWindowPicker() : lib_handle_(NULL), get_window_list_(NULL),
                                     get_window_list_desc_(NULL) {
}

MacWindowPicker::~MacWindowPicker() {
  if (lib_handle_ != NULL) {
    dlclose(lib_handle_);
  }
}

bool MacWindowPicker::Init() {
  // TODO: If this class grows to use more dynamically functions
  // from the CoreGraphics framework, consider using
  // webrtc/base/latebindingsymboltable.h.
  lib_handle_ = dlopen(kCoreGraphicsName, RTLD_NOW);
  if (lib_handle_ == NULL) {
    LOG(LS_ERROR) << "Could not load CoreGraphics";
    return false;
  }

  get_window_list_ = dlsym(lib_handle_, kWindowListCopyWindowInfo);
  get_window_list_desc_ =
      dlsym(lib_handle_, kWindowListCreateDescriptionFromArray);
  if (get_window_list_ == NULL || get_window_list_desc_ == NULL) {
    // The CGWindowListCopyWindowInfo and the
    // CGWindowListCreateDescriptionFromArray functions was introduced
    // in Leopard(10.5) so this is a normal failure on Tiger.
    LOG(LS_INFO) << "Failed to load Core Graphics symbols";
    dlclose(lib_handle_);
    lib_handle_ = NULL;
    return false;
  }

  return true;
}

bool MacWindowPicker::IsVisible(const WindowId& id) {
  // Init if we're not already inited.
  if (get_window_list_desc_ == NULL && !Init()) {
    return false;
  }
  CGWindowID ids[1];
  ids[0] = id.id();
  CFArrayRef window_id_array =
      CFArrayCreate(NULL, reinterpret_cast<const void **>(&ids), 1, NULL);

  CFArrayRef window_array =
      reinterpret_cast<CGWindowListCreateDescriptionFromArrayProc>(
          get_window_list_desc_)(window_id_array);
  if (window_array == NULL || 0 == CFArrayGetCount(window_array)) {
    // Could not find the window. It might have been closed.
    LOG(LS_INFO) << "Window not found";
    CFRelease(window_id_array);
    return false;
  }

  CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>(
      CFArrayGetValueAtIndex(window_array, 0));
  CFBooleanRef is_visible = reinterpret_cast<CFBooleanRef>(
      CFDictionaryGetValue(window, kCGWindowIsOnscreen));

  // Check that the window is visible. If not we might crash.
  bool visible = false;
  if (is_visible != NULL) {
    visible = CFBooleanGetValue(is_visible);
  }
  CFRelease(window_id_array);
  CFRelease(window_array);
  return visible;
}

bool MacWindowPicker::MoveToFront(const WindowId& id) {
  return false;
}

bool MacWindowPicker::GetDesktopList(DesktopDescriptionList* descriptions) {
  const uint32_t kMaxDisplays = 128;
  CGDirectDisplayID active_displays[kMaxDisplays];
  uint32_t display_count = 0;

  CGError err = CGGetActiveDisplayList(kMaxDisplays,
                                       active_displays,
                                       &display_count);
  if (err != kCGErrorSuccess) {
    LOG_E(LS_ERROR, OS, err) << "Failed to enumerate the active displays.";
    return false;
  }
  for (uint32_t i = 0; i < display_count; ++i) {
    DesktopId id(active_displays[i], static_cast<int>(i));
    // TODO: Figure out an appropriate desktop title.
    DesktopDescription desc(id, "");
    desc.set_primary(CGDisplayIsMain(id.id()));
    descriptions->push_back(desc);
  }
  return display_count > 0;
}

bool MacWindowPicker::GetDesktopDimensions(const DesktopId& id,
                                           int* width,
                                           int* height) {
  *width = CGDisplayPixelsWide(id.id());
  *height = CGDisplayPixelsHigh(id.id());
  return true;
}

bool MacWindowPicker::GetWindowList(WindowDescriptionList* descriptions) {
  // Init if we're not already inited.
  if (get_window_list_ == NULL && !Init()) {
    return false;
  }

  // Only get onscreen, non-desktop windows.
  CFArrayRef window_array =
      reinterpret_cast<CGWindowListCopyWindowInfoProc>(get_window_list_)(
          kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements,
          kCGNullWindowID);
  if (window_array == NULL) {
    return false;
  }

  // Check windows to make sure they have an id, title, and use window layer 0.
  CFIndex i;
  CFIndex count = CFArrayGetCount(window_array);
  for (i = 0; i < count; ++i) {
    CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>(
        CFArrayGetValueAtIndex(window_array, i));
    CFStringRef window_title = reinterpret_cast<CFStringRef>(
        CFDictionaryGetValue(window, kCGWindowName));
    CFNumberRef window_id = reinterpret_cast<CFNumberRef>(
        CFDictionaryGetValue(window, kCGWindowNumber));
    CFNumberRef window_layer = reinterpret_cast<CFNumberRef>(
        CFDictionaryGetValue(window, kCGWindowLayer));
    if (window_title != NULL && window_id != NULL && window_layer != NULL) {
      std::string title_str;
      int id_val, layer_val;
      ToUtf8(window_title, &title_str);
      CFNumberGetValue(window_id, kCFNumberIntType, &id_val);
      CFNumberGetValue(window_layer, kCFNumberIntType, &layer_val);

      // Discard windows without a title.
      if (layer_val == 0 && title_str.length() > 0) {
        WindowId id(static_cast<CGWindowID>(id_val));
        WindowDescription desc(id, title_str);
        descriptions->push_back(desc);
      }
    }
  }

  CFRelease(window_array);
  return true;
}

}  // namespace rtc
