--script for nnm-club.org (28/08/2013) only for SimpleTV 0.4.7r4 and above
--id в PasswordManager - alllostfilm

--откройте комментарий, пропишите прокси:
--local proxy = '46.175.151.234:8080'

function locallog(s)
	debug_in_file(os.date("%X") .. "\n" .. s .. "\n", "c:\\PortableApps\\debug.log")
end

function localanswer(s)
	debug_in_file(s, "c:\\PortableApps\\answer.html", 0)
end

function lostfilmLogout(session) -- returns rc
	local rc
	host = 'http://login1.bogi.ru/logout.php?target=http://lostfilm.tv/'
	rc = m_simpleTV.WinInet.Get(session, host)
	if rc ~= 200 then return rc end	
	host = 'http://lostfilm.tv/logout_iframe.php'
	rc = m_simpleTV.WinInet.Get(session, host)
	return rc
end

function lostfilmLogin(session)
	local header, host, body
	header =
	'Host: login1.bogi.ru\n' ..
	'Content-Type: application/x-www-form-urlencoded\n' ..
	'Referer: http://www.lostfilm.tv/\n'
	host = 'http://login1.bogi.ru/login.php?referer=http://www.lostfilm.tv'
	body = 'login=' .. login .. '&password=' .. password .. '&module=1&target=' .. inAdr .. '&repage=user&act=login'

	rc, answer = m_simpleTV.WinInet.Post(session, host, nil, header, body)
	if rc ~= 200 then return rc end

	header =
	'Host: www.lostfilm.tv\n' ..
	'Content-Type: application/x-www-form-urlencoded\n' ..
	'Referer: http://login1.bogi.ru/login.php?referer=http://www.lostfilm.tv\n'
	host = string.match(answer, 'form.-action="(.-)"')
	if rc ~= 200 then return rc end
	
	local params = string.gmatch(answer, '<input.->')
	local paramArray = {}
	local t
	for t in params do
		local name = string.match(t, 'input.-name="(.-)".-value')
		local value = string.match(t, 'input.-value="(.-)"') or ""
		if name ~= nil then table.insert(paramArray, name .. "=" .. value) end
	end
	body = table.concat(paramArray, "&")

	rc, answer = m_simpleTV.WinInet.Post(session, host, nil, header, body)
	if rc ~= 200 then return rc end
end

function prepareLostfilmNews(session, result_hash)
	result_hash.osd = {}
	local host = 'http://www.lostfilm.tv/browse.php'
	local rc, answer = m_simpleTV.WinInet.Get(session, host)
	if rc ~= 200 then return rc end
	
	local s_first = string.find(answer, '<div class=?"content_body">?')
	local s_end = string.find(answer, '<span class=?"d_pages_link_selected">?', s_first)
	local s_last = s_first
	if not s_first or not s_end then return 200 end
	local i = 1
	while true do
		local news_serial_name, news_episode_name, news_episode_number, quality_page_codes
		s_first, s_last, news_episode_number = string.find(answer, '<div style=?"float:?right.->.-%-%>(.-)</div>', s_first)
		if not s_first then break end
		s_first, s_last, news_serial_name = string.find(answer, '<div.-</div>.-<span.->(.-)</span>', s_first)
		if not s_first then break end
		s_first, s_last, news_episode_name = string.find(answer, '<span class=?"torrent_title">?.-<b>(.-)</b>', s_first)
		if not s_first then break end
		s_first, s_last, quality_page_codes = string.find(answer, "ShowAllReleases%((.-)%)", s_first)
		if not s_first then break end
		if s_last and s_last > s_end then break end
		news_episode_number = string.match(news_episode_number, '^%s*(.*%S)') or ''
		result_hash.osd[i] = {}
		result_hash.osd[i].Id = i
		result_hash.osd[i].Name = news_serial_name .. ": " .. news_episode_number .. " - " .. news_episode_name
		result_hash.osd[i].child = {}
		result_hash.osd[i].child.type = "quality"
		result_hash.osd[i].child.params = quality_page_codes
		result_hash.osd[i].child.osd_header = news_episode_name .. ": "
		i = i + 1
	end
	
	commonFill(result_hash)
	return rc
end

function prepareLostfilmQuality(session, result_hash)
	result_hash.osd = {}
	local c, s, e = string.match(result_hash.params, "'(.-)','(.-)','(.-)'")
	local host = 'http://www.lostfilm.tv/nrdr.php?c=' .. c .. '&s=' .. s .. '&e=' .. e
	local rc, answer = m_simpleTV.WinInet.Get(session, host)
	if rc ~= 200 then return rc end
	
	local downloads = string.gmatch(answer, '<tr.-<td.-(<a.-</a>)')
	local i = 1 
	for download in downloads do
		result_hash.osd[i] = {}
		result_hash.osd[i].Id = i
		result_hash.osd[i].torrent_ref, result_hash.osd[i].Name = string.match(download, 'href="(.-)".->(.-)</a>')
		i = i + 1
	end
	
	commonFill(result_hash)
	return rc
end

function prepareLostfilmSeasons(session, result_hash)
	result_hash.osd = {}
	local host = 'http://www.lostfilm.tv/browse.php?cat=' .. result_hash.params
	local rc, answer = m_simpleTV.WinInet.Get(session, host)
	if rc ~= 200 then return rc end
	
	local c1 = 0
	local i1 = 0
	local season_name
	
	while true do
		i1 = i1 + 1
		c1, _, season_name = string.find(answer, '<div class="content".-<div class="content_head".-<h2.->(.-)</h2>', c1 + 1)
		if season_name == nil then break end
		local next_content_position = string.find(answer, '<div class="content"', c1 + 1)
		if next_content_position == nil then 
			next_content_position = string.find(answer, '<div class=?"block_bottoml">?', c1 + 1)
			if next_content_position == nil then break end
		end
		result_hash.osd[i1] = {}
		result_hash.osd[i1].Id = i1
		result_hash.osd[i1].Name = season_name
		result_hash.osd[i1].child = {}
		result_hash.osd[i1].child.osd_header = season_name .. ": "
		result_hash.osd[i1].child.osd = {}
		local c2 = c1
		local i2 = 0
		local number
			while true do
			i2 = i2 + 1
			c2, _, number = string.find(answer, '<div class="t_row.-</td>.-<td class>?.-<span.->.-<span.->.-<span.->(.-)</span>', c2 + 1)
			if number == nil then break end
			if c2 > next_content_position then break end
			local name, ref
			c2, _, name = string.find(answer, '<div id="TitleDiv.-<span.->(.-)</span>', c2 + 1)
			c2, _, ref = string.find(answer, "ShowAllReleases%((.-)%)", c2 + 1)
			if name == nil then break end
			local episode_name = number .. ': ' .. name
			result_hash.osd[i1].child.osd[i2] = {}
			result_hash.osd[i1].child.osd[i2].Id = i2
			result_hash.osd[i1].child.osd[i2].Name = episode_name
			result_hash.osd[i1].child.osd[i2].child = {}
			result_hash.osd[i1].child.osd[i2].child.type = "quality"
			result_hash.osd[i1].child.osd[i2].child.osd_header = episode_name .. ": "
			result_hash.osd[i1].child.osd[i2].child.params = ref			
		end
		if table.maxn(result_hash.osd[i1].child.osd) == 0 then
			table.remove(result_hash.osd, i1)
			i1 = i1 - 1
		else
			commonFill(result_hash.osd[i1].child)
		end
	end
	
	commonFill(result_hash)
	return rc
end

function prepareLostfilmSerials(session, result_hash)
	result_hash.osd = {}
	local host = 'http://www.lostfilm.tv/serials.php'
	local rc, answer = m_simpleTV.WinInet.Get(session, host)
	if rc ~= 200 then return rc end
	
	local answer = string.match(answer, '<div class="mid".-<div class="bb"(.-)</div>.-</div>')
	local serials = string.gmatch(answer, '<a href="/browse%.php%?cat=.-" class="bb_a">.-<br>')
	local i = 1
	result_hash.osd[i] = {}
	result_hash.osd[i].Id = i
	result_hash.osd[i].Name = "НОВИНКИ!"
	result_hash.osd[i].child = {}
	result_hash.osd[i].child.type = "news"
	result_hash.osd[i].child.osd_header = "НОВИНКИ: " 
	i = i + 1
	for serial in serials do
		result_hash.osd[i] = {}
		result_hash.osd[i].Id = i
		result_hash.osd[i].child = {}
		result_hash.osd[i].child.params, result_hash.osd[i].Name = string.match(serial, 'cat=(.-)" class="bb_a">(.-)<br>')
		result_hash.osd[i].child.type = "seasons"
		result_hash.osd[i].child.osd_header = result_hash.osd[i].Name .. ": " 
		i = i + 1
	end
	
	commonFill(result_hash)
	return rc
end

function commonFill(global_hash)
	if table.maxn(global_hash.osd) == 0 then
		global_hash.osd[0] = {}
		global_hash.osd[0].Id = 1
		global_hash.osd[0].Name = "Ничего не найдено - назад"
		global_hash.osd_flags = 1 + 2
	else
		global_hash.osd_flags = 1 + 2 + 8
	end
end

function go_osd(session, global_hash)
	local rc = 200
	if global_hash == nil then return rc, nil
	elseif global_hash.osd then 
		-- already filled, will do nothing
	elseif global_hash.type == "seasons" then
		rc = prepareLostfilmSeasons(session, global_hash)
	elseif global_hash.type == "quality" then
		rc = prepareLostfilmQuality(session, global_hash)
	elseif global_hash.type == "news" then
		rc = prepareLostfilmNews(session, global_hash)
	elseif table.maxn(global_hash) == 0 then
		global_hash.osd_header = 'Lostfilm.tv:'
		rc = prepareLostfilmSerials(session, global_hash)
	else return rc, nil
	end
	if rc ~= 200 then return rc, nil end
	
	local select_error, selected_id
	while true do
		select_error, selected_id = m_simpleTV.OSD.ShowSelect(global_hash.osd_header, (selected_id or 1) - 1, global_hash.osd, 0, global_hash.osd_flags)
		if select_error ~= 1 then break end
		if global_hash.osd[selected_id].torrent_ref then return rc, global_hash.osd[selected_id].torrent_ref end	
		if global_hash.osd[selected_id].child ~= nil then
			rc, torrent_ref = go_osd(session, global_hash.osd[selected_id].child)
			if torrent_ref then return rc, torrent_ref end
		end
	end
	return rc, nil
end

------------------------------------------------------------
-- S T A R T
------------------------------------------------------------

if m_simpleTV.Control.ChangeAdress ~= 'No' then return end

local inAdr = m_simpleTV.Control.CurrentAdress
if not string.match(inAdr, 'alllostfilm') then return end

m_simpleTV.Control.ChangeAdress = 'Yes'
m_simpleTV.Control.CurrentAdress = ''

local res, login, password, head = xpcall(
	function()
		require('pm')
		return pm.GetPassword('lostfilm')
	end, err
)

if login == nil then login = '' end
if password == nil then password = '' end

if login == '' or password== '' then
	m_simpleTV.OSD.ShowMessage("Check 'lostfilm' in PasswordManager", 0x0000FF, 10)
	return 
end

local session
if proxy == nil then
	session = m_simpleTV.WinInet.New("Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.9.168 Version/11.52")
else
	session = m_simpleTV.WinInet.New("Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.9.168 Version/11.52", 0, 3, proxy) -- INTERNET_OPEN_TYPE_PROXY 
end

if session == nil then return end

m_simpleTV.WinInet.SetOptionInt(session, 2, 3000, 0) --INTERNET_OPTION_CONNECT_TIMEOUT
m_simpleTV.WinInet.SetOptionInt(session, 6, 5000, 0) --INTERNET_OPTION_RECEIVE_TIMEOUT
m_simpleTV.WinInet.SetOpenRequestFlags(session, 0x80000000) --INTERNET_FLAG_RELOAD

--[[
rc = lostfilmLogout(session)
if rc ~= 200 then
	m_simpleTV.WinInet.Close(session)
	m_simpleTV.OSD.ShowMessage("HTTP error - " .. rc, 0x0000FF)
	return
end
]]

local rc, answer = m_simpleTV.WinInet.Get(session, 'http://www.lostfilm.tv/serials.php')
if rc ~= 200 then
	m_simpleTV.WinInet.Close(session)
	m_simpleTV.OSD.ShowMessage("HTTP error - " .. rc, 0x0000FF)
	return
end

if not string.match(answer, 'http://login1%.bogi%.ru/logout%.php%?target=') then
	rc = lostfilmLogin(session)
	if rc ~= 200 then
		m_simpleTV.WinInet.Close(session)
		m_simpleTV.OSD.ShowMessage("HTTP error - " .. rc, 0x0000FF)
		return
	end
end

global_hash = {}
rc, torrent_ref = go_osd(session, global_hash)

if rc ~= 200 then
	m_simpleTV.WinInet.Close(session)
	m_simpleTV.OSD.ShowMessage("HTTP error - " .. rc, 0x0000FF)
	return
end	

if not torrent_ref then
	m_simpleTV.WinInet.Close(session)
	return
end

local tmpName = m_simpleTV.Common.GetTmpName()
rc, answer = m_simpleTV.WinInet.Post(session, torrent_ref, nil, header, '', tmpName)
if rc~=200 then
	m_simpleTV.WinInet.Close(session)
	m_simpleTV.OSD.ShowMessage("HTTP error - " .. rc, 0x0000FF)
	os.remove(tmpName)
	return
end

m_simpleTV.WinInet.Close(session)
m_simpleTV.Control.CurrentAdress = 'torrent://' .. tmpName
