/*
 *  TnFileResourceProxy.h
 *  Map Rendering Engine Proxy Common
 *
 *  Created by Thant on 03/25/2013
 *  Copyright 2013 TeleNav Inc. All rights reserved.
 *
 */

#ifndef TN_FILE_RESOURCE_PROXY_H
#define TN_FILE_RESOURCE_PROXY_H

#include <string>
#include <foundation/SharedPtr.h>
#include <boost/threadpool.hpp>
#include <RenderEngine/TnMapResourceData.h>
#include <TnUrl.h>

#include <foundation/Mutex.h>

/*  The tricky part about the translate function passed in is that
 *  if iOS can't find the resource, it doesn't return an empty
 *  path. Instead, it returns the original resource name. (Jian
 *  figured this out.) This version returns the original if no
 *  tranlate function is provided, but it returns an empty option
 *  if the provided translator fails to translate it. (This
 *  functionality probably belongs in the original translate
 *  function.) 
 */

typedef std::string const (*TnFileNameTranslatorFunc)(std::string const &);

class TnFileResourceProxy
{
public:

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

    virtual ~TnFileResourceProxy();

    static ptr Create(uint32_t threadCount, TnFileNameTranslatorFunc = 0);

    /* In development mode, the file proxy will first try to find the
     * resource stripped of its path. This is to compensate for the
     * fact that iOS does not (yet?) support uploading resource files
     * to the device in subdirectories.
     */
    void SetDevMode(bool);

    // TODO: Synchronous file requests should be their own proxy, and
    // all other resource requests should be considered asynchronous.

    virtual bool RequestResourceSynchronously(ITnMapResourceData::ptr const & data);
    virtual void RequestResource(ITnMapResourceData::ptr const & data, uint32_t priority);

    // CancelRequest currently doesn't do anything
    virtual void CancelRequest(ITnMapResourceData::ptr const & data);

private:

    TnFileResourceProxy(uint32_t threadCount, TnFileNameTranslatorFunc translatorFunc);
    bool ReadFile(ITnMapResourceData::ptr const & data);

    void HandleRequest(ITnMapResourceData::ptr const & data);

    boost::threadpool::prio_pool m_threadpool;

    // File name translation

    bool m_devMode;
    TnFileNameTranslatorFunc const m_fileNameTranslator;

    std::string GetResourcePath(ITnMapResourceData::ptr const & data);

    /*  The tricky part about the translate function passed in is that
     *  if iOS can't find the resource, it doesn't return an empty
     *  path. Instead, it returns the original resource name. (Jian
     *  figured this out.) This version returns the original if no
     *  tranlate function is provided, but it returns an empty option
     *  if the provided translator fails to translate it. (This
     *  functionality probably belongs in the original translate
     *  function.) 
     */
    boost::optional<std::string> Translate(std::string const & name);
};


#endif
