/* -*-c++-*- */
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
 * Copyright 2010 Pelican Ventures, Inc.
 * 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 SEAMLESS_PATCHGROUP
#define SEAMLESS_PATCHGROUP 1

#include <osg/PagedLOD>
#include <osg/Vec2d>

#include <osgDB/Registry>

#include <osgEarth/TileKey>

#include "PatchInfo"

namespace seamless
{
class Patch;
class PatchSet;
class PatchOptions;

class PatchGroup : public osg::PagedLOD
{
public:
    PatchGroup();
    PatchGroup(const PatchGroup&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);

    META_Node(seamless, PatchGroup);

    virtual void traverse(osg::NodeVisitor& nv);
    // patch extents come from the PatchOptions object stored with the node.
    void getPatchExtents(osg::Vec2d& lowerLeft, osg::Vec2d& upperRight) const;
    void setOptions(PatchOptions* options);
    PatchOptions* getOptions();
    const PatchOptions* getOptions() const;
protected:
    ~PatchGroup();
};

// Database options for creating a patch

class PatchOptions : public osgDB::Options, public PatchInfo
{
public:
    PatchOptions();
    PatchOptions(const std::string& str);
    PatchOptions(const PatchOptions& rhs,
                 const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
    ~PatchOptions();

    META_Object(seamless, PatchOptions);
    void setPatchExtents(const osg::Vec2d& lowerLeft,
                         const osg::Vec2d& upperRight)
    {
        _lowerLeft = lowerLeft;  _upperRight = upperRight;
    }
    void getPatchExtents(osg::Vec2d& lowerLeft, osg::Vec2d& upperRight) const
    {
        lowerLeft = _lowerLeft;  upperRight = _upperRight;
    }
    void setPatchLevel(int level) { _level = level; }
    int getPatchLevel() const { return _level; }
    void setPatchSet(PatchSet* patchSet);
    PatchSet* getPatchSet() const;
    void setTileKey(const osgEarth::TileKey& key) { _tileKey = key; }
    osgEarth::TileKey getTileKey() { return _tileKey; }
    const osgEarth::TileKey& getTileKey() const { return _tileKey; }
protected:
    osg::Vec2d _lowerLeft;
    osg::Vec2d _upperRight;
    int _level;
    osg::ref_ptr<PatchSet> _patchSet;
    osgEarth::TileKey _tileKey;
};

inline void PatchGroup::setOptions(PatchOptions* options)
{
    setDatabaseOptions(options);
}

inline PatchOptions* PatchGroup::getOptions()
{
    return static_cast<PatchOptions*>(getDatabaseOptions());
}

inline const PatchOptions* PatchGroup::getOptions() const
{
    return static_cast<const PatchOptions*>(getDatabaseOptions());
}
}
#endif
