// __author__ = David Terracino (davet@lycosemail.com)
//              Juan Carlos De Abreu (jcabreur@gmail.com)

#include "Clipboard.h"

BEGIN_TEG_NAMESPACE();

// Clipboard constructor.
Clipboard::Clipboard() {}

// Clipboard destructor.
Clipboard::~Clipboard() {}

// Retrieves text from the clipboard.
//  Parameters:
//    text - pointer to a string where the text is to be put.
//    hWnd - window handle to be used by clipboard.
BOOL Clipboard::getText(std::tstring& text, HWND hWnd) const {
  HGLOBAL hGlobal; // Global memory handle.
  LPSTR lpszData;  // Pointer to clipboard data.

  // First, open the clipboard. OpenClipboard() takes one parameter, the handle
  // of the window that will temporarily be it's owner. If NULL is passed, the
  // current process is assumed.
  OpenClipboard(hWnd);

  // Request a pointer to the text on the clipboard.
  hGlobal = GetClipboardData(CF_TEXT);

  // If there was no text on the clipboard, we have been returned a NULL handle.
  if (hGlobal == NULL) return FALSE;

  // Now we have a global memory handle to the text stored on the clipboard. We
  // have to lock this global handle so that we have access to it.
  lpszData = (LPSTR)GlobalLock(hGlobal);
  // Now get the size of the text on the clipboard.
  const unsigned long nSize = GlobalSize(hGlobal) - 1;
  text.resize(nSize);

  // Now, copy the text into the return buffer.
  for (UINT i = 0; i < nSize; ++i) text[i] = *(lpszData + i);

  // Now, simply unlock the global memory pointer and close the clipboard.
  GlobalUnlock(hGlobal);
  CloseClipboard();

  return TRUE;
}

// Places text on the clipboard.
//  Parameters:
//    lpszBuffer - pointer to a string where the text is to be put.
//    hWnd       - window handle to be used by clipboard.
BOOL Clipboard::setText(const std::tstring& text, HWND hWnd) const {
  HGLOBAL hGlobal;     // Global memory handle.
  LPSTR lpszData;      // Pointer to clipboard data.

  // First, open the clipboard. OpenClipboard() takes one parameter, the handle
  // of the window that will temporarily be it's owner. If NULL is passed, the
  // current process is assumed. After opening, empty the clipboard so we can
  // put our text on it.
  OpenClipboard(hWnd);
  EmptyClipboard();

  // Get the size of the string in the buffer that was passed into the
  // function, so we know how much global memory to allocate for the string.
  const unsigned long nSize = static_cast<int> (text.size());

  // Allocate the memory for the string.
  hGlobal = GlobalAlloc(GMEM_ZEROINIT, nSize + 1);
	
  // If we got any error during the memory allocation, we have been returned a
  // NULL handle.
  if (hGlobal == NULL) return FALSE;

  // Now we have a global memory handle to the text stored on the clipboard. We
  // have to lock this global handle so that we have access to it.
  lpszData = (LPSTR)GlobalLock(hGlobal);

  // Now, copy the text from the buffer into the allocated global memory pointer.
  for (UINT i = 0; i < nSize; ++i)
    *(lpszData + i) = text[i];
  *(lpszData + nSize) = 0;

  // Now, simply unlock the global memory pointer, set the clipboard data type
  // and pointer, and close the clipboard.
  GlobalUnlock(hGlobal);
  SetClipboardData(CF_TEXT, hGlobal);
  CloseClipboard();

  return TRUE;
}

END_TEG_NAMESPACE();
