/* -*-c++-*- */
/* osgEarth - Geospatial SDK for OpenSceneGraph
 * Copyright 2020 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/>
 */
#pragma once

#include <osgEarth/Common>
#include <osgEarth/Symbol>
#include <osgEarth/Expression>

namespace osgEarth
{
    using namespace osgEarth;

    /**
     * Symbol that directs the GeometryCompiler to create extruded 3D geometry
     * from 2D vector data.
     * 
     * Notes on Direction and height sign.
     * 
     * - DIRECTION_UP with +height: walls [0..+H], roof at +H, normal +Z
     * - DIRECTION_UP with -height: walls [-H..0], roof at 0, normal +Z
     * 
     * - DIRECTION_DOWN with +height: walls [0..-H], roof at -H, normal -Z
     * - DIRECTION_DOWN with -height: walls [+H..0], roof at 0, normal -Z
     */
    class OSGEARTH_EXPORT ExtrusionSymbol : public Symbol
    {
    public:
        META_Object(osgEarth, ExtrusionSymbol);

        ExtrusionSymbol(const ExtrusionSymbol& rhs,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
        ExtrusionSymbol( const Config& conf =Config() );

        //! Extrusion direction
        enum Direction {
            DIRECTION_UP,
            DIRECTION_DOWN
        };

        //! Height to which to extrude geometry from the footprint
        OE_OPTION(float, height, 10.0f);

        //! Simple expression to evaluate to get height
        OE_OPTION(NumericExpression, heightExpression, {});

        //! Whether the top cap of the extruded geometry should be flat
        OE_OPTION(bool, flatten, true);

        //! Name of a style describing how to symbolize the extruded walls
        OE_OPTION(std::string, wallStyleName);

        //! Wall skin name, if you don't want to use a style
        OE_OPTION(std::string, wallSkinName);

        //! Name of a style describing how to symbolize the elevated rooftop 
        OE_OPTION(std::string, roofStyleName);

        //! Roof skin name, if you don't want to use a style
        OE_OPTION(std::string, roofSkinName);

        //! Percentage by which to darken the color of the bottom of the walls relative
        //! to the main wall color (default = 0.0, range = [0..1])
        OE_OPTION(float, wallGradientPercentage, 0.0f);

        //! Percentage by which to shade the wells to simulate lighting [0..1]
        OE_OPTION(float, wallShadePercentage, 0.0f);

        //! Direction to extrude. Default is UP (+Z).
        OE_OPTION(Direction, direction, DIRECTION_UP);
        
    public:
        Config getConfig() const override;
        void mergeConfig(const Config& conf) override;
        static void parseSLD(const Config& c, class Style& style);
    };
} // namespace osgEarth
