package ThingModel.Proto;

message Property {

	required int32 string_key = 1;

	enum Type {
		LOCATION_POINT = 0;
		LOCATION_LATLNG = 1;
		LOCATION_EQUATORIAL = 2;
		STRING = 3;
		DOUBLE = 4;
		INT = 5;
		BOOLEAN = 6;
		DATETIME = 7;
	}

	required Type type = 2 [default = STRING];

	message Location {

		required double x = 1 [default = 0.0];
		required double y = 2 [default = 0.0];
		optional double z = 3 [default = 0.0];

		// WGS84 by default
		optional int32 string_system = 4;

		// When the z attribute is not present
		optional bool z_null = 5 [default = false];
	}

	message String {
		optional string value = 1;

		/**
		 *	A string can be cached using StringDeclaration
		 *	It's just an option, and a developer
		 *	is allowed to ignore this feature
		 *	when he want to send a string property.
		 */
		optional int32 string_value = 2 [default = 0];	
	}

	optional Location location_value = 3;
	optional String string_value = 4;
	optional double double_value = 5;
	optional sint32 int_value = 6;
	optional bool boolean_value = 7;
	optional int64 datetime_value = 8;


}

message PropertyType {
	required int32 string_key = 1;

	enum Type {
		LOCATION = 0;
		STRING = 1;
		DOUBLE = 2;
		INT = 3;
		BOOLEAN = 4;
		DATETIME = 5;
	}

	required Type type = 2 [default = STRING];
	required bool required = 3 [default = true];

	optional int32 string_name = 4;
	optional int32 string_description = 5;
}

/**
 *	In order to reduce networks exchanges,
 *	a string must be sent only one time
 *	in the connection lifetime.
 *
 *	The value is the string and the key is a unique
 *	number representing the string.
 *
 *	The key must not be a hash like a truncated
 *	md5 or sha1. Collisions risks are important
 *	with a 32bits key.
 *
 *	Instead, it's better to use a counter. 0 for
 *	the first string decleration, 1 for the second…
 *	And the Protocol Buffers encoding is more efficient
 *	with small numbers.
 *
 *	Each connection should use two dictionaries
 *	between these declarations. One dictionary
 *	for the emission and another one for the reception.
 *
 *	A string declaration can replace a previous one.
 *	It is not possible to remove a string declaration.
 *	Duplicates, the same string with differents keys, are
 *	allowed but developers must try to avoid that.
 */
message StringDeclaration {
	required string value = 1;
	required int32 key = 2;
}


message Thing {
	required int32 string_id = 1;
	required int32 string_type_name = 2;

	repeated Property properties = 3;

	// Use int32 string ids
	repeated int32 connections = 4 [packed = true];
	optional bool connections_change = 5 [default = false];
}


message ThingType {
	required int32 string_name = 1;

	optional int32 string_description = 2;

	repeated PropertyType properties = 3;	
}


message Transaction {
	repeated StringDeclaration string_declarations = 1;

	repeated Thing things_publish_list = 2;
	repeated int32 things_remove_list = 3 [packed = true];

	// Can be declared once
	// And we can't remove a ThingType
	repeated ThingType thingtypes_declaration_list = 4;

	// Identification of the sender
	required int32 string_sender_id = 5;
}