/*
 *	Shell Folder stuff (...and all the OLE-Objects of SHELL32.DLL)
 *
 *	Copyright 1997	Marcus Meissner
 *	Copyright 1998	Juergen Schmied
 *
 *  !!! currently work in progress on all classes !!!
 *  <contact juergen.schmied@metronet.de, 980801>
 */

#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "ole.h"
#include "ole2.h"
#include "debug.h"
#include "compobj.h"
#include "interfaces.h"
#include "shlobj.h"
#include "shell.h"
#include "winerror.h"
#include "winnls.h"
#include "winproc.h"
#include "commctrl.h"

#include "shell32_main.h"


/******************************************************************************
* foreward declaration
*/

/* IExtractIcon implementation*/
static HRESULT WINAPI IExtractIcon_QueryInterface(LPEXTRACTICON, REFIID, LPVOID *);
static ULONG WINAPI IExtractIcon_AddRef(LPEXTRACTICON);
static ULONG WINAPI IExtractIcon_AddRef(LPEXTRACTICON);
static ULONG WINAPI IExtractIcon_Release(LPEXTRACTICON);
static HRESULT WINAPI IExtractIcon_GetIconLocation(LPEXTRACTICON, UINT32, LPSTR, UINT32, int *, UINT32 *);
static HRESULT WINAPI IExtractIcon_Extract(LPEXTRACTICON, LPCSTR, UINT32, HICON32 *, HICON32 *, UINT32);

/* IShellLink Implementation */
static HRESULT WINAPI IShellLink_QueryInterface(LPSHELLLINK,REFIID,LPVOID*);
static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK);
static ULONG WINAPI IShellLink_Release(LPSHELLLINK);


/***********************************************************************
*   IExtractIcon implementation
*/
static struct IExtractIcon_VTable eivt = 
{ IExtractIcon_QueryInterface,
  IExtractIcon_AddRef,
  IExtractIcon_Release,
  IExtractIcon_GetIconLocation,
  IExtractIcon_Extract
};
/**************************************************************************
*  IExtractIcon_Constructor
*/
LPEXTRACTICON IExtractIcon_Constructor(LPCITEMIDLIST pidl)
{ LPEXTRACTICON ei;
  ei=(LPEXTRACTICON)HeapAlloc(GetProcessHeap(),0,sizeof(IExtractIcon));
  ei->ref=1;
  ei->lpvtbl=&eivt;
  ei->pidl=ILClone(pidl);
  
  TRACE(shell,"(%p)\n",ei);
  return ei;
}
/**************************************************************************
 *  IExtractIcon_QueryInterface
 */
static HRESULT WINAPI IExtractIcon_QueryInterface( LPEXTRACTICON 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_IExtractIcon))  /*IExtractIcon*/
  {    *ppvObj = (IExtractIcon*)this;
  }   

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

/**************************************************************************
*  IExtractIcon_AddRef
*/
static ULONG WINAPI IExtractIcon_AddRef(LPEXTRACTICON this)
{ TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
  return ++(this->ref);
}
/**************************************************************************
*  IExtractIcon_Release
*/
static ULONG WINAPI IExtractIcon_Release(LPEXTRACTICON this)
{ TRACE(shell,"(%p)->()\n",this);
  if (!--(this->ref)) 
  { TRACE(shell," destroying IExtractIcon(%p)\n",this);
    SHFree(this->pidl);
    HeapFree(GetProcessHeap(),0,this);
    return 0;
  }
  return this->ref;
}
/**************************************************************************
*  IExtractIcon_GetIconLocation
* NOTE
*  FIXME returns allways the icon no. 3 (closed Folder)
*/
static HRESULT WINAPI IExtractIcon_GetIconLocation(LPEXTRACTICON this, UINT32 uFlags, LPSTR szIconFile, UINT32 cchMax, int * piIndex, UINT32 * pwFlags)
{ FIXME (shell,"(%p) (flags=%u file=%s max=%u %p %p) semi-stub\n", this, uFlags, szIconFile, cchMax, piIndex, pwFlags);
	if (!szIconFile)
	{ *piIndex = 20;
	}
	else
	{ *piIndex = 3;
	}
	*pwFlags = GIL_NOTFILENAME;

	return NOERROR;
}
/**************************************************************************
*  IExtractIcon_Extract
*/
static HRESULT WINAPI IExtractIcon_Extract(LPEXTRACTICON this, LPCSTR pszFile, UINT32 nIconIndex, HICON32 *phiconLarge, HICON32 *phiconSmall, UINT32 nIconSize)
{ FIXME (shell,"(%p) (file=%s index=%u %p %p size=%u) semi-stub\n", this, pszFile, nIconIndex, phiconLarge, phiconSmall, nIconSize);
  *phiconLarge = pImageList_GetIcon(ShellBigIconList, nIconIndex, ILD_TRANSPARENT);
  *phiconSmall = pImageList_GetIcon(ShellSmallIconList, nIconIndex, ILD_TRANSPARENT);
  return S_OK;
}

/**************************************************************************
* IShellLink Implementation
*/

static struct IShellLink_VTable slvt = {
  IShellLink_QueryInterface,
  IShellLink_AddRef,
  IShellLink_Release,
    (void *)0xcafe0004,
    (void *)0xcafe0005,
    (void *)0xcafe0006,
    (void *)0xcafe0007,
    (void *)0xcafe0008,
    (void *)0xcafe0009,
    (void *)0xcafe0010,
    (void *)0xcafe0011,
    (void *)0xcafe0012,
    (void *)0xcafe0013,
    (void *)0xcafe0014,
    (void *)0xcafe0015,
    (void *)0xcafe0016,
    (void *)0xcafe0017,
    (void *)0xcafe0018,
    (void *)0xcafe0019,
    (void *)0xcafe0020,
    (void *)0xcafe0021
};

/**************************************************************************
 *	  IShellLink_Constructor
 */
LPSHELLLINK IShellLink_Constructor() 
{	LPSHELLLINK sl;

	sl = (LPSHELLLINK)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLink));
	sl->ref = 1;
	sl->lpvtbl = &slvt;
	TRACE(shell,"(%p)->()\n",sl);
	return sl;
}

/**************************************************************************
 *  IShellLink::QueryInterface
 */
static HRESULT WINAPI IShellLink_QueryInterface(
  LPSHELLLINK this, REFIID riid, LPVOID *ppvObj)
{  char    xriid[50];
   WINE_StringFromCLSID((LPCLSID)riid,xriid);
   TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid);

  *ppvObj = NULL;

  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
  { *ppvObj = this; 
  }
  else if(IsEqualIID(riid, &IID_IShellLink))  /*IShellLink*/
  {    *ppvObj = (LPSHELLLINK)this;
  }   

  if(*ppvObj)
  { (*(LPSHELLLINK*)ppvObj)->lpvtbl->fnAddRef(this);      
    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
    return S_OK;
  }
    TRACE(shell,"-- Interface: E_NOINTERFACE\n");
  return E_NOINTERFACE;
}  
/******************************************************************************
 * IShellLink_AddRef
 */
static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK this)
{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
    return ++(this->ref);
}
/******************************************************************************
 * IClassFactory_Release
 */
static ULONG WINAPI IShellLink_Release(LPSHELLLINK this)
{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
  if (!--(this->ref)) 
  { TRACE(shell,"-- destroying IShellLink(%p)\n",this);
    HeapFree(GetProcessHeap(),0,this);
    return 0;
  }
  return this->ref;
}


