#include <iostream>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/range.hpp>
#include <comdef.h>
#include <comutil.h>
#import <msxml6.dll>

_bstr_t ToBStr(const std::wstring& s)
{
	return _bstr_t(SysAllocStringLen(s.c_str(), s.size()), false);
}

std::wstring ToWString(const _bstr_t& s)
{
	return std::wstring(static_cast<PCWSTR>(s), static_cast<PCWSTR>(s) + s.length());
}

boost::iterator_range<const wchar_t*> BStrRange(const _bstr_t& s)
{
	return boost::make_iterator_range(static_cast<PCWSTR>(s), static_cast<PCWSTR>(s) + s.length());
}

std::wstring GetTinyUrlString(const std::wstring& url)
{
	MSXML2::IXMLHTTPRequestPtr xmlhttp;
	HRESULT hr = xmlhttp.CreateInstance("Msxml2.XMLHTTP");
	if (FAILED(hr))
	{
		throw _com_error(hr);
	}
	xmlhttp->open(L"GET", ToBStr(L"http://tinyurl.com/api-create.php?url=" + url));
	xmlhttp->send();
	_bstr_t result = xmlhttp->GetresponseText();
	if (boost::algorithm::iequals(BStrRange(result), L"error"))
	{
		throw std::runtime_error("Tinyurl returns error");
	}
	return ToWString(result);
}

int main()
{
	HRESULT hr = CoInitialize(0);
	if (FAILED(hr))
	{
		throw _com_error(hr);
	}
	std::wcout << GetTinyUrlString(L"http://ll.jus.or.jp/2008/info/xgihyo") << std::endl;
	CoUninitialize();
}
