[{isys_group name="tom.popup.visualization"}]
<div id="popup-connection">
	<h3 class="popup-header">
		<img class="fr mouse-pointer popup-closer" alt="x" src="[{$dir_images}]prototip/styles/default/close.png">
		<span>[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION"}]</span>

		<button id="C__CONNECTION_POPUP__FUNCTION_CONNECT_SELECTED" class="btn btn-small ml20" type="button" disabled>
			<img src="[{$dir_images}]icons/silk/connect.png" class="mr5" /><span>[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_CONNECT_SELECTED_CONNECTORS"}]</span>
		</button>

		<button id="C__CONNECTION_POPUP__FUNCTION_CHANGE_CABLE" class="btn btn-small" type="button" disabled>
			<img src="[{$dir_images}]tree/kabel.gif" class="mr5" /><span>[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_CHANGE_CABELS"}]</span>
		</button>

		<button id="C__CONNECTION_POPUP__FUNCTION_DISCONNECT_SELECTED" class="btn btn-small" type="button" disabled>
			<img src="[{$dir_images}]icons/silk/cross.png" class="mr5" /><span>[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_DISCONNECT_SELECTED_CONNECTORS"}]</span>
		</button>

		<label class="ml10" title="[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_AUTOMATIC_CABLE_SELECTION_TOOLTIP" p_bHtmlEncode=false}]">
			<input type="checkbox" class="mr5" id="C__CONNECTION_POPUP__AUTOMATIC_CABLE_SELECTION" [{if $automatic_cabling}]checked="checked"[{/if}] />
			<span>[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_AUTOMATIC_CABLE_SELECTION"}]</span>
		</label>
	</h3>

	<div class="popup-content">
		<table class="w100" cellspacing="0" style="table-layout: fixed">
			<colgroup>
				<col style="width:50%" />
				<col style="width:110px" />
				<col style="width:50%" />
			</colgroup>
			<tr>
				<td id="C__CONNECTION_POPUP__LOCAL">
					<div class="pb5 pl5">
						<div class="mt5 input-group input-size-block">
							[{isys type="f_popup" p_strPopupType="browser_object_ng" name="C__CONNECTION_POPUP__LOCAL_OBJECT"}]

							[{if $isCablingActive}]
							<a href="[{$cablingUrl}]" target="_blank" class="input-group-addon cabling-addon-link" title="[{isys type="lang" ident="LC__MODULE__CABLING__OPEN_IN_ADDON"}]">
								<img src="[{$dir_images}]icons/silk/disconnect.png" />
							</a>
							[{/if}]
						</div>

						<br class="cb" />
					</div>

					<div id="C__CONNECTION_POPUP__LOCAL_SWITCHER" class="center box-lightgrey gradient p5 ml5" style="position: relative;">
						<strong>[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_IN"}]</strong>
						<button type="button" class="btn btn-small ml20" id="C__CONNECTION_POPUP__LOCAL_INOUT_SWITCH" data-inout="0">
							<img src="[{$dir_images}]icons/silk/arrow_switch.png" />
						</button>
						<input type="checkbox" id="C__CONNECTION_POPUP__LOCAL_SELECT_ALL" />
						<strong>[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_OUT"}]</strong>
					</div>

					<div id="C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS" class="ml5"></div>
				</td>
				<td id="C__CONNECTION_POPUP__CONNECTION" style="padding-top: 63px;">
					<button type="button" class="btn">
						<img src="[{$dir_images}]icons/silk/arrow_left_right.png" />
					</button>
					<!-- Awesome visualization goes here -->
				</td>
				<td id="C__CONNECTION_POPUP__DESTINATION">
					<div class="pr5 pb5">
						<div class="mt5 input-group input-size-block">
							[{isys type="f_popup" p_strPopupType="browser_object_ng" name="C__CONNECTION_POPUP__DESTINATION_OBJECT"}]

							[{if $isCablingActive}]
							<a href="[{$cablingUrl}]" target="_blank" class="input-group-addon cabling-addon-link" title="[{isys type="lang" ident="LC__MODULE__CABLING__OPEN_IN_ADDON"}]">
								<img src="[{$dir_images}]icons/silk/disconnect.png" />
							</a>
							[{/if}]
						</div>

						<br class="cb" />
					</div>

					<div id="C__CONNECTION_POPUP__DESTINATION_SWITCHER" class="center box-lightgrey gradient p5 mr5" style="position: relative;">
						<input type="checkbox" id="C__CONNECTION_POPUP__DESTINATION_SELECT_ALL" />
						<strong>[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_IN"}]</strong>
						<button type="button" class="btn btn-small mr20" id="C__CONNECTION_POPUP__DESTINATION_INOUT_SWITCH" data-inout="0">
							<img src="[{$dir_images}]icons/silk/arrow_switch.png" />
						</button>
						<strong>[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_OUT"}]</strong>
					</div>

					<div id="C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS" class="mr5"></div>
				</td>
			</tr>
		</table>
	</div>

	<div id="C__CONNECTION_POPUP__MODAL" class="light hide">
		<div id="C__CONNECTION_POPUP__LOADING" class="box-white hide">
			<img src="[{$dir_images}]ajax-loading.gif" class="mr5" /><span>[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_SAVING"}]</span>
		</div>

		<div id="C__CONNECTION_POPUP__CABLE_BROWSER" class="bg-white border border-darkgrey blurred-shadow hide">

		</div>
	</div>
</div>
<script type="text/javascript">
	(function () {
		"use strict";

		window.idoit.Require.addModule('popupConnectionCable', '[{$dir_tools}]js/popups/connectionCable.js');

		var $popup                    = $('popup-connection'),
		    $automaticCableSelection  = $('C__CONNECTION_POPUP__AUTOMATIC_CABLE_SELECTION'),
		    $local                    = $('C__CONNECTION_POPUP__LOCAL'),
		    $localInOutSwitcher       = $('C__CONNECTION_POPUP__LOCAL_INOUT_SWITCH'),
		    $localList                = $('C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS'),
		    $localToggleAll           = $('C__CONNECTION_POPUP__LOCAL_SELECT_ALL'),
		    $localObjectView          = $('C__CONNECTION_POPUP__LOCAL_OBJECT__VIEW'),
		    $localObjectHidden        = $('C__CONNECTION_POPUP__LOCAL_OBJECT__HIDDEN'),
		    $localLastCheckbox        = null,
		    localObjectID             = $localObjectHidden.getValue(),
		    localData                 = {"in":[], "out":[]},
		    $destination              = $('C__CONNECTION_POPUP__DESTINATION'),
		    $destinationInOutSwitcher = $('C__CONNECTION_POPUP__DESTINATION_INOUT_SWITCH'),
		    $destinationList          = $('C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS'),
		    $destinationToggleAll     = $('C__CONNECTION_POPUP__DESTINATION_SELECT_ALL'),
		    $destinationObjectView    = $('C__CONNECTION_POPUP__DESTINATION_OBJECT__VIEW'),
		    $destinationObjectHidden  = $('C__CONNECTION_POPUP__DESTINATION_OBJECT__HIDDEN'),
		    $destinationLastCheckbox  = null,
		    destinationObjectID       = 0,
		    destinationData           = {"in":[], "out":[]},
		    $visualization            = $('C__CONNECTION_POPUP__CONNECTION'),
		    $connectSelectedButton    = $('C__CONNECTION_POPUP__FUNCTION_CONNECT_SELECTED'),
		    $changeCablesButton       = $('C__CONNECTION_POPUP__FUNCTION_CHANGE_CABLE'),
		    $disconnectSelectedButton = $('C__CONNECTION_POPUP__FUNCTION_DISCONNECT_SELECTED'),
		    $modalBox                 = $('C__CONNECTION_POPUP__MODAL'),
		    $modalLoading             = $('C__CONNECTION_POPUP__LOADING'),
		    $modalCableBrowser        = $('C__CONNECTION_POPUP__CABLE_BROWSER'),
		    localClickedIndex         = null,
		    destinationClickedIndex   = null,
		    reRendering               = 0,
			dataChanged               = false;

		// Close the popup, when clicking ".popup-closer" elements.
		$popup.select('.popup-closer').invoke('on', 'click', function () {
			popup_close($popup.up('.popup'));

			if (dataChanged) {
				document.location.reload();
            }
		});

		$local.on('update:objectSelection', function (ev) {
            var $openInCabling = $local.down('.cabling-addon-link');

            localClickedIndex = null;

            localObjectID = $localObjectHidden.getValue();

            $localList
		        .update(new Element('div', {className: 'p15'})
		        .update(new Element('img', {src: window.dir_images + 'ajax-loading.gif', className: 'mr5'}))
		        .insert(new Element('span').update('[{isys type="lang" ident="LC__UNIVERSAL__LOADING"}]')));

            // If existent - set the "open in cabling" link.
			if ($openInCabling) {
                $openInCabling.writeAttribute('href', '[{$cablingUrl}]/' + localObjectID);
			}

			getObjectConnectors(localObjectID, function (data) {
				localData = data;

				$visualization.fire('reset:visualization');

				reRendering = 0;

				if (ev.memo.hasOwnProperty('renderAll') && ev.memo.renderAll) {
					++ reRendering;
					renderList(false);
				}

				++ reRendering;
				renderList(true);
			});
		});

		$localList.on('click', 'button.connection', function (ev) {
			var $button   = ev.findElement('button'),
			    selfClick = $button.hasClassName('btn-green');

			$localList.select('.btn-green')
			          .invoke('removeClassName', 'btn-green');

			if (selfClick)
			{
				$destinationList.removeClassName('connect-to').select('button.connection')
	                .invoke('writeAttribute', 'title', '[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_CONNECT_WITH" p_bHtmlEncode=false}]');

				return;
			}

			$button.addClassName('btn-green');

			checkDirectConnection();

			$destinationList.addClassName('connect-to').select('button.connection')
                .invoke('writeAttribute', 'title', '[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_CONNECTOR" p_bHtmlEncode=false}]');
		});

		$localList.on('click', 'button.hopper', function (ev) {
			var $button = ev.findElement('button'),
			    $li = $button.up('li'),
				$siblingConnection = $li.down('.sibling-connected-with[title][data-target-id]'),
				object;

			localClickedIndex = null;

			// This prevents the "$localList.on('click', 'li', ...);" event (which re-sets the localClickedIndex).
			ev.preventDefault();
			ev.stopPropagation();
			ev.stopImmediatePropagation();

			$destinationObjectView.setValue($localObjectView.getValue()).writeAttribute('data-last-value', $localObjectView.getValue());
			$destinationObjectHidden.setValue($localObjectHidden.getValue());
			$destinationList.fire('update:objectSelection');

			if ($localInOutSwitcher.readAttribute('data-inout') != $destinationInOutSwitcher.readAttribute('data-inout')) {
				$destinationInOutSwitcher.simulate('click');
			}

			if ($siblingConnection) {
				object = $siblingConnection.readAttribute('title').split(' > ').splice(0, 2).join(' >> ');

				if (($localInOutSwitcher.readAttribute('data-inout') == '1' && $siblingConnection.readAttribute('data-target-inout') == '2') || $localInOutSwitcher.readAttribute('data-inout') == '0' && $siblingConnection.readAttribute('data-target-inout') == '1') {
					$localInOutSwitcher.simulate('click');
				}

				$localObjectView.setValue(object).writeAttribute('data-last-value', object);
				$localObjectHidden.setValue($siblingConnection.readAttribute('data-target-id'));
				$localList.fire('update:objectSelection');
			} else {
				$localList.fire('reset:objectSelection');
			}

			destinationClickedIndex = $li.previousSiblings().size();
		});

		$localList.on('mouseover', 'li', function (ev) {
			var $li = ev.findElement('li');

			$destinationList.select('li[data-id="' + $li.readAttribute('data-connector-id') + '"]').invoke('addClassName', 'hover');

			$visualization.fire('highlight:local', {'index': $li.previousSiblings().size()});
		});

		$localList.on('mouseout', 'li', function () {
			$destinationList.select('.hover').invoke('removeClassName', 'hover');

			$visualization.fire('highlight:none');
		});

		$localList.on('click', 'li', function (ev) {
			var $li         = ev.findElement('li'),
			    connectorID = $li.readAttribute('data-connector-id'),
			    $connector;

			$localList.select('li').invoke('removeClassName', 'clicked');
			$destinationList.select('li').invoke('removeClassName', 'clicked');

			localClickedIndex = $li.previousSiblings().size();
			destinationClickedIndex = null;

			if (connectorID !== null)
			{
				$connector = $destinationList.down('[data-id="' + connectorID + '"]');

				if ($connector)
				{
					destinationClickedIndex = $connector.previousSiblings().size();
				}
			}

			$visualization.fire('highlight:permanent');
			$visualization.fire('highlight:none');
			highlightListItems();
		});

		$localToggleAll.on('click', function () {
			$localList.select('input:not([disabled])').invoke('setValue', $localToggleAll.checked ? 1 : 0);

			updateConnectSelectedConnectorsButton();
		});

		$localList.on('click', 'input', function (ev) {
			var $checkbox = ev.findElement('input');

			if ($localLastCheckbox && window.keyPressedShift) {
				selectRange($checkbox, $localLastCheckbox).invoke('setValue', $checkbox.checked ? 1 : 0);
			}

			$localLastCheckbox = $checkbox;

			updateConnectSelectedConnectorsButton();
		});

		$localList.on('click', '.connected-with', function (ev) {
			var $span = ev.findElement('span'),
			    objectId = $span.readAttribute('data-target-id'),
			    objectTitle = $span.readAttribute('title').split(' > ').splice(0, 2).join(' >> ');

			if (objectId == $destinationObjectHidden.getValue()) {
				$destinationInOutSwitcher.simulate('click');

				return;
			}

			$destinationObjectHidden.setValue(objectId);
			$destinationObjectView.setValue(objectTitle).writeAttribute('data-last-value', objectTitle);

			if (($destinationInOutSwitcher.readAttribute('data-inout') == '1' && $span.readAttribute('data-target-inout') == '1') || $destinationInOutSwitcher.readAttribute('data-inout') == '0' && $span.readAttribute('data-target-inout') == '2') {
				$destinationInOutSwitcher.simulate('click');
			}

			$destination.fire('update:objectSelection', {renderAll:true});
		});

		$localList.on('click', '.sibling-connected-with', function (ev) {
			var $span = ev.findElement('span'),
			    objectId = $span.readAttribute('data-target-id'),
			    objectTitle = $span.readAttribute('title').split(' > ').splice(0, 2).join(' >> ');

			$localObjectHidden.setValue(objectId);
			$localObjectView.setValue(objectTitle).writeAttribute('data-last-value', objectTitle);

			$local.fire('update:objectSelection', {renderAll:true});
		});

		[$localInOutSwitcher, $destinationInOutSwitcher].invoke('on', 'click', function (ev) {
			var $button = ev.findElement('button'),
				$inOutDiv = $button.up('div'),
				status = !($button.readAttribute('data-inout') == '1'),
				onlyReRenderCurrent = $button.retrieve('onlyReRenderCurrent', false);

			$button.store('onlyReRenderCurrent', false);

			if (status)
			{
				$inOutDiv
					.down('strong').update('[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_OUT"}]')
					.next('strong').update('[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_IN"}]');
			}
			else
			{
				$inOutDiv
					.down('strong').update('[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_IN"}]')
					.next('strong').update('[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_OUT"}]');
			}

			$button.writeAttribute('data-inout', (status + 0));

			$visualization.fire('reset:visualization');

			// @todo This should only happen for the "not-switched" side (but isn't as easy right now).
			destinationClickedIndex = null;
			localClickedIndex = null;

			reRendering = 0;

			spinConnectors(this.id == 'C__CONNECTION_POPUP__LOCAL_INOUT_SWITCH');

			if (!onlyReRenderCurrent) {
				++reRendering;
				renderList(this.id != 'C__CONNECTION_POPUP__LOCAL_INOUT_SWITCH');
			}
		});

		$destination.on('update:objectSelection', function (ev) {
            var $openInCabling = $destination.down('.cabling-addon-link');

			destinationClickedIndex = null;

			destinationObjectID = $destinationObjectHidden.getValue();

			$destinationList.update(new Element('div', {className: 'p15'})
					.update(new Element('img', {src: window.dir_images + 'ajax-loading.gif', className: 'mr5'}))
					.insert(new Element('span').update('[{isys type="lang" ident="LC__UNIVERSAL__LOADING"}]')));

			if ($openInCabling) {
                $openInCabling.writeAttribute('href', '[{$cablingUrl}]/' + destinationObjectID);
			}

			getObjectConnectors(destinationObjectID, function (data) {
				destinationData = data;

				$visualization.fire('reset:visualization');

				reRendering = 0;

				if (ev.memo.hasOwnProperty('renderAll') && ev.memo.renderAll) {
					++reRendering;
					renderList(true);
				}

				++reRendering;
				renderList(false);
			});
		});

		$local.on('reset:objectSelection', function () {
			localClickedIndex = null;
			localObjectID = 0;
			localData = {"in":[], "out":[]};

			$localObjectView.setValue('').writeAttribute('data-last-value', '');
			$localObjectHidden.setValue('');

			$visualization.fire('reset:visualization');

			reRendering = 2;
			renderList(true);
			renderList(false);
		});

		$destination.on('reset:objectSelection', function () {
			destinationClickedIndex = null;
			destinationObjectID = 0;
			destinationData = {"in":[], "out":[]};

			$destinationObjectView.setValue('').writeAttribute('data-last-value', '');
			$destinationObjectHidden.setValue('');

			$visualization.fire('reset:visualization');

			reRendering = 2;
			renderList(true);
			renderList(false);
		});

		$destinationList.on('click', 'button.connection', function (ev) {
			var $button   = ev.findElement('button'),
			    selfClick = $button.hasClassName('btn-green');

			$destinationList.select('.btn-green')
	            .invoke('removeClassName', 'btn-green');

			if (selfClick)
			{
				$localList.removeClassName('connect-to').select('button.connection')
			        .invoke('writeAttribute', 'title', '[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_CONNECT_WITH" p_bHtmlEncode=false}]');

				return;
			}

			$button.addClassName('btn-green');

			checkDirectConnection();

			$localList.addClassName('connect-to').select('button.connection')
	            .invoke('writeAttribute', 'title', '[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_CONNECTOR" p_bHtmlEncode=false}]');
		});

		$destinationList.on('click', 'button.hopper', function (ev) {
			var $button = ev.findElement('button'),
			    $li = $button.up('li'),
			    $siblingConnection = $li.down('.sibling-connected-with[title][data-target-id]'),
			    object;

			destinationClickedIndex = null;

			// This prevents the "$destinationList.on('click', 'li', ...);" event (which re-sets the destinationClickedIndex).
			ev.preventDefault();
			ev.stopPropagation();
			ev.stopImmediatePropagation();

			$localObjectView.setValue($destinationObjectView.getValue()).writeAttribute('data-last-value', $destinationObjectView.getValue());
			$localObjectHidden.setValue($destinationObjectHidden.getValue());
			$localList.fire('update:objectSelection');

			if ($destinationInOutSwitcher.readAttribute('data-inout') != $localInOutSwitcher.readAttribute('data-inout')) {
				$localInOutSwitcher.simulate('click');
			}

			if ($siblingConnection) {
				object = $siblingConnection.readAttribute('title').split(' > ').splice(0, 2).join(' >> ');

				if (($destinationInOutSwitcher.readAttribute('data-inout') == '0' && $siblingConnection.readAttribute('data-target-inout') == '2') || $destinationInOutSwitcher.readAttribute('data-inout') == '1' && $siblingConnection.readAttribute('data-target-inout') == '1') {
					$destinationInOutSwitcher.simulate('click');
				}

				$destinationObjectView.setValue(object).writeAttribute('data-last-value', object);
				$destinationObjectHidden.setValue($siblingConnection.readAttribute('data-target-id'));
				$destinationList.fire('update:objectSelection');
			} else {
				$destinationList.fire('reset:objectSelection');
			}

			localClickedIndex = $li.previousSiblings().size();

		});

		$destinationList.on('mouseover', 'li', function (ev) {
			var $li = ev.findElement('li');

			$localList.select('li[data-id="' + $li.readAttribute('data-connector-id') + '"]').invoke('addClassName', 'hover');

			$visualization.fire('highlight:destination', {'index': $li.previousSiblings().size()});
		});

		$destinationList.on('mouseout', 'li', function () {
			$localList.select('.hover').invoke('removeClassName', 'hover');

			$visualization.fire('highlight:none');
		});

		$destinationList.on('click', 'li', function (ev) {
			var $li         = ev.findElement('li'),
			    connectorID = $li.readAttribute('data-connector-id'),
			    $connector;

			$localList.select('li').invoke('removeClassName', 'clicked');
			$destinationList.select('li').invoke('removeClassName', 'clicked');

			localClickedIndex = null;
			destinationClickedIndex = $li.previousSiblings().size();

			if (connectorID !== null)
			{
				$connector = $localList.down('[data-id="' + connectorID + '"]');

				if ($connector)
				{
					localClickedIndex = $connector.previousSiblings().size();
				}
			}

			$visualization.fire('highlight:permanent');
			$visualization.fire('highlight:none');
			highlightListItems();
		});

		$destinationToggleAll.on('click', function () {
			$destinationList.select('input:not([disabled])').invoke('setValue', $destinationToggleAll.checked ? 1 : 0);

			updateConnectSelectedConnectorsButton();
		});

		$destinationList.on('click', 'input', function (ev) {
			var $checkbox = ev.findElement('input');

			if ($destinationLastCheckbox && window.keyPressedShift) {
				selectRange($checkbox, $destinationLastCheckbox).invoke('setValue', $checkbox.checked ? 1 : 0);
			}

			$destinationLastCheckbox = $checkbox;

			updateConnectSelectedConnectorsButton();
		});

		$destinationList.on('click', '.connected-with', function (ev) {
			var $span = ev.findElement('span'),
			    objectId = $span.readAttribute('data-target-id'),
				objectTitle = $span.readAttribute('title').split(' > ').splice(0, 2).join(' >> ');

			if (objectId == $localObjectHidden.getValue()) {
				$localInOutSwitcher.simulate('click');
				return;
			}

			$localObjectHidden.setValue(objectId);
			$localObjectView.setValue(objectTitle).writeAttribute('data-last-value', objectTitle);

			if (($localInOutSwitcher.readAttribute('data-inout') == '0' && $span.readAttribute('data-target-inout') == '1') || ($localInOutSwitcher.readAttribute('data-inout') == '1' && $span.readAttribute('data-target-inout') == '2')) {
				$localInOutSwitcher.simulate('click');
			}

			$local.fire('update:objectSelection', {renderAll:true});
		});

		$destinationList.on('click', '.sibling-connected-with', function (ev) {
			var $span = ev.findElement('span'),
			    objectId = $span.readAttribute('data-target-id'),
			    objectTitle = $span.readAttribute('title').split(' > ').splice(0, 2).join(' >> ');

			$destinationObjectHidden.setValue(objectId);
			$destinationObjectView.setValue(objectTitle).writeAttribute('data-last-value', objectTitle);

			$destination.fire('update:objectSelection', {renderAll:true});
		});

		$connectSelectedButton.on('click', function () {
			connectConnectors(
				$localList.select('input:checked:not([disabled])').invoke('up', 'li').invoke('readAttribute', 'data-id').join(),
				$destinationList.select('input:checked:not([disabled])').invoke('up', 'li').invoke('readAttribute', 'data-id').join()
			);
		});

		$changeCablesButton.on('click', function () {
			var $cables = $popup.select('li[data-cable-id] input:checked:not([disabled])');

			if (! $cables.length) {
				idoit.Notify.warning('[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_NO_CABLE_CONNECTION"}]', {life:5});

				return;
			}

			$modalCableBrowser.fire('update:gui', {cables:$cables.invoke('up', 'li').invoke('readAttribute', 'data-cable-id').compact()});
			$modalCableBrowser.fire('show:gui');
		});

		$disconnectSelectedButton.on('click', function () {
			if (confirm('[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_DETACH_CONFIRM" p_bHtmlEncode=false}]')) {
				detachConnector($popup.select('li input:checked:not([disabled])').invoke('up', 'li').invoke('readAttribute', 'data-id').join());
			}
		});

		$visualization.down('button').on('click', function (ev) {
			var tmp;

			tmp = $localObjectView.getValue();
			$localObjectView.setValue($destinationObjectView.getValue());
			$destinationObjectView.setValue(tmp);

			tmp = $localObjectHidden.getValue();
			$localObjectHidden.setValue($destinationObjectHidden.getValue());
			$destinationObjectHidden.setValue(tmp);

			tmp = $localObjectView.readAttribute('data-last-value');
			$localObjectView.writeAttribute('data-last-value', $destinationObjectView.readAttribute('data-last-value'));
			$destinationObjectView.writeAttribute('data-last-value', tmp);

			if ($localInOutSwitcher.readAttribute('data-inout') == $destinationInOutSwitcher.readAttribute('data-inout'))
			{
				$localInOutSwitcher.simulate('click');
				$destinationInOutSwitcher.simulate('click');
			}

			// In this case we need to render the lists multiple times, depending on which request finishes first :/
			$local.fire('update:objectSelection', {renderAll:true});
			$destination.fire('update:objectSelection', {renderAll:true});
		});

		$popup.on('click', 'button.detach:enabled', function (ev) {
			var $button = ev.findElement('button');

			if (confirm('[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_DETACH_CONFIRM_SINGLE" p_bHtmlEncode=false}]')) {
				detachConnector($button.up('li').readAttribute('data-id'));
			}
		});

		function checkDirectConnection () {
			var $connectorA = $localList.down('.btn-green'),
			    $connectorB = $destinationList.down('.btn-green'),
			    connA,
			    connB;

			if (!$connectorA || !$connectorB)
			{
				return;
			}

			connA = $connectorA.up('li').readAttribute('data-id');
			connB = $connectorB.up('li').readAttribute('data-id');

			if (connA == connB)
			{
				idoit.Notify.warning('[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_CONNECT_WITH_ITSELF"}]', {life: 5});
				return;
			}

			if (confirm('[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_CONFIRM_CONNECT_SELECTED_CONNECTORS" p_bHtmlEncode=false}]')) {
				$localList.select('input:checked:not([disabled])').invoke('setValue', 0);
				$destinationList.select('input:checked:not([disabled])').invoke('setValue', 0);

				$connectorA.up('li').down('input').setValue(1);
				$connectorB.up('li').down('input').setValue(1);

				updateConnectSelectedConnectorsButton();

				$connectSelectedButton.simulate('click');

				// connectConnectors(connA, connB);
			}
		}

		function spinConnectors(local) {
			var $list = (local ? $localList.down('ul') : $destinationList.down('ul'));

			if (Prototype.Browser.IE) {
				++ reRendering;
				renderList(local);
			} else {
				new Effect.Morph($list, {
					duration:     0.1,
					beforeUpdate: function (anim) {
						anim.element.setStyle({
							'-ms-transform': 'rotateY(' + (anim.position * 90) + 'deg)',
							'-webkit-transform': 'rotateY(' + (anim.position * 90) + 'deg)',
							'-moz-transform': 'rotateY(' + (anim.position * 90) + 'deg)',
							transform: 'rotateY(' + (anim.position * 90) + 'deg)'
						});
					},
					afterFinish:  function () {
						++ reRendering;
						renderList(local, true);

						// Re-select, because "renderList" updates the element.
						var $list = (local ? $localList.down('ul') : $destinationList.down('ul'));

						new Effect.Morph($list, {
							duration:     0.1,
							beforeUpdate: function (anim) {
								anim.element.setStyle({
									'-ms-transform': 'rotateY(-' + (90 - (anim.position * 90)) + 'deg)',
									'-webkit-transform': 'rotateY(-' + (90 - (anim.position * 90)) + 'deg)',
									'-moz-transform': 'rotateY(-' + (90 - (anim.position * 90)) + 'deg)',
									transform: 'rotateY(-' + (90 - (anim.position * 90)) + 'deg)'
								});
							}
						});
					}
				});
			}
		}

		function updateConnectSelectedConnectorsButton () {
			var $localCheckboxes = $localList.select('input:checked:not([disabled])'),
				$destinationCheckboxes = $destinationList.select('input:checked:not([disabled])'),
				message = '[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_NEED_TO_SELECT_EQUALLY" p_bHtmlEncode=false}]';

			if ($localCheckboxes.length && $localCheckboxes.length === $destinationCheckboxes.length) {
				$connectSelectedButton.enable().writeAttribute('title', null).removeClassName('mouse-help');
			} else {
				message = message.replace(':a', $localCheckboxes.length).replace(':b', $destinationCheckboxes.length);

				$connectSelectedButton.disable().writeAttribute('title', message).addClassName('mouse-help');
			}

			if ($localCheckboxes.invoke('up', 'li[data-connector-id]').compact().length + $destinationCheckboxes.invoke('up', 'li[data-connector-id]').compact().length) {
				$disconnectSelectedButton.enable()
					.writeAttribute('title', null)
					.removeClassName('mouse-help');
			} else {
				$disconnectSelectedButton.disable()
					.writeAttribute('title', '[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_NEED_TO_SELECT_AT_LEAST_ONE" p_bHtmlEncode=false}]')
					.addClassName('mouse-help');
			}

			if ($localCheckboxes.invoke('up', 'li[data-cable-id]').compact().length + $destinationCheckboxes.invoke('up', 'li[data-cable-id]').compact().length) {
				$changeCablesButton.enable()
	                .writeAttribute('title', null)
	                .removeClassName('mouse-help');
			} else {
				$changeCablesButton.disable()
                    .writeAttribute('title', '[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_NEED_TO_SELECT_AT_LEAST_ONE_CABLE" p_bHtmlEncode=false}]')
                    .addClassName('mouse-help');
			}
		}

		function getObjectConnectors(objectID, callback) {
			if (objectID > 0) {
				new Ajax.Request('[{$ajaxURL}]', {
					parameters: {
						id:   objectID,
						func: 'loadConnectorData'
					},
					method:     'post',
					onSuccess:  function (xhr) {
						var json = xhr.responseJSON;

						if (is_json_response(xhr, true))
						{
							if (json.success)
							{
								callback(json.data);
							}
							else
							{
								idoit.Notify.error(json.message, {sticky: true});
							}
						}
					}
				});
			} else {
				callback({"in": [], "out": []});
			}
		}

		function getLocalData(connectorID, inOut)
		{
			var i;

			for (i in localData[inOut])
			{
				if (localData[inOut].hasOwnProperty(i) && localData[inOut][i].id == connectorID)
				{
					return localData[inOut][i];
				}
			}

			return null;
		}

		function getDestinationData(connectorID, inOut)
		{
			var i;

			for (i in destinationData[inOut])
			{
				if (destinationData[inOut].hasOwnProperty(i) && destinationData[inOut][i].id == connectorID)
				{
					return destinationData[inOut][i];
				}
			}

			return null;
		}

		function connectConnectors(connectorA, connectorB) {
			var tmpA = connectorA.split(','), tmpB = connectorB.split(','), i;

			for (i in tmpA) {
				if (tmpA.hasOwnProperty(i) && tmpB.in_array(tmpA[i])) {
					idoit.Notify.info(('[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_CONNECTED_MULTIPLE_TIMES"}]'.replace(':id', tmpA[i])), {life:5});
				}
			}

			if (! $automaticCableSelection.checked) {
				$modalCableBrowser.fire('update:gui', {
					local:       $localList.select('input:checked:not([disabled])').invoke('up', 'li').invoke('readAttribute', 'data-id').compact(),
					destination: $destinationList.select('input:checked:not([disabled])').invoke('up', 'li').invoke('readAttribute', 'data-id').compact()
				});

				$modalCableBrowser.fire('define:callbackSave', {
					callback: function (changes) {
						var i, cables = [];

						connectorA = [];
						connectorB = [];

						for (i in changes) {
							if (changes.hasOwnProperty(i)) {
								connectorA.push(changes[i].connA);
								connectorB.push(changes[i].connB);
								cables.push(changes[i].to);
							}
						}

						connectConnectorsCall(connectorA.join(), connectorB.join(), cables.join());
					}
				});

				$modalCableBrowser.fire('define:callbackAbort', {
					callback: function () {
						// Do nothing for now.
					}
				});

				$modalCableBrowser.fire('show:gui');
			} else {
				connectConnectorsCall(connectorA, connectorB, null);
			}
		}

		function connectConnectorsCall(connectorA, connectorB, cables)
		{
			$modalBox.removeClassName('hide');
			$modalLoading.removeClassName('hide');

			new Ajax.Request('[{$ajaxURL}]', {
				parameters: {
					a:      connectorA,
					b:      connectorB,
					cables: cables,
					func:   'connectConnectors'
				},
				method:     'post',
				onSuccess:  function (xhr) {
					var json = xhr.responseJSON;

                    dataChanged = true;

					if (is_json_response(xhr, true))
					{
						if (json.success)
						{
							$local.fire('update:objectSelection', {renderAll: true});
							$destination.fire('update:objectSelection', {renderAll: true});
						}
						else
						{
							idoit.Notify.error(json.message, {sticky: true});
						}
					}

					$modalBox.addClassName('hide');
					$modalLoading.addClassName('hide');
				}
			});
		}

		function unsetConnectorData (conn)
		{
			delete conn.connectorId;
			delete conn.connectorTitle;
			delete conn.connectorInOut;
			delete conn.connectorObjId;
			delete conn.connectorObjTitle;
			delete conn.connectorObjTypeTitle;
		}

		function detachConnector (connector)
		{
			$modalBox.removeClassName('hide');
			$modalLoading.removeClassName('hide');

			new Ajax.Request('[{$ajaxURL}]', {
				parameters: {
					connector: connector,
					func:      'detachConnector'
				},
				method:     'post',
				onSuccess:  function (xhr) {
					var json = xhr.responseJSON,
					    connectors = connector.split(','),
					    i, i2;

                    dataChanged = true;

					if (is_json_response(xhr, true))
					{
						if (json.success)
						{
							// Check if all "detach" calls have returned true - if NOT we reload the lists (via ajax).
							if (json.data.length == json.data.filter(function(self) {return self;}).length)
							{
								// Remove all connection information of the selected connectors.
								for (i in connectors)
								{
									if (connectors.hasOwnProperty(i))
									{
										for (i2 in localData.in)
										{
											if (!localData.in.hasOwnProperty(i2))
											{
												continue;
											}

											if (localData.in[i2].id == connectors[i] || localData.in[i2].connectorId == connectors[i])
											{
												unsetConnectorData(localData.in[i2]);
											}

											if (localData.out[i2].id == connectors[i] || localData.out[i2].connectorId == connectors[i])
											{
												unsetConnectorData(localData.out[i2]);
											}
										}

										for (i2 in destinationData.in)
										{
											if (!destinationData.in.hasOwnProperty(i2))
											{
												continue;
											}

											if (destinationData.in[i2].id == connectors[i] || destinationData.in[i2].connectorId == connectors[i])
											{
												unsetConnectorData(destinationData.in[i2]);
											}

											if (destinationData.out[i2].id == connectors[i] || destinationData.out[i2].connectorId == connectors[i])
											{
												unsetConnectorData(destinationData.out[i2]);
											}
										}
									}
								}

								reRendering = 2;
								renderList(true);
								renderList(false);
							}
							else
							{
								$local.fire('update:objectSelection', {renderAll:true});
								$destination.fire('update:objectSelection', {renderAll:true});
							}
						}
						else
						{
							idoit.Notify.error(json.message, {sticky: true});
						}
					}

					$modalBox.addClassName('hide');
					$modalLoading.addClassName('hide');
				}
			});
		} // function

		function prepareListData(listData)
		{
		    var i;

			for (i in listData)
			{
				if (listData.hasOwnProperty(i))
				{
					listData[i].directlyConnected = false;
				}
			}

			return listData;

			// This can cause errors.
			return listData.sort(function (a, b) {
				return a.title.localeCompare(b.title);
			});
		}

		function selectRange($checkboxA, $checkboxB) {
			var inRange = false;

			return $checkboxA.up('ul').select('input:not([disabled])').filter(function ($checkbox) {
				if (!inRange && $checkbox !== $checkboxA && $checkbox !== $checkboxB)
				{
					return false;
				}
				else if ($checkbox === $checkboxA || $checkbox === $checkboxB)
				{
					inRange = !inRange;
					return true;
				}
				else if (inRange)
				{
					return true;
				}
			})
		}

		function renderList(local, rotated)
		{
			var i, i2, matching = [], data, siblingData, localPreparedData, destinationPreparedData,
			    $ul = new Element('ul', {className: 'm0 list-style-none'}), $li;

			if (rotated)
			{
				$ul.setStyle({transform:'rotateY(-90deg)'});
			}

			localPreparedData = prepareListData(($localInOutSwitcher.readAttribute('data-inout') === '0' ? localData.out : localData.in));
			destinationPreparedData = prepareListData(($destinationInOutSwitcher.readAttribute('data-inout') === '0' ? destinationData.in : destinationData.out));

			if (local) {
				$localToggleAll.setValue(0);
				siblingData = ($localInOutSwitcher.readAttribute('data-inout') === '0') ? localData.in : localData.out;
			} else {
				$destinationToggleAll.setValue(0);
				siblingData = ($destinationInOutSwitcher.readAttribute('data-inout') === '0') ? destinationData.out : destinationData.in;
			}

			for (i in localPreparedData) {
				if (! localPreparedData.hasOwnProperty(i) || !localPreparedData[i].hasOwnProperty('connectorId')) {
					continue;
				}

				for (i2 in destinationPreparedData) {
					if (! destinationPreparedData.hasOwnProperty(i2) || destinationPreparedData[i2].id === null) {
						continue;
					}

					if (localPreparedData[i].connectorId == destinationPreparedData[i2].id) {
						localPreparedData[i].directlyConnected = true;
						destinationPreparedData[i2].directlyConnected = true;

						matching.push([parseInt(i), parseInt(i2)]);
					}
				}
			}

			data = (local ? localPreparedData : destinationPreparedData);

			if (!data.length)
			{
				if (local ? localObjectID : destinationObjectID) {
					$ul.update(new Element('li')
						.update(new Element('img', {src:window.dir_images + 'icons/silk/information.png', className:'mr5'}))
						.insert(new Element('span').update('[{isys type="lang" ident="LC__CMDB__FILTER__NOTHING_FOUND_STD"}]')))
				} else {
					$ul.update(new Element('li')
						.update(new Element('img', {src:window.dir_images + 'icons/silk/information.png', className:'mr5'}))
						.insert(new Element('span').update('[{isys type="lang" ident="LC__CMDB__BROWSER_OBJECT__PLEASE_CHOOSE"}]')))
				}
			}

			for (i in data) {
				if (!data.hasOwnProperty(i)) {
					continue;
				}

				var $checkbox = new Element('input', {type:'checkbox', value:(local?'local-':'destination-') + data[i].id}),
					$connector = new Element('span', {className:'connector-name'}).update(data[i].title),
				    $connection = new Element('span', {className: 'connected-with ml5 text-red mouse-pointer'}),
				    $siblingConnector = new Element('span', {className:'connector-sibling-name'}).update(siblingData[i].title),
				    $siblingConnection = new Element('span', {className: 'sibling-connected-with ml5 text-red mouse-pointer'}),
					$connectWith = new Element('button', {type:'button', className:'btn btn-small connection'}),
					$cableContainer = new Element('div', {className:'connector-cable-container'}),
					$cable = new Element('div', {className:'connector-cable'}).update(data[i].cableTitle),
					$hopper = new Element('button', {type:'button', className:'btn btn-small hopper', title:'[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_HOP" p_bHtmlEncode=false}]'}),
					$detach = new Element('button', {type:'button', className:'btn btn-small detach', title:'[{isys type="lang" ident="LC__UNIVERSAL__DETACH" p_bHtmlEncode=false}]', disabled: true})
							.update(new Element('img', {src:window.dir_images + 'icons/silk/cross.png'}));

				if (data[i].id === null) {
					$checkbox.disable();
				}

				$li = new Element('li', {'data-id': data[i].id, 'data-connector-id': (data[i].connectorId || null), 'data-cable-id': (data[i].cableId || null)});

				if (local) {
					$connectWith.writeAttribute({title:'[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_CONNECT_WITH" p_bHtmlEncode=false}]'})
			            .update(new Element('img', {src:window.dir_images + 'icons/silk/disconnect.png'}));

					$hopper.update(new Element('img', {src: window.dir_images + 'icons/silk/arrow_left.png'}));

					$li
					    .update($siblingConnector.insert($siblingConnection))
					    .insert($checkbox)
					    .insert($connector.insert($connection))
						.insert($hopper)
					    .insert($connectWith)
						.insert($detach);
				} else {
					$connectWith.writeAttribute({title:'[{isys type="lang" ident="LC__CABLE_CONNECTION__POPUP_CONNECTION_CONNECT_WITH" p_bHtmlEncode=false}]'})
					    .update(new Element('img', {src:window.dir_images + 'icons/silk/disconnect.png'}));

					$hopper.update(new Element('img', {src: window.dir_images + 'icons/silk/arrow_right.png'}));

					$li
						.update($checkbox)
						.insert($connector.insert($connection))
						.insert($siblingConnector.insert($siblingConnection))
						.insert($detach)
						.insert($connectWith)
						.insert($hopper);
				}

				if (!data[i].hasOwnProperty('id') || !data[i].id) {
                    $connectWith.disable();
                }

				if (data[i].hasOwnProperty('connectorId') && data[i].connectorId > 0) {
					$li.addClassName('connected');
					$detach.enable();

					if (data[i].directlyConnected) {
						$li.addClassName('directly-connected')
						   .insert($cableContainer
							   .update($cable.writeAttribute({'data-cable-id': data[i].cableId})));

						// In case of an direct connection, we don not want to display this button.
						$connection.remove();
					} else {
						$connection.update(data[i].connectorObjTitle).writeAttribute({
							title:               data[i].connectorObjTypeTitle + ' > ' + data[i].connectorObjTitle + ' > ' + data[i].connectorTitle,
							'data-target-id':    data[i].connectorObjId,
							'data-target-inout': data[i].connectorInOut
						});
					}
				} else {
					$connection.remove();
				}

				if (siblingData[i].hasOwnProperty('connectorId') && siblingData[i].connectorId > 0) {
					$siblingConnection.update(siblingData[i].connectorObjTitle).writeAttribute({
						title:               siblingData[i].connectorObjTypeTitle + ' > ' + siblingData[i].connectorObjTitle + ' > ' + siblingData[i].connectorTitle,
						'data-target-id':    siblingData[i].connectorObjId,
						'data-target-inout': siblingData[i].connectorInOut
					});
				}

				$ul.insert($li);
			}

			if (local)
			{
				$localList.removeClassName('connect-to').update($ul);
			}
			else
			{
				$destinationList.removeClassName('connect-to').update($ul);
			}

			$visualization.fire('update:dimension');
			$visualization.fire('reset:visualization');
			$visualization.fire('highlight:permanent');
			$visualization.fire('update:visualization', {'matching': matching});
			$visualization.fire('highlight:none');

			updateConnectSelectedConnectorsButton();

			--reRendering;

			if (reRendering === 0) {
				highlightListItems();
			}
		}

		function highlightListItems () {
			var tmp, $tmp;

			if (localClickedIndex === null && destinationClickedIndex === null) {
				return;
			}

			// The destination list has a clicked item - try to find the connected "local" connector.
			if (localClickedIndex !== null && destinationClickedIndex === null) {
				tmp = $localList
					.down('li', localClickedIndex)
					.readAttribute('data-connector-id');

				if (tmp !== null) {
					$tmp = $destinationList.down('[data-id="' + tmp + '"]');
				}

				if ($tmp) {
					destinationClickedIndex = $tmp.previousSiblings().size();
				}
			}

			// The local list has a clicked item - try to find the connected "destination" connector.
			if (localClickedIndex === null && destinationClickedIndex !== null) {
				tmp = $destinationList
					.down('li', destinationClickedIndex)
					.readAttribute('data-connector-id');

				if (tmp !== null) {
					$tmp = $localList.down('[data-id="' + tmp + '"]');
				}

				if ($tmp) {
					localClickedIndex = $tmp.previousSiblings().size();
				}
			}

			// Both sides have been "clicked" - check, if the connections match!
			if (localClickedIndex !== null && destinationClickedIndex !== null) {
				tmp = $destinationList
						.down('li', destinationClickedIndex)
						.readAttribute('data-connector-id');

				if (tmp !== null) {
					$tmp = $localList.down('[data-id="' + tmp + '"]');
				} else {
					destinationClickedIndex = null;
				}

				if ($tmp) {
					if (localClickedIndex != $tmp.previousSiblings().size()) {
						localClickedIndex = null;
					}
				} else {
					localClickedIndex = null;
				}
			}

			if (localClickedIndex !== null) {
				$localList
					.down('li', localClickedIndex)
					.addClassName('clicked');
			} else {
				$localList.select('.clicked').invoke('removeClassName', 'clicked');
			}

			if (destinationClickedIndex !== null) {
				$destinationList
					.down('li', destinationClickedIndex)
					.addClassName('clicked');
			} else {
				$destinationList.select('.clicked').invoke('removeClassName', 'clicked');
			}
		}

        $automaticCableSelection.on('change', function () {
            new Ajax.Request('[{$ajaxURL}]', {
                parameters: {
                    value: ($automaticCableSelection.checked ? 1 : 0),
                    func:  'setAutomaticCableDefault'
                },
                method:     'post'
            });
        });

		idoit.Require.require(['d3', 'd3VisConnection', 'popupConnectionCable'], function () {
			var visualization,
				connectionCable;

			/*********************************************
			 * Visualization events                      *
			 *********************************************/
			$visualization.on('update:visualization', function (ev) {
				visualization.setData(ev.memo.matching).update();
			});

			$visualization.on('update:dimension', function () {
				visualization.updateDimension(null, Math.max($localList.getHeight(), $destinationList.getHeight()));
			});

			$visualization.on('reset:visualization', function () {
				visualization.reset();
			});

			$visualization.on('highlight:permanent', function () {
				visualization.highlightPermanent(localClickedIndex, destinationClickedIndex);
			});

			$visualization.on('highlight:local', function (ev) {
				visualization.highlight(ev.memo.index, null);
			});

			$visualization.on('highlight:destination', function (ev) {
				visualization.highlight(null, ev.memo.index);
			});

			$visualization.on('highlight:none', function () {
				visualization.highlight(null, null);
			});

			/*********************************************
			 * Cable connection events                   *
			 *********************************************/
			$modalCableBrowser.on('show:gui', function () {
				$modalCableBrowser.removeClassName('hide');
				$modalBox.addClassName('dark').removeClassName('light').removeClassName('hide');
			});

			$modalCableBrowser.on('update:gui', function (ev) {
				if (Object.isArray(ev.memo.cables)) {
					connectionCable.setCables(ev.memo.cables).setConnectors([], []).update();
				} else if (Object.isArray(ev.memo.local) && Object.isArray(ev.memo.destination)) {
					connectionCable.setCables([]).setConnectors(ev.memo.local, ev.memo.destination).update();
				}
			});

			$modalCableBrowser.on('define:callbackSave', function (ev) {
				connectionCable.setSaveCallback(ev.memo.callback);
			});

			$modalCableBrowser.on('define:callbackAbort', function (ev) {
				connectionCable.setAbortCallback(ev.memo.callback);
			});

			$modalCableBrowser.on('click', '.modal-closer', function () {
				if (Object.isFunction(connectionCable.options.abortCallback)) {
					// Call the "abort callback".
					connectionCable.options.abortCallback();
				}

				$modalCableBrowser.addClassName('hide');
				$modalBox.addClassName('light').removeClassName('dark').addClassName('hide');

				// Remove the callbacks.
				connectionCable.setAbortCallback(null);
				connectionCable.setSaveCallback(null);

				// Remove all green buttons and checked checkboxes.
				$localList.removeClassName('connect-to').select('.btn-green').invoke('removeClassName', 'btn-green');
				$localList.select('input:checked').invoke('setValue', 0);
				$destinationList.removeClassName('connect-to').select('.btn-green').invoke('removeClassName', 'btn-green');
				$destinationList.select('input:checked').invoke('setValue', 0);
			});

			$modalCableBrowser.on('click', '.modal-accept', function () {
				connectionCable.saveCables(function () {
                    dataChanged = true;

					$local.fire('update:objectSelection', {renderAll:true});
					$destination.fire('update:objectSelection', {renderAll:true});

					$modalCableBrowser.addClassName('hide');
					$modalBox.addClassName('light').removeClassName('dark').addClassName('hide');

					// Remove the callbacks.
					connectionCable.setAbortCallback(null);
					connectionCable.setSaveCallback(null);
				});
			});

			/*********************************************
			 * Creating class instances                  *
			 *********************************************/
			//connection = new window.Connection('', {});

			visualization = new window.ConnectionVisualization($visualization, {
				heigt: Math.max($localList.getHeight(), $destinationList.getHeight())
			});

			connectionCable = new window.ConnectionCable($modalCableBrowser, {
				url:      '[{$ajaxURL}]',
				width:    500,
				height:   400
			});

			$local.fire('update:objectSelection');
			$destination.fire('reset:objectSelection');
		});
	}());
</script>
<style type="text/css">
	#popup-connection {
		height: 100%;
		position: relative;
	}

	#popup-connection * {
		box-sizing: border-box;
	}

	#popup-connection img {
		vertical-align: middle;
	}

	#popup-connection td {
		vertical-align: top;
	}

	#popup-connection .popup-content {
		position: absolute !important;
		top: 41px;
		bottom: 0;
	}

	#popup-connection .box-lightgrey.gradient button.btn {
		margin: -2px;
	}

	#popup-connection .popup-header button.btn {
		margin: -4px 0 -4px 0;
	}

	#C__CONNECTION_POPUP__CONNECTION {
		width: 110px;
	}

	#C__CONNECTION_POPUP__CONNECTION button {
		position:absolute;
		top:5px;
		left: auto;
		margin:0 40px;
	}

	#C__CONNECTION_POPUP__CONNECTION path {
		stroke: #e0e0e0;
		fill: transparent;
		stroke-width: 5px;
		stroke-linecap: round;
		stroke-linejoin: round;
	}

	#C__CONNECTION_POPUP__CONNECTION path.highlight {
		stroke: #36a9f7;
	}

	#C__CONNECTION_POPUP__LOCAL_SWITCHER strong:first-of-type,
	#C__CONNECTION_POPUP__LOCAL_SWITCHER strong:last-of-type,
	#C__CONNECTION_POPUP__DESTINATION_SWITCHER strong:first-of-type,
	#C__CONNECTION_POPUP__DESTINATION_SWITCHER strong:last-of-type {
		position: absolute;
		top: 5px;
		left: 5px;
	}

	#C__CONNECTION_POPUP__LOCAL_SWITCHER strong:last-of-type {
		left: auto;
		right: 33px;
	}

	#C__CONNECTION_POPUP__DESTINATION_SWITCHER strong:first-of-type {
		left: 28px;
	}

	#C__CONNECTION_POPUP__DESTINATION_SWITCHER strong:last-of-type {
		left: auto;
		right: 5px;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS {
		-webkit-perspective: 1000px;
		-moz-perspective: 1000px;
		perspective: 1000px;

		-webkit-perspective-origin: center 200px;
		-moz-perspective-origin: center 200px;
		perspective-origin: center 200px;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS .connector-cable-container,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS .connector-cable-container {
		display: none;
		right: -50px;
		width: 50px;
		height: 20px;
		top: 6px;
		position: absolute;
	}

	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS .connector-cable-container {
		left: -50px;
		right: auto;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS .connector-cable,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS .connector-cable {
		position: absolute;
		width: 40px;
		background: #36a9f7;
		border-radius: 8px;
		text-align: center;
		padding: 0 5px;
		color: #fff;
		right: 0;
	}

	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS .connector-cable {
		left: 0;
		right: auto;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li {
		padding: 5px;
		background: #fff;
		height: 30px;
		line-height: 20px;
		position: relative;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li:nth-child(2n+1),
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li:nth-child(2n+1) {
		background: #eee;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li.clicked,
	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li.clicked:hover,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li.clicked,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li.clicked:hover {
		background: #36a9f7;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li:hover,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li:hover {
		background: #9CCDF7;
	}

	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li.directly-connected {
		border-left: 4px solid #e0e0e0 !important;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li.directly-connected {
		border-right: 4px solid #e0e0e0 !important;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li {
		border-right: 4px solid transparent;
		border-left: 4px solid transparent;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li.directly-connected:hover,
	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li.directly-connected.hover,
	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li.directly-connected.clicked {
		border-right: 4px solid #36a9f7 !important;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li.directly-connected:hover .connector-cable-container,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li.directly-connected:hover .connector-cable-container {
		display: block;
	}

	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li.directly-connected:hover,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li.directly-connected.hover,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li.directly-connected.clicked {
		border-left: 4px solid #36a9f7 !important;
	}

	#C__CONNECTION_POPUP__LOCAL_SELECT_ALL {
		margin: 2px 8px 0 5px;
		float: right;
	}

	#C__CONNECTION_POPUP__DESTINATION_SELECT_ALL {
		margin: 2px 5px 0 3px;
		float: left;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li input,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li input {
		margin: 3px 5px 0 0;
		float: right;
	}

	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li input {
		float: left;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li button,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li button {
		opacity: 0;
		position: absolute;
		left:50%;
		margin-left:-14px;
		top:5px;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li button.connection {
		margin-left:14px;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li button.detach {
		margin-left:42px;
	}

	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li button.connection {
		margin-left:-42px;
	}

	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li button.detach {
		margin-left:-70px;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li:hover button,
	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li button.btn-green,
	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li button.hopper,
	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS.connect-to li button.connection,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li:hover button,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li button.btn-green,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li button.hopper,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS.connect-to li button.connection {
		opacity: 1;
	}

	/* Because we overwrite the opacity of all buttons we need to re-add this stylings */
	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li:hover button[disabled],
	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS li:hover button.disabled,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li:hover button[disabled],
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS li:hover button.disabled {
		opacity: 0.5;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS .connector-name,
	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS .connector-sibling-name,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS .connector-name,
	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS .connector-sibling-name {
		max-width: 50%;
		text-overflow: ellipsis;
		overflow: hidden;
		white-space: nowrap;
		display: block;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS .connector-sibling-name {
		float: left;
		margin-left: 5px;
	}

	#C__CONNECTION_POPUP__LOCAL_OBJECT_CONNECTORS .connector-name {
		float: right;
		margin-right: 5px;
		max-width: 43%;
	}

	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS .connector-name {
		float: left;
		max-width: 45%;
	}

	#C__CONNECTION_POPUP__DESTINATION_OBJECT_CONNECTORS .connector-sibling-name {
		float: right;
		margin-right: 5px;
		max-width: 47%;
	}

	#C__CONNECTION_POPUP__MODAL {
		position: absolute;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
	}

	#C__CONNECTION_POPUP__MODAL.light {
		background-color: rgba(255, 255, 255, .3);
	}

	#C__CONNECTION_POPUP__MODAL.dark {
		background-color: rgba(0, 0, 0, .3);
	}

	#C__CONNECTION_POPUP__LOADING {
		position: absolute;
		top: 50%;
		left: 50%;
		width: 250px;
		height: 30px;
		margin-left: -125px;
		margin-top: -15px;
		line-height: 30px;
		text-align: center;
	}

	#C__CONNECTION_POPUP__CABLE_BROWSER {
		position: absolute;
		top: 50%;
		left: 50%;
	}
</style>
[{/isys_group}]