// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/clipboard_util.h"

#include <shellapi.h>
#include <shlwapi.h>
#include <wininet.h>

#include "base/basictypes.h"
#include "base/logging.h"
#include "base/scoped_handle.h"
#include "base/string_util.h"

namespace {

bool GetUrlFromHDrop(IDataObject* data_object, std::wstring* url,
                     std::wstring* title) {
  DCHECK(data_object && url && title);

  STGMEDIUM medium;
  if (FAILED(data_object->GetData(ClipboardUtil::GetCFHDropFormat(), &medium)))
    return false;

  HDROP hdrop = static_cast<HDROP>(GlobalLock(medium.hGlobal));

  if (!hdrop)
    return false;

  bool success = false;
  wchar_t filename[MAX_PATH];
  if (DragQueryFileW(hdrop, 0, filename, arraysize(filename))) {
    wchar_t url_buffer[INTERNET_MAX_URL_LENGTH];
    if (0 == _wcsicmp(PathFindExtensionW(filename), L".url") &&
        GetPrivateProfileStringW(L"InternetShortcut", L"url", 0, url_buffer,
                                 arraysize(url_buffer), filename)) {
      *url = url_buffer;
      PathRemoveExtension(filename);
      title->assign(PathFindFileName(filename));
      success = true;
    }
  }

  DragFinish(hdrop);
  GlobalUnlock(medium.hGlobal);
  // We don't need to call ReleaseStgMedium here because as far as I can tell,
  // DragFinish frees the hGlobal for us.
  return success;
}

bool SplitUrlAndTitle(const std::wstring& str, std::wstring* url,
    std::wstring* title) {
  DCHECK(url && title);
  size_t newline_pos = str.find('\n');
  bool success = false;
  if (newline_pos != std::string::npos) {
    *url = str.substr(0, newline_pos);
    title->assign(str.substr(newline_pos + 1));
    success = true;
  } else {
    *url = str;
    title->assign(str);
    success = true;
  }
  return success;
}

}  // namespace


FORMATETC* ClipboardUtil::GetUrlFormat() {
  static UINT cf = RegisterClipboardFormat(CFSTR_INETURLA);
  static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  return &format;
}

FORMATETC* ClipboardUtil::GetUrlWFormat() {
  static UINT cf = RegisterClipboardFormat(CFSTR_INETURLW);
  static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  return &format;
}

FORMATETC* ClipboardUtil::GetMozUrlFormat() {
  // The format is "URL\nTitle"
  static UINT cf = RegisterClipboardFormat(L"text/x-moz-url");
  static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  return &format;
}

FORMATETC* ClipboardUtil::GetPlainTextFormat() {
  // We don't need to register this format since it's a built in format.
  static FORMATETC format = {CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  return &format;
}

FORMATETC* ClipboardUtil::GetPlainTextWFormat() {
  // We don't need to register this format since it's a built in format.
  static FORMATETC format = {CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1,
                             TYMED_HGLOBAL};
  return &format;
}

FORMATETC* ClipboardUtil::GetFilenameWFormat() {
  static UINT cf = RegisterClipboardFormat(CFSTR_FILENAMEW);
  static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  return &format;
}

FORMATETC* ClipboardUtil::GetFilenameFormat()
{
  static UINT cf = RegisterClipboardFormat(CFSTR_FILENAMEA);
  static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  return &format;
}

FORMATETC* ClipboardUtil::GetHtmlFormat() {
  static UINT cf = RegisterClipboardFormat(L"HTML Format");
  static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  return &format;
}

FORMATETC* ClipboardUtil::GetTextHtmlFormat() {
  static UINT cf = RegisterClipboardFormat(L"text/html");
  static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  return &format;
}

FORMATETC* ClipboardUtil::GetCFHDropFormat() {
  // We don't need to register this format since it's a built in format.
  static FORMATETC format = {CF_HDROP, 0, DVASPECT_CONTENT, -1,
                             TYMED_HGLOBAL};
  return &format;
}

FORMATETC* ClipboardUtil::GetFileDescriptorFormat() {
  static UINT cf = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);
  static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  return &format;
}

FORMATETC* ClipboardUtil::GetFileContentFormatZero() {
  static UINT cf = RegisterClipboardFormat(CFSTR_FILECONTENTS);
  static FORMATETC format = {cf, 0, DVASPECT_CONTENT, 0, TYMED_HGLOBAL};
  return &format;
}

FORMATETC* ClipboardUtil::GetWebKitSmartPasteFormat() {
  static UINT cf = RegisterClipboardFormat(L"WebKit Smart Paste Format");
  static FORMATETC format = {cf, 0, DVASPECT_CONTENT, 0, TYMED_HGLOBAL};
  return &format;
}


bool ClipboardUtil::HasUrl(IDataObject* data_object) {
  DCHECK(data_object);
  return SUCCEEDED(data_object->QueryGetData(GetMozUrlFormat())) ||
      SUCCEEDED(data_object->QueryGetData(GetUrlWFormat())) ||
      SUCCEEDED(data_object->QueryGetData(GetUrlFormat())) ||
      SUCCEEDED(data_object->QueryGetData(GetFilenameWFormat())) ||
      SUCCEEDED(data_object->QueryGetData(GetFilenameFormat()));
}

bool ClipboardUtil::HasFilenames(IDataObject* data_object) {
  DCHECK(data_object);
  return SUCCEEDED(data_object->QueryGetData(GetCFHDropFormat()));
}

bool ClipboardUtil::HasPlainText(IDataObject* data_object) {
  DCHECK(data_object);
  return SUCCEEDED(data_object->QueryGetData(GetPlainTextWFormat())) ||
      SUCCEEDED(data_object->QueryGetData(GetPlainTextFormat()));
}


bool ClipboardUtil::GetUrl(IDataObject* data_object,
    std::wstring* url, std::wstring* title) {
  DCHECK(data_object && url && title);
  if (!HasUrl(data_object))
    return false;

  // Try to extract a URL from |data_object| in a variety of formats.
  STGMEDIUM store;
  if (GetUrlFromHDrop(data_object, url, title)) {
    return true;
  }

  if (SUCCEEDED(data_object->GetData(GetMozUrlFormat(), &store)) ||
      SUCCEEDED(data_object->GetData(GetUrlWFormat(), &store))) {
    // Mozilla URL format or unicode URL
    ScopedHGlobal<wchar_t> data(store.hGlobal);
    bool success = SplitUrlAndTitle(data.get(), url, title);
    ReleaseStgMedium(&store);
    if (success)
      return true;
  }

  if (SUCCEEDED(data_object->GetData(GetUrlFormat(), &store))) {
    // URL using ascii
    ScopedHGlobal<char> data(store.hGlobal);
    bool success = SplitUrlAndTitle(UTF8ToWide(data.get()), url, title);
    ReleaseStgMedium(&store);
    if (success)
      return true;
  }

  if (SUCCEEDED(data_object->GetData(GetFilenameWFormat(), &store))) {
    // filename using unicode
    ScopedHGlobal<wchar_t> data(store.hGlobal);
    bool success = false;
    if (data.get() && data.get()[0] && (PathFileExists(data.get()) ||
                                        PathIsUNC(data.get()))) {
      wchar_t file_url[INTERNET_MAX_URL_LENGTH];
      DWORD file_url_len = sizeof(file_url) / sizeof(file_url[0]);
      if (SUCCEEDED(::UrlCreateFromPathW(data.get(), file_url, &file_url_len,
                                         0))) {
        *url = file_url;
        title->assign(file_url);
        success = true;
      }
    }
    ReleaseStgMedium(&store);
    if (success)
      return true;
  }

  if (SUCCEEDED(data_object->GetData(GetFilenameFormat(), &store))) {
    // filename using ascii
    ScopedHGlobal<char> data(store.hGlobal);
    bool success = false;
    if (data.get() && data.get()[0] && (PathFileExistsA(data.get()) ||
                                        PathIsUNCA(data.get()))) {
      char file_url[INTERNET_MAX_URL_LENGTH];
      DWORD file_url_len = sizeof(file_url) / sizeof(file_url[0]);
      if (SUCCEEDED(::UrlCreateFromPathA(data.get(), file_url, &file_url_len, 0))) {
        *url = UTF8ToWide(file_url);
        title->assign(*url);
        success = true;
      }
    }
    ReleaseStgMedium(&store);
    if (success)
      return true;
  }

  return false;
}

bool ClipboardUtil::GetFilenames(IDataObject* data_object,
                                 std::vector<std::wstring>* filenames) {
  DCHECK(data_object && filenames);
  if (!HasFilenames(data_object))
    return false;

  STGMEDIUM medium;
  if (FAILED(data_object->GetData(GetCFHDropFormat(), &medium)))
    return false;

  HDROP hdrop = static_cast<HDROP>(GlobalLock(medium.hGlobal));
  if (!hdrop)
    return false;

  const int kMaxFilenameLen = 4096;
  const unsigned num_files = DragQueryFileW(hdrop, 0xffffffff, 0, 0);
  for (unsigned int i = 0; i < num_files; ++i) {
    wchar_t filename[kMaxFilenameLen];
    if (!DragQueryFileW(hdrop, i, filename, kMaxFilenameLen))
      continue;
    filenames->push_back(filename);
  }

  DragFinish(hdrop);
  GlobalUnlock(medium.hGlobal);
  // We don't need to call ReleaseStgMedium here because as far as I can tell,
  // DragFinish frees the hGlobal for us.
  return true;
}

bool ClipboardUtil::GetPlainText(IDataObject* data_object,
                                 std::wstring* plain_text) {
  DCHECK(data_object && plain_text);
  if (!HasPlainText(data_object))
    return false;

  STGMEDIUM store;
  bool success = false;
  if (SUCCEEDED(data_object->GetData(GetPlainTextWFormat(), &store))) {
    // Unicode text
    ScopedHGlobal<wchar_t> data(store.hGlobal);
    plain_text->assign(data.get());
    ReleaseStgMedium(&store);
    success = true;
  } else if (SUCCEEDED(data_object->GetData(GetPlainTextFormat(), &store))) {
    // ascii text
    ScopedHGlobal<char> data(store.hGlobal);
    plain_text->assign(UTF8ToWide(data.get()));
    ReleaseStgMedium(&store);
    success = true;
  } else {
    //If a file is dropped on the window, it does not provide either of the
    //plain text formats, so here we try to forcibly get a url.
    std::wstring title;
    success = GetUrl(data_object, plain_text, &title);
  }

  return success;
}

bool ClipboardUtil::GetCFHtml(IDataObject* data_object,
                              std::wstring* cf_html) {
  DCHECK(data_object && cf_html);
  if (FAILED(data_object->QueryGetData(GetHtmlFormat())))
    return false;

  STGMEDIUM store;
  if (FAILED(data_object->GetData(GetHtmlFormat(), &store)))
    return false;

  // MS CF html
  ScopedHGlobal<char> data(store.hGlobal);
  cf_html->assign(UTF8ToWide(std::string(data.get(), data.Size())));
  ReleaseStgMedium(&store);
  return true;
}

bool ClipboardUtil::GetTextHtml(IDataObject* data_object,
                                std::wstring* text_html) {
  DCHECK(data_object && text_html);
  if (FAILED(data_object->QueryGetData(GetTextHtmlFormat())))
    return false;

  STGMEDIUM store;
  if (FAILED(data_object->GetData(GetTextHtmlFormat(), &store)))
    return false;

  // raw html
  ScopedHGlobal<wchar_t> data(store.hGlobal);
  text_html->assign(data.get());
  ReleaseStgMedium(&store);
  return true;
}

bool ClipboardUtil::GetFileContents(IDataObject* data_object,
    std::wstring* filename, std::string* file_contents) {
  DCHECK(data_object && filename && file_contents);
  bool has_data =
      SUCCEEDED(data_object->QueryGetData(GetFileContentFormatZero())) ||
      SUCCEEDED(data_object->QueryGetData(GetFileDescriptorFormat()));

  if (!has_data)
    return false;

  STGMEDIUM content;
  // The call to GetData can be very slow depending on what is in
  // |data_object|.
  if (SUCCEEDED(data_object->GetData(GetFileContentFormatZero(), &content))) {
    if (TYMED_HGLOBAL == content.tymed) {
      ScopedHGlobal<char> data(content.hGlobal);
      // The size includes the trailing NULL byte.  We don't want it.
      file_contents->assign(data.get(), data.Size() - 1);
    }
    ReleaseStgMedium(&content);
  }

  STGMEDIUM description;
  if (SUCCEEDED(data_object->GetData(GetFileDescriptorFormat(),
                                     &description))) {
    ScopedHGlobal<FILEGROUPDESCRIPTOR> fgd(description.hGlobal);
    // We expect there to be at least one file in here.
    DCHECK(fgd->cItems >= 1);
    filename->assign(fgd->fgd[0].cFileName);
    ReleaseStgMedium(&description);
  }
  return true;
}

