/*
 * @copyright   Copyright (C) 2010-2024 Combodo SAS
 * @license     http://opensource.org/licenses/AGPL-3.0
 */

;
$(function()
{
	// the widget definition, where 'itop' is the namespace,
	// 'object_details' the widget name
	$.widget( 'itop.object_details', $.itop.panel,
	{
		// default options
		options:
		{
		},
		css_classes:
		{
		},
		js_selectors:
		{
		},
   
		// the constructor
		_create: function()
		{
			this._super();

			this._initializeSubmittingButtonsObserver();
		},
		// events bound via _bind are removed automatically
		// revert other modifications here
		_destroy: function()
		{
			this._super();
		},

		_bindEvents: function ()
		{
			this._super();

			// Keep URL's hash parameters when clicking on a link of the header
			// Note: ":first" used to only target the header of the object, not what could be in the content of its body
			this.element.find('[data-role="ibo-panel--header-right"]').first().on('click', 'a', function() {
				aMatches = /#(.*)$/.exec(window.location.href);
				if (aMatches != null) {
					currentHash = aMatches[1];
					if (/#(.*)$/.test(this.href)) {
						this.href = this.href.replace(/#(.*)$/, '#'+currentHash);
					}
				}
			});
		},
		/**
		 * Initialize the observer on the submitting buttons (cancel, apply, transitions, ...) to display only the grouped button depending on the available space
		 * @private
		 */
		_initializeSubmittingButtonsObserver: function()
		{
			// This only applies in edit mode
			if (this._getObjectMode() !== 'edit') {
				return false;
			}

			// If no ResizeObserver, fallback is that transition buttons will overflow on smaller screen
			if (window.ResizeObserver === undefined) {
				return false;
			}

			// Check if transitions available
			const oHeaderElem = this.element.find('[data-role="ibo-panel--header"]').first();
			const oButtonsToolbarElem = oHeaderElem.find('[data-role="ibo-panel--header-right"] [data-role="ibo-toolbar"]');
			const oTransitionButtonsElems = oButtonsToolbarElem.find('[name="next_action"][data-role="ibo-button"]');
			if (oHeaderElem.find('[name="next_action"][data-role="ibo-button"]').length === 0) {
				return false;
			}

			let iCurrentHeaderWidth = 0;
			let iCurrentHeaderHeight = 0;
			let hTimeout = null;
			const oObserver = new ResizeObserver(function(aEntries) {
				// Throttle the processing in order to limit CPU usage
				clearTimeout(hTimeout);
				hTimeout = setTimeout(() => {
					let iNewHeaderWidth = parseInt(oHeaderElem.outerWidth());
					let iNewHeaderHeight = parseInt(oHeaderElem.outerHeight());
					if (Math.abs(iNewHeaderWidth - iCurrentHeaderWidth) < 5 && Math.abs(iNewHeaderHeight - iCurrentHeaderHeight) === 0) {
						return;
					}

					let oLastTransitionButton = oButtonsToolbarElem.find('[name="next_action"][data-role="ibo-button"]:last');

					// 1. Make transition buttons invisible BUT occuping space, so we can check where the last one would be
					oTransitionButtonsElems.css('visibility', 'hidden');
					oTransitionButtonsElems.removeClass('ibo-is-hidden');
					// 2. Measure position
					let iLastTransitionButtonBorderX = parseInt(oLastTransitionButton.offset().left + oLastTransitionButton.outerWidth());
					// 3. Make transition buttons invisible AND not occuping space again
					oTransitionButtonsElems.addClass('ibo-is-hidden');
					oTransitionButtonsElems.css('visibility', '');

					let iPanelRightBorderX = parseInt(oHeaderElem.offset().left + oHeaderElem.outerWidth());

					if (iLastTransitionButtonBorderX > iPanelRightBorderX) {
						oButtonsToolbarElem.find('.action[data-role="ibo-button"]:not([name="cancel"])').addClass('ibo-is-hidden');
						oButtonsToolbarElem.find('[data-role="ibo-button-group"]:last').removeClass('ibo-is-hidden');
					}
					else {
						oButtonsToolbarElem.find('.action[data-role="ibo-button"]:not([name="cancel"])').removeClass('ibo-is-hidden');
						oButtonsToolbarElem.find('[data-role="ibo-button-group"]:last').addClass('ibo-is-hidden');
					}

					iCurrentHeaderWidth = parseInt(oHeaderElem.outerWidth());
					iCurrentHeaderHeight = parseInt(oHeaderElem.outerHeight());

				}, 100);
			});
			// Note: ":first" used to only target the header of the object, not what could be in the content of its body
			oObserver.observe(oHeaderElem[0]);
		},

		// Helpers
		/**
		 * @return {String} The current object display mode ({@see PHP \cmdbAbstractObject for possible values})
		 * @private
		 */
		_getObjectMode: function()
		{
			return this.element.attr('data-object-mode');
		}
	});
});
