/*
 *	IEnumFORMATETC, IDataObject
 *
 * selecting and droping objects within the shell and/or common dialogs
 *
 *	Copyright 1998	<juergen.schmied@metronet.de>
 */
#include "debug.h"
#include "shlobj.h"
#include "pidl.h"
#include "winerror.h"
#include "shell32_main.h"

UINT32 cfShellIDList=0;
UINT32 cfFileGroupDesc=0;
UINT32 cfFileContents=0;

/***********************************************************************
*   IEnumFORMATETC implementation
*/
static HRESULT WINAPI IEnumFORMATETC_QueryInterface (LPENUMFORMATETC this, REFIID riid, LPVOID * ppvObj);
static ULONG WINAPI IEnumFORMATETC_AddRef (LPENUMFORMATETC this);
static ULONG WINAPI IEnumFORMATETC_Release (LPENUMFORMATETC this);
static HRESULT WINAPI IEnumFORMATETC_Next(LPENUMFORMATETC this, ULONG celt, FORMATETC32 *rgelt, ULONG *pceltFethed);
static HRESULT WINAPI IEnumFORMATETC_Skip(LPENUMFORMATETC this, ULONG celt);
static HRESULT WINAPI IEnumFORMATETC_Reset(LPENUMFORMATETC this);
static HRESULT WINAPI IEnumFORMATETC_Clone(LPENUMFORMATETC this, LPENUMFORMATETC* ppenum);

static struct IEnumFORMATETC_VTable efvt = 
{	IEnumFORMATETC_QueryInterface,
	IEnumFORMATETC_AddRef,
	IEnumFORMATETC_Release,
	IEnumFORMATETC_Next,
	IEnumFORMATETC_Skip,
	IEnumFORMATETC_Reset,
	IEnumFORMATETC_Clone
};

extern LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT32 cfmt, const FORMATETC32 afmt[])
{	LPENUMFORMATETC ef;
	DWORD size=cfmt * sizeof(FORMATETC32);
	
	ef=(LPENUMFORMATETC)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumFORMATETC));
	ef->ref=1;
	ef->lpvtbl=&efvt;

	ef->posFmt = 0;
	ef->countFmt = cfmt;
	ef->pFmt = SHAlloc (size);

	if (ef->pFmt)
	{ memcpy(ef->pFmt, afmt, size);
	}

	TRACE(shell,"(%p)->()\n",ef);
	return ef;
}
static HRESULT WINAPI IEnumFORMATETC_QueryInterface (LPENUMFORMATETC this, REFIID riid, LPVOID * ppvObj)
{	char    xriid[50];
	WINE_StringFromCLSID((LPCLSID)riid,xriid);
	TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);

			*ppvObj = NULL;

	if(IsEqualIID(riid, &IID_IUnknown))
	{ *ppvObj = this; 
	}
	else if(IsEqualIID(riid, &IID_IEnumFORMATETC))
	{ *ppvObj = (IDataObject*)this;
	}   

	if(*ppvObj)
	{ (*(LPENUMFORMATETC*)ppvObj)->lpvtbl->fnAddRef(this);      
	  TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
	  return S_OK;
	}
	TRACE(shell,"-- Interface: E_NOINTERFACE\n");
	return E_NOINTERFACE;

}
static ULONG WINAPI IEnumFORMATETC_AddRef (LPENUMFORMATETC this)
{	TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
	return ++(this->ref);
}
static ULONG WINAPI IEnumFORMATETC_Release (LPENUMFORMATETC this)
{	TRACE(shell,"(%p)->()\n",this);
	if (!--(this->ref)) 
	{ TRACE(shell," destroying IEnumFORMATETC(%p)\n",this);
	  if (this->pFmt)
	  { SHFree (this->pFmt);
	  }
	  HeapFree(GetProcessHeap(),0,this);
	  return 0;
	}
	return this->ref;
}
static HRESULT WINAPI IEnumFORMATETC_Next(LPENUMFORMATETC this, ULONG celt, FORMATETC32 *rgelt, ULONG *pceltFethed)
{	UINT32 cfetch;
	HRESULT hres = S_FALSE;

	TRACE (shell, "(%p)->()\n", this);

        if (this->posFmt < this->countFmt)
        { cfetch = this->countFmt - this->posFmt;
	  if (cfetch >= celt)
	  { cfetch = celt;
	    hres = S_OK;
	  }
	  memcpy(rgelt, &this->pFmt[this->posFmt], cfetch * sizeof(FORMATETC32));
	  this->posFmt += cfetch;
	}
	else
	{ cfetch = 0;
        }

        if (pceltFethed)
        { *pceltFethed = cfetch;
        }

        return hres;
}
static HRESULT WINAPI IEnumFORMATETC_Skip(LPENUMFORMATETC this, ULONG celt)
{	FIXME (shell, "(%p)->(num=%lu)\n", this, celt);

	this->posFmt += celt;
	if (this->posFmt > this->countFmt)
        { this->posFmt = this->countFmt;
	  return S_FALSE;
	}
	return S_OK;
}
static HRESULT WINAPI IEnumFORMATETC_Reset(LPENUMFORMATETC this)
{	FIXME (shell, "(%p)->()\n", this);

        this->posFmt = 0;
        return S_OK;
}
static HRESULT WINAPI IEnumFORMATETC_Clone(LPENUMFORMATETC this, LPENUMFORMATETC* ppenum)
{	FIXME (shell, "(%p)->(ppenum=%p)\n", this, ppenum);
	return E_NOTIMPL;
}

/***********************************************************************
*   IDataObject implementation
*/

static HRESULT WINAPI IDataObject_QueryInterface (LPDATAOBJECT, REFIID riid, LPVOID * ppvObj);
static ULONG WINAPI IDataObject_AddRef (LPDATAOBJECT);
static ULONG WINAPI IDataObject_Release (LPDATAOBJECT);
static HRESULT WINAPI IDataObject_GetData (LPDATAOBJECT, LPFORMATETC32 pformatetcIn, STGMEDIUM32 *pmedium);
static HRESULT WINAPI IDataObject_GetDataHere(LPDATAOBJECT, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium);
static HRESULT WINAPI IDataObject_QueryGetData(LPDATAOBJECT, LPFORMATETC32 pformatetc);
static HRESULT WINAPI IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT, LPFORMATETC32 pformatectIn, LPFORMATETC32 pformatetcOut);
static HRESULT WINAPI IDataObject_SetData(LPDATAOBJECT, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium, BOOL32 fRelease);
static HRESULT WINAPI IDataObject_EnumFormatEtc(LPDATAOBJECT, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc);
static HRESULT WINAPI IDataObject_DAdvise (LPDATAOBJECT, LPFORMATETC32 *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
static HRESULT WINAPI IDataObject_DUnadvise(LPDATAOBJECT, DWORD dwConnection);
static HRESULT WINAPI IDataObject_EnumDAdvise(LPDATAOBJECT, IEnumSTATDATA **ppenumAdvise);

static struct IDataObject_VTable dtovt = 
{	IDataObject_QueryInterface,
	IDataObject_AddRef,
	IDataObject_Release,
	IDataObject_GetData,
	IDataObject_GetDataHere,
	IDataObject_QueryGetData,
	IDataObject_GetCanonicalFormatEtc,
	IDataObject_SetData,
	IDataObject_EnumFormatEtc,
	IDataObject_DAdvise,
	IDataObject_DUnadvise,
	IDataObject_EnumDAdvise
};

/**************************************************************************
*  IDataObject_Constructor
*/
LPDATAOBJECT IDataObject_Constructor(HWND32 hwndOwner, LPSHELLFOLDER psf, LPITEMIDLIST * apidl, UINT32 cidl)
{	LPDATAOBJECT dto;
	if (!(dto = (LPDATAOBJECT)HeapAlloc(GetProcessHeap(),0,sizeof(IDataObject))))
	  return NULL;
	  
	dto->ref=1;
	dto->lpvtbl=&dtovt;
	dto->psf=psf;
	dto->pidl=ILClone(psf->mpidl); /* FIXME:add a reference and don't copy*/

	/* fill the ItemID List List */
	dto->lpill = IDLList_Constructor (8);
	if (! dto->lpill )
	  return NULL;
	  
	dto->lpill->lpvtbl->fnAddItems(dto->lpill, apidl, cidl); 
	
	TRACE(shell,"(%p)->(sf=%p apidl=%p cidl=%u)\n",dto, psf, apidl, cidl);
	return dto;
}
/***************************************************************************
*  IDataObject_QueryInterface
*/
static HRESULT WINAPI IDataObject_QueryInterface (LPDATAOBJECT this, REFIID riid, LPVOID * ppvObj)
{	char    xriid[50];
	WINE_StringFromCLSID((LPCLSID)riid,xriid);
	TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);

	*ppvObj = NULL;

	if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
	{ *ppvObj = this; 
	}
	else if(IsEqualIID(riid, &IID_IDataObject))  /*IDataObject*/
	{ *ppvObj = (IDataObject*)this;
	}   

	if(*ppvObj)
	{ (*(LPDATAOBJECT*)ppvObj)->lpvtbl->fnAddRef(this);      
	  TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
	  return S_OK;
	}
	TRACE(shell,"-- Interface: E_NOINTERFACE\n");
	return E_NOINTERFACE;
}   
/**************************************************************************
*  IDataObject_AddRef
*/
static ULONG WINAPI IDataObject_AddRef(LPDATAOBJECT this)
{	TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
	return ++(this->ref);
}
/**************************************************************************
*  IDataObject_Release
*/
static ULONG WINAPI IDataObject_Release(LPDATAOBJECT this)
{	TRACE(shell,"(%p)->()\n",this);
	if (!--(this->ref)) 
	{ TRACE(shell," destroying IDataObject(%p)\n",this);
	  IDLList_Destructor(this->lpill);
	  HeapFree(GetProcessHeap(),0,this);
	  return 0;
	}
	return this->ref;
}
/**************************************************************************
* DATAOBJECT_InitShellIDList (internal)
*
* NOTES
*  get or register the "Shell IDList Array" clipformat
*/
static BOOL32 DATAOBJECT_InitShellIDList()
{	if (cfShellIDList)
        { return(TRUE);
        }

        cfShellIDList = RegisterClipboardFormat32A(CFSTR_SHELLIDLIST);
        return(cfShellIDList != 0);
}

/**************************************************************************
* DATAOBJECT_InitFileGroupDesc (internal)
*
* NOTES
*  get or register the "FileGroupDescriptor" clipformat
*/
static BOOL32 DATAOBJECT_InitFileGroupDesc()
{	if (cfFileGroupDesc)
        { return(TRUE);
        }

        cfFileGroupDesc = RegisterClipboardFormat32A(CFSTR_FILEDESCRIPTORA);
        return(cfFileGroupDesc != 0);
}
/**************************************************************************
* DATAOBJECT_InitFileContents (internal)
* 
* NOTES
 * get or register the "FileContents" clipformat
*/
static BOOL32 DATAOBJECT_InitFileContents()
{	if (cfFileContents)
        { return(TRUE);
        }

        cfFileContents = RegisterClipboardFormat32A(CFSTR_FILECONTENTS);
        return(cfFileContents != 0);
}


/**************************************************************************
* interface implementation
*/
static HRESULT WINAPI IDataObject_GetData (LPDATAOBJECT this, LPFORMATETC32 pformatetcIn, STGMEDIUM32 *pmedium)
{	char	temp[256];
	UINT32	cItems;
	DWORD	size, size1, size2;
	LPITEMIDLIST pidl;
	LPCIDA pcida;
	HGLOBAL32 hmem;
	
	GetClipboardFormatName32A (pformatetcIn->cfFormat, temp, 256);
	FIXME (shell, "(%p)->(%p %p format=%s)\n", this, pformatetcIn, pmedium, temp);

	if (!DATAOBJECT_InitShellIDList())	/* is the clipformat registred? */
        { return(E_UNEXPECTED);
        }
	
        if (pformatetcIn->cfFormat == cfShellIDList)
        { if (pformatetcIn->ptd==NULL 
		&& (pformatetcIn->dwAspect & DVASPECT_CONTENT) 
		&& pformatetcIn->lindex==-1
		&& (pformatetcIn->tymed&TYMED_HGLOBAL))
	  { cItems = this->lpill->lpvtbl->fnGetCount(this->lpill);
	    if (cItems < 1)
	    { return(E_UNEXPECTED);
	    }
	    pidl = this->lpill->lpvtbl->fnGetElement(this->lpill, 0);

	    pdump(this->pidl);
	    pdump(pidl);
	    
	    /*hack consider only the first item*/
	    cItems = 2;
	    size = sizeof(CIDA) + sizeof (UINT32)*(cItems-1);
	    size1 = ILGetSize (this->pidl);
	    size2 = ILGetSize (pidl);
	    hmem = GlobalAlloc32(GMEM_FIXED, size+size1+size2);
	    pcida = GlobalLock32 (hmem);
	    if (!pcida)
	    { return(E_OUTOFMEMORY);
	    }

	    pcida->cidl = 1;
	    pcida->aoffset[0] = size;
	    pcida->aoffset[1] = size+size1;

	    TRACE(shell,"-- %lu %lu %lu\n",size, size1, size2 );
	    TRACE(shell,"-- %p %p\n",this->pidl, pidl);
	    TRACE(shell,"-- %p %p %p\n",pcida, (void*)pcida+size,(void*)pcida+size+size1);
	    
	    memcpy ((void*)pcida+size, this->pidl, size1);
	    memcpy ((void*)pcida+size+size1, pidl, size2);
	    TRACE(shell,"-- after copy\n");

	    GlobalUnlock32(hmem);
	    
	    pmedium->tymed = TYMED_HGLOBAL;
	    pmedium->u.hGlobal = (HGLOBAL32)pcida;
	    pmedium->pUnkForRelease = NULL;
	    TRACE(shell,"-- ready\n");
	    return(NOERROR);
	  }
	}
	FIXME (shell, "-- clipformat not implemented\n");
	return (E_INVALIDARG);
}
static HRESULT WINAPI IDataObject_GetDataHere(LPDATAOBJECT this, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium)
{	FIXME (shell, "(%p)->()\n", this);
	return E_NOTIMPL;
}
static HRESULT WINAPI IDataObject_QueryGetData(LPDATAOBJECT this, LPFORMATETC32 pformatetc)
{	FIXME (shell, "(%p)->()\n", this);
	return E_NOTIMPL;
}
static HRESULT WINAPI IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT this, LPFORMATETC32 pformatectIn, LPFORMATETC32 pformatetcOut)
{	FIXME (shell, "(%p)->()\n", this);
	return E_NOTIMPL;
}
static HRESULT WINAPI IDataObject_SetData(LPDATAOBJECT this, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium, BOOL32 fRelease)
{	FIXME (shell, "(%p)->()\n", this);
	return E_NOTIMPL;
}
static HRESULT WINAPI IDataObject_EnumFormatEtc(LPDATAOBJECT this, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
{	FIXME (shell, "(%p)->()\n", this);
	return E_NOTIMPL;
}
static HRESULT WINAPI IDataObject_DAdvise (LPDATAOBJECT this, LPFORMATETC32 *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
{	FIXME (shell, "(%p)->()\n", this);
	return E_NOTIMPL;
}
static HRESULT WINAPI IDataObject_DUnadvise(LPDATAOBJECT this, DWORD dwConnection)
{	FIXME (shell, "(%p)->()\n", this);
	return E_NOTIMPL;
}
static HRESULT WINAPI IDataObject_EnumDAdvise(LPDATAOBJECT this, IEnumSTATDATA **ppenumAdvise)
{	FIXME (shell, "(%p)->()\n", this);
	return E_NOTIMPL;
}
