#ifndef USER_TI
#define USER_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 "icinga/customvarobject.hpp"

#include "base/array.hpp"

namespace icinga
{

class User;

template<>
class TypeImpl<User> : public TypeImpl<CustomVarObject>
{
public:
	DECLARE_PTR_TYPEDEFS(TypeImpl<User>);

	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<User> : public CustomVarObject
{
public:
	DECLARE_PTR_TYPEDEFS(ObjectImpl<User>);

	void Validate(int types, const ValidationUtils& utils) override;
	void SimpleValidateDisplayName(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidatePeriodRaw(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateEmail(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidatePager(const Lazy<String>& value, const ValidationUtils& utils);
	void SimpleValidateGroups(const Lazy<Array::Ptr>& avalue, const ValidationUtils& utils);
	void SimpleValidateTypes(const Lazy<Array::Ptr>& avalue, const ValidationUtils& utils);
	void SimpleValidateStates(const Lazy<Array::Ptr>& avalue, const ValidationUtils& utils);
	void SimpleValidateTypeFilter(const Lazy<int>& value, const ValidationUtils& utils);
	void SimpleValidateStateFilter(const Lazy<int>& value, const ValidationUtils& utils);
	void SimpleValidateLastNotification(const Lazy<Timestamp>& value, const ValidationUtils& utils);
	void SimpleValidateEnableNotifications(const Lazy<bool>& value, const ValidationUtils& utils);
public:
	ObjectImpl<User>();
public:
	~ObjectImpl<User>() 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:
	String GetDisplayName() const;
public:
	String GetPeriodRaw() const;
public:
	String GetEmail() const;
public:
	String GetPager() const;
public:
	Array::Ptr GetGroups() const;
public:
	virtual Array::Ptr GetTypes() const = 0;
public:
	virtual Array::Ptr GetStates() const = 0;
public:
	int GetTypeFilter() const;
public:
	int GetStateFilter() const;
public:
	Timestamp GetLastNotification() const;
public:
	bool GetEnableNotifications() const;
public:
	void SetDisplayName(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetPeriodRaw(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetEmail(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetPager(const String& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetGroups(const Array::Ptr& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	virtual void SetTypes(const Array::Ptr& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	virtual void SetStates(const Array::Ptr& value, bool suppress_events = false, const Value& cookie = Empty) = 0;
public:
	void SetTypeFilter(int value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetStateFilter(int value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetLastNotification(const Timestamp& value, bool suppress_events = false, const Value& cookie = Empty);
public:
	void SetEnableNotifications(bool value, bool suppress_events = false, const Value& cookie = Empty);
protected:
	void TrackPeriodRaw(const String& oldValue, const String& newValue);
	void TrackGroups(const Array::Ptr& oldValue, const Array::Ptr& newValue);
public:
	Object::Ptr NavigatePeriodRaw() const;
protected:
	void Start(bool runtimeCreated = false) override;
	void Stop(bool runtimeRemoved = false) override;
public:
	virtual void NotifyDisplayName(const Value& cookie = Empty);
public:
	virtual void NotifyPeriodRaw(const Value& cookie = Empty);
public:
	virtual void NotifyEmail(const Value& cookie = Empty);
public:
	virtual void NotifyPager(const Value& cookie = Empty);
public:
	virtual void NotifyGroups(const Value& cookie = Empty);
public:
	virtual void NotifyTypes(const Value& cookie = Empty);
public:
	virtual void NotifyStates(const Value& cookie = Empty);
public:
	virtual void NotifyTypeFilter(const Value& cookie = Empty);
public:
	virtual void NotifyStateFilter(const Value& cookie = Empty);
public:
	virtual void NotifyLastNotification(const Value& cookie = Empty);
public:
	virtual void NotifyEnableNotifications(const Value& cookie = Empty);
private:
	inline String GetDefaultDisplayName() const;
private:
	inline String GetDefaultPeriodRaw() const;
private:
	inline String GetDefaultEmail() const;
private:
	inline String GetDefaultPager() const;
private:
	inline Array::Ptr GetDefaultGroups() const;
private:
	inline Array::Ptr GetDefaultTypes() const;
private:
	inline Array::Ptr GetDefaultStates() const;
private:
	inline int GetDefaultTypeFilter() const;
private:
	inline int GetDefaultStateFilter() const;
private:
	inline Timestamp GetDefaultLastNotification() const;
private:
	inline bool GetDefaultEnableNotifications() const;
protected:
	virtual void ValidateDisplayName(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidatePeriodRaw(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateEmail(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidatePager(const Lazy<String>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateGroups(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateTypes(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateStates(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateTypeFilter(const Lazy<int>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateStateFilter(const Lazy<int>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateLastNotification(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils);
protected:
	virtual void ValidateEnableNotifications(const Lazy<bool>& lvalue, const ValidationUtils& utils);
private:
	AtomicOrLocked<String> m_DisplayName;
	AtomicOrLocked<String> m_PeriodRaw;
	AtomicOrLocked<String> m_Email;
	AtomicOrLocked<String> m_Pager;
	AtomicOrLocked<Array::Ptr> m_Groups;
	AtomicOrLocked<int> m_TypeFilter;
	AtomicOrLocked<int> m_StateFilter;
	AtomicOrLocked<Timestamp> m_LastNotification;
	AtomicOrLocked<bool> m_EnableNotifications;
public:
	static boost::signals2::signal<void (const intrusive_ptr<User>&, const Value&)> OnDisplayNameChanged;
	static boost::signals2::signal<void (const intrusive_ptr<User>&, const Value&)> OnPeriodRawChanged;
	static boost::signals2::signal<void (const intrusive_ptr<User>&, const Value&)> OnEmailChanged;
	static boost::signals2::signal<void (const intrusive_ptr<User>&, const Value&)> OnPagerChanged;
	static boost::signals2::signal<void (const intrusive_ptr<User>&, const Value&)> OnGroupsChanged;
	static boost::signals2::signal<void (const intrusive_ptr<User>&, const Value&, const Value&)> OnGroupsChangedWithOldValue;
	static boost::signals2::signal<void (const intrusive_ptr<User>&, const Value&)> OnTypesChanged;
	static boost::signals2::signal<void (const intrusive_ptr<User>&, const Value&)> OnStatesChanged;
	static boost::signals2::signal<void (const intrusive_ptr<User>&, const Value&)> OnTypeFilterChanged;
	static boost::signals2::signal<void (const intrusive_ptr<User>&, const Value&)> OnStateFilterChanged;
	static boost::signals2::signal<void (const intrusive_ptr<User>&, const Value&)> OnLastNotificationChanged;
	static boost::signals2::signal<void (const intrusive_ptr<User>&, const Value&)> OnEnableNotificationsChanged;
};

}
#endif /* USER_TI */
