--------------------------------------------------------------------------------
local function SetRealRect( widget, rect )
	local screen = widgetsSystem:GetPosConverterParams()
	local ratio = screen.fullVirtualSizeX / screen.realSizeX

	local placement = widget:GetPlacementPlain()
	
	local parent = widget:GetParent()
	local p_rect = parent and parent:GetRealRect()
		or { x1 = 0, y1 = 0, x2 = screen.realSizeX, y2 = screen.realSizeY }
		
	local x1, y1 = rect.x1, rect.y1
	local x2, y2 = rect.x2, rect.y2
	local x, y = x2 - x1, y2 - y1
	
	local p_x1, p_y1 = p_rect.x1, p_rect.y1
	local p_x2, p_y2 = p_rect.x2, p_rect.y2
	local p_x, p_y = p_x2 - p_x1, p_y2 - p_y1
	
	local alignX, alignY = placement.alignX, placement.alignY
	
	placement = {
		posX = alignX == WIDGET_ALIGN_CENTER
			and ( x1 + x2 - p_x1 - p_x2 ) / 2 * ratio
			or ( x1 - p_x1 ) * ( alignX ~= WIDGET_ALIGN_LOW_ABS and ratio or 1 ),
			
		posY = alignY == WIDGET_ALIGN_CENTER
			and ( y1 + y2 - p_y1 - p_y2 ) / 2 * ratio
			or ( y1 - p_y1 ) * ( alignY ~= WIDGET_ALIGN_LOW_ABS and ratio or 1 ),
		
		alignX = alignX, alignY = alignY,
		sizingX = placement.sizingX, sizingY = placement.sizingY,
		
		highPosX = ( p_x2 - x2 ) * ratio, highPosY = ( p_y2 - y2 ) * ratio,
		sizeX = x * ratio, sizeY = y * ratio
	}

	widget:SetPlacementPlain( placement )
	
	return placement
end
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
local widgetDnD, hash, proxy = {}, {}
--------------------------------------------------------------------------------
local function DnDDragTo( event )
	local widget, init, rect = proxy.widget, proxy.init, proxy.rect
	local x, y = event.posX - init.posX, event.posY - init.posY
	
	SetRealRect( widget, {
		x1 = rect.x1 + x, x2 = rect.x2 + x,
		y1 = rect.y1 + y, y2 = rect.y2 + y,
	} )
end
--------------------------------------------------------------------------------
local Engage
--------------------------------------------------------------------------------
local function DnDDragCancelled( event )
	SetRealRect( widget, proxy.rect )
	Engage( false )
end
--------------------------------------------------------------------------------
local function DnDDropAttempt( event )
	mission.DNDConfirmDropAttempt()
	Engage( false )
end
--------------------------------------------------------------------------------
Engage = function( enable )
	local register = enable
		and common.RegisterEventHandler
		or common.UnRegisterEventHandler
		
	register( DnDDragTo, "EVENT_DND_DRAG_TO" )
	register( DnDDragCancelled, "EVENT_DND_DRAG_CANCELLED" )
	register( DnDDropAttempt, "EVENT_DND_DROP_ATTEMPT" )
end
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
common.RegisterEventHandler( function ( event )
	local widget = hash[ event.srcWidget:GetInstanceId() ]
	
	if widget then
		proxy = { init = event, widget = widget, rect = widget:GetRealRect() }
		mission.DNDConfirmPickAttempt()
	end
	
	Engage( widget ~= nil )
end, "EVENT_DND_PICK_ATTEMPT" )
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
function widgetDnD.DnDRegister( widget )
	hash[ widget:GetInstanceId() ] = widget
end
--------------------------------------------------------------------------------
function widgetDnD.DnDUnRegister( widget )
	hash[ widget:GetInstanceId() ] = nil
end
--------------------------------------------------------------------------------
local enabled = {}
--------------------------------------------------------------------------------
function widgetDnD.DnDEnable( widget, enable )
	local instanceId = widget:GetInstanceId()
	
	if enabled[ instanceId ] ~= enable then
		enabled[ instanceId ] = enable

		local index = common.RequestIntegerByInstanceId( instanceId ) * 1000 + 254
		mission.DNDRegister( widget, index, true )
	else
		mission.DNDUnregister( widget )
	end
end
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
local widget = mainForm:GetChildChecked( "MainPanel", false )
widgetDnD.DnDRegister( widget )
widgetDnD.DnDEnable( widget, true )
--------------------------------------------------------------------------------