/* Uprising - Windows Shell Extension for Subversion
 * Copyright (C) 2001-2002  Jay Freeman (saurik)
*/

/*
 *        Redistribution and use in source and binary
 * forms, with or without modification, are permitted
 * provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the
 *    above copyright notice, this list of conditions
 *    and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the
 *    above copyright notice, this list of conditions
 *    and the following disclaimer in the documentation
 *    and/or other materials provided with the
 *    distribution.
 * 3. The name of the author may not be used to endorse
 *    or promote products derived from this software
 *    without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "stdafx.h"
#include "diapexis/ComRefactor.h"

#include "General.h"
#include "Resource.h"
#include "Status.h"

namespace Uprising {

UINT CALLBACK PageCallbackProc(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp) {
    General *general = reinterpret_cast<General *>(ppsp->lParam);

    if (uMsg == PSPCB_RELEASE) {
        //free ( (void*) ppsp->lParam );
        general->_uk().Release();
    }

    return 1;
}

BOOL CALLBACK PageDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
        case WM_ERASEBKGND:
            ::MessageBox(NULL, L"WM_ERASEBKGND", L"Message", MB_OK);
        break;
    }

    return FALSE;
}

STDMETHODIMP General::Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pDataObj, HKEY hProgID) {
    FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
    STGMEDIUM stg;

    if (FAILED(pDataObj->GetData(&etc, &stg)))
        return E_INVALIDARG;

    HDROP hDrop = (HDROP) ::GlobalLock(stg.hGlobal);
    if (hDrop == NULL) {
        ::ReleaseStgMedium(&stg);
        return E_INVALIDARG;
    }

    UINT uNumFiles = ::DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);

    apr_pool_t *pool;
    apr_pool_create(&pool, NULL);
    svn_error_init_pool(pool);

    char evilbuf[MAX_PATH];
    TCHAR szFile[MAX_PATH];

    bool applicable(false);

    for (UINT uFile(0); uFile < uNumFiles; ++uFile) {
        if (0 == ::DragQueryFile(hDrop, uFile, szFile, MAX_PATH))
            continue;
        _snprintf(evilbuf, MAX_PATH, "%S", szFile);
        svn_stringbuf_t *pathbuf = svn_stringbuf_create(evilbuf, pool);
        svn_path_internal_style(pathbuf);

        svn_wc_status_t *status = NULL;
        svn_wc_status(&status, pathbuf, pool);

        if (status == NULL ||
            status->text_status == svn_wc_status_unversioned ||
            status->text_status == svn_wc_status_none
        ) {
            continue;
        }

        applicable = true;
    }

    ::GlobalUnlock(stg.hGlobal);
    ::ReleaseStgMedium(&stg);
    apr_pool_destroy(pool);

    return applicable ? S_OK : E_FAIL;
}

STDMETHODIMP General::AddPages(LPFNSVADDPROPSHEETPAGE pfnAddPage, LPARAM lParam) {
    PROPSHEETPAGE psp;

    psp.dwSize		= sizeof(psp);
    psp.dwFlags		= PSP_USEREFPARENT | PSP_USETITLE | PSP_USECALLBACK;
    psp.hInstance	= Diapexis::Module;
    psp.pszTemplate	= MAKEINTRESOURCE(IDD_PROPPAGE);
    psp.hIcon		= 0;
    psp.pszTitle	= TEXT("Subversion");
    psp.pfnDlgProc	= (DLGPROC) PageDlgProc;
    psp.pcRefParent	= &Diapexis::DllUsage;
    psp.pfnCallback	= PageCallbackProc;
    psp.lParam		= reinterpret_cast<LPARAM>(this);

    HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(&psp);
    if (hPage == NULL) return E_OUTOFMEMORY;

    if (!pfnAddPage(hPage, lParam)) {
        ::DestroyPropertySheetPage(hPage);
        return E_FAIL;
    }

    _uk().AddRef();
    return S_OK;
}

STDMETHODIMP General::ReplacePage(EXPPS uPageID, LPFNSVADDPROPSHEETPAGE pfnReplaceWith, LPARAM lParam) {
    return E_NOTIMPL;
}

}