--[[
	SpiegelTV-App
	Vers.: 0.6
	Copyright (C) 2020, fritz

	License: GPL

	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public
	License as published by the Free Software Foundation; either
	version 2 of the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	General Public License for more details.

	You should have received a copy of the GNU General Public
	License along with this program; if not, write to the
	Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
	Boston, MA  02110-1301, USA.

        Copyright (C) for the linked videos and for the Spiegel-Logo by SpiegelTV or the respective owners!
        Copyright (C) for the Base64 encoder/decoder function by Alex Kloss <alexthkloss@web.de>, licensed under the terms of the LGPL
]]

--Objekte
function script_path()
	local str = debug.getinfo(2, "S").source:sub(2)
	return str:match("(.*/)")
end

function init()
	n = neutrino();
	p = {}
	func = {}
	pmid = 0
	stream = 1
        tmpPath = "/tmp"
	spiegel_online = decodeImage("data:image/png;base64,[encoded data, 6944 characters]")
end

function add_stream(t,u,f,d)
  p[#p+1]={title=t,url=u,from=f,description=d,access=stream}
end

function getdata(Url,outputfile)
	if Url == nil then return nil end
	if Curl == nil then
		Curl = curl.new()
	end
	local ret, data = Curl:download{url=Url,A="40tude_Dialog/2.0.8.1de",followRedir=true,o=outputfile }

	if ret == CURL.OK then
		return data
	else
		return nil
	end
end

-- UTF8 in Umlaute wandeln
function conv_str(_string)
	if _string == nil then return _string end
        _string = string.gsub(_string,'\\n','');
        _string = string.gsub(_string,'\\','');
	_string = string.gsub(_string,"&Auml;","Ä");
	_string = string.gsub(_string,"&auml;","ä");
	_string = string.gsub(_string,"&Ouml;","Ö");
	_string = string.gsub(_string,"&ouml;","ö");
	_string = string.gsub(_string,"&Uuml;","Ü");
	_string = string.gsub(_string,"&uuml;","ü");
	_string = string.gsub(_string,"&szlig;","ß");
	_string = string.gsub(_string,"&egrave;","è");
	_string = string.gsub(_string,"&eacute;","é");
	_string = string.gsub(_string,"&amp;","&");
	_string = string.gsub(_string,"&ndash;","-");
	_string = string.gsub(_string,"&lt;","<");
	_string = string.gsub(_string,"&gt;",">");
	_string = string.gsub(_string,"&quot;","");
	_string = string.gsub(_string,"&apos;","'");
	_string = string.gsub(_string,"&#x00c4","Ä");
	_string = string.gsub(_string,"u00c4","Ä");
	_string = string.gsub(_string,"&#x00e4","ä");
	_string = string.gsub(_string,"u00e4","ä");
	_string = string.gsub(_string,"&#x00d6","Ö");
	_string = string.gsub(_string,"u00d6","Ö");
	_string = string.gsub(_string,"&#x00f6","ö");
	_string = string.gsub(_string,"u00f6","ö");
	_string = string.gsub(_string,"&#x00dc","Ü");
	_string = string.gsub(_string,"u00dc","Ü");
	_string = string.gsub(_string,"&#x00fc","ü");
	_string = string.gsub(_string,"u00fc","ü");
	_string = string.gsub(_string,"&#x00df","ß");
	_string = string.gsub(_string,"u00df","ß");
	_string = string.gsub(_string,"&#039","'");
	_string = string.gsub(_string,'&#34','"');
	_string = string.gsub(_string,"&#261","ą");
	_string = string.gsub(_string,";","");
--	_string = string.gsub(_string,"SPIEGEL TV: ","");
	_string = string.gsub(_string,'u201e','„');
	_string = string.gsub(_string,'u201c','“');
	_string = string.gsub(_string,'u00d8','ø');
	_string = string.gsub(_string,'u00a0',' ');
	_string = string.gsub(_string,'u0142','ł');
	_string = string.gsub(_string,'u00b0','°');
	_string = string.gsub(_string,'u0302','̂ ');
	_string = string.gsub(_string,'u031e','̞');
	_string = string.gsub(_string,'u0301','́');
	_string = string.gsub(_string,'u201d','́');
	_string = string.gsub(_string,'u2018','‘');
	_string = string.gsub(_string,'u2013','–');
	_string = string.gsub(_string,'u2026','…');
	_string = string.gsub(_string,'u00bf',''); -- ¿
	_string = string.gsub(_string,'u00bb','»');
	_string = string.gsub(_string,'u00ab','«');
	_string = string.gsub(_string,'u00f8','ø');
	_string = string.gsub(_string,'u2026','…');
	_string = string.gsub(_string,'u00aa','ª');
	_string = string.gsub(_string,"%s+%s+", "")
	return _string
end

-- ####################################################################
-- Base64 encoder/decoder function

-- character table string
local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

-- decode
function dec(data)
	data = string.gsub(data, '[^'..b..'=]', '')
	return (data:gsub('.', function(x)
    	if (x == '=') then return '' end
    	local r,f='',(b:find(x)-1)
    	for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
    	return r;
	end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
    	if (#x ~= 8) then return '' end
    	local c=0
    	for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
    	return string.char(c)
	end))
end

function decodeImage(b64Image)
	local imgTyp = b64Image:match("data:image/(.-);base64,")
	local repData = "data:image/" .. imgTyp .. ";base64,"
	local b64Data = string.gsub(b64Image, repData, "");

	local tmpImg = os.tmpname()
	local retImg = tmpImg .. "." .. imgTyp

	local f = io.open(retImg, "w+")
	f:write(dec(b64Data))
	f:close()
	os.remove(tmpImg)

	return retImg
end
-- ####################################################################

function fill_playlist()
	local data = getdata('https://www.spiegel.de/thema/spiegel-tv/index.rss',nil)
	if data then
		for  item in data:gmatch('<item>(.-)</item>')  do
			local title = item:match("<title>(.-)</title>") -- Sendungstitel
			local url = item:match('<link>(http.-)</link>') -- URL
			local date1 = item:match("<pubDate>.-,(.-)%+.-</pubDate>") -- Sendungsdatum
			local date = "Sendung vom:" ..date1
			local description = item:match("<description>(.-)</description>") -- Sendungsbeschreibung
			if description == nil then
				description = "Spiegel TV stellt für diese Sendung keinen Begleittext bereit."
			end
			if url and title then
				add_stream(conv_str(title), url, date, conv_str(description) )
--				add_stream(conv_str(title), url, url, conv_str(description) )-- only for testing
			end
            end
	end
end

-- epg-Fenster
local epg = ""
local title = ""

function epgInfo (xres, yres, aspectRatio, framerate)
	if #epg < 1 then return end
	local dx = 800;
	local dy = 400;
	local x = 240;
	local y = 0;

	local hw = n:getRenderWidth(FONT['MENU'],title) + 20
	if hw > 400 then
		dy = hw
	end
	if dy >  SCREEN.END_X - SCREEN.OFF_X - 20 then
		dy = SCREEN.END_X - SCREEN.OFF_X - 20
	end
	local wh = cwindow.new{x=x, y=y, dx=dx, dy=dy, title="", icon=spiegel_online, has_shadow="true", show_header="true", show_footer="false"};  -- with out footer
	dy = dy + wh:headerHeight()

	local ct = ctext.new{parent=wh, x=20, y=0, dx=0, dy=dy, text = epg, font_text=FONT['MENU'], mode = "ALIGN_SCROLL | DECODE_HTML"};
 	h = ct:getLines() * n:FontHeight(FONT['MENU'])
	h = (ct:getLines() +4) * n:FontHeight(FONT['MENU'])
	if h > SCREEN.END_Y - SCREEN.OFF_Y -20 then
		h = SCREEN.END_Y - SCREEN.OFF_Y -20
	end
 	wh:setDimensionsAll(x,y,dx,h)
        ct:setDimensionsAll(20,0,dx-40,h)
	wh:setCenterPos{3}
	wh:paint()

	repeat
		msg, data = n:GetInput(500)
		if msg == RC.up or msg == RC.page_up then
			ct:scroll{dir="up"};
		elseif msg == RC.down or msg == RC.page_down then
			ct:scroll{dir="down"};
		end
	until msg == RC.ok or msg == RC.home or msg == RC.info
	wh:hide()
end

function set_pmid(id)
  pmid=tonumber(id);
  return MENU_RETURN["EXIT_ALL"];
end

function select_playitem()
--local m=menu.new{name="SpiegelTV", icon=""} -- only text
  local m=menu.new{name="", icon=spiegel_online} -- only logo,, default

  for i,r in  ipairs(p) do
    m:addItem{type="forwarder", action="set_pmid", id=i, icon="streaming", name=r.title, hint=r.from, hint_icon="hint_reload"}
  end

  repeat
    pmid=0
    m:exec()
    if pmid==0 then
      return
    end

    local vPlay = nil
    local url=func[p[pmid].access](p[pmid].url)
    if url~=nil then
      if  vPlay  ==  nil  then
	vPlay  =  video.new()
      end

	if title == nil then
		title = p[pmid].title
	end
	local js_data = getdata(url,nil)
	local url1 = js_data:match('ediaId&.-&.-;(.-)&')

	if url1 == nil then
		print("Video URL not  found") 
	end

	local js_url = getdata('https://vcdn01.spiegel.de/v2/media/' .. url1,nil)

	local url = js_url:match('180p.-"file":"(https:.-videos.-mp4)"') 

	if url == nil then
		url = js_url:match('720p.-"file":"(https.-videos.-mp4)"') 
	end
	if url == nil then
		url = js_url:match('"file":"(https.-videos.-mp4)"') 
	end


	local description = js_url:match('"description":"(.-)"') 
	if description == nil then
		description = p[pmid].description
	end

	if url then
		epg = p[pmid].title .. "\n\n" .. conv_str(description) .. "\n\n" ..p[pmid].from
		vPlay:setInfoFunc("epgInfo")
--		vPlay:PlayFile("SpiegelTV",url,p[pmid].title,url); -- with url, only for testing
		vPlay:PlayFile("SpiegelTV",url,p[pmid].title);
	else
		print("Video URL not  found")
		local h = hintbox.new{ title="Info", text="Das Video ist nicht mehr verfügbar!", icon="info"};
	end

   end
  until false
end


--Main
init()
func={
  [stream]=function (x) return x end,
}
fill_playlist()
select_playitem()
os.execute("rm /tmp/lua*.png");
