/*
 *	Copyright 1997	Marcus Meissner
 *	Copyright 1998	Juergen Schmied
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "objbase.h"
#include "undocshell.h"
#include "shlguid.h"

#include "wine/debug.h"

#include "pidl.h"
#include "shell32_main.h"
#include "shfldr.h"
#include "shresdef.h"

WINE_DEFAULT_DEBUG_CHANNEL(shell);

/***********************************************************************
*   IExtractIconW implementation
*/
typedef struct
{
        IExtractIconW      IExtractIconW_iface;
        IExtractIconA      IExtractIconA_iface;
        IPersistFile       IPersistFile_iface;
	LONG               ref;
	LPITEMIDLIST       pidl;
} IExtractIconWImpl;

static inline IExtractIconWImpl *impl_from_IExtractIconW(IExtractIconW *iface)
{
    return CONTAINING_RECORD(iface, IExtractIconWImpl, IExtractIconW_iface);
}

static inline IExtractIconWImpl *impl_from_IExtractIconA(IExtractIconA *iface)
{
    return CONTAINING_RECORD(iface, IExtractIconWImpl, IExtractIconA_iface);
}

static inline IExtractIconWImpl *impl_from_IPersistFile(IPersistFile *iface)
{
    return CONTAINING_RECORD(iface, IExtractIconWImpl, IPersistFile_iface);
}


/**************************************************************************
 *  IExtractIconW::QueryInterface
 */
static HRESULT WINAPI IExtractIconW_fnQueryInterface(IExtractIconW *iface, REFIID riid,
        void **ppv)
{
    IExtractIconWImpl *This = impl_from_IExtractIconW(iface);

    TRACE("(%p)->(\n\tIID:\t%s,%p)\n", This, debugstr_guid(riid), ppv);

    *ppv = NULL;
    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IExtractIconW))
        *ppv = iface;
    else if (IsEqualIID(riid, &IID_IPersistFile))
        *ppv = &This->IPersistFile_iface;
    else if (IsEqualIID(riid, &IID_IExtractIconA))
        *ppv = &This->IExtractIconA_iface;

    if(*ppv)
    {
        IUnknown_AddRef((IUnknown*)*ppv);
        TRACE("-- Interface: (%p)->(%p)\n", ppv, *ppv);
        return S_OK;
    }
    TRACE("-- Interface: E_NOINTERFACE\n");
    return E_NOINTERFACE;
}

/**************************************************************************
*  IExtractIconW::AddRef
*/
static ULONG WINAPI IExtractIconW_fnAddRef(IExtractIconW * iface)
{
        IExtractIconWImpl *This = impl_from_IExtractIconW(iface);
	ULONG refCount = InterlockedIncrement(&This->ref);

	TRACE("(%p)->(count=%u)\n", This, refCount - 1);

	return refCount;
}
/**************************************************************************
*  IExtractIconW::Release
*/
static ULONG WINAPI IExtractIconW_fnRelease(IExtractIconW * iface)
{
        IExtractIconWImpl *This = impl_from_IExtractIconW(iface);
	ULONG refCount = InterlockedDecrement(&This->ref);

	TRACE("(%p)->(count=%u)\n", This, refCount + 1);

	if (!refCount)
	{
	  TRACE(" destroying IExtractIcon(%p)\n",This);
	  SHFree(This->pidl);
	  HeapFree(GetProcessHeap(),0,This);
	  return 0;
	}
	return refCount;
}

static HRESULT getIconLocationForFolder(IExtractIconWImpl *This, UINT uFlags, LPWSTR szIconFile,
        UINT cchMax, int *piIndex, UINT *pwFlags)
{
    int icon_idx;
    WCHAR wszPath[MAX_PATH];
    WCHAR wszCLSIDValue[CHARS_IN_GUID];
    static const WCHAR shellClassInfo[] = { '.','S','h','e','l','l','C','l','a','s','s','I','n','f','o',0 };
    static const WCHAR iconFile[] = { 'I','c','o','n','F','i','l','e',0 };
    static const WCHAR clsid[] = { 'C','L','S','I','D',0 };
    static const WCHAR clsid2[] = { 'C','L','S','I','D','2',0 };
    static const WCHAR iconIndex[] = { 'I','c','o','n','I','n','d','e','x',0 };

    if (SHELL32_GetCustomFolderAttribute(This->pidl, shellClassInfo, iconFile,
        wszPath, MAX_PATH))
    {
        WCHAR wszIconIndex[10];
        SHELL32_GetCustomFolderAttribute(This->pidl, shellClassInfo, iconIndex,
            wszIconIndex, 10);
        *piIndex = atoiW(wszIconIndex);
    }
    else if (SHELL32_GetCustomFolderAttribute(This->pidl, shellClassInfo, clsid,
        wszCLSIDValue, CHARS_IN_GUID) &&
        HCR_GetDefaultIconW(wszCLSIDValue, szIconFile, cchMax, &icon_idx))
    {
       *piIndex = icon_idx;
    }
    else if (SHELL32_GetCustomFolderAttribute(This->pidl, shellClassInfo, clsid2,
        wszCLSIDValue, CHARS_IN_GUID) &&
        HCR_GetDefaultIconW(wszCLSIDValue, szIconFile, cchMax, &icon_idx))
    {
       *piIndex = icon_idx;
    }
    else
    {
        static const WCHAR folder[] = { 'F','o','l','d','e','r',0 };

        if (!HCR_GetDefaultIconW(folder, szIconFile, cchMax, &icon_idx))
        {
            lstrcpynW(szIconFile, swShell32Name, cchMax);
            icon_idx = -IDI_SHELL_FOLDER;
        }

        if (uFlags & GIL_OPENICON)
            *piIndex = icon_idx<0? icon_idx-1: icon_idx+1;
        else
            *piIndex = icon_idx;
    }

    return S_OK;
}

WCHAR swShell32Name[MAX_PATH];

/**************************************************************************
*  IExtractIconW::GetIconLocation
*
* mapping filetype to icon
*/
static HRESULT WINAPI IExtractIconW_fnGetIconLocation(IExtractIconW * iface, UINT uFlags,
        LPWSTR szIconFile, UINT cchMax, int * piIndex, UINT * pwFlags)
{
        IExtractIconWImpl *This = impl_from_IExtractIconW(iface);
	char	sTemp[MAX_PATH];
	int		icon_idx;
	GUID const * riid;
	LPITEMIDLIST	pSimplePidl = ILFindLastID(This->pidl);

	TRACE("(%p) (flags=%u %p %u %p %p)\n", This, uFlags, szIconFile, cchMax, piIndex, pwFlags);

	if (pwFlags)
	  *pwFlags = 0;

	if (_ILIsDesktop(pSimplePidl))
	{
	  lstrcpynW(szIconFile, swShell32Name, cchMax);
	  *piIndex = -IDI_SHELL_DESKTOP;
	}

	/* my computer and other shell extensions */
	else if ((riid = _ILGetGUIDPointer(pSimplePidl)))
	{
	  static const WCHAR fmt[] = { 'C','L','S','I','D','\\',
       '{','%','0','8','l','x','-','%','0','4','x','-','%','0','4','x','-',
       '%','0','2','x','%','0','2','x','-','%','0','2','x', '%','0','2','x',
       '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','}',0 };
	  WCHAR xriid[50];

	  sprintfW(xriid, fmt,
	          riid->Data1, riid->Data2, riid->Data3,
	          riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
	          riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]);

	  if (HCR_GetDefaultIconW(xriid, szIconFile, cchMax, &icon_idx))
	  {
	    *piIndex = icon_idx;
	  }
	  else
	  {
	    lstrcpynW(szIconFile, swShell32Name, cchMax);
            if(IsEqualGUID(riid, &CLSID_MyComputer))
                *piIndex = -IDI_SHELL_MY_COMPUTER;
            else if(IsEqualGUID(riid, &CLSID_MyDocuments))
                *piIndex = -IDI_SHELL_MY_DOCUMENTS;
            else if(IsEqualGUID(riid, &CLSID_NetworkPlaces))
                *piIndex = -IDI_SHELL_MY_NETWORK_PLACES;
            else if(IsEqualGUID(riid, &CLSID_UnixFolder) ||
                    IsEqualGUID(riid, &CLSID_UnixDosFolder))
                *piIndex = -IDI_SHELL_DRIVE;
            else
                *piIndex = -IDI_SHELL_FOLDER;
	  }
	}

	else if (_ILIsDrive (pSimplePidl))
	{
	  static const WCHAR drive[] = { 'D','r','i','v','e',0 };

	  int icon_idx = -1;

	  if (_ILGetDrive(pSimplePidl, sTemp, MAX_PATH))
	  {
		switch(GetDriveTypeA(sTemp))
		{
                  case DRIVE_REMOVABLE:   icon_idx = IDI_SHELL_FLOPPY;        break;
                  case DRIVE_CDROM:       icon_idx = IDI_SHELL_CDROM;         break;
                  case DRIVE_REMOTE:      icon_idx = IDI_SHELL_NETDRIVE;      break;
                  case DRIVE_RAMDISK:     icon_idx = IDI_SHELL_RAMDISK;       break;
		}
	  }

	  if (icon_idx != -1)
	  {
		lstrcpynW(szIconFile, swShell32Name, cchMax);
		*piIndex = -icon_idx;
	  }
	  else
	  {
		if (HCR_GetDefaultIconW(drive, szIconFile, cchMax, &icon_idx))
		{
		  *piIndex = icon_idx;
		}
		else
		{
		  lstrcpynW(szIconFile, swShell32Name, cchMax);
		  *piIndex = -IDI_SHELL_DRIVE;
		}
	  }
	}
	else if (_ILIsFolder (pSimplePidl))
	{
            getIconLocationForFolder(This, uFlags, szIconFile, cchMax, piIndex, pwFlags);
	}
	else
	{
	  BOOL found = FALSE;

	  if (_ILIsCPanelStruct(pSimplePidl))
	  {
	    if (SUCCEEDED(CPanel_GetIconLocationW(pSimplePidl, szIconFile, cchMax, piIndex)))
		found = TRUE;
	  }
	  else if (_ILGetExtension(pSimplePidl, sTemp, MAX_PATH))
	  {
	    if (HCR_MapTypeToValueA(sTemp, sTemp, MAX_PATH, TRUE)
		&& HCR_GetDefaultIconA(sTemp, sTemp, MAX_PATH, &icon_idx))
	    {
	      if (!lstrcmpA("%1", sTemp))		/* icon is in the file */
	      {
		SHGetPathFromIDListW(This->pidl, szIconFile);
		*piIndex = 0;
	      }
	      else
	      {
		MultiByteToWideChar(CP_ACP, 0, sTemp, -1, szIconFile, cchMax);
		*piIndex = icon_idx;
	      }

	      found = TRUE;
	    }
	    else if (!lstrcmpiA(sTemp, "lnkfile"))
	    {
	      /* extract icon from shell shortcut */
	      IShellFolder* dsf;
	      IShellLinkW* psl;

	      if (SUCCEEDED(SHGetDesktopFolder(&dsf)))
	      {
		HRESULT hr = IShellFolder_GetUIObjectOf(dsf, NULL, 1, (LPCITEMIDLIST*)&This->pidl, &IID_IShellLinkW, NULL, (LPVOID*)&psl);

		if (SUCCEEDED(hr))
		{
		  hr = IShellLinkW_GetIconLocation(psl, szIconFile, MAX_PATH, piIndex);

		  if (SUCCEEDED(hr) && *szIconFile)
		    found = TRUE;

		  IShellLinkW_Release(psl);
		}

		IShellFolder_Release(dsf);
	      }
	    }
	  }

	  if (!found)					/* default icon */
	  {
	    lstrcpynW(szIconFile, swShell32Name, cchMax);
	    *piIndex = 0;
	  }
	}

	TRACE("-- %s %x\n", debugstr_w(szIconFile), *piIndex);
	return S_OK;
}

/**************************************************************************
*  IExtractIconW::Extract
*/
static HRESULT WINAPI IExtractIconW_fnExtract(IExtractIconW * iface, LPCWSTR pszFile,
        UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize)
{
        IExtractIconWImpl *This = impl_from_IExtractIconW(iface);
        int index;
        HIMAGELIST big_icons, small_icons;

        FIXME("(%p) (file=%s index=%d %p %p size=%08x) semi-stub\n", This, debugstr_w(pszFile),
                (signed)nIconIndex, phiconLarge, phiconSmall, nIconSize);

        index = SIC_GetIconIndex(pszFile, nIconIndex, 0);
        Shell_GetImageLists( &big_icons, &small_icons );
	if (phiconLarge)
	  *phiconLarge = ImageList_GetIcon(big_icons, index, ILD_TRANSPARENT);

	if (phiconSmall)
	  *phiconSmall = ImageList_GetIcon(small_icons, index, ILD_TRANSPARENT);

	return S_OK;
}

static const IExtractIconWVtbl eivt =
{
	IExtractIconW_fnQueryInterface,
	IExtractIconW_fnAddRef,
	IExtractIconW_fnRelease,
	IExtractIconW_fnGetIconLocation,
	IExtractIconW_fnExtract
};

/**************************************************************************
 *  IExtractIconA::QueryInterface
 */
static HRESULT WINAPI IExtractIconA_fnQueryInterface(IExtractIconA * iface, REFIID riid,
        void **ppv)
{
    IExtractIconWImpl *This = impl_from_IExtractIconA(iface);

    return IExtractIconW_QueryInterface(&This->IExtractIconW_iface, riid, ppv);
}

/**************************************************************************
*  IExtractIconA::AddRef
*/
static ULONG WINAPI IExtractIconA_fnAddRef(IExtractIconA * iface)
{
    IExtractIconWImpl *This = impl_from_IExtractIconA(iface);

    return IExtractIconW_AddRef(&This->IExtractIconW_iface);
}
/**************************************************************************
*  IExtractIconA::Release
*/
static ULONG WINAPI IExtractIconA_fnRelease(IExtractIconA * iface)
{
    IExtractIconWImpl *This = impl_from_IExtractIconA(iface);

    return IExtractIconW_Release(&This->IExtractIconW_iface);
}
/**************************************************************************
*  IExtractIconA::GetIconLocation
*
* mapping filetype to icon
*/
static HRESULT WINAPI IExtractIconA_fnGetIconLocation(IExtractIconA * iface, UINT uFlags,
        LPSTR szIconFile, UINT cchMax, int * piIndex, UINT * pwFlags)
{
        IExtractIconWImpl *This = impl_from_IExtractIconA(iface);
	HRESULT ret;
	LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, cchMax * sizeof(WCHAR));

	TRACE("(%p) (flags=%u %p %u %p %p)\n", This, uFlags, szIconFile, cchMax, piIndex, pwFlags);

        ret = IExtractIconW_GetIconLocation(&This->IExtractIconW_iface, uFlags, lpwstrFile, cchMax,
                piIndex, pwFlags);
	WideCharToMultiByte(CP_ACP, 0, lpwstrFile, -1, szIconFile, cchMax, NULL, NULL);
	HeapFree(GetProcessHeap(), 0, lpwstrFile);

	TRACE("-- %s %x\n", szIconFile, *piIndex);
	return ret;
}
/**************************************************************************
*  IExtractIconA::Extract
*/
static HRESULT WINAPI IExtractIconA_fnExtract(IExtractIconA * iface, LPCSTR pszFile,
        UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize)
{
        IExtractIconWImpl *This = impl_from_IExtractIconA(iface);
	HRESULT ret;
	INT len = MultiByteToWideChar(CP_ACP, 0, pszFile, -1, NULL, 0);
	LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));

	TRACE("(%p) (file=%p index=%u %p %p size=%u)\n", This, pszFile, nIconIndex, phiconLarge, phiconSmall, nIconSize);

	MultiByteToWideChar(CP_ACP, 0, pszFile, -1, lpwstrFile, len);
        ret = IExtractIconW_Extract(&This->IExtractIconW_iface, lpwstrFile, nIconIndex, phiconLarge,
                phiconSmall, nIconSize);
	HeapFree(GetProcessHeap(), 0, lpwstrFile);
	return ret;
}

static const IExtractIconAVtbl eiavt =
{
	IExtractIconA_fnQueryInterface,
	IExtractIconA_fnAddRef,
	IExtractIconA_fnRelease,
	IExtractIconA_fnGetIconLocation,
	IExtractIconA_fnExtract
};

/************************************************************************
 * IEIPersistFile::QueryInterface
 */
static HRESULT WINAPI IEIPersistFile_fnQueryInterface(IPersistFile *iface, REFIID iid,
        void **ppv)
{
    IExtractIconWImpl *This = impl_from_IPersistFile(iface);

    return IExtractIconW_QueryInterface(&This->IExtractIconW_iface, iid, ppv);
}

/************************************************************************
 * IEIPersistFile::AddRef
 */
static ULONG WINAPI IEIPersistFile_fnAddRef(IPersistFile *iface)
{
    IExtractIconWImpl *This = impl_from_IPersistFile(iface);

    return IExtractIconW_AddRef(&This->IExtractIconW_iface);
}

/************************************************************************
 * IEIPersistFile::Release
 */
static ULONG WINAPI IEIPersistFile_fnRelease(IPersistFile *iface)
{
    IExtractIconWImpl *This = impl_from_IPersistFile(iface);

    return IExtractIconW_Release(&This->IExtractIconW_iface);
}

/************************************************************************
 * IEIPersistFile::GetClassID
 */
static HRESULT WINAPI IEIPersistFile_fnGetClassID(IPersistFile *iface, LPCLSID lpClassId)
{
	CLSID StdFolderID = { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };

	if (lpClassId==NULL)
	  return E_POINTER;

	*lpClassId = StdFolderID;

	return S_OK;
}

/************************************************************************
 * IEIPersistFile_Load
 */
static HRESULT WINAPI IEIPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR pszFileName,
        DWORD dwMode)
{
    IExtractIconWImpl *This = impl_from_IPersistFile(iface);

    FIXME("%p\n", This);
    return E_NOTIMPL;
}

static const IPersistFileVtbl pfvt =
{
	IEIPersistFile_fnQueryInterface,
	IEIPersistFile_fnAddRef,
	IEIPersistFile_fnRelease,
	IEIPersistFile_fnGetClassID,
	(void *) 0xdeadbeef /* IEIPersistFile_fnIsDirty */,
	IEIPersistFile_fnLoad,
	(void *) 0xdeadbeef /* IEIPersistFile_fnSave */,
	(void *) 0xdeadbeef /* IEIPersistFile_fnSaveCompleted */,
	(void *) 0xdeadbeef /* IEIPersistFile_fnGetCurFile */
};

static IExtractIconWImpl *extracticon_create(LPCITEMIDLIST pidl)
{
    IExtractIconWImpl *ei;

    TRACE("%p\n", pidl);

    ei = HeapAlloc(GetProcessHeap(), 0, sizeof(*ei));
    ei->ref=1;
    ei->IExtractIconW_iface.lpVtbl = &eivt;
    ei->IExtractIconA_iface.lpVtbl = &eiavt;
    ei->IPersistFile_iface.lpVtbl = &pfvt;
    ei->pidl=ILClone(pidl);

    pdump(pidl);

    TRACE("(%p)\n", ei);
    return ei;
}

IExtractIconW *IExtractIconW_Constructor(LPCITEMIDLIST pidl)
{
    IExtractIconWImpl *ei = extracticon_create(pidl);

    return &ei->IExtractIconW_iface;
}

IExtractIconA *IExtractIconA_Constructor(LPCITEMIDLIST pidl)
{
    IExtractIconWImpl *ei = extracticon_create(pidl);

    return &ei->IExtractIconA_iface;
}
