/**
 * Data Output MVC view
 * 
 * Allows user to view and configure network connections
 * 
 * @category    Webserver
 * @package     ATProcessor
 * @author      Sam Meredith <sam@aandtinstruments.com>
 * @version     0.1
 */

class DataOutputView extends BasicView 
{
    constructor(controller) {
		super(controller);
		
		this.connectionTypes = "";
		this.formats = "";
		this.adaptors = "";
    }

    bindEvents() {
		super.bindEvents();

        $(document).on('click', '#add-network', this.controller.addConnection.bind(this.controller));
		$(document).on('click', '.analogue-close', this.controller.closeConnection.bind(this.controller));

		$('#output-frequency').on('change', this.controller.globalFrequencyChanged.bind(this.controller));
		
		// Bind methods to handle change of data in network containers. 
		$(document).on('change', '.connectionName', this.controller.connectionNameChanged.bind(this.controller));
		$(document).on('change', '[name="directionSelect"]', this.connectionTypeChanged.bind(this));
		$(document).on('change', '[name="adaptorSelect"]', this.controller.adaptorAddressChanged.bind(this.controller));
		$(document).on('change', '[name="UDPAddress"]', this.controller.connectionAddressChanged.bind(this.controller));
		$(document).on('change', '[name="UDPFormat"]', this.controller.formatChanged.bind(this.controller));
		$(document).on('change', '[name="outputFreq"] input', this.controller.frequencyChanged.bind(this.controller));
		$(document).on('change', '[name="Port"]', this.controller.portChanged.bind(this.controller));
		$(document).on('click',  '[name="broadcast"] input', this.toggleBroadcast.bind(this));
		$(document).on('click',  '[name="Enabled"]', this.controller.toggleEnable.bind(this.controller));

    }

	// Handler for change in connection type.
	connectionTypeChanged(e)
	{
		this.updateInputFields($(e.target).closest('section'));
		this.controller.connectionTypeChanged(e);
	}

	// Add a connection to the page
	drawConnection(connectionData, connectionNumber) {
		let $container = $("#network-container");

		$container.append(
				'<section class="top-wrapper box" data-connection="' + connectionNumber + '">'
			+		'<span class="analogue-close"><i class="fa fa-times"></i></span>'
			+		'<fieldset>'
			+			'<legend class="connectionLegend">'
			+				'<input class="connectionName" type="text" value="' + connectionData.connectionname + '">'
			+			'</legend>'
			+			'<div class="flex-row">'
			+				'<div class="flex-half">'
			+					'<div class="flex-heading">'
			+						'<h2>Connection Type</h2>'
			+					'</div>'
			+					'<select name="directionSelect">'
			+						this.connectionTypes
			+					'</select>'
			+				'</div>'/*
							Per connection output frequency has never worked.
							Replaced with single global output frequency for now.
			+				'<div class="flex-half" name="outputFreq">'
			+					'<div class="flex-heading">'
			+						'<h2>Output Frequency</h2>'
			+					'</div>'
			+					'<div class="input-unit">'
			+						'<input type="number" value="' + connectionData.outputfrequency + '">'
			+						'<span>Hz</span>'
			+					'</div>'
			+				'</div>'*/
			+			'</div>'
			+			'<div class="flex-row">'
			+				'<div class="flex-half">'
			+					'<div class="flex-heading">'
			+						'<div class="tooltip-wrapper">'
			+							'<h2>Adapter Address</h2>'
			+							'<div class="tooltip">'
			+								'<p>The IP address of the adapter connecting this device to the network. '
			+								'Generally you should select the address which matches the boats network (default 192.168.x.x).</p>'
			+							'</div>'
			+						'</div>'
			+					'</div>'		
			+					'<select name="adaptorSelect">'
			+						this.adaptors
			+					'</select>'
			+				'</div>'
			+			'</div>'
			+			'<div class="flex-row" name="connectionAddress">'
			+				'<div class="flex-half">'
			+					'<div class="flex-heading">'
			+						'<div class="tooltip-wrapper">'
			+							'<h2>Connection Address</h2>'
			+							'<div class="tooltip">'
			+								'<p>The IP address of the destination device to be connected to the ATP.</p>'
			+							'</div>'
			+						'</div>'
			+					'</div>'
			+					'<input type="text" name="UDPAddress" value="' + (connectionData.udpaddress || "") + '">'
			+				'</div>'
			+				'<div class="flex-half" name="broadcast">'
			+					'<div class="flex-heading">'
			+						'<div class="tooltip-wrapper">'
			+							'<h2>Broadcast</h2>'
			+							'<div class="tooltip" tooltip-position="left">'
			+								'<p>'
			+									'If checked, will transmit to or receive from the adapter broadcast address (e.g. 172.16.255.255).'
			+								'</p>'
			+							'</div>'
			+						'</div>'
			+					'</div>'
			+					'<input type="checkbox" ' + ((connectionData.udpbroadcast == true) ? "checked" : "") + '>'
			+				'</div>'
			+			'</div>'
			+			'<div class="flex-row">'
			+				'<div class="flex-half">'
			+					'<div class="flex-heading">'
			+						'<h2>Format</h2>'
			+					'</div>'
			+					'<select name="UDPFormat">'
			+						this.formats
			+					'</select>'
			+				'</div>'
			+				'<div class="flex-half">'
			+					'<div class="flex-heading">'
			+						'<h2>Port</h2>'
			+					'</div>'
			+					'<input type="number" value="' + connectionData.port + '" name="Port">'
			+				'</div>'
			+			'</div>'
			+			'<div class="flex-row">'
			+				'<div class="flex-half">'
			+					'<div class="flex-heading">'
			+						'<h2>Enable</h2>'
			+					'</div>'
			+					'<input type="checkbox" name="Enabled" ' + ((connectionData.enabled == true) ? "checked" : "") + '>'
			+				'</div>'
			+			'</div>'
			+		'</fieldset>'
			+	'</section>'
		);

		let $connection = $container.children('[data-connection="' + connectionNumber + '"]');
		$connection.find('[name="directionSelect"] option[value="' + connectionData.connectiontype + '"]').prop('selected', 'selected');
		$connection.find('[name="adaptorSelect"] option[value="' + connectionData.adaptoraddress + '"]').prop('selected', 'selected');
		$connection.find('[name="UDPFormat"] option[value="' + connectionData.format + '"]').prop('selected', 'selected');
		this.toggleConnectionAddress($connection.find('[name="UDPAddress"]'), $connection.find('[name="broadcast"] input').is(':checked'));
		this.updateInputFields($connection);
	}

	// Handle broadcast box toggle
	toggleBroadcast(e) {
		let $container = $(e.target).closest('section');
		let connectionAddress = $container.find('[name="UDPAddress"]');

		this.toggleConnectionAddress(connectionAddress, $(e.target).is(':checked'));
		this.controller.toggleBroadcast(e);
	}

	// Hide or show connection address in response to broadcast toggle
	toggleConnectionAddress($input, disabled) {
		if (disabled) {
			$input.prop('disabled', true);
			$input.attr('value', $input.val());
			$input.val('');
		} else {
			$input.prop('disabled', false);
			$input.val($input.attr('value'));
		}
	}

	// Handle changes to the input fields based on connection type selection.
	updateInputFields($connection)
	{
		let val = $connection.find('[name="directionSelect"]').val();
 
		switch (val) 
		{
			case "TCP Server":
				$connection.find('[name="connectionAddress"]').hide();
				$connection.find('[name="broadcast"]').hide();
				$connection.find('[name="outputFreq"]').hide();
				break;
			 case "UDP Output":
				$connection.find('[name="outputFreq"]').show();
				$connection.find('[name="connectionAddress"]').show();
				$connection.find('[name="broadcast"]').show();
				break;
			case "UDP Input":
				$connection.find('[name="connectionAddress"]').show();
				$connection.find('[name="broadcast"]').show();
				$connection.find('[name="outputFreq"]').hide();
				break;				
		}
	}

    // Draw connection containers
    update(model)
    {
		let self = this;

		// Construct connnection options
		self.connectionTypes = "<option disabled selected value hidden></option>";
		model.connectionTypes.forEach(function(connectionType) {
			self.connectionTypes += '<option value="' + connectionType + '">'
				+ connectionType + '</option>';
		});
 
		// Construct format options
		self.formats = "<option disabled selected value hidden></option>";
		model.formats.forEach(function(format) {
			self.formats += '<option value="' + format + '">' + format + '</option>';
		});

		// Construct adaptor options
		self.adaptors = '<option disabled selected value hidden></option>';
		model.adaptors.forEach(function(adaptor) {
			self.adaptors += '<option value="' + adaptor + '">' + adaptor + '</option>';
		})

		$('#output-frequency').val(model.outputFrequency);

		$('#network-container').empty();
		for (var connection in model.savedConnections) {
			if (model.savedConnections.hasOwnProperty(connection)) {
				this.drawConnection(model.savedConnections[connection], parseInt(connection) + 1);
			}
		}
	}
}