#ifndef ICINGAAPPLICATION_TI
#define ICINGAAPPLICATION_TI

#include "base/object.hpp"
#include "base/type.hpp"
#include "base/value.hpp"
#include "base/array.hpp"
#include "base/atomic.hpp"
#include "base/dictionary.hpp"
#include <boost/signals2.hpp>

#include "base/application.hpp"

namespace icinga
{

class IcingaApplication;

template<>
class TypeImpl<IcingaApplication> : public TypeImpl<Application>
{
public:
	DECLARE_PTR_TYPEDEFS(TypeImpl<IcingaApplication>);

	TypeImpl();
	~TypeImpl() override;

	String GetName() const override;
	int GetAttributes() const override;
	Type::Ptr GetBaseType() const override;
	int GetFieldId(const String& name) const override;
	Field GetFieldInfo(int id) const override;
	int GetFieldCount() const override;
	ObjectFactory GetFactory() const override;
	int GetActivationPriority() const override;
public:
	void RegisterAttributeHandler(int fieldId, const Type::AttributeHandler& callback) override;
};


template<>
class ObjectImpl<IcingaApplication> : public Application
{
public:
	DECLARE_PTR_TYPEDEFS(ObjectImpl<IcingaApplication>);

	void Validate(int types, const ValidationUtils& utils) override;
	void SimpleValidateEnvironment(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateVars(const Lazy<Dictionary::Ptr>& value, const ValidationUtils& utils);
	void SimpleValidateEnableNotifications(const Lazy<bool>& value, const ValidationUtils& utils);
	void SimpleValidateEnableEventHandlers(const Lazy<bool>& value, const ValidationUtils& utils);
	void SimpleValidateEnableFlapping(const Lazy<bool>& value, const ValidationUtils& utils);
	void SimpleValidateEnableHostChecks(const Lazy<bool>& value, const ValidationUtils& utils);
	void SimpleValidateEnableServiceChecks(const Lazy<bool>& value, const ValidationUtils& utils);
	void SimpleValidateEnablePerfdata(const Lazy<bool>& value, const ValidationUtils& utils);
public:
	ObjectImpl<IcingaApplication>();
public:
	~ObjectImpl<IcingaApplication>() override;
public:
	void SetField(int id, const Value& value, bool suppress_events = false, const Value& cookie = Empty) override;
public:
	Value GetField(int id) const override;
public:
	void ValidateField(int id, const Lazy<Value>& lvalue, const ValidationUtils& utils) override;
public:
	void NotifyField(int id, const Value& cookie = Empty) override;
public:
	Object::Ptr NavigateField(int id) const override;
public:
	virtual String GetEnvironment() const = 0;
public:
	Dictionary::Ptr GetVars() const;
public:
	bool GetEnableNotifications() const;
public:
	bool GetEnableEventHandlers() const;
public:
	bool GetEnableFlapping() const;
public:
	bool GetEnableHostChecks() const;
public:
	bool GetEnableServiceChecks() const;
public:
	bool GetEnablePerfdata() const;
public:
	virtual void SetEnvironment(const String& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	void SetVars(const Dictionary::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetEnableNotifications(bool value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetEnableEventHandlers(bool value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetEnableFlapping(bool value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetEnableHostChecks(bool value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetEnableServiceChecks(bool value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetEnablePerfdata(bool value, bool suppress_events = false, const Value& cookie = Empty);
protected:
public:
	virtual void NotifyEnvironment(const Value& cookie = Empty);
public:
	virtual void NotifyVars(const Value& cookie = Empty);
public:
	virtual void NotifyEnableNotifications(const Value& cookie = Empty);
public:
	virtual void NotifyEnableEventHandlers(const Value& cookie = Empty);
public:
	virtual void NotifyEnableFlapping(const Value& cookie = Empty);
public:
	virtual void NotifyEnableHostChecks(const Value& cookie = Empty);
public:
	virtual void NotifyEnableServiceChecks(const Value& cookie = Empty);
public:
	virtual void NotifyEnablePerfdata(const Value& cookie = Empty);
private:
	inline String GetDefaultEnvironment() const;
private:
	inline Dictionary::Ptr GetDefaultVars() const;
private:
	inline bool GetDefaultEnableNotifications() const;
private:
	inline bool GetDefaultEnableEventHandlers() const;
private:
	inline bool GetDefaultEnableFlapping() const;
private:
	inline bool GetDefaultEnableHostChecks() const;
private:
	inline bool GetDefaultEnableServiceChecks() const;
private:
	inline bool GetDefaultEnablePerfdata() const;
protected:
	virtual void ValidateEnvironment(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateVars(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateEnableNotifications(const Lazy<bool>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateEnableEventHandlers(const Lazy<bool>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateEnableFlapping(const Lazy<bool>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateEnableHostChecks(const Lazy<bool>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateEnableServiceChecks(const Lazy<bool>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateEnablePerfdata(const Lazy<bool>& lvalue, const ValidationUtils& utils);
private:
	AtomicOrLocked<Dictionary::Ptr> m_Vars;
	AtomicOrLocked<bool> m_EnableNotifications;
	AtomicOrLocked<bool> m_EnableEventHandlers;
	AtomicOrLocked<bool> m_EnableFlapping;
	AtomicOrLocked<bool> m_EnableHostChecks;
	AtomicOrLocked<bool> m_EnableServiceChecks;
	AtomicOrLocked<bool> m_EnablePerfdata;
public:
	static boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> OnEnvironmentChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> OnVarsChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> OnEnableNotificationsChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> OnEnableEventHandlersChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> OnEnableFlappingChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> OnEnableHostChecksChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> OnEnableServiceChecksChanged;
	static boost::signals2::signal<void (const intrusive_ptr<IcingaApplication>&, const Value&)> OnEnablePerfdataChanged;
};

}
#endif /* ICINGAAPPLICATION_TI */
