import xbmc, xbmcgui, xbmcplugin, xbmcaddon, xbmcvfs
import sys, random
import urllib, urllib2, cookielib
import re, base64
from array import *
from htmlentitydefs import name2codepoint as n2cp

# new since v0.95
import urlresolver

thisPlugin = int(sys.argv[1])
print thisPlugin

edenCompatibility = xbmcplugin.getSetting("caching")
if edenCompatibility=="true":
	useCaching=True
else:
	useCaching=False
	print "-- switched off caching for eden-compatibility"

addonInfo = xbmcaddon.Addon(id='plugin.video.burningseries')
cacheFile = addonInfo.getAddonInfo('path')+"/cache.data"

urlHost = "http://www.burning-seri.es/"

# by Alphabet
regexContentA = "<ul id='serSeries'>(.*?)</ul>"
regexContentB = '<li><a href="(.*?)">(.*?)</a></li>'
regexContentC = '<div class="genre">.*?<span><strong>(.*?)</strong></span>.*?<ul>(.*?)</ul>.*?</div>'

regexSeasonsA = '<ul class="pages">.*?</ul>'
regexSeasonsB = '<li.*?><a href="(.*?)">([^<]+)</a></li>'
regexSeasonsPic = 'id="sp_right">.*?<img src="(.*?)" alt="[cC]+over"/>'

regexEpisodesA = '<table>.*?</table>'
# till v1.1.6 -> regexEpisodesB = '(<td>([^<]+)</td>.*?<td><a href="([^"]+)">.*?(<strong>[^<]+</strong>)?\s+(<span lang="en">[^<]+</span>)?.*?<td class="nowrap">.*?<a class.*?</td>.*?</tr>)'
regexEpisodesB = '(<td>([^<]+)</td>[\\n\s]+<td><a href="([^"]+)">[\\n\s]+(<strong>[^<]+</strong>)?[\\n\s]+(<span lang="en">[^<]+</span>)?[\\n\s]+</a></td>[\\n\s]+<td class="nowrap">[\\n\s]+<a class.*?</td>.*?</tr>)'
regexEpisodesC = '<strong>(.*?)</strong>'
regexEpisodesD = '<span lang="en">(.*?)</span>'

regexHostsA = 'Episode</h3>.*?<ul style="width: [0-9]{1,3}px;">(.*?)</ul>.*?</section>'
regexHostsB = '<a.*?href="(.*?)"><span.*?class="icon (.*?)"></span>(.*?)</a>'
# ------------------------

def showContent(sortType):
	
	global thisPlugin
	print "[bs] -- showContent started"
	seriesList = {}
	serie =[]
	picture = ""

	content = getUrl(urlHost+"serie-genre").replace("&amp;","&")
	#print content
	matchC = re.compile(regexContentC,re.DOTALL).findall(content)
	for n in matchC:
		#print n
		matchB = re.compile(regexContentB,re.DOTALL).findall(n[1])
		for m in matchB:
			if sortType[0] == "G":
				serie = [n[0]+" : "+m[1].strip(),m[0],picture]
				lKey = n[0]
			if sortType[0] == "A":
				serie = [m[1].strip()+" ("+n[0]+")",m[0],picture]
				helper = ord(m[1][0])
				if helper>90:
					helper = helper-32
				if (helper>64) and (helper<91):
					lKey = chr(helper).upper()
				else:
					lKey = "0"
			if lKey in seriesList:
				seriesList[lKey].append(serie)
			else:
				seriesList[lKey] = []
				seriesList[lKey].append(serie)
				
	if len(sortType)==1:
		addDirectoryItem("- sort by Alphabet", {"sortType": "A"})
		addDirectoryItem("- sort by Genre", {"sortType": "G"})
		addDirectoryItem("", {"sortType": "A"})
		for key in sorted(seriesList):
			skey = key
			if key =="0":
				skey = "0-9 etc"
			addDirectoryItem(skey+" (%d)" % len(seriesList[key]), {"sortType": sortType+key})
	else:
		sKey = sortType[1:]
		for s in sorted(seriesList[sKey], key=lambda f:f[0]):
			if useCaching:
				cachedPic = readPictureData(s[1])
				if cachedPic:
					picture = cachedPic
					print "[bs] -- cached pic existing - "+picture
				else:
					print "[bs] -- pic not in cache"
					cPic = getUrl(urlHost+s[1]).replace("&amp;","&")
					matchPic = re.compile(regexSeasonsPic,re.DOTALL).findall(cPic)
					picture = urlHost+matchPic[0]
					cachedPic = writePictureData(urllib.unquote(s[1]), picture)
			addDirectoryItem(s[0], {"urlS": s[1], "series":s[1]},picture)
	print "[bs] --- showContent ok"	
	xbmcplugin.endOfDirectory(thisPlugin)

def showSeasons(urlS,series):
	global thisPlugin
	matchCover = ""
	print "[bs] --- showSeasons started with "+urlS
	print "[bs] --- series Data"
	print series
	content = getUrl(urlS)
	matchA = re.compile(regexSeasonsA,re.DOTALL).findall(content)
	if matchA:
		matchB = re.compile(regexSeasonsB,re.DOTALL).findall(matchA[0])
		print "-- matchB"
		#print matchB
		
		for m in matchB:
			if useCaching:
				matchCover = readPictureData(series)
				print "[bs] -- showSeasons cached Picture - "+matchCover
			preString = ""
			if is_number(m[1]):
				preString = "Staffel "
			addDirectoryItem(preString+m[1], {"urlE": m[0], "series":series}, matchCover)
	else:
		addDirectoryItem("ERROR in Seasons matchA", {"urlS": urlS})
	print "[bs] --- showSeasons ok"	
	xbmcplugin.endOfDirectory(thisPlugin)

def showEpisodes(urlE,series):
	global thisPlugin
	matchCover = ""
	print "[bs] ---- showEpisodes started with "+urlE
	content = getUrl(urlE)
	print "--- series Data"
	print series
	matchA = re.compile(regexEpisodesA,re.DOTALL).findall(content)
	if useCaching:
		print "[bs] -- showEpisodes -- reading cached picture - "+series
		matchCover = readPictureData(series)
		print "[bs] -- showSeasons cached Picture - "+matchCover
	print "[bs] ---matchA"
	print matchA
	if matchA:
		print "found matchA - now regexing"
		matchB = re.compile(regexEpisodesB,re.DOTALL).findall(matchA[0])
		print "matchB regexed"
		if matchB:
			print "[bs] ---matchB"
			print matchB
			for m in matchB:
				print m
				matchD = re.compile(regexEpisodesD,re.DOTALL).findall(m[0])
				print matchD
				if matchD:
					englishTitle = " - "+matchD[0]
				else:
					englishTitle = ""
				mS = re.compile(regexEpisodesC,re.DOTALL).findall(m[0])
				print mS
				if mS:
					print mS
					matchStrong = " - "+mS[0]
				else:
					matchStrong = ""
				addDirectoryItem(m[1].strip()+matchStrong+englishTitle, {"urlH": m[2], "series":series},matchCover)
		else:
			addDirectoryItem("ERROR in Episodes B regex - matchB", {"urlH": ""})
	else:
		addDirectoryItem("ERROR in Episodes A regex - matchA", {"urlH": ""})
	print "[bs] ---- showEpisodes ok"	
	xbmcplugin.endOfDirectory(thisPlugin)

def showHosts(urlH, series):
	global thisPlugin
	matchCover = ""
	print "[bs] ----- showHosts started with "+urlH
	if useCaching:
		matchCover = readPictureData(series)
		print "[bs] -- showSeasons cached Picture - "+matchCover
	content = getUrl(urlH)
	#print "-- showHosts"
	#print content
	matchA = re.compile(regexHostsA,re.DOTALL).findall(content)
	print "[bs] -- matchesA"
	print matchA
	matchB = re.compile(regexHostsB,re.DOTALL).findall(matchA[0])
	print "[bs] -- matchB"
	print matchB
	addDirectoryItem("INFO - urlResolver is now active!", {"urlV": "/"})
	for m in matchB:
			#print m
			addDirectoryItem("Play from "+m[2].strip(), {"urlV": m[0]},matchCover)
			print "[bs] -- "+m[1]+" : "+m[0]  
	print "[bs] ----- showHosts ok"	
	xbmcplugin.endOfDirectory(thisPlugin)
	
def showVideo(urlV):

	global thisPlugin
	print "[bs] --->> showVideo started on "+urlV
	content = getUrl(urlV)
	#print content
	matchVideo = re.compile('<div id="video_actions">.*?<div>.*?<a href="(.*?)" target="_blank"><span',re.DOTALL).findall(content)
	print "[bs] --> matchVideo - "+matchVideo[0]
	# --- sockShare ---
	#if urlV.find("Sockshare")>0 :
	#	matchA = re.compile('<a href="http://www.sockshare.com/file/(.*?)" target="_blank"><span',re.DOTALL).findall(content)
	#	print "-- matchA"
	#	print matchA
	#	newUrl ="http://www.sockshare.com/embed/"+matchA[0]
	#	content = getUrl(newUrl)
	#	print "-- content"
	#	print content
	#	matchB = re.compile('value="(.*?)" name="(.*?)"').findall(content)
	#	print "-- input hidden"
	#	print matchB
	#	
	#	matchB = re.compile("playlist: '/get_file.php?(.*?)',").findall(content)
	#	print "-> newUrl"
	#	newUrl = 'http://www.sockshare.com/get_file.php?'+matchB[0]
	#	print newUrl
	#	contentVideo2 =  getUrl(newUrl)
	#	print "-- contentVideo2"
	#	print contentVideo2
	#	
	#	videoLink=findVideoUrl[0].replace("','","");
	#	print "VideoLink :"+videoLink
	#	#print findKeys
	#	#videoLink = findKeys[0]
	#
	## --- RapidVideo ---
	#if urlV.find("RapidVideo")>0 :
	#	#matchB = re.compile('video_actions">.*?<a href="(.*?)" target="_blank"><span',re.DOTALL).findall(content)
	#	print "-> matchB"
	#	print matchB
	#	contentXML =  getUrl(matchB[0])
	#	print "-- ContentXML"
	#	print contentXML
	#	findKeys = re.compile('flashvars=\'file=(.*?)&amp;').findall(contentXML)
	#	print "-- findKeys"
	#	print findKeys
	#	videoLink = findKeys[0]
	#	
	## --- VideoBB ---
	#if urlV.find("VideoBB")>0 :
	#	matchB = re.compile('video_actions">.*?<a href="(.*?)" target="_blank"><span',re.DOTALL).findall(content)
	#	print "-> matchB"
	#	print matchB
	#	varsUrl =  getUrl(matchB[0])
	#	getJSONUrl = re.compile('value="setting=(.*?)" name').findall(varsUrl)
	#	print "-> JSONUrl encoded"
	#	print getJSONUrl[0]
	#	JSONurl = base64.b64decode(getJSONUrl[0])
	#	print "-> JSONUrl decoded"
	#	print JSONurl
	#	videoUrl = getUrl(JSONurl)
	#	#print videoUrl
	#	isVideoUrl = re.compile('"token1":"(.*?)"').findall(videoUrl)
	#	print "-> VideoUrl encoded"
	#	print isVideoUrl[0]
	#	videoLink = base64.b64decode(isVideoUrl[0])
 	#	print "-> VideoUrl decoded"
	#	
	#	# --- Putlocker ---
	#if urlV.find("PutLocker")>0 :
	#	matchB = re.compile('video_actions">.*?<a href="(.*?)" target="_blank"><span',re.DOTALL).findall(content)
	#	print "-> matchB"
	#	print matchB
	#	varsUrl =  getUrl(matchB[0])
	#	gethashValue = re.compile('type="hidden" value="(.*?)" name="hash"').findall(varsUrl)
	#	values = {'hash': gethashValue[0], 'confirm':'Continue as Free User'}
	#	print values
	#	user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
	#	headers = { 'User-Agent' : user_agent }
	#	cjar = cookielib.LWPCookieJar()
	#	cjar = urllib2.HTTPCookieProcessor(cjar) 
	#	opener = urllib2.build_opener(cjar)
	#	urllib2.install_opener(opener)
	#	data = urllib.urlencode(values)
	#	req = urllib2.Request(matchB[0], data, headers)
	#	response = urllib2.urlopen(req)
	#	link = response.read()
	#	code = re.compile("stream=(.+?)'").findall(link)
	#	req = urllib2.Request('http://www.putlocker.com/get_file.php?stream='+code[0])
	#	req.add_header('User-Agent', user_agent)
	#	response = urllib2.urlopen(req)
	#	link=response.read()
	#	videoLink = re.compile('<media:content url="(.+?)"').findall(link)[0]
	#
	videoLink = urlresolver.resolve(matchVideo[0]);
	print "[bs] --> urlResolver returns - "
	print videoLink
	if videoLink:
		print "[bs] --> urlResolver videoLink --"
		print videoLink
		videoLink = decode_htmlentities(videoLink)
		xbmc.Player().play(videoLink)
	else:
		addDirectoryItem("ERROR!", {"urlV": "/"})
		addDirectoryItem("Video deleted or urlResolver cant handle Host", {"urlV": "/"})
		addDirectoryItem("SORRY!", {"urlV": "/"})
		xbmcplugin.endOfDirectory(thisPlugin)

# -------- helper ------

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

def baseN(num,b,numerals="0123456789abcdefghijklmnopqrstuvwxyz"):
	return ((num == 0) and numerals[0]) or (baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b])

def getUrl(url):
	try:
		req = urllib2.Request(url)
		req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
		response = urllib2.urlopen(req)
		return response.read()
		response.close()
	except:
		return False

def addDirectoryItem(name, parameters={},pic=""):
	iconpic = pic
	if pic == "":
		iconpic = "DefaultFolder.png"
	li = xbmcgui.ListItem(name,iconImage=iconpic, thumbnailImage=pic)
	url = sys.argv[0] + '?' + urllib.urlencode(parameters)
	return xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=url, listitem=li, isFolder=True)

def parameters_string_to_dict(parameters):
    ''' Convert parameters encoded in a URL to a dict. '''
    paramDict = {}
    if parameters:
        paramPairs = parameters[1:].split("&")
        for paramsPair in paramPairs:
            paramSplits = paramsPair.split('=')
            if (len(paramSplits)) == 2:
                paramDict[paramSplits[0]] = paramSplits[1]
    return paramDict

def substitute_entity(match):
    ent = match.group(3)
    
    if match.group(1) == "#":
        if match.group(2) == '':
            return unichr(int(ent))
        elif match.group(2) == 'x':
            return unichr(int('0x'+ent, 16))
    else:
        cp = n2cp.get(ent)

        if cp:
            return unichr(cp)
        else:
            return match.group()

def decode_htmlentities(string):
	entity_re = re.compile(r'&(#?)(x?)(\w+);')
	return entity_re.subn(substitute_entity, string)[0]

# since v1.1.0
def writePictureData(id,url):
	global cacheFile
	f = xbmcvfs.File(cacheFile)
	d = f.read()
	f.close()
	f = xbmcvfs.File(cacheFile, 'w')
	b = d+id+"<>"+url+"\n"
	result = f.write(b)
	print "[bs] -- write  "+cacheFile+" -> "+ id + " <> " +url
	f.close()
	return result

def readPictureData(id):
	global cacheFile
	f = xbmcvfs.file(cacheFile)
	b = f.read()
	f.close()
	cacheData = b.splitlines()
	for n in cacheData:
		splittedData = n.split("<>")
		if splittedData[0]==id:
			print "[bs] -- found "+id+" in cache.data"
			return splittedData[1]
	return False

# ----- main -----
params = parameters_string_to_dict(sys.argv[2])
sortType = str(params.get("sortType", ""))
urlSeasons = str(params.get("urlS", ""))
urlEpisodes = str(params.get("urlE", ""))
urlHosts = str(params.get("urlH", ""))
urlVideo = str(params.get("urlV", ""))
dataSeries = urllib.unquote(str(params.get("series", "")))

if not sys.argv[2]:
	# new start
	ok = showContent("A")
else:
	if sortType:
		ok = showContent(sortType)
	
	if urlSeasons:
		newUrl = urlHost + urllib.unquote(urlSeasons)
		#print newUrl
		ok = showSeasons(newUrl,dataSeries)
	if urlEpisodes:
		newUrl = urlHost + urllib.unquote(urlEpisodes)
		#print newUrl
		ok = showEpisodes(newUrl,dataSeries)
	if urlHosts:
		newUrl = urlHost + urllib.unquote(urlHosts)
		#print newUrl
		ok = showHosts(newUrl,dataSeries)
	if urlVideo:
		newUrl = urlHost + urllib.unquote(urlVideo)
		#print newUrl
		ok = showVideo(newUrl)