/**
 * This file is used for widgets designer mode
 */

jQuery( document ).on( 'mouseover', '.evo_container[data-code]', function()
{	// Initialize and Show container designer block:
	var container = jQuery( this );

	if( jQuery( '.evo_designer.evo_designer__widget[data-widget-block-clicked=1]' ).length == 0 )
	{	// Unmark currently selected sub-container only when this is not event of clicking on child widget of the subcontainer:
		// To be sure all previous designer blocks are hidden before show new one:
		jQuery( '.evo_designer__container' ).hide();
	}

	// Initialize designer block for widget container:
	evo_widget_initialize_designer_container_block( container );
} );

/**
 * Initialize designer block for widget container
 *
 * @param object Widget
 */
function evo_widget_initialize_designer_container_block( container )
{
	if( jQuery( evo_widget_container_block_selector( container.data( 'code' ) ) ).length )
	{	// Just display a designer block if it already has been initialized previous time:
		evo_widget_update_container_position( container );
		return;
	}

	// Fix z-index issue:
	evo_widget_fix_parent_zindex( container );

	// Initialize a container designer block only first time:
	var container_actions = '';
	if( container.data( 'can-edit' ) == '1' )
	{	// Display a panel with actions if current user has a permission to edit widgets:
		container_actions = '<div class="evo_designer__actions">' +
				b2evo_widget_icon_list +
				b2evo_widget_icon_add +
			'</div>';
	}
	jQuery( 'body' ).append( '<div class="evo_designer evo_designer__container" data-code="' + container.data( 'code' ) + '">' +
			'<div><div class="evo_designer__title">Container: ' + container.data( 'name' ) + '</div>' + container_actions + '</div>' +
		'</div>' );
	evo_widget_update_container_position( container );
}

jQuery( document ).on( 'mouseover', '.evo_widget[data-id]', function( e )
{	// Initialize and Show widget designer block:
	var widget = jQuery( this );

	if( jQuery( '.evo_designer.evo_designer__status_process[data-container="' + widget.data( 'container' ) + '"]' ).length ||
	    jQuery( '.evo_designer.evo_designer__status_success[data-container="' + widget.data( 'container' ) + '"]' ).length )
	{	// Don't show other widget designer block from the same container while previous one in process:
		return;
	}

	jQuery( '.evo_designer.evo_designer__subcontainer_active, .evo_designer.evo_designer__subcontainer_inactive' ).each( function()
	{
		if( ! ( e.pageX >= jQuery( this ).offset().left - 3 && e.pageY >= jQuery( this ).offset().top - 3 && // top-left point
		        e.pageX <= jQuery( this ).offset().left + jQuery( this ).width() + 3 && e.pageY <= jQuery( this ).offset().top + jQuery( this ).height() + 3 ) ) // bottom-right point
		{	// If mouse cursor is outside of current active sub-container,
			// Hide current desinger block:
			jQuery( this ).hide();
			// Unmark active subcontainer widget:
			jQuery( '.evo_widget.evo_widget__subcontainer_active[data-id=' + jQuery( this ).data( 'id' )+ ']' ).removeClass( 'evo_widget__subcontainer_active' );
		}
	} );

	// Initialize designer block for widget:
	evo_widget_initialize_designer_block( widget );
} );


/**
 * Initialize designer block for widget
 *
 * @param object Widget
 */
function evo_widget_initialize_designer_block( widget )
{
	var designer_block_selector = evo_widget_designer_block_selector( widget );
	if( jQuery( designer_block_selector ).length )
	{	// Just display a designer block if it already has been initialized previous time:
		evo_widget_update_designer_position( widget );
		return;
	}

	// Fix z-index issue:
	evo_widget_fix_parent_zindex( widget );

	// Get all same widgets from the same container:
	var same_widgets = evo_widget_get_duplicates( widget );

	// Initialize a widget designer block only first time:
	var designer_block_start = '<div class="evo_designer evo_designer__widget" data-id="' + widget.data( 'id' ) + '" data-container="' + widget.data( 'container' ) + '">';
	var designer_block_end = '</div>';
	jQuery( 'body' ).append( designer_block_start + '<div><div class="evo_designer__title">' + widget.data( 'type' ) + '</div></div>' + designer_block_end );
	if( widget.data( 'can-edit' ) == '1' )
	{	// Display a panel with actions if current user has a permission to edit widget:
		var additional_widget_icons = '';
		if( widget.hasClass( 'widget_core_subcontainer' ) )
		{	// Icons to add and list widgets in sub-container:
			additional_widget_icons += b2evo_widget_icon_add + b2evo_widget_icon_list;
		}
		jQuery( '>div', designer_block_selector ).append( '<div class="evo_designer__actions">' +
				additional_widget_icons +
				b2evo_widget_icon_top +
				b2evo_widget_icon_up +
				b2evo_widget_icon_down +
				b2evo_widget_icon_bottom +
				b2evo_widget_icon_duplicate +
				b2evo_widget_icon_disable +
			'</div>' );
		var next_widget = same_widgets.eq( same_widgets.length - 1 ).next( '.evo_widget' );
		if( next_widget.length == 0 )
		{	// Hide action icon to move widget down if it is the last widget in container:
			jQuery( designer_block_selector ).find( '.evo_designer__action_order_down' ).hide();
		}
		if( next_widget.next( '.evo_widget' ).length == 0 )
		{	// Hide action icon to move widget to bottom if it is the penultimate widget in container:
			jQuery( designer_block_selector ).find( '.evo_designer__action_order_bottom' ).hide();
		}
		var prev_widget = same_widgets.eq( 0 ).prev( '.evo_widget' );
		if( prev_widget.length == 0 )
		{	// Hide action icon to move widget up if it is the first widget in container:
			jQuery( designer_block_selector ).find( '.evo_designer__action_order_up' ).hide();
		}
		if( prev_widget.prev( '.evo_widget' ).length == 0 )
		{	// Hide action icon to move widget to top if it is the second widget in container:
			jQuery( designer_block_selector ).find( '.evo_designer__action_order_top' ).hide();
		}
	}
	for( var w = 2; w <= same_widgets.length; w++ )
	{	// Initialize additional designer blocks for blocks of the same widget, e.g. for items/posts list widget in Menu container:
		jQuery( 'body' ).append( designer_block_start + designer_block_end );
	}
	// Set correct position for new created designer block:
	evo_widget_update_designer_position( widget );

	if( widget.hasClass( 'widget_core_subcontainer' ) )
	{	// If widget is a subcontainer,
		// Set unique number for subcontainer because same subcontainer widget may be used several times on the same page
		var subcontainer_unique_num = jQuery( '.evo_widget.widget_core_subcontainer[data-unique-num]' ).length + 1;
		widget.attr( 'data-unique-num', subcontainer_unique_num );
		jQuery( designer_block_selector ).attr( 'data-unique-num', subcontainer_unique_num );
	}
}

jQuery( document ).on( 'mouseover', '.evo_designer__widget', function()
{	// Show container designer block:
	var widget = jQuery( evo_widget_selector( jQuery( this ) ) );
	var container_block = jQuery( evo_widget_container_block_selector( widget.data( 'container' ) ) );
	if( ! container_block.is( ':visible' ) )
	{
		container_block.show();
	}
} );

jQuery( document ).on( 'click', '.evo_designer__action_add, .evo_designer__action_list', function( e )
{	// Link to add widget or to manage widgets of the container:
	if( typeof( b2evo_widget_add_url ) != 'undefined' )
	{	// If global widget add/list form url is defined:
		var container_block = jQuery( this ).closest( '.evo_designer__container' );
		if( container_block.length )
		{	// This is a container:
			var container = jQuery( evo_widget_container_selector( container_block ) );
			if( container.length && container.data( 'can-edit' ) == '1' )
			{
				var container_name = container.data( 'name' );
				var container_code = container.data( 'code' );
			}
		}
		else
		{	// This may be a widget "Sub-Container":
			var widget_block = jQuery( this ).closest( '.evo_designer__widget' );
			if( widget_block.length )
			{
				var widget = jQuery( evo_widget_selector( widget_block ) );
				if( widget.length &&
				    widget.hasClass( 'widget_core_subcontainer' ) &&
				    widget.data( 'can-edit' ) == '1' )
				{	// This is a widget "Sub-Container":
					var container_name = widget.data( 'subcontainer-name' );
					var container_code = widget.data( 'subcontainer-code' );
				}
			}
		}

		if( typeof( container_name ) != 'undefined' )
		{	// Load widget add form or widgets list only if it is allowed for current user:
			var widget_action_url = jQuery( this ).hasClass( 'evo_designer__action_add' ) ? b2evo_widget_add_url : b2evo_widget_list_url;
			jQuery( '.evo_customizer__wrapper', window.parent.document ).removeClass( 'evo_customizer__collapsed' );
			jQuery( '#evo_customizer__backoffice', window.parent.document ).get( 0 ).contentWindow.location
				.href = widget_action_url.replace( '$container$', container_name ).replace( '$container_code$', container_code );
		}
	}
} );

jQuery( document ).on( 'click', '.evo_designer__container', function( e )
{	// Link to add new widget to empty container:
	if( jQuery( e.target ).is( '.evo_designer__action' ) )
	{	// Ignore if click is on action icons:
		return;
	}

	if( jQuery( evo_widget_container_selector( jQuery( this ) ) ).find( '.evo_widget' ).length > 0 )
	{	// Skip not empty container:
		return;
	}

	// Call event to add new widget:
	jQuery( this ).find( '.evo_designer__action_add' ).click();
} );

jQuery( document ).on( 'click', '.evo_designer__widget', function( e )
{	// Link to edit widget:
	if( jQuery( e.target ).is( '.evo_designer__action' ) )
	{	// Ignore if click is on action icons:
		return;
	}

	// Mark currently clicking widget in order to don't hide/inactive parent subcontainer:
	var widget_block = jQuery( this );
	widget_block.attr( 'data-widget-block-clicked', 1 );

	var widget = jQuery( evo_widget_selector( jQuery( this ) ) );

	if( typeof( b2evo_widget_edit_url ) != 'undefined' )
	{	// If global widget edit form url is defined:
		var widget_ID = jQuery( this ).data( 'id' );
		if( widget.length && widget.data( 'can-edit' ) == '1' )
		{	// Load widget edit form only if it is allowed for current user:
			jQuery( '.evo_customizer__wrapper', window.parent.document ).removeClass( 'evo_customizer__collapsed' );
			jQuery( '#evo_customizer__backoffice', window.parent.document ).get( 0 ).contentWindow.location
				.href = b2evo_widget_edit_url.replace( '$wi_ID$', widget_ID );

			// Animate moving desinger box to left back-office panel:
			if( ! jQuery( '.evo_designer__widget_animation', window.parent.document ).length )
			{	// Create temp for for animation:
				jQuery( 'body', window.parent.document ).append( '<div class="evo_designer__widget_animation"></div>' );
			}
			jQuery( '.evo_designer__widget_animation', window.parent.document ).show()
			.css(
			{
				top: jQuery( this ).position().top + jQuery( '#evo_customizer__frontoffice', window.parent.document ).offset().top,
				left: jQuery( this ).position().left+ jQuery( '#evo_customizer__frontoffice', window.parent.document ).offset().left,
				width: jQuery( this ).outerWidth(),
				height: jQuery( this ).outerHeight(),
				opacity: 1,
			} )
			.animate(
			{
				left: 0,
				top: '120px',
				width: jQuery( '#evo_customizer__backoffice', window.parent.document ).width(),
				height: jQuery( '#evo_customizer__backoffice', window.parent.document ).height() - 160,
			} )
			.animate( { opacity: 0 }, 10, function()
			{
				jQuery( this ).hide();
				// Remove flag after clict event was ended here:
				widget_block.removeAttr( 'data-widget-block-clicked' );
			} );

			jQuery( '.evo_widget[data-z-index]' ).each( function()
			{	// Revert z-index of previous active widget blocks,
				// in order to keep only single current block with active html elements(links, forms, etc.):
				jQuery( this ).css( 'z-index', jQuery( this ).data( 'z-index' ) )
					.removeData( 'z-index' );
			} );

			// NOTE: Ignore sub-containers to allow click on widgets to edit them:
			if( ! widget.hasClass( 'widget_core_subcontainer' ) &&
			    ! widget.hasClass( 'widget_core_subcontainer_row' ) )
			{	// Move original widget block over designer widger block(frame/box with grey border and action icons),
				// in order to make active html elements(links, forms, etc.) inside original widget block:
				widget.attr( 'data-z-index', widget.css( 'z-index' ) )
					.css( 'z-index', parseInt( jQuery( this ).css( 'z-index' ) ) + 1 );
				// Set auto z-index for parent sub-container widgets in order to make the clicked widget active over the wrapper sub-sontainer:
				var parent_subcontainer = widget.parents( '.widget_core_subcontainer, .widget_core_subcontainer_row' );
				while( parent_subcontainer.length > 0 )
				{
					parent_subcontainer.attr( 'data-z-index', parent_subcontainer.css( 'z-index' ) )
						.css( 'z-index', 'auto' );
					parent_subcontainer = parent_subcontainer.parents( '.widget_core_subcontainer, .widget_core_subcontainer_row' );
				}
			}
		}
	}

	if( widget.hasClass( 'widget_core_subcontainer' ) || widget.hasClass( 'widget_core_subcontainer_row' ) )
	{	// If widget is a subcontainer:
		if( ! jQuery( this ).hasClass( 'evo_designer__subcontainer_active' ) )
		{
			// Mark currently active parent subcontainer to inactive:
			jQuery( '.evo_designer__subcontainer_active' ).addClass( 'evo_designer__subcontainer_inactive' );
			// Add subcontainer style to widget designer block to mark it with blue border style:
			jQuery( this ).addClass( 'evo_designer__subcontainer_active' );
			// Mark current subcontainer widget to active status by temp class:
			widget.addClass( 'evo_widget__subcontainer_active' );

			// Store coordinates of all child widgets(and sub-containers) to know when cursor over and out,
			// because z-index doesn't work properly with child element if parent already has z-index:
			evo_subcontainer_widgets = new Array();
			evo_subcontainer_containers = new Array();
			var subcontainer_wrapper = widget;
			if( widget.hasClass( 'widget_core_subcontainer_row' ) )
			{	// This widget contains several sub-containers:
				subcontainer_wrapper = widget.find( '.evo_container' );
				subcontainer_wrapper.each( function()
				{	// We need these data to display sub-containers without widgets:
					if( jQuery( this ).find( '.evo_widget' ).length > 0 )
					{	// Skip not empty containers, because they are visible by event of child widgets:
						return;
					}
					evo_subcontainer_containers.push( new Array(
						jQuery( this ).data( 'code' ),
						jQuery( this ).offset().top - 3,
						jQuery( this ).offset().left - 3,
						jQuery( this ).offset().top + jQuery( this ).height() + 3,
						jQuery( this ).offset().left + jQuery( this ).width() + 3 ) );
				} );
			}
			subcontainer_wrapper.children( '.evo_widget' ).each( function()
			{
				evo_subcontainer_widgets.push( new Array(
					jQuery( this ).data( 'id' ),
					jQuery( this ).offset().top - 3,
					jQuery( this ).offset().left - 3,
					jQuery( this ).offset().top + jQuery( this ).height() + 3,
					jQuery( this ).offset().left + jQuery( this ).width() + 3 ) );
			} );
		}
	}
} );

jQuery( document ).on( 'mouseout', '.evo_designer__widget', function( e )
{	// Hide widget designer block:
	if( ! jQuery( e.toElement ).closest( '.evo_designer__widget' ).length )
	{	// Hide it only when cursor is really out of designer block:
		evo_widget_hide_designer_block( jQuery( this ) );
	}
} );

jQuery( document ).on( 'mouseout', '.evo_designer__container', function( e )
{	// Hide container designer block:
	if( ! jQuery( e.toElement ).closest( '.evo_designer__container' ).length )
	{	// Hide it only when cursor is really out of designer block:
		jQuery( this ).hide();
	}
} );

jQuery( document ).on( 'mousemove', function( e )
{	// Detect if mouse cursor was out designer blocks:
	if( jQuery( '.evo_designer' ).is( ':visible' ) &&
	    ! jQuery( e.target ).hasClass( 'evo_designer' ) &&
	    ! jQuery( e.target ).closest( '.evo_designer' ).length &&
	    ! jQuery( e.target ).closest( '.evo_container[data-code]' ).length &&
	    ! jQuery( e.target ).closest( '.evo_widget[data-id]' ).length )
	{	// Hide all designer blocks if mouse cursor was out them but they were not hidden by some wrong reason:
		jQuery( '.evo_designer' ).removeClass( 'evo_designer__subcontainer_active evo_designer__subcontainer_inactive' ).hide();
		// Unmark active subcontainer widget:
		jQuery( '.evo_widget.evo_widget__subcontainer_active' ).removeClass( 'evo_widget__subcontainer_active' );
	}

	if( jQuery( '.evo_designer__subcontainer_active' ).length > 0 &&
	    ( ( typeof( evo_subcontainer_widgets ) != 'undefined' && evo_subcontainer_widgets.length > 0 ) ||
	      ( typeof( evo_subcontainer_containers ) != 'undefined' && evo_subcontainer_containers.length > 0 ) ) )
	{	// If sub-container is selected to edit its widgets:
		var active_subcontainer_designer_block = jQuery( '.evo_designer__subcontainer_active' );
		var subcontainer_zindex = parseInt( active_subcontainer_designer_block.css( 'z-index' ) );
		var active_subcontainer_widgets = jQuery( '.evo_widget.evo_widget__subcontainer_active' );
		var one_subcontainer_is_displayed = true; // Single sub-container widget doesn't contain other sub-containers, Set TRUE in order to don't try to search empty sub-containers below.
		if( active_subcontainer_widgets.hasClass( 'widget_core_subcontainer_row' ) )
		{	// This widget may contains sub-containers:
			active_subcontainer_widgets = active_subcontainer_widgets.find( '.evo_container' );
			one_subcontainer_is_displayed = false;
		}
		for( var i = 0; i < evo_subcontainer_widgets.length; i++ )
		{	// Detect what widget designer block should be visible depending on current cursor position:
			var widget = active_subcontainer_widgets.children( '.evo_widget[data-id="' + evo_subcontainer_widgets[i][0] + '"]' );
			if( widget.length == 0 ||
			    widget.data( 'id' ) == jQuery( e.target ).data( 'id' ) ||
			    jQuery( e.target ).closest( '.evo_designer__widget[data-id=' + widget.data( 'id' ) + ']' ).length > 0 )
			{	// Skip it because currently cursor is over displayed designer block of one of sub-container widgets:
				continue;
			}

			if( e.pageX >= evo_subcontainer_widgets[i][2] && e.pageY >= evo_subcontainer_widgets[i][1] && // top-left point
			    e.pageX <= evo_subcontainer_widgets[i][4] && e.pageY <= evo_subcontainer_widgets[i][3] ) // bottom-right point
			{	// Initialize and display widget designer block because cursor is over current widget:
				evo_widget_initialize_designer_block( widget );
				// Set z-index to make it over designer block of current sub-container:
				jQuery( evo_widget_designer_block_selector( widget ) ).css( 'z-index', subcontainer_zindex + 2  );
				if( widget.parent().hasClass( 'evo_container' ) )
				{	// Initialize and display also designer block for container:
					evo_widget_initialize_designer_container_block( widget.parent() );
					one_subcontainer_is_displayed = true;
					jQuery( evo_widget_container_block_selector( widget.data( 'container' ) ) ).css( 'z-index', subcontainer_zindex + 1 );
					// Hide designer block of another container from the same current active subcontainer:
					jQuery( '.evo_widget.evo_widget__subcontainer_active .evo_container' ).each( function()
					{
						if( jQuery( this ).data( 'code' ) != widget.data( 'container' ) )
						{
							jQuery( evo_widget_container_block_selector( jQuery( this ).data( 'code' ) ) ).hide();
						}
					} );
				}
			}
			else
			{	// Hide designer block:
				jQuery( evo_widget_designer_block_selector( widget ) ).hide();
			}
		}
		if( ! one_subcontainer_is_displayed )
		{	// This widget may contains sub-containers but currently it is empty so we should probably display it right now:
			for( var i = 0; i < evo_subcontainer_containers.length; i++ )
			{	// Detect what sub-container designer block should be visible depending on current cursor position:
				var subcontainer = active_subcontainer_widgets.filter( '.evo_container[data-code="' + evo_subcontainer_containers[i][0] + '"]' );
				if( subcontainer.length == 0 ||
				    subcontainer.data( 'code' ) == jQuery( e.target ).data( 'code' ) ||
				    jQuery( e.target ).closest( '.evo_designer__container[data-code=' + subcontainer.data( 'code' ) + ']' ).length > 0 )
				{	// Skip it because currently cursor is over displayed designer block of one of sub-containers:
					continue;
				}

				if( e.pageX >= evo_subcontainer_containers[i][2] && e.pageY >= evo_subcontainer_containers[i][1] && // top-left point
						e.pageX <= evo_subcontainer_containers[i][4] && e.pageY <= evo_subcontainer_containers[i][3] ) // bottom-right point
				{	// Initialize and display sub-container designer block because cursor is over it:
					evo_widget_initialize_designer_container_block( subcontainer );
					// Set z-index to make it over designer block of current sub-container:
					jQuery( evo_widget_container_block_selector( subcontainer.data( 'code' ) ) ).css( 'z-index', subcontainer_zindex + 1 );
					active_subcontainer_designer_block.show();
				}
				else
				{
					jQuery( evo_widget_container_block_selector( subcontainer.data( 'code' ) ) ).hide();
				}
			}
		}
	}
} );

jQuery( document ).on( 'click', '.evo_designer__action_order_top, .evo_designer__action_order_up, .evo_designer__action_order_down, .evo_designer__action_order_bottom', function()
{	// Change an order of widget:
	var designer_block = jQuery( this ).closest( '.evo_designer__widget' );
	var widget = jQuery( evo_widget_selector( designer_block ) );
	var order_type = 'top';
	if( jQuery( this ).hasClass( 'evo_designer__action_order_up' ) )
	{
		order_type = 'up';
	}
	else if( jQuery( this ).hasClass( 'evo_designer__action_order_down' ) )
	{
		order_type = 'down';
	}
	else if( jQuery( this ).hasClass( 'evo_designer__action_order_bottom' ) )
	{
		order_type = 'bottom';
	}

	// Re-select designer block because it may be several blocks for some widgets, e.g. for items/posts list widget in Menu container:
	designer_block = jQuery( evo_widget_designer_block_selector( widget ) );

	// Mark current widget with process class:
	designer_block.removeClass( 'evo_designer__status_failed' ).addClass( 'evo_designer__status_process' );

	// Save current index of the widget in container:
	var widget_index = widget.index();

	// Change an order of the widget with near widget:
	evo_widget_reorder( widget, order_type );

	var widgets_ids = [];
	var container_wrapper = evo_widget_container_wrapper( widget );
	container_wrapper.children( '.evo_widget[data-id]' ).each( function()
	{
		if( widgets_ids.indexOf( jQuery( this ).data( 'id' ) ) == -1 )
		{	// Don't send ID of the same widget:
			widgets_ids.push( jQuery( this ).data( 'id' ) );
		}
	} );

	jQuery.ajax(
	{
		type: 'POST',
		url: htsrv_url + 'anon_async.php',
		data: {
			'blog': b2evo_widget_blog,
			'crumb_widget': b2evo_widget_crumb,
			'action': 'reorder_widgets',
			'container': widget.data( 'container' ),
			'widgets': widgets_ids,
		},
		success: function( result )
		{	// If order has been updated successfully:
			result = ajax_debug_clear( result );
			if( result != '' )
			{	// Error:
				evo_widget_display_error( result, widget, order_type, widget_index );
			}
			else
			{	// Success:
				designer_block.removeClass( 'evo_designer__status_process evo_designer__status_failed' ).addClass( 'evo_designer__status_success' );
				evo_widget_update_designer_position( widget );
				setTimeout( function()
				{
					evo_widget_hide_designer_block( designer_block );
					designer_block.removeClass( 'evo_designer__status_success' );
				}, 500 );
			}
		},
		error: function( jqXHR, textStatus, errorThrown )
		{	// Display error text on error request:
			var error_text = ( jqXHR.statusText == 'Bad Crumb Request' ? ajax_debug_clear( jqXHR.responseText ) : evo_js_lang_server_error );
			evo_widget_display_error( error_text + ' ' + evo_js_lang_sync_error, widget, order_type, widget_index );
		}
	} );
} );

jQuery( document ).on( 'click', '.evo_designer__action_duplicate', function()
{	// Duplicate widget:
	var designer_block = jQuery( this ).closest( '.evo_designer__widget' );
	var widget = jQuery( evo_widget_selector( designer_block ) );

	if( typeof( b2evo_widget_duplicate_url ) != 'undefined' )
	{	// If global widget duplicate url is defined:
		jQuery( '#evo_customizer__backoffice', window.parent.document ).get( 0 ).contentWindow.location
				.href = b2evo_widget_duplicate_url.replace( '$wi_ID$', widget.data( 'id' ) ).replace( '$crumb_widget$', b2evo_widget_crumb );
	}
} );

jQuery( document ).on( 'click', '.evo_designer__action_disable', function()
{	// Disable widget:
	var designer_block = jQuery( this ).closest( '.evo_designer__widget' );
	var widget = jQuery( evo_widget_selector( designer_block ) );

	// Mark current widget with process class:
	designer_block.removeClass( 'evo_designer__status_failed' ).addClass( 'evo_designer__status_process' );

	jQuery.ajax(
	{
		type: 'POST',
		url: htsrv_url + 'anon_async.php',
		data: {
			'blog': b2evo_widget_blog,
			'crumb_widget': b2evo_widget_crumb,
			'action': 'disable_widget',
			'wi_ID': widget.data( 'id' ),
		},
		success: function( result )
		{	// If order has been updated successfully:
			result = ajax_debug_clear( result );
			if( result != '' )
			{	// Error:
				evo_widget_display_error( result, widget, 'disable' );
			}
			else
			{	// Success:
				designer_block.removeClass( 'evo_designer__status_process evo_designer__status_failed' ).addClass( 'evo_designer__status_success' );
				setTimeout( function()
				{
					var container = widget.parent();
					evo_widget_hide_designer_block( designer_block );
					widget.slideUp( 400, function()
					{	// Remove widget and designer block from page completely after animation:
						widget.remove();
						designer_block.remove();
						// Update visibility of up/down action icons of first/last widgets:
						evo_widget_update_order_actions( container );
					} );
				}, 500 );
			}
		},
		error: function( jqXHR, textStatus, errorThrown )
		{	// Display error text on error request:
			var error_text = ( jqXHR.statusText == 'Bad Crumb Request' ? ajax_debug_clear( jqXHR.responseText ) : evo_js_lang_server_error );
			evo_widget_display_error( error_text + ' ' + evo_js_lang_sync_error, widget, order_type );
		}
	} );
} );


jQuery( document ).ready( function()
{
	jQuery( 'div' ).scroll( function()
	{	// Update position of all visible designer blocks on scroll all divs with enabled css overflow scroll property:
		jQuery( '.evo_designer__widget[data-id]:visible' ).each( function()
		{
			evo_widget_update_designer_position( jQuery( evo_widget_selector( jQuery( this ) ) ) );
		} );
	} );
} );


/**
 * Get all duplicates of the same widget in the container, e.g. for items/posts list widget in Menu container
 *
 * @param object Widget
 * @return object Widgets
 */
function evo_widget_get_duplicates( widget )
{
	return widget.closest( '.evo_container' ).find( '.evo_widget[data-id=' + widget.data( 'id' ) + ']' );
}


/**
 * Get jQuery selector for widget by designer block
 *
 * @param object Designer block
 * @returns string
 */
function evo_widget_selector( designer_block )
{
	var additional_select = '';
	if( designer_block.data( 'unique-num' ) > 0 )
	{	// Use additional select, e-g when same subcontainer widget is used in several
		// places on the same page, and it is not enough to select it only by widget ID:
		additional_select = '[data-unique-num=' + designer_block.data( 'unique-num' ) + ']';
	}

	return '.evo_widget[data-id=' + designer_block.data( 'id' ) + ']' + additional_select;
}


/**
 * Get jQuery selector for designer block by widget
 *
 * @param object Widget
 * @returns string
 */
function evo_widget_designer_block_selector( widget )
{
	var additional_select = '';
	if( widget.data( 'unique-num' ) > 0 )
	{	// Use additional select, e-g when same subcontainer widget is used in several
		// places on the same page, and it is not enough to select it only by widget ID:
		additional_select = '[data-unique-num=' + widget.data( 'unique-num' ) + ']';
	}

	return '.evo_designer__widget[data-id=' + widget.data( 'id' ) + ']' + additional_select;
}


/**
 * Get jQuery selector for widget container by containerdesigner block
 *
 * @param object Container designer block
 * @returns string
 */
function evo_widget_container_selector( container_block )
{
	return '.evo_container[data-code="' + container_block.data( 'code' ) + '"]';
}


/**
 * Get jQuery selector for container designer block by widget
 *
 * @param string Container code
 * @returns string
 */
function evo_widget_container_block_selector( container_code )
{
	return '.evo_designer__container[data-code="' + container_code + '"]';
}


/**
 * Display an error after failed widget action
 *
 * @param string Error message
 * @param object Widget
 * @param string Action: 'top', 'up', 'down', 'disable'
 * @param integer Widget index/position before action
 */
function evo_widget_display_error( error, widget, action, widget_index )
{
	jQuery( evo_widget_designer_block_selector( widget ) ).removeClass( 'evo_designer__status_process' ).addClass( 'evo_designer__status_failed' );
	alert( error );
	if( action != 'disable' )
	{	// Revert widget order back:
		evo_widget_reorder( widget, widget_index );
	}
}


/**
 * Change an order of the widget with near widget in same container
 *
 * @param object Widget
 * @param string|integer Order direction: 'top', 'up', 'down', 'bottom' or number of index
 */
function evo_widget_reorder( widget, direction )
{
	var curr_widget = widget.eq( 0 );

	switch( direction )
	{
		case 'top':
			// Move HTML of the widget to the top:
			var near_widget = evo_widget_get_duplicates( curr_widget.closest( '.evo_container' ).find( '.evo_widget' ).first() );
			near_widget.eq( 0 ).before( widget );
			break;

		case 'up':
			// Move HTML of the widget before previous widget:
			var near_widget = evo_widget_get_duplicates( curr_widget.prev() );
			near_widget.eq( 0 ).before( widget );
			break;

		case 'bottom':
			// Move HTML of the widget to the bottom:
			var near_widget = evo_widget_get_duplicates( curr_widget.closest( '.evo_container' ).find( '.evo_widget' ).last() );
			near_widget.eq( near_widget.length - 1 ).after( widget );
			break;

		case 'down':
			// Move HTML of the widget after next widget:
			var near_widget = evo_widget_get_duplicates( widget.eq( widget.length - 1 ).next() );
			near_widget.eq( near_widget.length - 1 ).after( widget );
			break;

		default:
			// Move to specific index:
			var widget_index = parseInt( direction );
			var near_widget = evo_widget_get_duplicates( curr_widget.closest( '.evo_container' ).find( '.evo_widget' ).eq( widget_index ) );
			if( widget_index == 0 )
			{
				near_widget.eq( 0 ).before( widget );
			}
			else
			{
				near_widget.eq( 0 ).after( widget );
			}
	}

	// Update visibility of up/down action icons of first, second, penultimate and last widgets:
	evo_widget_update_order_actions( evo_widget_container_wrapper( widget ) );

	evo_widget_update_designer_position( widget );
	evo_widget_update_designer_position( near_widget, false );
}


/**
 * Update visibility of up/down action icons of first/last widgets:
 *
 * @param object Widget
 */
function evo_widget_update_order_actions( container )
{
	var container_widgets = container.children( '.evo_widget' );
	var widget_num = 1;
	var prev_widget_ID = 0;
	container_widgets.each( function()
	{
		var designer_block = jQuery( evo_widget_designer_block_selector( jQuery( this ) ) ).eq( 0 );
		if( designer_block.length )
		{	// If designer block is initialized:
			if( prev_widget_ID != designer_block.data( 'id' ) )
			{	// If it is block for next different widget:
				designer_block.find( '.evo_designer__action_order_top, .evo_designer__action_order_up, .evo_designer__action_order_down, .evo_designer__action_order_bottom' ).show();
			}
			if( widget_num == 1 )
			{	// Hide action icon to move widget up for the first widget in container:
				designer_block.find( '.evo_designer__action_order_up' ).hide();
			}
			if( widget_num <= 2 )
			{	// Hide action icon to move widget to top for the second widget in container:
				designer_block.find( '.evo_designer__action_order_top' ).hide();
			}
			if( widget_num == container_widgets.length )
			{	// Hide action icon to move widget down for the last widget in container:
				designer_block.find( '.evo_designer__action_order_down' ).hide();
			}
			if( widget_num >= container_widgets.length - 1 )
			{	// Hide action icon to move widget to bottom for the penultimate widget in container:
				designer_block.find( '.evo_designer__action_order_bottom' ).hide();
			}
			prev_widget_ID = designer_block.data( 'id' );
		}
		widget_num++;
	} );
}


/**
 * Update position of widget designer block
 *
 * @param object Widget
 * @param boolean Show widget desginer block, TRUE by default
 */
function evo_widget_update_designer_position( widget, show )
{
	var w = 0;
	var border = 3;
	var designer_blocks = jQuery( evo_widget_designer_block_selector( widget ) );
	evo_widget_get_duplicates( widget ).each( function()
	{	// We should display several designer blocks for widget blocks with same ID, e.g. for items/posts list widget in Menu container:
		var curr_widget = jQuery( this );
		var widget_top = curr_widget.offset().top - border;
		var widget_left = curr_widget.offset().left - border;
		var designer_block = designer_blocks.eq( w );

		var designer_block_actions_width = designer_block.find( '.evo_designer__actions' ).outerWidth() + 1;
		if( widget_left < designer_block_actions_width - border )
		{	// Fix body left margin space in order to display widget actions panel:
			jQuery( 'body' ).css( 'margin-left', designer_block_actions_width + 'px' );
			widget_left = designer_block_actions_width - border;
		}

		var designer_block_title_height = designer_block.find( '.evo_designer__title' ).outerHeight() + 1;
		if( widget_top < designer_block_title_height - border )
		{	// Fix body top margin space in order to display widget title:
			jQuery( 'body' ).css( 'margin-top', designer_block_title_height + 'px' );
			widget_top = designer_block_title_height - border;
		}

		designer_block.css( {
				'top': widget_top,
				'left': widget_left,
				'width': curr_widget.outerWidth() + border + 2,
				'height': curr_widget.outerHeight() + border + 2,
			} );
		if( typeof( show ) == 'undefined' || show )
		{	// Show widget desginer block:
			designer_block.show();
		}

		w++;
	} );

	// Also update container position:
	evo_widget_update_container_position( widget.parent() );
}


/**
 * Update position of container designer block
 *
 * @param object Container
 */
function evo_widget_update_container_position( container )
{
	var border = 3;
	var container_block = jQuery( evo_widget_container_block_selector( container.data( 'code' ) ) );
	var container_top = container.offset().top - border;
	var container_left = container.offset().left - border;
	var container_width = container.outerWidth() + border + 2;
	var container_height = container.outerHeight() + border + 2;
	if( container_left < 0 )
	{	// Limit container designer block left position to the left window border:
		container_left = 0;
	}
	var container_right = container_left + container_width;
	var container_bottom = container_top + container_height;

	var container_block_actions_width = container_block.find( '.evo_designer__actions' ).outerWidth();
	if( container_right + container_block_actions_width > jQuery( window ).width() + 2*border )
	{	// Fix body right margin space in order to display container actions panel:
		jQuery( 'body' ).css( 'margin-right', ( container_block_actions_width + border ) + 'px' );
		container_width -= container_block_actions_width;
	}

	var container_block_title_height = container_block.find( '.evo_designer__title' ).outerHeight();
	if( container_block_title_height > 0 && container_bottom + container_block_title_height > jQuery( 'body' ).height() - border )
	{	// Fix body bottom margin space in order to display container title:
		jQuery( 'body' ).css( 'margin-bottom', container_block_title_height + 'px' );
	}

	container_block.css( {
			'top': container_top,
			'left': container_left,
			'width': container_width,
			'height': container_height,
		} )
		.show();
}


/**
 * Hide widget designer block
 *
 * @param object Designer block
 */
function evo_widget_hide_designer_block( designer_block )
{
	if( ! designer_block.hasClass( 'evo_designer__status_process' ) &&
	    ! designer_block.hasClass( 'evo_designer__status_failed' ) &&
	    ! designer_block.hasClass( 'evo_designer__subcontainer_active' ) )
	{	// Hide only when widget is not in process:
		jQuery( evo_widget_designer_block_selector( jQuery( evo_widget_selector( designer_block ) ) ) ).hide();
	}
}


/**
 * Fix issue of parent z-index to make designer mode work properly
 *
 * @param object Source
 */
function evo_widget_fix_parent_zindex( parent )
{
	while( parent )
	{
		if( ! parent.hasClass( 'evo_widget' ) &&
			parent.css( 'z-index' ) != 'auto' &&
			parent.css( 'z-index' ) != 0 )
		{	// Change not default z-index to auto, because it breaks designer mode structure:
			parent.css( 'z-index', 'auto' );
		}
		if( parent.prop( 'nodeName' ) == 'BODY' )
		{	// Stop on body html element and don't up:
			break;
		}
		// Switch to next parent:
		parent = parent.parent();
	}
}


/**
 * Get container or sub-container wrapper
 *
 * @param object Widget
 * @return object Container/Sub-container
 */
function evo_widget_container_wrapper( widget )
{
	// Check if the requested widget is located in sub-container:
	var container_wrapper = widget.closest( '.widget_core_subcontainer[data-id!=' + widget.data( 'id' ) + ']' );

	if( container_wrapper.length == 0 )
	{	// If widget is in normal container and not in sub-container:
		container_wrapper = widget.parent();
	}

	return container_wrapper;
}