/*
 *	clipboard helper functions
 *
 *	Copyright 2000	Juergen Schmied <juergen.schmied@debitel.de>
 *
 * For copy & paste functions within contextmenus does the shell use
 * the OLE clipboard functions in combination with dataobjects.
 * The OLE32.DLL gets loaded with LoadLibrary
 *
 * - a right mousebutton-copy sets the following formats:
 *  classic:
 *	Shell IDList Array
 *	Prefered Drop Effect
 *	Shell Object Offsets
 *	HDROP
 *	FileName
 *  ole:
 *	OlePrivateData (ClipboardDataObjectInterface)
 *
 */

#include <string.h>

#include "debugtools.h"

#include "pidl.h"
#include "wine/undocshell.h"
#include "shell32_main.h"

DEFAULT_DEBUG_CHANNEL(shell);

static int refClipCount = 0;
static HINSTANCE hShellOle32 = 0;

/**************************************************************************
 * InitShellOle
 *
 * 
 */
void InitShellOle(void)
{
}

/**************************************************************************
 * FreeShellOle
 *
 * unload OLE32.DLL
 */
void FreeShellOle(void)
{
	if (!--refClipCount)
	{
	  pOleUninitialize();
	  FreeLibrary(hShellOle32);
	}
}

/**************************************************************************
 * LoadShellOle
 *
 * make sure OLE32.DLL is loaded
 */
BOOL GetShellOle(void)
{
	if(!refClipCount)
	{
	  hShellOle32 = LoadLibraryA("ole32.dll");
	  if(hShellOle32)
	  {
	    pOleInitialize=(void*)GetProcAddress(hShellOle32,"OleInitialize");
	    pOleUninitialize=(void*)GetProcAddress(hShellOle32,"OleUninitialize");
	    pRegisterDragDrop=(void*)GetProcAddress(hShellOle32,"RegisterDragDrop");
	    pRevokeDragDrop=(void*)GetProcAddress(hShellOle32,"RevokeDragDrop");
	    pDoDragDrop=(void*)GetProcAddress(hShellOle32,"DoDragDrop");
	    pReleaseStgMedium=(void*)GetProcAddress(hShellOle32,"ReleaseStgMedium");
	    pOleSetClipboard=(void*)GetProcAddress(hShellOle32,"OleSetClipboard");
	    pOleGetClipboard=(void*)GetProcAddress(hShellOle32,"OleGetClipboard");

	    pOleInitialize(NULL);
	    refClipCount++;
	  }
	}
	return TRUE;
}

/**************************************************************************
 * RenderHDROP
 *
 * creates a CF_HDROP structure
 */
HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
{
	int i;
	int rootsize = 0,size = 0;
	char szRootPath[MAX_PATH];
	char szFileName[MAX_PATH];
	HGLOBAL hGlobal;
	DROPFILES *pDropFiles;
	int offset;
	
	TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);

	/* get the size needed */
	size = sizeof(DROPFILES);

	SHGetPathFromIDListA(pidlRoot, szRootPath);
	PathAddBackslashA(szRootPath);
	rootsize = strlen(szRootPath);
	
	for (i=0; i<cidl;i++)
	{
	  _ILSimpleGetText(apidl[i], szFileName, MAX_PATH);
	  size += rootsize + strlen(szFileName) + 1;
	}

	size++;

	/* Fill the structure */
	hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
	if(!hGlobal) return hGlobal;

        pDropFiles = (DROPFILES *)GlobalLock(hGlobal);
        pDropFiles->pFiles = sizeof(DROPFILES);
        pDropFiles->fWide = FALSE;

	offset = pDropFiles->pFiles;
	strcpy(szFileName, szRootPath);
	
	for (i=0; i<cidl;i++)
	{
	  
	  _ILSimpleGetText(apidl[i], szFileName + rootsize, MAX_PATH - rootsize);
	  size = strlen(szFileName) + 1;
	  strcpy(((char*)pDropFiles)+offset, szFileName);
	  offset += size;
	}

	((char*)pDropFiles)[offset] = 0;
	GlobalUnlock(hGlobal);

	return hGlobal;
}

HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
{
	int i,offset = 0, sizePidl, size;
	HGLOBAL hGlobal;
	LPCIDA	pcida;

	TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);

	/* get the size needed */
	size = sizeof(CIDA) + sizeof (UINT)*(cidl);	/* header */
	size += ILGetSize (pidlRoot);			/* root pidl */
	for(i=0; i<cidl; i++)
	{
	  size += ILGetSize(apidl[i]);			/* child pidls */
	}

	/* fill the structure */
	hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);		
	if(!hGlobal) return hGlobal;
	pcida = GlobalLock (hGlobal);
	pcida->cidl = cidl;

	/* root pidl */
	offset = sizeof(CIDA) + sizeof (UINT)*(cidl);
	pcida->aoffset[0] = offset;			/* first element */
	sizePidl = ILGetSize (pidlRoot);
	memcpy(((LPBYTE)pcida)+offset, pidlRoot, sizePidl);
	offset += sizePidl;

	for(i=0; i<cidl; i++)				/* child pidls */
	{
	  pcida->aoffset[i+1] = offset;
	  sizePidl = ILGetSize(apidl[i]);
	  memcpy(((LPBYTE)pcida)+offset, apidl[i], sizePidl);
	  offset += sizePidl;
	}

	GlobalUnlock(hGlobal);
	return hGlobal;
}

HGLOBAL RenderSHELLIDLISTOFFSET (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
{
	FIXME("\n");
	return 0;
}

HGLOBAL RenderFILECONTENTS (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
{
	FIXME("\n");
	return 0;
}

HGLOBAL RenderFILEDESCRIPTOR (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
{
	FIXME("\n");
	return 0;
}

HGLOBAL RenderFILENAME (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
{
	int len, size = 0;
	char szTemp[MAX_PATH], *szFileName;
	HGLOBAL hGlobal;
	
	TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);

	/* build name of first file */
	SHGetPathFromIDListA(pidlRoot, szTemp);
	PathAddBackslashA(szTemp);
	len = strlen(szTemp);
	_ILSimpleGetText(apidl[0], szTemp+len, MAX_PATH - len);
	size = strlen(szTemp) + 1;

	/* fill the structure */
	hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
	if(!hGlobal) return hGlobal;
        szFileName = (char *)GlobalLock(hGlobal);
	GlobalUnlock(hGlobal);
	return hGlobal;
}

HGLOBAL RenderPREFEREDDROPEFFECT (DWORD dwFlags)
{
	DWORD * pdwFlag;
	HGLOBAL hGlobal;
	
	TRACE("(0x%08lx)\n", dwFlags);

	hGlobal = GlobalAlloc(GHND|GMEM_SHARE, sizeof(DWORD));
	if(!hGlobal) return hGlobal;
        pdwFlag = (DWORD*)GlobalLock(hGlobal);
	*pdwFlag = dwFlags;
	GlobalUnlock(hGlobal);
	return hGlobal;
}

/**************************************************************************
 * IsDataInClipboard
 *
 * checks if there is something in the clipboard we can use
 */
BOOL IsDataInClipboard (HWND hwnd)
{
	BOOL ret = FALSE;
	
	if (OpenClipboard(hwnd))
	{
	  if (GetOpenClipboardWindow())
	  {
	    ret = IsClipboardFormatAvailable(CF_TEXT);
	  }
	  CloseClipboard();
	}
	return ret;
}
