/* -*-c++-*- */
/* osgEarth - Geospatial SDK for OpenSceneGraph
 * Copyright 2008-2014 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_REX_LOADER
#define OSGEARTH_REX_LOADER 1

#include "Common"
#include "LoadTileData"

#include <osgEarth/Threading>
#include <osgEarth/FrameClock>
#include <osg/Node>
#include <queue>

namespace osgEarth { namespace REX
{
    using namespace osgEarth;
    using namespace osgEarth::Threading;

    /**
     * A queue that merges new tile data into the respective tile.
     */
    class Merger : public osg::Node
    {
    public:
        //! Construct a new merger
        Merger();

        //! Maximum number of merges to perform per UPDATE frame
        //! Default = unlimited
        void setMergesPerFrame(unsigned value);

        //! clear it
        void clear();

        //! Merge the tile load results into the host tile
        void merge(
            LoadTileDataOperationPtr data,
            osg::NodeVisitor& nv);

    public:
        void traverse(osg::NodeVisitor& nv) override;

        void releaseGLObjects(osg::State* state) const override;

    protected:
        virtual ~Merger();
    private:

        // GL objects compile task
        struct ToCompile {
            std::shared_ptr<LoadTileDataOperation> _data;
            Future<osg::ref_ptr<osg::Node>> _compiled;
        };

        // Queue of GL object compilations to perform per-merge,
        // if an ICO is installed
        using CompileQueue = std::list<ToCompile>;
        CompileQueue _compileQueue;
        CompileQueue _tempQueue;

        // Queue of tile data to merge during UPDATE traversal
        using MergeQueue = std::queue<LoadTileDataOperationPtr>;
        MergeQueue _mergeQueue;
        JobArena::Metrics::Arena::Ptr _metrics;

        Mutex _mutex;
        unsigned _mergesPerFrame;

        FrameClock _clock;
    };

} }


#endif // OSGEARTH_REX_LOADER
