EegeoSearchQuery::EegeoSearchQuery(Eegeo::Web::IWebLoadRequestFactory& webRequestFactory,
                                   Eegeo::Helpers::UrlHelpers::IUrlEncoder& urlEncoder,
                                   const Search::SdkModel::SearchQuery& query,
                                   const std::string& apiKey,
                                   Eegeo::Helpers::ICallback0& completionCallback)
    : m_apiKey(apiKey)
    , m_completionCallback(completionCallback)
    , m_responseString("")
    , m_isSuccess(false)
    , m_webRequestCompleteCallback(this, &EegeoSearchQuery::OnWebResponseReceived)
{
    std::string encodedQuery;
    urlEncoder.UrlEncode(query.Query(), encodedQuery);

    std::stringstream urlstream;
    urlstream << "https://poi.eegeo.com/v1";
    if (query.IsCategory())
    {
        urlstream << "/category?c=";
    }
    else
    {
        urlstream << "/search?s=";
    }
    urlstream << encodedQuery;
    urlstream << "&r=" << std::setprecision(4) << query.Radius();
    urlstream << "&lat=" << std::setprecision(8) << query.Location().GetLatitudeInDegrees();
    urlstream << "&lon=" << std::setprecision(8) << query.Location().GetLongitudeInDegrees();
    urlstream << "&apikey=" << m_apiKey;

    std::string url = urlstream.str();
    m_pWebLoadRequest = webRequestFactory.Begin(Eegeo::Web::HttpVerbs::GET, url, m_webRequestCompleteCallback).Build();
    m_pWebLoadRequest->Load();
}
 YelpBusinessQuery::YelpBusinessQuery(
                                      const std::string& requestUrl,
                                      Eegeo::Helpers::ICallback1<const Search::SdkModel::IdentitySearchCallbackData&>& completionCallback,
                                      Eegeo::Web::IWebLoadRequestFactory& webRequestFactory,
                                      const YelpBusinessJsonParser& yelpBusinessParser)
     : m_pWebLoadRequest(NULL)
     , m_completionCallback(completionCallback)
     , m_yelpBusinessParser(yelpBusinessParser)
     , m_dispatched(false)
     , m_webRequestCompleteCallback(this, &YelpBusinessQuery::HandleWebResponseComplete)
 {
     m_pWebLoadRequest = webRequestFactory.Begin(Eegeo::Web::HttpVerbs::Values::GET, requestUrl, m_webRequestCompleteCallback).Build();
 }
 EegeoInteriorSearchQuery::EegeoInteriorSearchQuery(Eegeo::Web::IWebLoadRequestFactory& webRequestFactory,
                                                    Eegeo::Helpers::UrlHelpers::IUrlEncoder& urlEncoder,
                                                    const Search::SdkModel::SearchQuery& query,
                                                    const std::string& serviceUrl,
                                                    const std::string& apiKey,
                                                    const Eegeo::Resources::Interiors::InteriorId& interiorId,
                                                    int floorIdx,
                                                    Eegeo::Helpers::ICallback0& completionCallback)
 : m_apiKey(apiKey)
 , m_completionCallback(completionCallback)
 , m_responseString("")
 , m_isSuccess(false)
 , m_interiorId(interiorId)
 , m_floorIdx(floorIdx)
 , m_webRequestCompleteCallback(this, &EegeoInteriorSearchQuery::OnWebResponseReceived)
 {
     Eegeo_ASSERT(query.IsCategory(), "Only support category indoor queries");
     const int maximumNumberOfResults = 99;
     
     std::string encodedQuery;
     urlEncoder.UrlEncode(query.Query(), encodedQuery);
     
     std::stringstream urlstream;
     urlstream.setf(std::ios_base::fixed);
     urlstream << serviceUrl;
     urlstream << "/indoor?";
     if (!encodedQuery.empty())
     {
         urlstream << "t=" << encodedQuery << "&";
     }
     urlstream << "f=";
     urlstream << m_floorIdx;
     urlstream << "&i=";
     urlstream << m_interiorId.Value();
     urlstream << "&n=" << maximumNumberOfResults;
     urlstream << "&apikey=" << m_apiKey;
     
     std::string url = urlstream.str();
     m_pWebLoadRequest = webRequestFactory.Begin(Eegeo::Web::HttpVerbs::GET, url, m_webRequestCompleteCallback).Build();
     m_pWebLoadRequest->Load();
 }
 GeoNamesSearchQuery::GeoNamesSearchQuery(Eegeo::Web::IWebLoadRequestFactory& webRequestFactory,
                                          Eegeo::Helpers::UrlHelpers::IUrlEncoder& urlEncoder,
                                          const Search::SdkModel::SearchQuery& query,
                                          Eegeo::Helpers::ICallback0& completionCallback,
                                          const std::string& geoNamesUserName)
 : m_completionCallback(completionCallback)
 , m_responseString("")
 , m_isSuccess(false)
 , m_webRequestCompleteCallback(this, &GeoNamesSearchQuery::OnWebResponseReceived)
 {
     std::string encodedQuery;
     urlEncoder.UrlEncode(query.Query(), encodedQuery);
     
     std::string url = "http://api.geonames.org/searchJSON?q="
     + encodedQuery
     + "&maxRows=1&featureClass=A&featureClass=P&orderby=relevance&username="
     + geoNamesUserName;
     
     m_pWebLoadRequest = webRequestFactory.Begin(Eegeo::Web::HttpVerbs::GET, url, m_webRequestCompleteCallback).Build();
     m_pWebLoadRequest->Load();
 }