// Copyright (c) 2011 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 "ui/base/dragdrop/drop_target_win.h"

#include <shlobj.h>

#include "base/logging.h"

namespace ui {

IDropTargetHelper* DropTargetWin::cached_drop_target_helper_ = NULL;

DropTargetWin::DropTargetWin(HWND hwnd)
    : hwnd_(hwnd),
      ref_count_(0) {
  DCHECK(hwnd);
  HRESULT result = RegisterDragDrop(hwnd, this);
  DCHECK(SUCCEEDED(result));
}

DropTargetWin::~DropTargetWin() {
}

// static
IDropTargetHelper* DropTargetWin::DropHelper() {
  if (!cached_drop_target_helper_) {
    CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER,
                     IID_IDropTargetHelper,
                     reinterpret_cast<void**>(&cached_drop_target_helper_));
  }
  return cached_drop_target_helper_;
}

///////////////////////////////////////////////////////////////////////////////
// DropTargetWin, IDropTarget implementation:

HRESULT DropTargetWin::DragEnter(IDataObject* data_object,
                                 DWORD key_state,
                                 POINTL cursor_position,
                                 DWORD* effect) {
  // Tell the helper that we entered so it can update the drag image.
  IDropTargetHelper* drop_helper = DropHelper();
  if (drop_helper) {
    drop_helper->DragEnter(GetHWND(), data_object,
                           reinterpret_cast<POINT*>(&cursor_position), *effect);
  }

  current_data_object_ = data_object;
  POINT screen_pt = { cursor_position.x, cursor_position.y };
  *effect =
      OnDragEnter(current_data_object_.get(), key_state, screen_pt, *effect);
  return S_OK;
}

HRESULT DropTargetWin::DragOver(DWORD key_state,
                                POINTL cursor_position,
                                DWORD* effect) {
  // Tell the helper that we moved over it so it can update the drag image.
  IDropTargetHelper* drop_helper = DropHelper();
  if (drop_helper)
    drop_helper->DragOver(reinterpret_cast<POINT*>(&cursor_position), *effect);

  POINT screen_pt = { cursor_position.x, cursor_position.y };
  *effect =
      OnDragOver(current_data_object_.get(), key_state, screen_pt, *effect);
  return S_OK;
}

HRESULT DropTargetWin::DragLeave() {
  // Tell the helper that we moved out of it so it can update the drag image.
  IDropTargetHelper* drop_helper = DropHelper();
  if (drop_helper)
    drop_helper->DragLeave();

  OnDragLeave(current_data_object_.get());

  current_data_object_ = NULL;
  return S_OK;
}

HRESULT DropTargetWin::Drop(IDataObject* data_object,
                            DWORD key_state,
                            POINTL cursor_position,
                            DWORD* effect) {
  // Tell the helper that we dropped onto it so it can update the drag image.
  IDropTargetHelper* drop_helper = DropHelper();
  if (drop_helper) {
    drop_helper->Drop(current_data_object_.get(),
                      reinterpret_cast<POINT*>(&cursor_position), *effect);
  }

  POINT screen_pt = { cursor_position.x, cursor_position.y };
  *effect = OnDrop(current_data_object_.get(), key_state, screen_pt, *effect);
  return S_OK;
}

///////////////////////////////////////////////////////////////////////////////
// DropTargetWin, IUnknown implementation:

HRESULT DropTargetWin::QueryInterface(const IID& iid, void** object) {
  *object = NULL;
  if (IsEqualIID(iid, IID_IUnknown) || IsEqualIID(iid, IID_IDropTarget)) {
    *object = this;
  } else {
    return E_NOINTERFACE;
  }
  AddRef();
  return S_OK;
}

ULONG DropTargetWin::AddRef() {
  return ++ref_count_;
}

ULONG DropTargetWin::Release() {
  if (--ref_count_ == 0) {
    delete this;
    return 0U;
  }
  return ref_count_;
}

DWORD DropTargetWin::OnDragEnter(IDataObject* data_object,
                                 DWORD key_state,
                                 POINT cursor_position,
                                 DWORD effect) {
  return DROPEFFECT_NONE;
}

DWORD DropTargetWin::OnDragOver(IDataObject* data_object,
                                DWORD key_state,
                                POINT cursor_position,
                                DWORD effect) {
  return DROPEFFECT_NONE;
}

void DropTargetWin::OnDragLeave(IDataObject* data_object) {
}

DWORD DropTargetWin::OnDrop(IDataObject* data_object,
                            DWORD key_state,
                            POINT cursor_position,
                            DWORD effect) {
  return DROPEFFECT_NONE;
}

}  // namespace ui
