/*
 * Ole 2 Create functions implementation
 *
 * Copyright (C) 1999-2000 Abey George
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <string.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/debug.h"
#include "ole2.h"
#include "olestd.h"
#include "winreg.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);

#define MAX_CLIPFORMAT_NAME   80

/******************************************************************************
 *		OleQueryCreateFromData [OLE32.117]
 *
 * Author   : Abey George
 * Checks whether an object can become an embedded object.
 * the clipboard or OLE drag and drop.
 * Returns  : S_OK - Format that supports Embedded object creation are present.
 *            OLE_E_STATIC - Format that supports static object creation are present.
 *            S_FALSE - No acceptable format is available.
 */

HRESULT WINAPI OleQueryCreateFromData(LPDATAOBJECT pSrcDataObject)
{
  IEnumFORMATETC *pfmt;
  FORMATETC fmt;
  CHAR szFmtName[MAX_CLIPFORMAT_NAME];
  BOOL bFoundStatic = FALSE;

  HRESULT hr = IDataObject_EnumFormatEtc(pSrcDataObject, DATADIR_GET, &pfmt);

  if (hr == S_OK)
    hr = IEnumFORMATETC_Next(pfmt, 1, &fmt, NULL);

  while (hr == S_OK)
  {
    GetClipboardFormatNameA(fmt.cfFormat, szFmtName, MAX_CLIPFORMAT_NAME-1);

    /* first, Check for Embedded Object, Embed Source or Filename */

    if (!strcmp(szFmtName, CF_EMBEDDEDOBJECT) || !strcmp(szFmtName, CF_EMBEDSOURCE) || !strcmp(szFmtName, CF_FILENAME))
      return S_OK;

    /* Check for Metafile, Bitmap or DIB */

    if (fmt.cfFormat == CF_METAFILEPICT || fmt.cfFormat == CF_BITMAP || fmt.cfFormat == CF_DIB)
      bFoundStatic = TRUE;

    hr = IEnumFORMATETC_Next(pfmt, 1, &fmt, NULL);
  }

  /* Found a static format, but no embed format */

  if (bFoundStatic)
    return OLE_S_STATIC;

  return S_FALSE;
}

/******************************************************************************
 *		OleCreateFromData        [OLE32.92]
 *
 * Author   : Abey George
 * Creates an embedded object from data transfer object retrieved from
 * the clipboard or OLE drag and drop.
 * Returns  : S_OK - Embedded object was created successfully.
 *            OLE_E_STATIC - OLE can create only a static object
 *            DV_E_FORMATETC - No acceptable format is available (only error return code)
 * TODO : CF_FILENAME, CF_EMBEDEDOBJECT formats. Parameter renderopt is currently ignored.
 */

HRESULT WINAPI OleCreateFromData(LPDATAOBJECT pSrcDataObject, REFIID riid,
                DWORD renderopt, LPFORMATETC pFormatEtc,
                LPOLECLIENTSITE pClientSite, LPSTORAGE pStg,
                LPVOID* ppvObj)
{
  IEnumFORMATETC *pfmt;
  FORMATETC fmt;
  CHAR szFmtName[MAX_CLIPFORMAT_NAME];
  STGMEDIUM std;
  HRESULT hr;
  HRESULT hr1;

  hr = IDataObject_EnumFormatEtc(pSrcDataObject, DATADIR_GET, &pfmt);

  if (hr == S_OK)
  {
    memset(&std, 0, sizeof(STGMEDIUM));

    hr = IEnumFORMATETC_Next(pfmt, 1, &fmt, NULL);
    while (hr == S_OK)
    {
      GetClipboardFormatNameA(fmt.cfFormat, szFmtName, MAX_CLIPFORMAT_NAME-1);

      /* first, Check for Embedded Object, Embed Source or Filename */
      /* TODO: Currently checks only for Embed Source. */

      if (!strcmp(szFmtName, CF_EMBEDSOURCE))
      {
        std.tymed = TYMED_HGLOBAL;

        if ((hr1 = IDataObject_GetData(pSrcDataObject, &fmt, &std)) == S_OK)
        {
          ILockBytes *ptrILockBytes = 0;
          IStorage *pStorage = 0;
          IOleObject *pOleObject = 0;
          IPersistStorage *pPersistStorage = 0;
          CLSID clsID;

          /* Create ILock bytes */

          hr1 = CreateILockBytesOnHGlobal(std.u.hGlobal, FALSE, &ptrILockBytes);

          /* Open storage on the ILock bytes */

          if (hr1 == S_OK)
            hr1 = StgOpenStorageOnILockBytes(ptrILockBytes, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &pStorage);

          /* Get Class ID from the opened storage */

          if (hr1 == S_OK)
            hr1 = ReadClassStg(pStorage, &clsID);

          /* Create default handler for Persist storage */

          if (hr1 == S_OK)
            hr1 = OleCreateDefaultHandler(&clsID, NULL, &IID_IPersistStorage, (LPVOID*)&pPersistStorage);

          /* Load the storage to Persist storage */

          if (hr1 == S_OK)
            hr1 = IPersistStorage_Load(pPersistStorage, pStorage);

          /* Query for IOleObject */

          if (hr1 == S_OK)
            hr1 = IPersistStorage_QueryInterface(pPersistStorage, &IID_IOleObject, (LPVOID*)&pOleObject);

          /* Set client site with the IOleObject */

          if (hr1 == S_OK)
            hr1 = IOleObject_SetClientSite(pOleObject, pClientSite);

          IPersistStorage_Release(pPersistStorage);
          /* Query for the requested interface */

          if (hr1 == S_OK)
            hr1 = IPersistStorage_QueryInterface(pPersistStorage, riid, ppvObj);

          IPersistStorage_Release(pPersistStorage);

          IStorage_Release(pStorage);

          if (hr1 == S_OK)
            return S_OK;
        }

        /* Return error */

        return DV_E_FORMATETC;
      }

      hr = IEnumFORMATETC_Next(pfmt, 1, &fmt, NULL);
    }
  }

  return DV_E_FORMATETC;
}

