/*++

  shmenu.cpp

  this is for IShellMenu and related stuff.  eventually all
  of the fsmenu.c functionality should be in here

--*/




class CFMDropTarget : public IDropTarget 
{
public:

    CFMDropTarget();
    ~CFMDropTarget();

    HRESULT Init (
        HWND hwnd, 
        IShellFolder *psf, 
        LPITEMIDLIST pidl,
        DWORD dwFlags);

    // IUnknown methods

    virtual STDMETHODIMP  QueryInterface(REFIID riid, PVOID *ppvObj);
    virtual STDMETHODIMP_(ULONG) AddRef(void);
    virtual STDMETHODIMP_(ULONG) Release(void);

    STDMETHODIMP DragEnter(
        IDataObject *pdata,
        DWORD grfKeyState,
        POINTL pt,
        DWORD *pdwEffect)
    {return _pdrop->DragEnter(pdata, grfKeyState, pt, pdwEffect);}
    
    STDMETHODIMP DragOver( 
        DWORD grfKeyState,
        POINTL pt,
        DWORD *pdwEffect)
    {return _pdrop->DragOver(grfKeyState, pt, pdwEffect);}
    
    STDMETHODIMP DragLeave( void)
    {return _pdrop->DragLeave();}
    
    STDMETHODIMP  Drop( 
        IDataObject *pDataObj,
        DWORD grfKeyState,
        POINTL pt,
        DWORD *pdwEffect)
    {return _pdrop->Drop(pDataObj, grfKeyState, pt, pdwEffect);}

private:

    ULONG _cRef;
    IShellFolder *_psf;     //  the psf to use...
    LPITEMIDLIST _pidl;
    DWORD _dwFlags;
    IDropTarget *_pdrop;      //  the actual droptarget


}

CFMDropTarget :: CFMDropTarget ()
{
    _cRef = 1;
    DllAddRef();
}

CFMDropTarget :: ~CFMDropTarget ()
{
    SAFERELEASE(_psf);
    if(pidl)
        ILFree(pidl);
    SAFERELEASE(_pdrop);
    DllRelease();
}

HRESULT
CFMDropTarget :: QueryInterface(REFIID riid, PVOID *ppvObj)
{
    HRESULT hr = E_NOINTERFACE;


    *ppvObj = NULL;

    if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDropTarget))
    {
        AddRef();
        *ppvObj = (LPVOID) SAFECAST(this, IDropTarget*);
        hr = S_OK;

    }

    return hr;
}


ULONG
CFMDropTarget :: AddRef(void)
{

    _cRef++;

    return _cRef;

}

ULONG
CFMDropTarget :: Release(void)
{
    ASSERT (_cRef > 0);

    cRef--;

    if (!cRef)
    {
        //time to go bye bye
        delete this;
        return 0;
    }

    return cRef;

}

// FEATURE: ZEKEL we are just using the psf here...we need to support more
HRESULT Init (
        HWND hwnd, 
        IShellFolder *psf, 
        LPITEMIDLIST pidl,
        DWORD dwFlags)
{
    HRESULT hr = E_INVALIDARG;

    if(psf)
        hr = psf->QueryInterface(IID_IShellFolder, (LPVOID *) &_psf);

    _pidl = ILClone(pidl);
    _dwFlags = dwFlags;

    if(SUCCEEDED(hr) && _psf && _pidl)
    {
        hr = _psf->CreateViewObject(hwnd, IID_IDropTarget, (LPVOID*) &_pdrop);
    }

    return hr;
}

//FEATURE: ZEKEL right now this doesnt support ordering, and assumes that you 
//want to drop right onto the current menu.  this is just a start.
//pidl and dwFlags are just dummy params
HRESULT
CFMDropTarget_CreateAndInit(
                            HWND hwnd, 
                            IShellFolder *psf, 
                            LPITEMIDLIST pidl,
                            DWORD dwFlags,
                            LPVOID *ppvObj)
{
    HRESULT hr = E_OUTOFMEMORY;
    CFMDropTarget *pdt;

    ASSERT(ppvObj)
    if(ppvObj)
        *ppvObj = NULL;
    else
        return E_INVALIDARG;


    pdt = new CFMDropTargetNULL;

    if (pdt)
    {
        hr = pdt->Init(hwnd, psf, pidl, dwFlags);

        if (SUCCEEDED(hr))
            *ppvObj= SAFECAST(pdt, IDropTarget * );
        else
            pdt->Release();
    }
    
    return hr;
}

    if (psf)
    {


        hr = psf->QueryInterface(IID_IShellFolder, (LPVOID *) &psfMine);

        if(SUCCEEDED(hr) && psfMine)
        {


    }


#if 0  // ZEKEL
    {
        if(pmgoi->dwFlags & (MNGO_TOPGAP | MNGO_BOTTOMGAP))
        {
            //then we need to use the current psf as the droptarget
            // and the pidl is just a marker
        }
        else
        {
            //  we need to use the pidl's psf as the droptarget if possible
                DWORD dwAttr = SFGAO_DROPTARGET;
                hr = psf->lpVtbl->GetAttributesOf(1, (LPCITEMIDLIST*)&pfmi->pidl, &dwAttr);
                if (SUCCEEDED(hres) && (dwAttr & SFGAO_DROPTARGET))
                {
                    hr = psf->lpVtbl->GetUIObjectOf(hwnd, 1, (LPCITEMIDLIST*)&pfmi->pidl,
                                              IID_IDropTarget, NULL, (LPVOID*)&_pdropgtCur);
                }
        }
#endif