/* -*-c++-*- */
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
 * Copyright 2008-2013 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_JS_FEATURE_CONTEXT_H
#define OSGEARTH_DRIVER_JS_FEATURE_CONTEXT_H 1

#include <osgEarth/StringUtils>
#include <osgEarthFeatures/Feature>
//#include <osgEarthFeatures/Script>
//#include <osgEarthFeatures/ScriptEngine>

#include <v8.h>

// ---------------------------------------------------------------------------

class JSFeature
{
public:
  static v8::Handle<v8::Object> WrapFeature(v8::Isolate* isolate, osgEarth::Features::Feature* feature, bool freeObject=false);
  static const std::string& GetObjectType() { return _objectType; }

protected:
  static const std::string _objectType;

  static v8::Handle<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
  static v8::Handle<v8::ObjectTemplate> GetAttributesObjectTemplate(v8::Isolate* isolate);

  static v8::Handle<v8::Value> GetFeatureAttr(const std::string& attr, osgEarth::Features::Feature const* feature);
  static void PropertyCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info);
  static void AttrPropertyCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info);

  static void FreeFeatureCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* handle, osgEarth::Features::Feature* parameter);
};

// ---------------------------------------------------------------------------

class JSSymbologyGeometry
{
public:
  static v8::Handle<v8::Object> WrapGeometry(v8::Isolate* isolate, osgEarth::Symbology::Geometry* geometry, bool freeObject=false);
  static const std::string& GetObjectType() { return _objectType; }

protected:
  static const std::string _objectType;

  static v8::Handle<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
  static void PropertyCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info);
  static void IndexedPropertyCallback(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info);

  static void FreeGeometryCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* handle, osgEarth::Symbology::Geometry* parameter);
};

// ---------------------------------------------------------------------------

class JSBounds
{
public:
  static v8::Handle<v8::Object> WrapBounds(v8::Isolate* isolate, osgEarth::Bounds* bounds, bool freeObject=false);
  static const std::string& GetObjectType() { return _objectType; }
  
protected:
  static const std::string _objectType;

  static v8::Handle<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
  static void PropertyCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info);

  static void ContainsCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
  static void UnionCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
  static void IntersectionCallback(const v8::FunctionCallbackInfo<v8::Value>& info);

  static void FreeBoundsCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* handle, osgEarth::Bounds* parameter);
};

// ---------------------------------------------------------------------------

class JSVec3d
{
public:
  static v8::Handle<v8::Object> WrapVec3d(v8::Isolate* isolate, osg::Vec3d* vec, bool freeObject=false);
  static const std::string& GetObjectType() { return _objectType; }

protected:
  static const std::string _objectType;

  static v8::Handle<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
  static void PropertyCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info);
  static void IndexedPropertyCallback(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info);

  static void FreeVecCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* handle, osg::Vec3d* parameter);
};

// ---------------------------------------------------------------------------

class JSFilterContext
{
public:
  static v8::Handle<v8::Object> WrapFilterContext(v8::Isolate* isolate, osgEarth::Features::FilterContext* context, bool freeObject=false);
  static const std::string& GetObjectType() { return _objectType; }

protected:
  static const std::string _objectType;

  static v8::Handle<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
  static void PropertyCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info);

  static void ToLocalCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
  static void ToWorldCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
  static void ToMapCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
  static void FromMapCallback(const v8::FunctionCallbackInfo<v8::Value>& info);

  static void FreeContextCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* handle, osgEarth::Features::FilterContext* parameter);
};

// ---------------------------------------------------------------------------

class JSSession
{
public:
  static v8::Handle<v8::Object> WrapSession(v8::Isolate* isolate, osgEarth::Features::Session* session, bool freeObject=false);
  static const std::string& GetObjectType() { return _objectType; }

protected:
  static const std::string _objectType;

  static v8::Handle<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
  static void PropertyCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info);

#if 0
  static void ResolveUriCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
#endif

  static void FreeSessionCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* handle, osgEarth::Features::Session* parameter);
};

// ---------------------------------------------------------------------------

class JSMapInfo
{
public:
  static v8::Handle<v8::Object> WrapMapInfo(v8::Isolate* isolate, osgEarth::MapInfo* mapInfo, bool freeObject=false);
  static const std::string& GetObjectType() { return _objectType; }

protected:
  static const std::string _objectType;

  static v8::Handle<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
  static void PropertyCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info);

#if 0
  static void ToMapCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
  static void MapToWorldCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
  static void WorldToMapCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
#endif

  static void FreeMapInfoCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* handle, osgEarth::MapInfo* parameter);
};

// ---------------------------------------------------------------------------

class JSFeatureProfile
{
public:
  static v8::Handle<v8::Object> WrapFeatureProfile(v8::Isolate* isolate, osgEarth::Features::FeatureProfile* context, bool freeObject=false);
  static const std::string& GetObjectType() { return _objectType; }

protected:
  static const std::string _objectType;

  static v8::Handle<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
  static void PropertyCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info);

  static void FreeProfileCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* handle, osgEarth::Features::FeatureProfile* parameter);
};

// ---------------------------------------------------------------------------

class JSGeoExtent
{
public:
  static v8::Handle<v8::Object> WrapGeoExtent(v8::Isolate* isolate, osgEarth::GeoExtent* extent, bool freeObject=false);
  static const std::string& GetObjectType() { return _objectType; }

protected:
  static const std::string _objectType;

  static v8::Handle<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
  static void PropertyCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info);

  static void ContainsCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
  static void IntersectsCallback(const v8::FunctionCallbackInfo<v8::Value>& info);

  static void FreeGeoExtentCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* handle, osgEarth::GeoExtent* parameter);
};

// ---------------------------------------------------------------------------

class JSSpatialReference
{
public:
  static v8::Handle<v8::Object> WrapSpatialReference(v8::Isolate* isolate, osgEarth::SpatialReference* srs, bool freeObject=false);
  static const std::string& GetObjectType() { return _objectType; }

protected:
  static const std::string _objectType;

  static v8::Handle<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
  static void PropertyCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info);

  static void EquivalenceCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
  static void TangentPlaneCallback(const v8::FunctionCallbackInfo<v8::Value>& info);

  static void FreeSpatialReferenceCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* handle, osgEarth::SpatialReference* parameter);
};

// ---------------------------------------------------------------------------

#endif // OSGEARTH_DRIVER_JS_FEATURE_CONTEXT_H