/* -*-c++-*- */
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
* Copyright 2008-2010 Pelican Mapping
* http://osgearth.org
*
* osgEarth is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OSGEARTH_ENGINE_TILE_BUILDER
#define OSGEARTH_ENGINE_TILE_BUILDER 1

#include "Common"
#include "Tile"
#include <osgEarth/Map>
#include <osgEarth/TaskService>
#include <osg/Group>

using namespace osgEarth;

class TileBuilder : public osg::Referenced
{
public:
    struct SourceRepo
    {
        SourceRepo() { }

        void add( const CustomColorLayer& layer )
        {
            Threading::ScopedMutexLock lock(_m);
            _colorLayers[ layer.getUID() ] = layer;
        }

        void set( const CustomElevLayer& elevLayer )
        {
            // only one...no lock required
            _elevLayer = elevLayer;
        }

        ColorLayersByUID _colorLayers;
        CustomElevLayer _elevLayer;
        Threading::Mutex _m;
    };

    struct Job : public osg::Referenced
    {
        Job(const TileKey& key, const Map* map) : _key(key), _mapf(map, Map::TERRAIN_LAYERS) { }

        TileKey           _key;
        MapFrame          _mapf;
        SourceRepo        _repo;
        TaskRequestVector _tasks;
    };

public:
    TileBuilder(
        const Map*               map,
        const OSGTerrainOptions& terrainOptions,
        TaskService*             service );

    void createTile(
        const TileKey&      key,
        bool                parallelize,
        osg::ref_ptr<Tile>& out_tile,
        bool&               out_hasRealData,
        bool&               out_hasLodBlendedLayers );

    Job* createJob( const TileKey& key, Threading::MultiEvent& semaphore );

    void runJob( Job* job );

    void finalizeJob( 
        Job*                job, 
        osg::ref_ptr<Tile>& out_tile,
        bool&               out_hasRealData,
        bool&               out_hasLodBlending );

    TaskService* getTaskService() const { return _service; }

private:
    const Map*               _map;
    TaskService*             _service;
    const OSGTerrainOptions& _terrainOptions;
};

#endif // OSGEARTH_ENGINE_TILE_BUILDER
