--[[
миниигра с правильной расстановкой разных типов кристаллов по дырочкам
]]

place_objects_in_pos = {}
local self = place_objects_in_pos

self.params = {
	sound_select = "crystal_select", -- выделение кристалла
	sound_put = "crystal_put", -- положить кристалл на место
	crystal_types = 
	{ -- id разных типов кристаллов (клипы)
		"crystall_red", 
		"crystall_green", 
		"crystall_blue"
	}, 
	crystal_selection = "scene06_03_minigame_select", -- id клипа на выделение
	crystals = { 1, 1, 2, 2, 3, 3}, -- виды доступных изначально кристаллов
	crystals_pos = {24, 25, 26, 27, 28, 29}, -- позиции, в которых находятся кристаллы
	pos_size = sf.misc.FloatVector(20, 20), 
	pos_shine = "hole_shine", -- клип на подсветку лунки при наведении мыши
	win_positions = 
	{ -- куда что надо поместить для победы
		{
			crystal_type = 1, -- какой вид кристалла 
			pos = 12 -- какая позиция
		},
		{
			crystal_type = 1, -- какой вид кристалла 
			pos = 6 -- какая позиция
		},
		{
			crystal_type = 2, -- какой вид кристалла 
			pos = 22 -- какая позиция
		},
		{
			crystal_type = 2, -- какой вид кристалла 
			pos = 21 -- какая позиция
		},
		{
			crystal_type = 3, -- какой вид кристалла 
			pos = 13 -- какая позиция
		},
		{
			crystal_type = 3, -- какой вид кристалла 
			pos = 14 -- какая позиция
		}
	},
	positions = 
	{ -- геморрой с настройкой преломлений луча, если он попадет на эту позицию, а в ней стоит кристалл
		{ -- 1
			X = 685, Y = 196, angle = math.pi/5.5, -- позиция кристалла , угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(680, 195), -- позиция, в которую ставится луч
			cross = {6, 13} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 2
			X = 801, Y = 188, angle = 0, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(796, 188), -- позиция, в которую ставится луч
			cross = {} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 3
			X = 774, Y = 279, angle = math.pi/9, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(770, 279), -- позиция, в которую ставится луч
			cross = {5, 15, 17} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 4
			X = 860, Y = 367, angle = math.pi/6 - math.pi/40, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(855, 367), -- позиция, в которую ставится луч
			cross = {16} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 5
			X = 755, Y = 339, angle = -math.pi/7 + math.pi/64, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(747, 339), -- позиция, в которую ставится луч
			cross = {16} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 6
			X = 651, Y = 252, angle = -math.pi/14, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(645, 255), -- позиция, в которую ставится луч
			cross = {} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 7
			X = 548, Y = 255, angle = math.pi/9 - math.pi/24, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(545, 255), -- позиция, в которую ставится луч
			cross = {} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 8
			X = 434, Y = 194, angle = 13.4*math.pi/24, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(434, 192), -- позиция, в которую ставится луч
			cross = {9} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 9
			X = 227, Y = 160, angle = -2*math.pi/3, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(235, 160), -- позиция, в которую ставится луч
			cross = {} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 10
			X = 254, Y = 224, angle = -math.pi/2.8, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(250, 235), -- позиция, в которую ставится луч
			cross = {} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 11
			X = 286, Y = 288, angle = -1.06*math.pi/2, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(286, 295), -- позиция, в которую ставится луч
			cross = {7, 6} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 12
			X = 313, Y = 365, angle = math.pi/2, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(313, 360), -- позиция, в которую ставится луч
			cross = {} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 13
			X = 558, Y = 398, angle = 0.98*math.pi, --+ math.pi/44, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(565, 401), -- позиция, в которую ставится луч
			cross = {7, 29} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 14
			X = 631, Y = 407, angle = math.pi/6, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(625, 407), -- позиция, в которую ставится луч
			cross = {18, 19} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 15
			X = 729, Y = 416, angle = 1.08*math.pi/2, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(729, 410), -- позиция, в которую ставится луч
			cross = {14, 13, 12} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 16
			X = 812, Y = 471, angle = math.pi/3 , -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(812, 464), -- позиция, в которую ставится луч
			cross = {17} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 17
			X = 690, Y = 542, angle = 1.92*math.pi/3 + math.pi/24, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(695, 538), -- позиция, в которую ставится луч
			cross = {18, 11} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 18
			X = 589, Y = 489, angle = -math.pi/10, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(580, 489), -- позиция, в которую ставится луч
			cross = {} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 19
			X = 542, Y = 563, angle = 1.28*math.pi/2,--  + math.pi/80, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(545, 558), -- позиция, в которую ставится луч
			cross = {20, 22, 23} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 20
			X = 453, Y = 528, angle = 1.2*math.pi/3, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(463, 520), -- позиция, в которую ставится луч
			cross = {21} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 21
			X = 327, Y = 567, angle = 2.47*math.pi/3, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(333, 567), -- позиция, в которую ставится луч
			cross = {23} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 22
			X = 354, Y = 475, angle = 2.65*math.pi/3, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(363, 477), -- позиция, в которую ставится луч
			cross = {12, 11, 10, 9} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 23
			X = 227, Y = 422, angle = -2*math.pi/3, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(227, 427), -- позиция, в которую ставится луч
			cross = {12} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 24
			X = 180, Y = 117, angle = -2*math.pi/3, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(180, 117), -- позиция, в которую ставится луч
			cross = {} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 25
			X = 249, Y = 117, angle = -2*math.pi/3, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(249, 117), -- позиция, в которую ставится луч
			cross = {} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 26
			X = 321, Y = 117, angle = -2*math.pi/3, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(321, 117), -- позиция, в которую ставится луч
			cross = {} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 27
			X = 392, Y = 117, angle = -2*math.pi/3, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(392, 117), -- позиция, в которую ставится луч
			cross = {} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 28
			X = 462, Y = 117, angle = -2*math.pi/3, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(462, 117), -- позиция, в которую ставится луч
			cross = {} -- какие позиции пересекает луч, если проходит здесь
		},
		{ -- 29
			X = 532, Y = 117, angle = -2*math.pi/3, -- позиция, угол поворота луча в ней
			ray_pos = sf.misc.FloatVector(532, 125), -- позиция, в которую ставится луч
			cross = {} -- какие позиции пересекает луч, если проходит здесь
		}
	}	
}

function self.Init(_owner)
	sminigames.SetStandartScriptName(_owner, place_objects_in_pos)
	
	-- инициализация кристаллов
	self.crystals = {}
	for i = 1, #self.params.crystals do
		local name = self.params.crystal_types[self.params.crystals[i]] -- ресурс кристалла
		local widg = sf.gui.CClipWidget("crystal", 4, 0)
		widg.GetClip().Load(name, true)
		table.insert(self.crystals, {image = widg, obj_type = self.params.crystals[i], pos = 0})
		_owner.AddWidget(widg)
	end
	
	self.positions = {}
	for i, pos in ipairs(self.params.positions) do
		table.insert(self.positions, 0) -- все позиции свободны от кристаллов
	end
	
	self.first_init = true
	-- расставляем по дыркам
	for i = 1, #self.params.crystals do
		self.selected = i
		self.PlaceCrystal(_owner, self.params.crystals_pos[i])
	end
	self.selected = nil -- выбранный кристалл
	self.first_init = nil
	
	self.win = false
	self.timer = __create_timer("", "qe_level")
	
	self.pos_shine = sf.gui.CClipWidget("", 0, 0)
	if self.params.pos_shine and self.params.pos_shine ~= "" then
		self.pos_shine.GetClip().Load(self.params.pos_shine, true)
	end
	_owner.AddWidget(self.pos_shine)
	self.pos_shine.AddFlags(sf.gui.CWidget.FlagHidden)
end 

function self.OnMouseMove(_this, _pos, _state, _broadcast)
	if self.win then
		return true
	end
	
	local pos = self.IsPos(_pos)
	local crystal = self.IsCrystal(_pos)
	if pos and not crystal then
		local center = sf.misc.FloatVector(self.params.positions[pos].X, self.params.positions[pos].Y)
		if self.pos_shine then
			local size = self.pos_shine.GetClip().GetViewSize()
			local off = center - size/2
			self.pos_shine.SetOffset(off.X, off.Y)
			self.pos_shine.RemFlags(sf.gui.CWidget.FlagHidden)
		end
	else
		self.pos_shine.AddFlags(sf.gui.CWidget.FlagHidden)
	end
	return true
end

-- проверяет клик на объект
function self.IsCrystal(_pos)
	for i = 1, #self.crystals do
		local off = self.crystals[i].image.GetOffset()
		local size = self.crystals[i].image.GetClip().GetViewSize()
		if  off.X <= _pos.X and off.X + size.X >=_pos.X and off.Y <= _pos.Y and off.Y+size.Y >= _pos.Y then --and 
				-- sminigames.IsVisiblePoint(self.crystals[i].image.GetImage(), _pos.X - self.crystals[i].image.GetOffset().X, _pos.Y - self.crystals[i].image.GetOffset().Y) then
					return i
		end
	end
	return nil
end 

-- проверяет клик на позицию
function self.IsPos(_pos)
	for i, pos in ipairs(self.params.positions) do
		if (_pos.X >= pos.X - self.params.pos_size.X/2) and (_pos.X <= pos.X + self.params.pos_size.X/2) and
			(_pos.Y >= pos.Y - self.params.pos_size.Y/2) and (_pos.Y <= pos.Y + self.params.pos_size.Y/2) then
				return i
		end
	end
	return nil
end 

-- выделяет кристалл
function self.SelectCrystal(_owner, _i)
	self.DeselectCrystal(_owner)
	self.selected = _i
	
	if self.params.sound_select then
		sound(self.params.sound_select)
	end
	
	self.selection_clip = sf.gui.CClipWidget("", 1, 0)
	self.selection_clip.GetClip().Load(self.params.crystal_selection, true)
	
	local offset = self.crystals[self.selected].image.GetOffset() + self.crystals[self.selected].image.GetClip().GetViewSize()/2
	local size = self.selection_clip.GetClip().GetViewSize()
	self.selection_clip.SetOffset(offset.X - size.X/2, offset.Y - size.Y/2)
	
	_owner.AddWidget(self.selection_clip)
end

-- снимает выделение с кристалла
function self.DeselectCrystal(_owner)
	_owner.RemoveWidget(self.selection_clip)
	self.selection_clip = nil
	self.selected = nil
end	
-- помещает выбранный кристалл в позицию номер _pos
function self.PlaceCrystal(_owner, _pos)
	if self.params.sound_put and not self.first_init then
		sound(self.params.sound_put)
	end
	local sel = self.selected -- так короче
	
	self.positions[self.crystals[sel].pos] = 0
	local img = self.crystals[sel].image
	local sz = self.crystals[sel].image.GetClip().GetViewSize()
	img.SetOffset(self.params.positions[_pos].X - sz.X/2, self.params.positions[_pos].Y - sz.Y/2)
	self.crystals[sel].pos = _pos
	self.positions[_pos] = self.crystals[sel].obj_type
	
	self.DeselectCrystal(_owner)
end 
function self.OnMouseDown(_owner, _pos, _button, _keyboard_state, _broadcast)
	local crystal = self.IsCrystal(_pos)
	local pos = self.IsPos(_pos)
	if crystal then
		if self.selected == crystal then
			self.DeselectCrystal(_owner)
		else
			self.SelectCrystal(_owner, crystal)
		end
	elseif pos then
		if self.selected  and self.positions[pos] == 0 then
			self.PlaceCrystal(_owner, pos, true)
			self.CheckEnd(_owner)
		end
	end
	
	return true
end 

-- проверить победу
function self.CheckEnd(_owner)
	for i, win_pos in ipairs(self.params.win_positions) do
		if self.positions[win_pos.pos] ~= win_pos.crystal_type then
			return nil
		end
	end
	self.win = true
	
	_owner.OnEndGame()
end 
