/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

// File XResource.h
// Baudouin Raoult - ECMWF Feb 99

#ifndef XResource_H
#define XResource_H

// Headers
// #ifndef   machine_H
// #include <machine.h>
// #endif

// Forward declarations

// class ostream;
// typedef class _Pvts os_typespec; // Remove if not persistant

// 

#include <Xm/Xm.h>
#include "inc_iostream.h"

#include <string>
using std::string;

#ifndef Request_H
#include "Request.h"
#endif


class XResource {
public:

// -- Exceptions
	// None

// -- Contructors

	XResource(const string&, const string&);

// -- Destructor

	~XResource();
// -- Convertors
	// None

// -- Operators						   X


// -- Methods
	// None

// -- Overridden methods
	// None

// -- Class members
		
// -- Class methods
	static void setValues(Widget, const Request&);
	// Uncomment for persistent, remove otherwise
	// static os_typespec* get_os_typespec();

protected:

// -- Members
	// None
	string	name_; 
	string 	motif_;

// -- Methods
	
	// void print(ostream&) const; // Change to virtual if base class	

// -- Overridden methods
	// None

// -- Class members
	// None

// -- Class methods
	// None

private:

// No copy allowed

	XResource(const XResource&);
	XResource& operator=(const XResource&);

// -- Member
	// None

	
// -- Methods
	// None

	virtual void setValue(Widget,const Request&) = 0;

// -- Overridden methods
	// None

// -- Class members
	// None

// -- Class methods
	// None

// -- Friends

	//friend ostream& operator<<(ostream& s,const XResource& p)
	//	{ p.print(s); return s; }

};

template<class T>
class XBasicResource : public XResource{

	virtual void setValue(Widget w,const Request& r)
	{
		T value = r(name_.c_str());
		cout << "XResource::setValue: " << motif_.c_str() << " = " << value << endl;
	
		XtVaSetValues(w, motif_.c_str(), value, 0);
	}

public: 
	XBasicResource(const string& name, const string& motif):
		XResource(name,motif) {}

};	  


template <class T> 
class XEnum 
{
	typedef map<string,T> Map;
	Map map_;

public:
	XEnum(const string& name,  const T& motif) 
	{
		map_[name] = motif;
	}

	XEnum& operator+(const XEnum<T>& other)  
	{	
		const Map& o = other.map_;
		for(typename Map::const_iterator j = o.begin(); j != o.end(); ++j)
			map_.insert(*j);
		return *this;
	}

	operator Map() { return map_; } 
};


template<class T>
class XEnumResource : public XResource{
	typedef map<string,T> Map;
	Map map_;

	virtual void setValue(Widget w,const Request& r)
	{
		const char* value = r(name_.c_str());
		cout << "XEnumResource::setValue: " << value << " = " << int(map_[value]) << endl;
		XtVaSetValues(w,motif_.c_str(), map_[value], 0);
	}

public: 

	XEnumResource(const string& name, const string& motif, XEnum<T>& values):
		XResource(name, motif),
		map_(values) {}
};
/*
template <class T>
void* XResourceTranslator(const string& name, const string& motif, const T& d) {
       return 	new  XBasicResource<T>(name, motif);
}
*/

void* XResourceTranslator(const string& name, const string& motif);

template <class T>
void* XResourceTranslator(const string& name, const string& motif, XEnum<T>& values) {
       return 	new  XEnumResource<T>(name, motif, values);
}
	  
template <class T>
XEnum<T> XEnumTranslator(const string& name, const T& d) {
	return XEnum<T>(name, d);
}	
// If persistent, uncomment, otherwise remove
//#ifdef _ODI_OSSG_
//OS_MARK_SCHEMA_TYPE(XResource);
//#endif

#endif
