// WebRequest.cpp : Implementation of cWebRequest
#include "stdafx.h"
#include "DecalNet.h"
#include "WebRequest.h"

/////////////////////////////////////////////////////////////////////////////
// cWebRequest

STDMETHODIMP cWebRequest::Get(BSTR strURL)
{
   USES_CONVERSION;
   HRESULT hRes = ::URLOpenStream( NULL, OLE2T( strURL ), 0, this );
   m_strPost = _bstr_t();

	return hRes;
}

STDMETHODIMP cWebRequest::Post(BSTR strURL, BSTR strPostData)
{
   USES_CONVERSION;
   m_strPost = strPostData;
   HRESULT hRes = ::URLOpenStream( NULL, OLE2T( strURL ), 0, this );

	return hRes;
}

STDMETHODIMP cWebRequest::GetBindInfo(DWORD *pgrfBINDF, BINDINFO *pbindinfo)
{
   USES_CONVERSION;

   *pgrfBINDF = BINDF_ASYNCHRONOUS | BINDF_GETNEWESTVERSION | BINDF_ASYNCSTORAGE | BINDF_GETNEWESTVERSION | BINDF_NOWRITECACHE;

   if( m_strPost.length() != 0 )
   {
      // We're doing a post operation - set the data into an HGLOBAL
      ::memset( pbindinfo, 0, sizeof( BINDINFO ) );

      pbindinfo->cbSize = sizeof( BINDINFO );
      pbindinfo->szExtraInfo = NULL;

      LPCSTR strPost = OLE2A( m_strPost );
      int nLength = m_strPost.length();
      pbindinfo->stgmedData.tymed = TYMED_HGLOBAL;
      pbindinfo->stgmedData.hGlobal = ::GlobalAlloc( GPTR, nLength );
      pbindinfo->stgmedData.pUnkForRelease = static_cast< IBindStatusCallback * >( this );
      pbindinfo->stgmedData.pUnkForRelease->AddRef();

      ::memcpy( pbindinfo->stgmedData.hGlobal, strPost, nLength );

      // pbindinfo->grfBindInfoF = 0;
      pbindinfo->dwBindVerb = BINDVERB_POST;
      pbindinfo->dwCodePage = 0;
      pbindinfo->cbstgmedData = nLength;
      pbindinfo->grfBindInfoF = BINDINFOF_URLENCODESTGMEDDATA;
   }
   else
      pbindinfo->dwBindVerb = BINDVERB_GET;

   return S_OK;
}

STDMETHODIMP cWebRequest::OnDataAvailable(DWORD grfBSCF, DWORD dwSize, FORMATETC *pfmetc, STGMEDIUM *pstgmed )
{
   if( pstgmed->tymed != TYMED_ISTREAM )
      // We only support IStream format
      return E_INVALIDARG;

   char *strStr = new char[ dwSize + 1 ];
   pstgmed->pstm->Read( strStr, dwSize, NULL );
   strStr[ dwSize ] = '\0';

   m_strResult += strStr;
   delete[] strStr;

   return S_OK;
}

STDMETHODIMP cWebRequest::OnStopBinding(HRESULT hr, LPCWSTR sz)
{
   m_pBinding.Release();
   m_strPost = _bstr_t();

   Fire_End( ( SUCCEEDED( hr ) ) ? 200 : 400, m_strResult );

   return S_OK;
}

STDMETHODIMP cWebRequest::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeaders, DWORD, LPWSTR *pszAdditionalRequestHeaders)
{
   if( m_strPost.length() == 0 )
   {
      *pszAdditionalRequestHeaders = NULL;
      return S_OK;
   }

   // Append a content-type so the server will understand that this is a form submission
   LPCWSTR wszContent = L"Content-Type: application/x-www-form-urlencoded\r\n";
   *pszAdditionalRequestHeaders = reinterpret_cast< LPWSTR >( ::CoTaskMemAlloc( sizeof( wchar_t ) * ( ::wcslen( wszContent ) + 1 ) ) );
   ::wcscpy( *pszAdditionalRequestHeaders, wszContent );

   return S_OK;
}

STDMETHODIMP cWebRequest::OnResponse(DWORD dwResponseCode, LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
{
   *pszAdditionalRequestHeaders = NULL;
   return S_OK;
}
