/*
 *  TnPrefetch.h
 *
 *
 *  Use is documented here:
 *
 *  http://spaces.telenav.com:8080/display/eng/Prefetch+in+Qt+Test+App
 *
 *  Created by Thant on 4/16/2013
 *  Copyright 2013 TeleNav Inc. All rights reserved.
 *
 */

#ifndef TN_PREFETCH_INCLUDED
#define TN_PREFETCH_INCLUDED

#include <foundation/SharedPtr.h>
#include <boost/enable_shared_from_this.hpp>
#include <foundation/Math/LatLonHeight.hpp>
#include <foundation/Mutex.h>
#include <foundation/Locks.h>

#include <RenderEngine/ITnMapVectorDataProxy.h>
#include <RenderEngine/ITnMapTrafficProxy.h>
#include <RenderEngine/ITnMapRouteProxy.h>
#include <GenericProxy/TnPrefetchRouteData.h>


class TnPrefetch : public ITnMapRouteProxy, public boost::enable_shared_from_this<TnPrefetch>
{
public:

    typedef Tn::Foundation::shared_ptr<TnPrefetch> ptr;

    typedef TnPrefetchRouteData::RouteMap RouteMap;
    typedef TnPrefetchRouteData::RouteMapPtr RouteMapPtr;

    // To prevent creating an instance on the stack given
    // enable_shared_from_this.
    static TnPrefetch::ptr Create(ITnMapRouteProxy::ptr const &,
                                  ITnMapVectorDataProxy::ptr const &, 
                                  ITnMapTrafficProxy::ptr const &);

    /*  This prefetches the tiles around a specified location.
     *
     *  'radius' is in meters.
     *
     *  'level' is the new quadcoord level (where 0 is the whole
     *  earth). To convert from level to old-style TeleNav tile level,
     *  use TnMapTileId::LevelToZoom
     */

    void PrefetchArea(uint32_t baseTileSize,
                      Tn::math::LatLonHeight const & latlon,
                      double radius,
                      uint32_t level);

    /*  Prefetch tiles a specified range along the route. 'radius' is
     *  in meters.  The begin and end segment and edge indices
     *  correspond to the BeginSegment and BeginEdge calls used to
     *  feed the route. The beginSegmentIndex and beginEdgeIndex must
     *  be valid for the route.
     */
    void PrefetchRoute(uint32_t baseTileSize,
                       std::string const & routeName,
                       double radius,
                       uint32_t level,
                       uint32_t beginSegmentIndex,
                       uint32_t beginEdgeIndex,
                       double distance /* along route in meters */);

    /* The ITnMapRouteProxy part:
     *
     */
    virtual void RequestRoute(ITnMapRouteData::ptr const & data);
    virtual void RequestRoute(std::string const & name, 
                              ITnMapRouteData::ptr const & data);

    std::string QuotedRouteNames() const;

private:

    friend class TnPrefetchRouteData;
    void SetRoutes(RouteMapPtr const &);
    RouteMapPtr m_routes;

    TnPrefetch(ITnMapRouteProxy::ptr const &,
               ITnMapVectorDataProxy::ptr const &, 
               ITnMapTrafficProxy::ptr const &);

    void RequestPrefetch(TnMapTileId const &);

    void PrefetchRoute(uint32_t baseTileSize,
                       Tn::math::RoutePtr route,
                       double radius,
                       uint32_t level,
                       uint32_t begin,
                       double meters);

    ITnMapRouteProxy::ptr m_routeProxy;

    ITnMapVectorDataProxy::ptr m_vectorProxy;
    ITnMapTrafficProxy::ptr m_trafficProxy;

    Tn::Foundation::mutex m_mutex;
};

#endif
