/*
 * Helper functions for debugging
 *
 * Copyright 1998, 2002 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 <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "windef.h"
#include "wingdi.h"
#include "pidl.h"
#include "shldisp.h"
#include "wine/debug.h"
#include "debughlp.h"
#include "docobj.h"
#include "shell32_main.h"


WINE_DEFAULT_DEBUG_CHANNEL(pidl);

static
LPITEMIDLIST _dbg_ILGetNext(LPCITEMIDLIST pidl)
{
	WORD len;

	if(pidl)
	{
	  len =  pidl->mkid.cb;
	  if (len)
	  {
	    return (LPITEMIDLIST) (((LPBYTE)pidl)+len);
	  }
	}
	return NULL;
}

static
BOOL _dbg_ILIsDesktop(LPCITEMIDLIST pidl)
{
	return ( !pidl || (pidl && pidl->mkid.cb == 0x00) );
}

static
LPPIDLDATA _dbg_ILGetDataPointer(LPCITEMIDLIST pidl)
{
	if(pidl && pidl->mkid.cb != 0x00)
	  return (LPPIDLDATA)pidl->mkid.abID;
	return NULL;
}

static
LPSTR _dbg_ILGetTextPointer(LPCITEMIDLIST pidl)
{
	LPPIDLDATA pdata =_dbg_ILGetDataPointer(pidl);

	if (pdata)
	{
	  switch (pdata->type)
	  {
	    case PT_GUID:
	    case PT_SHELLEXT:
	    case PT_YAGUID:
	      return NULL;

	    case PT_DRIVE:
	    case PT_DRIVE1:
	    case PT_DRIVE2:
	    case PT_DRIVE3:
              return pdata->u.drive.szDriveName;

	    case PT_FOLDER:
	    case PT_FOLDER1:
	    case PT_VALUE:
	    case PT_IESPECIAL1:
	    case PT_IESPECIAL2:
              return pdata->u.file.szNames;

	    case PT_WORKGRP:
	    case PT_COMP:
	    case PT_NETWORK:
	    case PT_NETPROVIDER:
	    case PT_SHARE:
              return pdata->u.network.szNames;
	  }
	}
	return NULL;
}

static
LPWSTR _dbg_ILGetTextPointerW(LPCITEMIDLIST pidl)
{
	LPPIDLDATA pdata =_dbg_ILGetDataPointer(pidl);

	if (pdata)
	{
	  switch (pdata->type)
	  {
	    case PT_GUID:
	    case PT_SHELLEXT:
	    case PT_YAGUID:
	      return NULL;

	    case PT_DRIVE:
	    case PT_DRIVE1:
	    case PT_DRIVE2:
	    case PT_DRIVE3:
	      /* return (LPSTR)&(pdata->u.drive.szDriveName);*/
	      return NULL;

	    case PT_FOLDER:
	    case PT_FOLDER1:
	    case PT_VALUE:
	    case PT_IESPECIAL1:
	    case PT_IESPECIAL2:
	      /* return (LPSTR)&(pdata->u.file.szNames); */
	      return NULL;

	    case PT_WORKGRP:
	    case PT_COMP:
	    case PT_NETWORK:
	    case PT_NETPROVIDER:
	    case PT_SHARE:
	      /* return (LPSTR)&(pdata->u.network.szNames); */
	      return NULL;

	    case PT_VALUEW:
	      return (LPWSTR)pdata->u.file.szNames;
	  }
	}
	return NULL;
}


static
LPSTR _dbg_ILGetSTextPointer(LPCITEMIDLIST pidl)
{
	LPPIDLDATA pdata =_dbg_ILGetDataPointer(pidl);

	if (pdata)
	{
	  switch (pdata->type)
	  {
	    case PT_FOLDER:
	    case PT_VALUE:
	    case PT_IESPECIAL1:
	    case PT_IESPECIAL2:
              return pdata->u.file.szNames + strlen (pdata->u.file.szNames) + 1;

	    case PT_WORKGRP:
              return pdata->u.network.szNames + strlen (pdata->u.network.szNames) + 1;
	  }
	}
	return NULL;
}

static
LPWSTR _dbg_ILGetSTextPointerW(LPCITEMIDLIST pidl)
{
	LPPIDLDATA pdata =_dbg_ILGetDataPointer(pidl);

	if (pdata)
	{
	  switch (pdata->type)
	  {
	    case PT_FOLDER:
	    case PT_VALUE:
	    case PT_IESPECIAL1:
	    case PT_IESPECIAL2:
	      /*return (LPSTR)(pdata->u.file.szNames + strlen (pdata->u.file.szNames) + 1); */
	      return NULL;

	    case PT_WORKGRP:
	      /* return (LPSTR)(pdata->u.network.szNames + strlen (pdata->u.network.szNames) + 1); */
	      return NULL;

	    case PT_VALUEW:
	      return (LPWSTR)(pdata->u.file.szNames + lstrlenW ((LPWSTR)pdata->u.file.szNames) + 1);
	  }
	}
	return NULL;
}


static
IID* _dbg_ILGetGUIDPointer(LPCITEMIDLIST pidl)
{
	LPPIDLDATA pdata =_ILGetDataPointer(pidl);

	if (pdata)
	{
	  switch (pdata->type)
	  {
	    case PT_SHELLEXT:
	    case PT_GUID:
            case PT_YAGUID:
	      return &(pdata->u.guid.guid);
	  }
	}
	return NULL;
}

static
void _dbg_ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR szOut, UINT uOutSize)
{
	LPSTR		szSrc;
	LPWSTR		szSrcW;
	GUID const * 	riid;

	if (!pidl) return;

	if (szOut)
	  *szOut = 0;

	if (_dbg_ILIsDesktop(pidl))
	{
	 /* desktop */
	  if (szOut) lstrcpynA(szOut, "Desktop", uOutSize);
	}
	else if (( szSrc = _dbg_ILGetTextPointer(pidl) ))
	{
	  /* filesystem */
	  if (szOut) lstrcpynA(szOut, szSrc, uOutSize);
	}
	else if (( szSrcW = _dbg_ILGetTextPointerW(pidl) ))
	{
	  CHAR tmp[MAX_PATH];
	  /* unicode filesystem */
	  WideCharToMultiByte(CP_ACP,0,szSrcW, -1, tmp, MAX_PATH, NULL, NULL);
	  if (szOut) lstrcpynA(szOut, tmp, uOutSize);
	}
	else if (( riid = _dbg_ILGetGUIDPointer(pidl) ))
	{
	  if (szOut)
            sprintf( szOut, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
                 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] );
	}
}




void pdump (LPCITEMIDLIST pidl)
{
	LPCITEMIDLIST pidltemp = pidl;

	if (!TRACE_ON(pidl)) return;

	if (! pidltemp)
	{
	  MESSAGE ("-------- pidl=NULL (Desktop)\n");
	}
	else
	{
	  MESSAGE ("-------- pidl=%p\n", pidl);
	  if (pidltemp->mkid.cb)
	  {
	    do
	    {
          if (_ILIsUnicode(pidltemp))
          {
              DWORD dwAttrib = 0;
              LPPIDLDATA pData   = _dbg_ILGetDataPointer(pidltemp);
              DWORD type = pData ? pData->type : 0;
              LPWSTR szLongName   = _dbg_ILGetTextPointerW(pidltemp);
              LPWSTR szShortName  = _dbg_ILGetSTextPointerW(pidltemp);
              char szName[MAX_PATH];

              _dbg_ILSimpleGetText(pidltemp, szName, MAX_PATH);
              if ( pData && (PT_FOLDER == type || PT_VALUE == type) )
                dwAttrib = pData->u.file.uFileAttribs;

              MESSAGE ("[%p] size=%04u type=%x attr=0x%08x name=%s (%s,%s)\n",
                       pidltemp, pidltemp->mkid.cb, type, dwAttrib,
                           debugstr_a(szName), debugstr_w(szLongName), debugstr_w(szShortName));
          }
          else
          {
              DWORD dwAttrib = 0;
              LPPIDLDATA pData   = _dbg_ILGetDataPointer(pidltemp);
              DWORD type = pData ? pData->type : 0;
              LPSTR szLongName   = _dbg_ILGetTextPointer(pidltemp);
              LPSTR szShortName  = _dbg_ILGetSTextPointer(pidltemp);
              char szName[MAX_PATH];

              _dbg_ILSimpleGetText(pidltemp, szName, MAX_PATH);
              if ( pData && (PT_FOLDER == type || PT_VALUE == type) )
                dwAttrib = pData->u.file.uFileAttribs;

              MESSAGE ("[%p] size=%04u type=%x attr=0x%08x name=%s (%s,%s)\n",
                       pidltemp, pidltemp->mkid.cb, type, dwAttrib,
                           debugstr_a(szName), debugstr_a(szLongName), debugstr_a(szShortName));
          }

	      pidltemp = _dbg_ILGetNext(pidltemp);

	    } while (pidltemp && pidltemp->mkid.cb);
	  }
	  else
	  {
	    MESSAGE ("empty pidl (Desktop)\n");
	  }
	  pcheck(pidl);
	}
}

static void dump_pidl_hex( LPCITEMIDLIST pidl )
{
    const unsigned char *p = (const unsigned char *)pidl;
    const int max_bytes = 0x80;
#define max_line 0x10
    char szHex[max_line*3+1], szAscii[max_line+1];
    int i, n;

    n = pidl->mkid.cb;
    if( n>max_bytes )
        n = max_bytes;
    for( i=0; i<n; i++ )
    {
        sprintf( &szHex[ (i%max_line)*3 ], "%02X ", p[i] );
        szAscii[ (i%max_line) ] = isprint( p[i] ) ? p[i] : '.';

        /* print out at the end of each line and when we're finished */
        if( i!=(n-1) && (i%max_line) != (max_line-1) )
            continue;
        szAscii[ (i%max_line)+1 ] = 0;
        ERR("%-*s   %s\n", max_line*3, szHex, szAscii );
    }
}

BOOL pcheck( LPCITEMIDLIST pidl )
{
    DWORD type;
    LPCITEMIDLIST pidltemp = pidl;

    while( pidltemp && pidltemp->mkid.cb )
    {
        type = _dbg_ILGetDataPointer(pidltemp)->type;
        switch( type )
        {
        case PT_CPLAPPLET:
        case PT_GUID:
        case PT_SHELLEXT:
        case PT_DRIVE:
        case PT_DRIVE1:
        case PT_DRIVE2:
        case PT_DRIVE3:
        case PT_FOLDER:
        case PT_VALUE:
        case PT_VALUEW:
        case PT_FOLDER1:
        case PT_WORKGRP:
        case PT_COMP:
        case PT_NETPROVIDER:
        case PT_NETWORK:
        case PT_IESPECIAL1:
        case PT_YAGUID:
        case PT_IESPECIAL2:
        case PT_SHARE:
            break;
        default:
            ERR("unknown IDLIST %p [%p] size=%u type=%x\n",
                pidl, pidltemp, pidltemp->mkid.cb,type );
            dump_pidl_hex( pidltemp );
            return FALSE;
        }
        pidltemp = _dbg_ILGetNext(pidltemp);
    }
    return TRUE;
}

static const struct {
	REFIID riid;
	const char *name;
} InterfaceDesc[] = {
	{&IID_IUnknown,			"IID_IUnknown"},
	{&IID_IClassFactory,		"IID_IClassFactory"},
	{&IID_IShellView,		"IID_IShellView"},
	{&IID_IOleCommandTarget,	"IID_IOleCommandTarget"},
	{&IID_IDropTarget,		"IID_IDropTarget"},
	{&IID_IDropSource,		"IID_IDropSource"},
	{&IID_IViewObject,		"IID_IViewObject"},
	{&IID_IContextMenu,		"IID_IContextMenu"},
	{&IID_IShellExtInit,		"IID_IShellExtInit"},
	{&IID_IShellFolder,		"IID_IShellFolder"},
	{&IID_IShellFolder2,		"IID_IShellFolder2"},
	{&IID_IPersist,			"IID_IPersist"},
	{&IID_IPersistFolder,		"IID_IPersistFolder"},
	{&IID_IPersistFolder2,		"IID_IPersistFolder2"},
	{&IID_IPersistFolder3,		"IID_IPersistFolder3"},
	{&IID_IExtractIconA,		"IID_IExtractIconA"},
	{&IID_IExtractIconW,		"IID_IExtractIconW"},
	{&IID_IDataObject,		"IID_IDataObject"},
	{&IID_IAutoComplete,            "IID_IAutoComplete"},
	{&IID_IAutoComplete2,           "IID_IAutoComplete2"},
        {&IID_IShellLinkA,              "IID_IShellLinkA"},
        {&IID_IShellLinkW,              "IID_IShellLinkW"},
	{NULL,NULL}};

const char * shdebugstr_guid( const struct _GUID *id )
{
	int i;
	const char* name = NULL;
	char clsidbuf[100];

	if (!id) return "(null)";

	    for (i=0;InterfaceDesc[i].riid && !name;i++) {
	        if (IsEqualIID(InterfaceDesc[i].riid, id)) name = InterfaceDesc[i].name;
	    }
	    if (!name) {
		if (HCR_GetClassNameA(id, clsidbuf, 100))
		    name = clsidbuf;
	    }

            return wine_dbg_sprintf( "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x} (%s)",
                 id->Data1, id->Data2, id->Data3,
                 id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
                 id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7], name ? name : "unknown" );
}
