--[[
sminigames.save хранит все текущие значения номеров
]]

enter_password_scroll_circle = {}
local self = enter_password_scroll_circle

self.params = 
{
	init_numbers = {1, 2, 3, 3, 4, 5, 6, 7, 8}, -- начальные состояния лучей, количество цифр должно совпадать с количеством лучей. 
	password = {3, 8, 6, 5, 6, 7, 1, 2}, -- в каких состояниях должна быть игра в конце
	states = 8, -- количество состояний
	speed = 30, -- скорость вращения
	sound_rotation = "rotation_ring", -- звук вращения кольца
	cannot_win  = false, -- победить  можно
	image_layer = 3, -- слой, на котором будут отображаться отдельные лучи
	clips_on_move = -- клипы, которые проигрываются при движении круга
	{ -- слой, id, положение
		{layer = 1, clip="minigame_sun_eyes", offset = sf.misc.FloatVector(0,0)},
		{layer = 4, clip="minigame_sun_shine", offset = sf.misc.FloatVector(0,0)}
	}, 
	image_id_prefix = "sun_piece0" -- начало айдишников нарезанных кусков состояний
}


function self.Init(_owner)
	sminigames.SetStandartScriptName(_owner, enter_password_scroll_circle)
	
	self.timer = __create_timer("", "qe_level")
	
	self.angle = math.pi * 2 / #self.params.init_numbers
	
	_owner.AddFlags(sf.gui.CBaseWidget.FlagClipDraw)
	
	-- находим все изображения
	self.objects = {}
	local i = #self.params.init_numbers
	self.circle = __cast(_owner.GetWidget("round", true), sf.gui.CImageWidget)
	__assert(self.circle, "Нет кольца в dsfrontend'e")
	--self.circle.AddFlags(sf.gui.CWidget.FlagHidden)
	
	local width, height = self.circle.GetSize().X, self.circle.GetSize().Y
	local offset_x, offset_y = self.circle.GetOffset().X, self.circle.GetOffset().Y
	local center = sf.misc.FloatVector(offset_x + width/2, offset_y + height/2)

	-- если у нас первый запуск миниигры - инициализировать сохранение
	if not sminigames.save then
		sminigames.save = self.params.init_numbers
	end
	
	-- создаем картинки
	for i = 1, #self.params.init_numbers do
		local num = sminigames.save[i]
		local name = self.params.image_id_prefix
		
		
		if num < 10 then 
			name = name..0
		end
		name = name .. num
		local layer = self.params.layer
		if not layer then
			layer = 2
		end
		local img = sf.gui.CImageWidget(name , "img0"..i, layer, 0) 

		if img then
			_owner.AddWidget(img)
			local object = {image = img, angle = i * self.angle, num = num}
			self.MoveAndRotate(object.image, object.angle, center)
			table.insert(self.objects, object)
		end
	end
	
	self.moving = -1 -- ниче не крутится
	self.start_angle = 0
	self.new_angle = 0
	self.new_num = 0
	self.start = 0
	
	self.move_clips = {}

end

function self.RemoveMoveClips(_owner)
	if not self.move_clips then return end
	local i = #self.move_clips
	while (i > 0) do
		_owner.RemoveWidget(self.move_clips[i])
		table.remove(self.move_clips, i)
		i = i - 1
	end
	self.move_clips = {}
end

function self.AddMoveClips(_owner)
	if self.params.clips_on_move then
		self.RemoveMoveClips(_owner)
		for i = 1, #self.params.clips_on_move do
			local clip = sf.gui.CClipWidget("", self.params.clips_on_move[i].layer, 0)
			clip.GetClip().Load(self.params.clips_on_move[i].clip, true)

			clip.SetOffset(self.params.clips_on_move[i].offset.X, self.params.clips_on_move[i].offset.Y)
			_owner.AddWidget(clip)
			table.insert(self.move_clips, clip)
		end
	end
end

function self.CheckEnd(_owner)
	if not self.params.cannot_win then
		local flag = true
		for i = 1, #self.params.init_numbers do
			if self.params.password[i] ~= self.objects[i].num then
				flag = false
				return
			end
		end
	
		if flag then
			_owner.SetGameResult(1)
			_owner.OnEndGame()
		end
	end
end

-- повернуть треугольный кусочек 
function self.MoveAndRotate(_widget, _angle, _center)
	_widget.SetOffset(_center.X, _center.Y - _widget.GetSize().Y)
	_widget.SetRotation(sf.misc.MatrixRotation(_angle, 0,_widget.GetSize().Y))
	
end 

function self.IsObject(_owner, _pos)
	local width, height = self.circle.GetSize().X, self.circle.GetSize().Y
	local offset_x, offset_y = self.circle.GetOffset().X, self.circle.GetOffset().Y
	local center = sf.misc.FloatVector(offset_x + width/2, offset_y + height/2)
	for i = 1, #self.objects do
		local unrot_pos = self.GetUnrotatedPoint(_pos, i*self.angle, center) -- учитываем поворот виджета
		local o_x, o_y = self.objects[i].image.GetOffset().X, self.objects[i].image.GetOffset().Y
		if misc.GetRect(self.objects[i].image).IsContains(unrot_pos.X, unrot_pos.Y) and 
			sminigames.IsVisiblePoint(self.objects[i].image.GetImage(), unrot_pos.X - o_x, unrot_pos.Y - o_y) then
				-- попали в объекта
				return i
		end
	end
	return nil
end 

function self.GetUnrotatedPoint(_pos, _angle, _center)
	return _pos * sf.misc.MatrixRotation(-_angle, _center.X, _center.Y)	
end

-- обработать двойной клик как одинарный
function self.OnDoubleClick(_owner, _pos, _state, _broadcast)
	return self.OnMouseDown(_owner, _pos, sf.gui.CBaseWidget.LeftButton,_state, _broadcast)
end

function self.OnMouseDown(_owner, _pos, _button, _state, _broadcast)
	local obj = self.IsObject(_owner, _pos)
	
	if (not obj) or ( obj and obj ~= self.moving and self.moving > 0) then 
		-- не попали в объект или у нас уже двигается не кольцо, но не от этого объекта
		return false 
	else
		-- сначала нужно повернуть нижний круглый виджет на нужный угол
		local count = obj - self.objects[obj].num
		self.RotateCircle( count * self.angle)
		-- смотрим, какая была нажата кнопка
		if (_button == sf.gui.CBaseWidget.LeftButton) then
			if self.moving > 0 then
				-- кольцо уже движется
				self.new_angle = self.new_angle + self.angle
				self.new_num = self.new_num - 1
			else
				self.start_angle = count * self.angle
				self.new_angle = self.start_angle + self.angle
				self.new_num = self.objects[obj].num - 1
				self.moving = obj
				self.start = self.timer.Get().GetTime()
				_owner.RemoveWidget(self.objects[obj].image)
				
				self.AddMoveClips(_owner)
			end
		else
			if self.moving > 0 then
				-- кольцо уже движется
				self.new_angle = self.new_angle - self.angle
				self.new_num = self.new_num + 1
			else
				self.start_angle = count * self.angle
				self.new_angle = self.start_angle - self.angle
				self.new_num = self.objects[obj].num + 1
				self.moving = obj
				self.start = self.timer.Get().GetTime()
				_owner.RemoveWidget(self.objects[obj].image)
				self.AddMoveClips(_owner)
			end
		end
		
		if self.new_num > #self.params.init_numbers then
			self.new_num = 1
		elseif self.new_num == 0 then
			self.new_num = #self.params.init_numbers
		end
		
		return true
	end
end 

function self.RotateCircle(_angle)
	if _angle < 0 then
		_angle = _angle + (math.pi * 2) * (((math.abs(_angle) - (math.abs(_angle) % (math.pi * 2))) / math.pi * 2) + 1)
	end
	if	_angle > math.pi * 2 then
		_angle = _angle % (math.pi * 2)
	end
	self.circle.SetRotation(sf.misc.MatrixRotation(_angle, self.circle.GetSize().X / 2, self.circle.GetSize().Y / 2))
end

function self.OnUpdate(_owner)
	if self.moving > 0 then
		if self.params.sound_rotation then
			sound(self.params.sound_rotation)
		end
		
		local need_time = math.abs(self.new_angle - self.start_angle) / self.params.speed * 1000
		local cur_time = (self.timer.Get().GetTime() - self.start) / need_time
		if cur_time > 1 then
			cur_time = 1
		end
		
		local cur_angle = self.start_angle + (self.new_angle - self.start_angle)*cur_time
		self.RotateCircle(cur_angle)
		
		if cur_time == 1 then
			-- закончилось движение, надо обнулить параметры движения и добавить в массив новый image_widget
			local name = self.params.image_id_prefix
			if self.new_num < 10 then
				name = name .. 0
			end
			name = name .. self.new_num
			--self.circle.AddFlags(sf.gui.CWidget.FlagHidden)
			local img = sf.gui.CImageWidget(name , "img0"..self.moving, 2, 0) 
			local width, height = self.circle.GetSize().X, self.circle.GetSize().Y
			local offset_x, offset_y = self.circle.GetOffset().X, self.circle.GetOffset().Y
			local center = sf.misc.FloatVector(offset_x + width/2, offset_y + height/2)
			self.MoveAndRotate(img, self.moving*self.angle, center)
			_owner.AddWidget(img)
			self.objects[self.moving].image = img
			self.objects[self.moving].num = self.new_num
			
			sminigames.save[self.moving] = self.new_num -- сохранить значение 

			self.moving = -1
			self.start_angle = 0
			self.new_angle = 0
			self.new_num = 0
			self.start = 0
			
			self.RemoveMoveClips(_owner) -- удаляем клипы
			
			self.CheckEnd(_owner)
		end
	end
end
