local base = _G
module ('ttvcore')

----------------------------------------------------------------------------
UpdateID='TorrentTV01'
RetryCount=0
OrigAddress=''

local IsVip = false

local base_site = 'torrent-tv.ru'
local reserved_site = '1ttv.org'
local current_site = base_site
local base_site_gsub = 'torrent%-tv%.ru'
local reserved_site_active = false

local max_time_in_cache=3600
local cache_address={}
----------------------------------------------------------------------------
----------------------------------------------------------------------------
UsePasswordManager=1  --установите в 0, если не  хотите использовать PasswordManager
----------------------------------------------------------------------------
--*******************  Cache address
----------------------------------------------------------------------------
function RemoveAddressFromCache(oadr)
 local i = FindAddressInCache(oadr)
 if s == nil then return end
 base.table.remove(cache_address,i)
end
----------------------------------------------------------------------------
function ClearAddressCache()
  cache_address={}
end
----------------------------------------------------------------------------
function AddAddressToCache(oadr,radr)
 local i = FindAddressInCache(oadr)
 if i == nil then i=#cache_address+1 end
 
 cache_address[i]={}
 cache_address[i].oadr=oadr
 cache_address[i].radr=radr
 cache_address[i].time = base.os.clock()+max_time_in_cache
 
end
----------------------------------------------------------------------------
function GetAddressFromCache(address)
 
 local i = FindAddressInCache(address)
 if i == nil then return end
 
 if cache_address[i].time < base.os.clock() then 
   base.table.remove(cache_address,i)
   return 
end

 return cache_address[i].radr
end
----------------------------------------------------------------------------
function FindAddressInCache(oadr)
 for i=1,#cache_address do 
   if cache_address[i].oadr == oadr then return i end
 end  
end
----------------------------------------------------------------------------
----------------------------------------------------------------------------
----------------------------------------------------------------------------
local function TTVSetCookies()
  
 base.m_simpleTV.WinInet.SetCookies(base.m_simpleTV.User.TorrentTV.Session,'http://' .. current_site .. '/','','BHC=0;expires = Sat, 01-Jan-1970 00:00:00 GMT')	
 
 local adr = 'http://' .. current_site .. '/banhammer/pid'
 local rc,answer=base.m_simpleTV.WinInet.Get(base.m_simpleTV.User.TorrentTV.Session,adr)  
  
 if rc~=200 then return end
 
 local rawheader = base.m_simpleTV.WinInet.GetRawHeader(base.m_simpleTV.User.TorrentTV.Session)
 --base.debug_in_file(rawheader  .. '\n' )
	
 local token = base.findpattern(rawheader,'X%-BH%-Token:(.-)\n',1,12,2)
 if token==nil then return end
 --base.debug_in_file(token  .. '\n' )
 base.m_simpleTV.WinInet.SetCookies(base.m_simpleTV.User.TorrentTV.Session,'http://' .. current_site .. '/','','BHC=' .. token)
	 
end
----------------------------------------------------------------------------
local function TTVGet(adr,ShowError)
 
 local rc,answer
 for i=1,4 do
  rc,answer = base.m_simpleTV.WinInet.Get(base.m_simpleTV.User.TorrentTV.Session,adr)   
  --local cc = base.m_simpleTV.WinInet.GetCookies(base.m_simpleTV.User.TorrentTV.Session,'http://' .. current_site .. '/','')	
  --local sss = base.string.sub(answer,1,1024)
  --base.debug_in_file('New get(' .. i .. '), rc = ' .. rc .. '\n' .. 'Cookies=' .. (cc or '') .. sss  .. '\n\n' )  
 
   if rc ~= 200 then 
     if ShowError then  base.m_simpleTV.OSD.ShowMessage_UTF8( RuStr("Net error - " .. rc),255,5) end
	 return rc,answer
   end

  if not base.string.match(answer,'eraseCookieFromAllPaths%("BHC"%);') then return rc,answer  end
  if i>=4 then break end
  
  --base.debug_in_file('BHC detect\n' )	
  base.m_simpleTV.Common.Wait(500)
  TTVSetCookies()
  base.m_simpleTV.Common.Wait(500)
 end  

 --base.debug_in_file('End get\n\n\n\n\n\n\n' ) 
 return nil
end
----------------------------------------------------------------------------
function GetTTVAddress(inAdr,DoUpdate,Use1ttv)

 OrigAddress=inAdr
 
 if TorrentTVLogin(false) == nil then 
     if reserved_site_active then return end
	  base.m_simpleTV.OSD.ShowMessage_UTF8(RuStr('Основной сайт недоступен, используется резервный'),255,5,1)
	  base.m_simpleTV.Common.Wait(2000)
	  current_site = reserved_site 
	  reserved_site_active=true
	  
      return GetTTVAddress(inAdr,DoUpdate,Use1ttv)
 end
 
 if reserved_site_active==true then 
   inAdr = base.string.gsub(  inAdr, base_site_gsub, reserved_site)
 end

 local retAdr
 retAdr = GetAddressFromCache(inAdr)
 if retAdr~=nil then return retAdr end

 local rc,answer=TTVGet(inAdr,false)
 if rc==nil then return end 
 if rc~=200 then
 local stop = true
 if Use1ttv~=nil and reserved_site_active==false then 	  
	  base.m_simpleTV.OSD.ShowMessage_UTF8(RuStr('Основной сайт недоступен, используется резервный'),255,5,1)
	  base.m_simpleTV.Common.Wait(2000)
	  reserved_site_active=true
	  current_site = reserved_site 
	  TorrentTVCloseSession()
      return GetTTVAddress(inAdr,DoUpdate,Use1ttv)
  end
    
  if stop == true then
	  base.m_simpleTV.OSD.ShowMessage_UTF8(RuStr('Page not found (error ' .. rc .. ')'),255,5)
	  base.m_simpleTV.Common.Wait(2000)
	 if DoUpdate==true then UpdatePls_TTV() end
	 return	
  end				   
  
 end
  
 --local bum  = base.findpattern( answer,'lDateTime = %b""',1,13,1)
 --if bum~=nil then 
--      local qq = 'http://www.'.. current_site .. '/calendar.php?date=' .. base.os.time() .. '131' .. '&datetime=' .. bum
--	  base.m_simpleTV.WinInet.Get(base.m_simpleTV.User.TorrentTV.Session,qq)
--  end

 retAdr = base.findpattern( answer,'this%.loadTorrent%(%b""',1,18,1)
 if retAdr==nil then
	   retAdr = base.findpattern( answer,'this%.loadPlayer%(%b""',1,17,1)
	   if retAdr==nil then
	   	   base.m_simpleTV.OSD.ShowMessage_UTF8(RuStr("Not found torrent or ID"),255,5)
		   --base.debug_in_file('need update ' ..  base.tostring(DoUpdate) ..'\n')		   
		   base.m_simpleTV.Common.Wait(2000)
		   if DoUpdate==true then UpdatePls_TTV() end
	       return
	   end
	   retAdr  = 'PID=' .. retAdr 
 end
 
 RetryCount = 0
 retAdr = 'torrent://' .. base.m_simpleTV.Common.string_fromUTF8(retAdr)
 AddAddressToCache(inAdr,retAdr)
 return retAdr
end
----------------------------------------------------------------------------
function UpdatePls_TTV()

 --base.debug_in_file('start update\n')
 if not IsValidPlayListAddress(OrigAddress) then return end

 TorrentTVCloseSession()
 if RetryCount >=1 then return end
 local val=base.m_simpleTV.Config.GetConfigInt(base.m_simpleTV.Defines.ID_EXT_TORRENTTV_AUTOREFRESH)
 local NotUseTVS = base.m_simpleTV.Config.GetConfigInt(base.m_simpleTV.Defines.ID_EXT_TORRENTTV_NOT_USE_TVS) or 0
 if val~=0 then 
    RetryCount=RetryCount+1
    if NotUseTVS==1 or base.TVSources_var==nil or base.tvs_core==nil then
        if TorrentTVLogin() ~= true then return end
		base.dofile(base.m_simpleTV.MainScriptDir .. 'user\\TorrentTV\\TorrentTVRefreshPls.lua')  
		
		base.m_simpleTV.Control.CurrentAdress = OrigAddress		
      else
	  
	   base.TVSources_var.tmp.source = {}
       base.TVSources_var.tmp.source = base.tvs_core.tvs_GetSourceParam()		
       	   
	   for id_source,content in base.pairs(base.TVSources_var.tmp.source) do		            
		 if content.name == base.TVSources_var.CurrentSource then 
		    base.tvs_core.UpdateSource(id_source)		
			base.m_simpleTV.Control.CurrentAdress = 'repeatafterupdate'
			break
		 end
	   end
     end 
  end	 
end			
------------------------------------------------------------------------------------------
function IsTTVAddress(adr)

if  base.string.match(adr,'acelive$') or base.string.match(adr,'^torrent') then return false end

if  (not base.string.match( adr, 'torrent%-tv%.ru/torrent%-online%.php' ))
    and (not base.string.match( adr, 'torrent%-tv%.ru/torrent%-online%-min%.php' ))
    and (not base.string.match( adr, 'torrent%-tv%.ru/tv%-archive%-online%.php' ))   
	and (not base.string.match( adr, 'torrent%-tv%.ru/movie%-online%.php' ))   
   then return false end

return true
end
----------------------------------------------------------------------------
function TorrentTVCloseSession ()
  ClearAddressCache()
  if base.m_simpleTV.User.TorrentTV.Session~=nil then
    base.m_simpleTV.WinInet.Close(base.m_simpleTV.User.TorrentTV.Session)
	base.m_simpleTV.User.TorrentTV.Session=nil
  end
end
----------------------------------------------------------------------------
function GetPMState()

 if UsePasswordManager ~= 1 then return end
 local error_text,pm = base.pcall(base.require,'pm')
 local PM_detected 

 if base.package.loaded.pm~=nil then PM_detected = true end

return PM_detected
end
----------------------------------------------------------------------------
function GetLogin()
 
 local error_text,pm 
 local login,pass,head,error_type,error_text 
 
  if UsePasswordManager == 1 then 
	  error_text,pm = base.pcall(base.require,'pm')
  end 	
	   
  if UsePasswordManager == 1 and  base.package.loaded.pm then 
	
    err,login,pass,head  = pm.GetTestPassword('torrenttv','Torrent-TV')
	if err~=true then return end
	
  else  
    login=base.m_simpleTV.Config.GetConfigString(base.m_simpleTV.Defines.ID_EXT_TORRENTTV_LOGIN)
    pass=base.m_simpleTV.Config.GetConfigString(base.m_simpleTV.Defines.ID_EXT_TORRENTTV_PASS)
  end	
  
  if login==nil or login=='' or pass==nil or pass=='' then      
			base.m_simpleTV.OSD.ShowMessage_UTF8(RuStr("Для полноценной работы TTV требуется ввод логина и пароля"),0x00FFFF,10)
			base.m_simpleTV.Common.Wait(2000)
			return
	end
 return login,pass
end
----------------------------------------------------------------------------
function TorrentTVLogin (Anyway)

 if Anyway then TorrentTVCloseSession() end
 
 if base.m_simpleTV.User.TorrentTV.Session == nil then 
    base.m_simpleTV.User.TorrentTV.Session=base.m_simpleTV.WinInet.New('Opera/9.80 (Windows NT 6.1; Win64; x64) Presto/2.12.388 Version/12.17')
    if base.m_simpleTV.User.TorrentTV.Session == nil then return end 

    --INTERNET_OPTION_CONNECT_TIMEOUT
    base.m_simpleTV.WinInet.SetOptionInt(base.m_simpleTV.User.TorrentTV.Session,2,10000,0)
    --INTERNET_OPTION_RECEIVE_TIMEOUT
    base.m_simpleTV.WinInet.SetOptionInt(base.m_simpleTV.User.TorrentTV.Session,6,10000,0)
    --INTERNET_OPTION_FROM_CACHE_TIMEOUT
    --base.m_simpleTV.WinInet.SetOptionInt(base.m_simpleTV.User.TorrentTV.Session,63,2000,0)

	base.m_simpleTV.WinInet.SetOpenRequestFlags(base.m_simpleTV.User.TorrentTV.Session,0x80000000+0x04000000)
	
	base.m_simpleTV.WinInet.SetCookies(base.m_simpleTV.User.TorrentTV.Session,'http://' .. current_site .. '/','','PHPSESSID=0;expires = Sat, 01-Jan-1970 00:00:00 GMT')	
	--TTVSetCookies()	
	if TTVGet('http://' .. current_site .. '/favicon.ico')==nil then 
	   TorrentTVCloseSession()
	   return nil
	end	
  else 
   return true 
 end
    
 local login,pass = GetLogin()
 
 if login==nil or login=='' or pass==nil or pass=='' then      
	--base.m_simpleTV.WinInet.Get(base.m_simpleTV.User.TorrentTV.Session,'http://torrent-tv.ru')
	return true
 end
  
 login = base.string.gsub(login,'%@','%%40')
 local header = 'Content-Type: application/x-www-form-urlencoded\r\n'
 local body = 'email='.. login .. '&password=' .. pass .. '&enter=%D0%92%D0%BE%D0%B9%D1%82%D0%B8'
   
 local rc,answer=base.m_simpleTV.WinInet.Post(base.m_simpleTV.User.TorrentTV.Session,'http://' .. current_site .. '/auth.php',nil,header,body)
 
 if rc~=200 then 
     base.m_simpleTV.OSD.ShowMessage_UTF8(RuStr("Can't login"),255,5)	 
	 TorrentTVCloseSession()
     return nil
 end 
 
 local errtext = base.findpattern(answer,'class="alert alert%-error"(.-)</div>',1,0,0)
 if errtext == nil then
		base.m_simpleTV.OSD.ShowMessage_UTF8(RuStr("TTV - авторизация выполнена"),0xFF00,3)    
		return true
 end
 
 errtext = base.m_simpleTV.Common.string_fromUTF8(errtext,1251)
 errtext = base.findpattern(errtext,'<br>(.-)<br>',1,4,4)
  
 base.m_simpleTV.OSD.ShowMessage_UTF8(RuStr("TTV - ошибка авторизации (" ..  (errtext or '') .. ")"),255,5)    
 base.m_simpleTV.Common.Wait(3000)
 return nil
 
end
-----------------------------------------------------------------------------------------
function IsValidPlayListAddress (adr)
 
 if base.string.match (adr,'torrent%-online%.php') or base.string.match (adr,'torrent%-online%-min%.php') then  return true end
 return false
end
-----------------------------------------------------------------------------------------
function TorrentTVParceExt (answer,t,group,WithoutGroup)
local name,adr  
local m3ustr=''
  answer=base.m_simpleTV.Common.string_fromUTF8(answer)
  
 if WithoutGroup==1 then group='TorrentTV' end 
  
 local i = #t 
  
  for w in base.string.gmatch(answer,'<a (.-)</a>') do 
    name = base.findpattern(w,"<strong>(.-)</strong>",1,8,9)
	if name~=nil then
		name=base.string.gsub(name,'\n','')
		name=base.string.gsub(name,'\r','')
		name=base.string.gsub(name,',',' ')
		name=base.string.gsub(name,'\'','')
		adr  = base.findpattern(w,'href=%b""',1,6,1)

		if adr~=nil and IsValidPlayListAddress(adr)==true then 
		   
		   t[i] = {}
		   t[i].name    = base.string.gsub(name,',',' ') 
		   t[i].group   = group
		   t[i].address = 'http://' .. base_site .. '/' .. adr
		   i = i+1	 
			
         end			
    end 		
  end
 return m3ustr
end  
-----------------------------------------------------------------------------------------

function TorrentTVParceVIP (answer,t,group,WithoutGroup,HDGroup)

    local VIP_USE = base.m_simpleTV.Config.GetConfigInt(base.m_simpleTV.Defines.ID_EXT_TORRENTTV_VIP_USE)
	if VIP_USE == 0 then return false end
	local VIP_USELQ = base.m_simpleTV.Config.GetConfigInt(base.m_simpleTV.Defines.ID_EXT_TORRENTTV_VIP_USELQ)
	local VIP_LQGROUP = base.m_simpleTV.Config.GetConfigInt(base.m_simpleTV.Defines.ID_EXT_TORRENTTV_VIP_LQGROUP)
	if WithoutGroup==1 then group='TorrentTV' end 	
	
	local current_site_gsub = current_site:gsub("%.","%%."):gsub("%-","%%-")
	local viplink = answer:match("(http://api%." .. current_site_gsub .. "/t/.-)[\'|\"|\n]") 
	if not viplink then 
	  base.m_simpleTV.OSD.ShowMessage_UTF8(RuStr("TTV - не найдена ссылка на плейлист"),0xFF00,3)
	return false end
	
	viplink = viplink .. ( VIP_USELQ == 1 and '?mm=on' or '?mm=off') .. '&hash='.. base.os.time()
	
	local rc,answer = TTVGet( viplink ,false) 
 	
	if rc~=200 then  return  false
	end   
 	 
	answer = base.m_simpleTV.Common.string_fromUTF8(answer,1251)
	--if true then return end 
	
	local i = #t 
	local tname,tgroup,taddress, lgroup, lname
	for line in answer:gmatch('(#EXTINF:.-\n.-)\n') do                  -- блок канала
		tname,tgroup,taddress = line:match('.+,(.+) %((.+)%)\n(.+)')    -- название, группа и адрес
		if tgroup and tname and taddress then		
			lgroup, lname = tname:match('(Моб%. )(.+)')                 -- мобильные группа и название
			if lgroup then
				tname = (lname or tname)
				if VIP_LQGROUP == 1 then  
				   tgroup = 'LQ '.. tgroup
				else  
				   tname = tname .. ' LQ'
				end 
			end	
			if not lgroup and (tname:find(' HD') or tname:find('HD ')) and HDGroup == 1 then		
               tgroup = 'HD каналы'	
			end
			t[i] = {}
			t[i].name    = tname 
			t[i].group   = tgroup 
			t[i].address = taddress	 
			i = i+1
			base.m_simpleTV.OSD.ShowMessage_UTF8(RuStr("VIP - обработка "..i),0xFF00,3) 
		end
	end		
	--base.m_simpleTV.OSD.ShowMessage_UTF8(RuStr("TTV - обработка.."),0xFF00,3) 
	return true
end
-----------------------------------------------------------------------------------------  
function GetPlstAsM3u ()
  local t = GetPlstAsTable()
  if t == nil then return end
 
  local m3ustr='#EXTM3U  $ExtFilter="TorrentTV"\n'
 
 for i=1,#t do 
  
  m3ustr = m3ustr .. '#EXTINF:-1 update-code="' .. UpdateID .. t[i].group .. t[i].name .. '",' .. t[i].group .. ':' .. t[i].name .. '\n' .. t[i].address .. '\n' 		
 
 end
 --base.debug_in_file(m3ustr)
 return m3ustr
end
-----------------------------------------------------------------------------------------  
function RuStr (Str)
  return base.m_simpleTV.Common.string_toUTF8(Str,1251)
end
----------------------------------------------------------------------------------------  
function GetPlstAsTable (WithoutGroup,HDGroup)
 
 if TorrentTVLogin()==nil then return end
 
 local rc,answer =  TTVGet('http://' .. current_site ,true) 
 if rc~=200 then 
    base.m_simpleTV.OSD.ShowMessage_UTF8( RuStr("Net error - " .. rc),255,5)
    return
 end 
 answer=base.m_simpleTV.Common.string_fromUTF8(answer)
 
 if WithoutGroup==nil then 
	 WithoutGroup=base.m_simpleTV.Config.GetConfigInt(base.m_simpleTV.Defines.ID_EXT_TORRENTTV_WITHOUTGROUP) or 0
 end	 
  
 if  HDGroup == nil then
   HDGroup=base.m_simpleTV.Config.GetConfigInt(base.m_simpleTV.Defines.ID_EXT_TORRENTTV_HDGROUP) or 0
 end    

 local IsVip = answer:find('almost_vip') and true
 if IsVip then base.m_simpleTV.OSD.ShowMessage_UTF8(RuStr("TTV - авторизация выполнена - VIP"),0xFF00,3) 
 end
  
 local t ={}
 local Loaded = false
--local x = (IsVip==true and 'true' or 'false')
--base.debug_in_file( x .. '\n','D:\\SimpleTV\\LuaDebug.txt')
 
 if IsVip==true and base.m_simpleTV.Config.GetConfigInt(base.m_simpleTV.Defines.ID_EXT_TORRENTTV_VIP_USE) == 1 then
 		 local link = 'http://' ..  base_site .. '/c_playlist_file.php'.. '?hash='..base.os.time()
	     local rc, m3u = TTVGet( link,false) 
	     --base.debug_in_file( 'http://' ..  base_site .. '/c_playlist_file.php' .. '\n','D:\\SimpleTV\\LuaDebug.txt')
		 if rc==200 then 
			 Loaded = TorrentTVParceVIP (m3u,t,'VIP',WithoutGroup, HDGroup)
		 end

 end
 
 if Loaded==false then
	 local i=1
	 for w in base.string.gmatch(answer,'<li style="height: 19px;(.-)</ul></li>') do 
	  --base.debug_in_file('\n\n\n')
	  --base.debug_in_file(w .. '\n')
	  
	  local group = base.findpattern(w,'<a(.-)</a>',1,0,0)
	  if group~=nil then
	       group =  base.findpattern(group,'>(.-)<',1,1,1) 
	    end
	 --base.debug_in_file(group .. '\n')
		
	 if group ~= 'Избранное' then
	  if group ~= 'HD каналы' or (WithoutGroup==0 and HDGroup==1) then	
	   
	  if WithoutGroup==1 or group==nil then group='TorrentTV' end
	  
	    for ww in base.string.gmatch(w,'<li(.-)</li>') do 
		--base.debug_in_file('ww - ' .. ww .. '\n')
	      local tmp =  base.findpattern(ww,'<a(.-)</a>',1,0,0)
		  --base.debug_in_file('tmp - ' .. tmp .. '\n')
		  
		  if tmp~=nil then 
			local name = base.findpattern(tmp,'>(.-)<',1,1,1)
			local adr  = base.findpattern(tmp,'href=%b""',1,6,1)	  
	        if name~=nil and adr~=nil and IsValidPlayListAddress(adr)==true then
			   
			   t[i] = {}
			   t[i].name    = base.string.gsub(name,',',' ') 
			   t[i].group   = group
			   t[i].address = 'http://' ..  base_site .. '/' .. adr
			   i = i+1	 
	        end			
	      end		
	    end
	   end	
	  end 
	 end

	  
	 rc,answer=TTVGet('http://' .. current_site .. '/on_moderation.php',true) 
	 if rc==200 then 
	     TorrentTVParceExt (answer,t,'На модерации',WithoutGroup)
	 end   
 end 

 rc,answer=TTVGet('http://' .. current_site .. '/translations.php',true) 
 if rc==200 then 
     TorrentTVParceExt (answer,t,'Трансляции',WithoutGroup)
 end   

 return t
end 
----------------------------------------------------------------------------------
 function RemoveEmptyGroups()
 sqlstr = "DELETE * FROM Main WHERE id IN ( SELECT d.id FROM Main AS d LEFT JOIN Main AS m ON d.id = m.Group WHERE (((d.Id)>268435455) AND ((m.Group) Is Null)));"
  if base.m_simpleTV.Database.ExecuteSql(sqlstr,true) then 
     base.m_simpleTV.Common.RefreshPlayList()
  end 
end