var isPaused = false;

/**
 * Post field update request and update containers with the result
 * fields is an array of fieldIds, containers[fieldId] = [id1, id2, ...]
 **/
getFieldValues = function(fields, containers, id, instance) {
	if (!this.isPaused) {
		$.ajax({
			type: 'POST',
			url: '/fields.php',
			data: {action: 'getFields', fields: fields, id: id, instance: instance},
			success: function(data) {
				var fieldMatchRegex = /(0x.*)=\s?(.*)\r/g;
				var match = null;
				var parseFields = {};
				
				while ((match = fieldMatchRegex.exec(data)) !== null) {
						parseFields[match[1]] = match[2];
				}
				try {
					for (var i = 0; i < fields.length; i++) {
						if (Array.isArray(containers[fields[i]])) {
							for (var j = 0; j < containers[fields[i]].length; j++) {
								if (parseFields[fields[i]].toLowerCase() == 'hidden') {
									$('#' + containers[fields[i]][j]).hide();
								} else {
									$('#' + containers[fields[i]][j]).html(parseFields[fields[i]]);
									$('#' + containers[fields[i]][j]).show();
								}
							}
						} else {
							if (parseFields[fields[i]].toLowerCase() == 'hidden') {
								$('#' + containers[fields[i]]).hide();
							} else {
								$('#' + containers[fields[i]]).html(parseFields[fields[i]]);
								$('#' + containers[fields[i]]).show();
							}
						}
					}
				} catch (e) {
					if (e instanceof TypeError) {
						console.log('Field query failed. No response from processor.');
						return;
					} else {
						console.log(e.message);
					}
				}
			}
		});
	}
};


/**
 * Set an interval to update field containers, with fixed senderId and senderInstance
 **/
function FieldUpdateSender(fieldsAndContainers, senderId, senderInstance) {

	this.senderId = senderId;
	this.senderInstance = senderInstance;
	this.fields = [];
	this.containers = {};

	for (var i = 0; i < fieldsAndContainers.length; i++ ) {
		if (this.fields.indexOf(fieldsAndContainers[i]['field']) >= 0) {
			this.containers[fieldsAndContainers[i]['field']].push(fieldsAndContainers[i]['container']);
		} else {
			this.fields.push(fieldsAndContainers[i]['field']);
			(this.containers[fieldsAndContainers[i]['field']] = this.containers[fieldsAndContainers[i]['field']] || [])
				.push(fieldsAndContainers[i]['container']);
		}
	}

	//Update field containers every second
	this.auto_refresh = setInterval(getFieldValues, 1000, this.fields,
							this.containers, this.senderId, this.senderInstance);

	var that = this;
	
	$(document).on('fields-changed', function() {
		clearInterval(that.auto_refresh);
	});
}

/**
 * Get the set of fields, containers, [senderId, senderInstance] for the page and
 * call the approprate FieldUpdate
 **/
function getFields() {
	var senders = [];
	var fieldNames;
	var senderObjects = [];
	var fieldContainers = {};
	var fieldIds;
	
	//Get set of senderId, senderInstance, container, field values
	$('.field-container').each(function() {
		var senderId = $(this).attr('data-sender');
		var senderInstance = $(this).attr('data-instance');
		var container = $(this).attr("id");
		var field = $(this).attr('data-field');
		senderObjects.push({senderId: senderId, senderInstance: senderInstance, container: container, field: field});
	});	
	//Group by senderId
	senderObjects = senderObjects.reduce(function(accumulator, currentValue) {
		var senderId = currentValue["senderId"];
		delete currentValue.senderId;
		(accumulator[senderId] = accumulator[senderId] || []).push(currentValue);
		return accumulator;
	}, {});
	//Group by senderInstance
	for (var senderId in senderObjects) {
		if (senderObjects.hasOwnProperty(senderId)) {
			senderObjects[senderId] = senderObjects[senderId].reduce(function(accumulator, currentValue) {
				var senderInstance = currentValue["senderInstance"];
				delete currentValue.senderInstance;
				(accumulator[senderInstance] = accumulator[senderInstance] || []).
					push(currentValue);
				return accumulator;
			}, {});
		}
	}
	//Resulting object has form {senderId1: {senderInstance1: {field, container}, senderInstance2: {field,container}, ... }, senderId2: ... }
	for (var senderId in senderObjects) {
		if (senderObjects.hasOwnProperty(senderId)) {
			for (var senderInstance in senderObjects[senderId]) {
				if (senderObjects[senderId].hasOwnProperty(senderInstance)) {
					senderUpdate = new FieldUpdateSender(senderObjects[senderId][senderInstance], senderId, senderInstance);
				}
			}
		}
	}
}

/**
 * When fields are changed each interval call will clear, so start new ones.
 **/ 
$(document).on('fields-changed', function() {
	if ($('.field-container').length > 0) {
		getFields();

		if ($('#hold-button').length == 0) {
			$('body').append(
				'<a class="button button-gray button-medium hold-button" id="hold-button">Hold</a>'
			);
		}
	}
});	

/**
 * Default values for analogue inputs
 **/
linearTypes = {
	'0': {
		'Minimum': '0',
		'Maximum': '5',
		'Decimal Places': '0',
		'Format': '0x31',
		'FastnetChannel': '56',
		'FastnetChannelName': 'LINEAR1'
	},
	'1': {
		'Minimum': '-50',
		'Maximum': '50',
		'Decimal Places': '0',
		'Format': '0x31',
		'FastnetChannel': '11',
		'FastnetChannelName': 'RUDDER'
	},
	'2': {
		'Minimum': '-55',
		'Maximum': '55',
		'Decimal Places': '0',
		'Format': '0x31',
		'FastnetChannel': '56',
		'FastnetChannelName': 'MAST ROT'
	},
	'3': {
		'Minimum': '-45',
		'Maximum': '45',
		'Decimal Places': '0',
		'Format': '0x31',
		'FastnetChannel': '52',
		'FastnetChannelName': 'HEEL ANG'
	},
	'4': {
		'Minimum': '-60',
		'Maximum': '60',
		'Decimal Places': '0',
		'Format': '0x31',
		'FastnetChannel': '56',
		'FastnetChannelName': 'TRIM'
	},
	'5': {
		//Air Temp
		'Minimum': '-40',
		'Maximum': '80',
		'Decimal Places': '0',
		'Format': '0x31',
		'FastnetChannel': '29',
		'FastnetChannelName': ''
	},
	'6': {
		//Sea Temp
		'Minimum': '-5',
		'Maximum': '40',
		'Decimal Places': '0',
		'Format': '0x31',
		'FastnetChannel': '31',
		'FastnetChannelName': ''
	}
}
