/* -*-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_TERRAIN_TILE_MODEL_H
#define OSGEARTH_TERRAIN_TILE_MODEL_H 1

#include <osgEarth/Common>
#include <osgEarth/TileKey>
#include <osgEarth/ImageLayer>
#include <osgEarth/PatchLayer>
#include <osgEarth/Revisioning>
#include <osgEarth/HeightFieldUtils>
#include <osgEarth/TextureArena>
#include <osg/Texture>
#include <osg/Matrix>
#include <osg/Node>

namespace osgUtil {
    class StateToCompile;
}

namespace osgEarth
{
    using namespace Util;

    /**
     * Data model backing an individual terrain tile.
     */
    class OSGEARTH_EXPORT TerrainTileModel : public osg::Referenced
    {
    public:
        struct OSGEARTH_EXPORT Tile {
            Tile() : _revision(-1) { }
            OE_PROPERTY(int, revision);
            OE_PROPERTY(Texture::Ptr, texture);
            OE_PROPERTY(osg::Matrixf, matrix);
        };

        struct OSGEARTH_EXPORT ColorLayer : public Tile {
            using Vector = std::vector<ColorLayer>;
            OE_PROPERTY(osg::ref_ptr<Layer>, layer);
        };

        struct OSGEARTH_EXPORT Elevation : public Tile {
            Elevation();
            OE_PROPERTY(float, minHeight);
            OE_PROPERTY(float, maxHeight);
            OE_PROPERTY(osg::ref_ptr<const osg::HeightField>, heightField);
        };

        struct OSGEARTH_EXPORT NormalMap : public Tile {
            // empty
        };

        struct OSGEARTH_EXPORT LandCover : public ColorLayer {
            // empty
        };

    public:
        //! Create a new empty data model for a tile/revision pair
        TerrainTileModel(
            const TileKey&  key,
            const Revision& revision);

        //! Map model revision from which this model was created
        OE_PROPERTY(int, revision);

        //! Tile key corresponding to this model
        OE_PROPERTY(TileKey, key);

        //! Whether some data here requires updates
        OE_PROPERTY(bool, requiresUpdateTraversal);

        //! Imagery and other surface coloring layers
        OE_PROPERTY(ColorLayer::Vector, colorLayers);

        //! Indices of shared data layers
        OE_PROPERTY(std::vector<unsigned>, sharedLayerIndices);

        //! Elevation data
        OE_PROPERTY(Elevation, elevation);

        //! Normal map data
        OE_PROPERTY(NormalMap, normalMap);

        //! Land coverage data
        OE_PROPERTY(LandCover, landCover);

        //! Get a texture given a layer ID
        Texture::Ptr getTexture(UID layerUID) const;
        const osg::Matrixf& getMatrix(UID layerUID) const;

        //! Populates the output object with things that the
        //! ICO can pre-compile.
        //! @param out Where to place objects that need pre-compiling
        //! @param bindless Whether to treat textures as bindless textures
        //!   that will be managed by a TextureArena
        void getStateToCompile(
            osgUtil::StateToCompile& out,
            bool bindless) const;

    protected:
        bool _requiresUpdateTraverse;
    };
}

#endif // OSGEARTH_TERRAIN_TILE_MODEL_H
