// Copyright 2010 Google Inc. All Rights Reserved


#include "talk/base/macwindowpicker.h"

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

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

namespace talk_base {

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
  // talk/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(WindowId id) {
  // Init if we're not already inited.
  if (get_window_list_desc_ == NULL && !Init()) {
    return false;
  }
  CGWindowID ids[1];
  ids[0] = 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(WindowId id) {
  // TODO: Implement this method.
  // Init if we're not already inited.
  if (get_window_list_desc_ == NULL && !Init()) {
    return false;
  }
  CGWindowID ids[1];
  ids[0] = 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));
  CFStringRef window_name_ref = reinterpret_cast<CFStringRef>(
      CFDictionaryGetValue(window, kCGWindowName));
  CFNumberRef application_pid = reinterpret_cast<CFNumberRef>(
      CFDictionaryGetValue(window, kCGWindowOwnerPID));

  int pid_val;
  CFNumberGetValue(application_pid, kCFNumberIntType, &pid_val);
  std::string window_name;
  ToUtf8(window_name_ref, &window_name);

  // Build an applescript that sets the selected window to front
  // within the application. Then set the application to front.
  bool result = true;
  std::stringstream ss;
  ss << "tell application \"System Events\"\n"
     << "set proc to the first item of (every process whose unix id is "
     << pid_val
     << ")\n"
     << "tell proc to perform action \"AXRaise\" of window \""
     << window_name
     << "\"\n"
     << "set the frontmost of proc to true\n"
     << "end tell";
  if (!RunAppleScript(ss.str())) {
    // This might happen to for example X applications where the X
    // server spawns of processes with their own PID but the X server
    // is still registered as owner to the application windows. As a
    // workaround, we put the X server process to front, meaning that
    // all X applications will show up. The drawback with this
    // workaround is that the application that we really wanted to set
    // to front might be behind another X application.
    ProcessSerialNumber psn;
    pid_t pid = pid_val;
    int res = GetProcessForPID(pid, &psn);
    if (res != 0) {
      LOG(LS_ERROR) << "Failed getting process for pid";
      result = false;
    }
    res = SetFrontProcess(&psn);
    if (res != 0) {
      LOG(LS_ERROR) << "Failed setting process to front";
      result = false;
    }
  }
  CFRelease(window_id_array);
  CFRelease(window_array);
  return result;
}

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) {
        WindowDescription desc(id_val, title_str);
        descriptions->push_back(desc);
      }
    }
  }

  CFRelease(window_array);
  return true;
}

}  // namespace talk_base
