
/* -*-c++-*- */
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
 * Copyright 2016 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_DRIVER_KML_COMMON
#define OSGEARTH_DRIVER_KML_COMMON 1

#include <osgEarth/Common>
#include <osgEarth/URI>
#include <osgEarth/MapNode>
#include <osgEarth/SpatialReference>
#include <osgEarthSymbology/Style>
#include <osgEarthSymbology/StyleSheet>
#include <osgEarthSymbology/ResourceCache>
#include "KMLOptions"

#include "rapidxml.hpp"
#include "rapidxml_utils.hpp"
#include "rapidxml_ext.hpp"

using namespace rapidxml;

#define LC "[KML] "

#define for_one( NAME, FUNC, NODE, CX ) \
{ \
		xml_node<> *n = NODE->first_node(#NAME, 0, false); \
		if (n) {\
	        KML_##NAME instance; \
            instance. FUNC (n, CX); \
		}\
}


#define for_many( NAME, FUNC, NODE, CX ) \
{ \
   if (NODE) { \
       for (xml_node<>* n = NODE->first_node(#NAME, 0, false); n; n = n->next_sibling(#NAME, 0, false)) { \
	       KML_##NAME instance; \
		   instance. FUNC (n, CX); \
	   } \
   }\
}

#define for_features( FUNC, NODE, CX ) \
    for_many( Document,      FUNC, NODE, CX ); \
    for_many( Folder,        FUNC, NODE, CX ); \
    for_many( PhotoOverlay,  FUNC, NODE, CX ); \
    for_many( ScreenOverlay, FUNC, NODE, CX ); \
    for_many( GroundOverlay, FUNC, NODE, CX ); \
    for_many( NetworkLink,   FUNC, NODE, CX ); \
    for_many( Placemark,     FUNC, NODE, CX );

namespace osgEarth_kml
{
    using namespace osgEarth;
    using namespace osgEarth::Drivers;
    using namespace osgEarth::Symbology;

    struct KMLContext
    {
        MapNode*                              _mapNode;         // reference map node
        const KMLOptions*                     _options;         // user options
        osg::ref_ptr<StyleSheet>              _sheet;           // entire style sheet
        Style                                 _activeStyle;     // currently active style
        std::stack<osg::ref_ptr<osg::Group> > _groupStack;      // resulting scene graph
        osg::ref_ptr<const SpatialReference>  _srs;             // map's spatial reference
        osg::ref_ptr<const osgDB::Options>    _dbOptions;       // I/O options (caching, etc)
        std::string                           _referrer;        // The referrer for loading things from relative paths.
    };

    struct KMLUtils
    {
        // parse KML's many variants on a URL link.
        static std::string parseLink( xml_node<>* node )
		{
			if (node)
			{
				xml_node<>* link = node->first_node("link", 0, false);
				if ( link )
				{
					std::string url = getValue(link, "href");
					if (url.empty())
					{
						url = getValue(link, "href");
					}
					if (url.empty())
					{
						url = link->value();
					}
					return url;
				}
				else
				{
					link = node->first_node("url", 0, false);
                    if (link)
                    {
					    std::string url = getValue(link, "href");
					    if (url.empty())
					    {
    						url = link->value();
					    }
					    return url;
                    }
				}
			}
			return "";
        }
    };

} // namespace osgEarth_kml

#endif // OSGEARTH_DRIVER_KML_READER

