class 'ExtraMusicBase' (ExtraPageBase)

function ExtraMusicBase:__init(extraScreen, order)
	ExtraPageBase.__init(self, extraScreen, 'musicPage', order)

	self.sourceFileFormat	= 'Data/ExtraContent/Textures/Screens/Extra/Music/Tracks/track%s.wma'
	self.tracksFileFormat	= 'Data/Music/%s.ogg'
	self.trackNames			= {
								'music_1',
								'music_2',
								'music_3',
								'music_4'
							  }

	self.selectorYPos		= {145, 203, 262, 317}
	self.selectorFadeTime	= 0.1
	self.selectorMinOpacity	= 0.3

	self.buttons		= nil
	self.tracks			= {}
	self.index			= 1
	self.bPlaying		= false
	self.updateProgressBarConnector = nil
end
-------------------------------------------------------------------------------

function ExtraMusicBase:createContent()
	ExtraPageBase.createContent(self)

	local selector = self:getEntityNamed('selector')
	selector:setOpacity( self.selectorMinOpacity )
	selector:setY( self.selectorYPos[self.index] )
	
	self.buttons = self:createButtonsTable() or {}

	for id, info in pairs(self.buttons) do
		info.entity.onPress:add( info.callback )
		info.entity:setSFXTrackOnPress( info.sfx or getCommonSoundEntity('ButtonClick') )
	end
end
-------------------------------------------------------------------------------

--[[
 * Инициализация кнопок воспроизведения музыкальных треков и открытия скрина нот.
--]]
function ExtraMusicBase:createButtonsTable()
	local buttons = {}

	for i=1, 4 do
		buttons['track'..i] =
		{
			entity	 = self:getEntityNamed('bttn_play_track_'..i),
			callback = bind(self.playTrack, self, i)
		}
	end

	return buttons
end
-------------------------------------------------------------------------------

--[[
 * Переопределенны метод открытия "страницы". При открытии определяется, воспроизводится ли
 * любой из треков и скрывается либо кнопка запуска, либо кнопка остановки воспроизведения.
--]]
function ExtraMusicBase:show()
	ExtraPageBase.show(self)

	if self:isPlaying() then
		self.screen:getButton('play_music'):hide()
	else
		self.screen:getButton('stop_music'):hide()
	end

	self.screen:getButton('save'):setRespondable(false)
	self.screen:getButton('save'):setOpacity(self.selectorMinOpacity)
end
-------------------------------------------------------------------------------

function ExtraMusicBase:hide()
	self:stop()
	ExtraPageBase.hide(self)
end
-------------------------------------------------------------------------------

--[[
 * Вызывается при нажатии на кнопку "prev" в родительском "скрине".
--]]
function ExtraMusicBase:prev()
	local index = (self.index > 1) and (self.index - 1) or (#self.trackNames)
	self:playTrack(index)
end
-------------------------------------------------------------------------------

--[[
 * Вызывается при нажатии на кнопку "next" в родительском "скрине".
--]]
function ExtraMusicBase:next()
	local index = (self.index < #self.trackNames) and (self.index + 1) or 1
	self:playTrack(index)
end
-------------------------------------------------------------------------------

--[[
 * Вызывается при нажатии на кнопку "play_music" в родительском "скрине".
--]]
function ExtraMusicBase:play()
	self:playTrack(self.index)
end
-------------------------------------------------------------------------------

--[[
 * Вызывается при нажатии на кнопку "stop_music" в родительском "скрине".
--]]
function ExtraMusicBase:stop()
	self:stopTrack()
end
-------------------------------------------------------------------------------

--[[
 * Вызывается при нажатии на кнопку "save" в родительском "скрине".
--]]
function ExtraMusicBase:save()
	if self:isPlaying() then
		createYesNoScreen(	'CE_SAVE_TRACK_CONFIRMATION',
							bind(self.onSavingConfirmed, self),
							bind(self.onSavingCanceled,  self), false)
	end
end
-------------------------------------------------------------------------------

function ExtraMusicBase:onSavingConfirmed()
	if self:isPlaying() then
		local currentTrackIndex = self.index
		local prefix = GetString('CE_TRACK_PREFIX')
		local destinationName = {
									prefix..GetString('CE_TAB_MUSIC_1ST_TACK_NAME')..'.wma',
									prefix..GetString('CE_TAB_MUSIC_2ND_TACK_NAME')..'.wma',
									prefix..GetString('CE_TAB_MUSIC_3RD_TACK_NAME')..'.wma',
									prefix..GetString('CE_TAB_MUSIC_4TH_TACK_NAME')..'.wma'
								}

		copyResourceIntoMyMusicFolder(string.format(self.sourceFileFormat, currentTrackIndex), destinationName[currentTrackIndex])
	end
end
-------------------------------------------------------------------------------

function ExtraMusicBase:onSavingCanceled()
end
-------------------------------------------------------------------------------

--[[
 * Запускает проигрывание музыкального трека по заданому индексу.
 * @param	index		Индекс необходимого трека.
--]]
function ExtraMusicBase:playTrack(index)
	self:stopTrack()
	self:getTrack(index):play()

	self.index    = index
	self.bPlaying = true

	if self:isOpen() then
		self.screen:getButton('play_music'):hide()
		self.screen:getButton('stop_music'):show()
	end

	self:runProgressBar()
	self:onTrackStarted()
end
-------------------------------------------------------------------------------

--[[
 * Останавливает проигрывание текущего музыкального трека.
--]]
function ExtraMusicBase:stopTrack()
	if self.bPlaying then
		self:getTrack(self.index):stop()

		self.bPlaying = false

		if self:isOpen() then
			self.screen:getButton('play_music'):show()
			self.screen:getButton('stop_music'):hide()
		end

		self:stopProgressBar()
		self:onTrackStopped()
	end
end
-------------------------------------------------------------------------------

--[[
 * Метод возвращает MusicTrack по заданому индексу. Если трек еще не был создан, то
 * он создастся и добавится в таблицу треков. Путь к файлу определяется на основе
 * шаблона self.tracksFileFormat и имени из таблицы self.trackNames.
 * @param	index		Индекс необходимого трека.
--]]
function ExtraMusicBase:getTrack(index)
	local track = self.tracks[index]

	if not track then
		local trackName = self.trackNames[index]
		local fileName  = string.format(self.tracksFileFormat, trackName)

		track = CreateMusicTrack(fileName)
		track:setName		 ( trackName )
		track:attachTo		 ( self:getMainEntity() )
		track:setRepeated	 ( true )
		track:setFadeDuration( 0 )

		self.tracks[index] = track
	end

	return track
end
-------------------------------------------------------------------------------

--[[
 * Проверка воспроизводится ли в данный момент любой из звуковых треков.
--]]
function ExtraMusicBase:isPlaying()
	return self.bPlaying
end
-------------------------------------------------------------------------------

--[[
 * Зупускает логику отображения полосы прогресса.
--]]
function ExtraMusicBase:runProgressBar()
	local line = self:getEntityNamed('timeline')

	self.updateProgressBarConnector =
	line.onUpdate:add( bind(self.updateProgressBar, self) )

	line:setScaleX(0)
	line:setVisible(true)
end
-------------------------------------------------------------------------------

--[[
 * Метод описывает логику отображения полосы прогресса.
--]]
function ExtraMusicBase:updateProgressBar(target, dt)
	local track	= self:getTrack(self.index)
	local scale	= track:getTimePosition() / track:getDuration()
	-- print(track:getTimePosition() .. '   '..track:getDuration())

	self:getEntityNamed('timeline'):setScaleX(scale)
end
-------------------------------------------------------------------------------

--[[
 * Останавливает логику отображения полосы прогресса.
--]]
function ExtraMusicBase:stopProgressBar()
	if self.updateProgressBarConnector then
		self.updateProgressBarConnector:remove()
		self.updateProgressBarConnector = nil
	end

	self:getEntityNamed('timeline'):setVisible(false)
end
-------------------------------------------------------------------------------


--[[
 * Метод вызывается зразу после начала проигрывания музыкального трека.
 * Служит для описания дополнительной логики запуска проигрывания музыки. Таквой
 * логикой может быть проигрывание анимации на клавише трека, запуск "прогресс бара"
 * и т.п.
--]]
function ExtraMusicBase:onTrackStarted()
	-- local mainMusic = getGameRoot():getEntityNamed(NAME_MAIN_SOUND)
	-- if mainMusic then
	-- 	mainMusic:pause()
	-- end

	local selector	 = self:getEntityNamed('selector')
	local button	 = self.buttons['track'..self.index].entity
	local anim		 = self:getEntityNamed('anim_track'..self.index)
	local trebleClef = self:getEntityNamed('anim_trebleclef')

	selector:setY( self.selectorYPos[self.index] )
	selector:destroyEffectors()
	selector:ChangeOpacity(nil, 1, self.selectorFadeTime)

	button:hide()
	anim:play()
	anim:show()
	trebleClef:play()

	do
		local saveBatton = self.screen:getButton('save')
		saveBatton:setRespondable(true)
		saveBatton:destroyEffectors()
		saveBatton:ChangeOpacity(nil, 1, self.selectorFadeTime)
	end
end
-------------------------------------------------------------------------------

--[[
 * Метод вызывается зразу после прекращения проигрывания музыкального трека.
 * Служит для описания дополнительной логики при его остановке. Таквой
 * логикой может быть прекращение проигрывания анимации на клавише трека,
 * остановка "прогресс бара" и т.п.
--]]
function ExtraMusicBase:onTrackStopped()
	-- local mainMusic = getGameRoot():getEntityNamed(NAME_MAIN_SOUND)
	-- if mainMusic then
	-- 	mainMusic:play()
	-- end

	local selector	 = self:getEntityNamed('selector')
	local button	 = self.buttons['track'..self.index].entity
	local anim		 = self:getEntityNamed('anim_track'..self.index)
	local trebleClef = self:getEntityNamed('anim_trebleclef')

	selector:destroyEffectors()
	selector:ChangeOpacity(nil, self.selectorMinOpacity, self.selectorFadeTime)

	button:show()
	anim:hide()
	anim:stop()
	trebleClef:stop()
	trebleClef:rewind(false)

	do
		local saveBatton = self.screen:getButton('save')
		saveBatton:setRespondable(false)
		saveBatton:destroyEffectors()
		saveBatton:ChangeOpacity(nil, self.selectorMinOpacity, self.selectorFadeTime)
	end
end
-------------------------------------------------------------------------------

function ExtraMusicBase:getSourceFileName()
	local id = self.ids[self.index]
	return string.format(self.sourceFileFormat, id)
end
-------------------------------------------------------------------------------
