from __future__ import print_function
from Components.ActionMap import ActionMap, HelpableActionMap
from Components.ConfigList import ConfigListScreen, ConfigList
from Components.Label import Label
from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaBlend
from Components.Pixmap import Pixmap
from Components.Sources.List import List
from Components.config import getConfigListEntry, config, ConfigSubsection, ConfigSelection, ConfigOnOff, ConfigText, NoSave, ConfigNumber, ConfigSubList
from Screens.ChannelSelection import BouquetSelector
from Screens.ChoiceBox import ChoiceBox
from Screens.HelpMenu import HelpableScreen
from Screens.InputBox import InputBox
from Screens.MessageBox import MessageBox
from Screens.Screen import Screen
from ServiceReference import ServiceReference
from Tools.BoundFunction import boundFunction
from Tools.LoadPixmap import LoadPixmap
from enigma import eListboxPythonMultiContent, gFont, loadPNG, eServiceCenter, eServiceReference, RT_HALIGN_RIGHT, RT_HALIGN_CENTER, RT_HALIGN_LEFT, RT_VALIGN_CENTER, eEnv, eConsoleAppContainer, eDVBDB
import os
import xml.etree.cElementTree


class StreamRelayManager(Screen, HelpableScreen):
	skin = """
		<screen name="StreamRelayManager" position="center,100" size="1200,925" title="Stream Relay Manager - No bouquet selected">
			<widget font="Regular;27" render="Label" name="icamtext" zPosition="1" size="80,40" position="20,10" halign="center" valign="center" foregroundColor="#ffff00" />
			<widget font="Regular;27" render="Label" name="channeltext" zPosition="1" size="400,40" position="210,10" halign="left" valign="center" foregroundColor="#ffff00" />
			<widget source="list" render="Listbox" position="10,50" size="1180,800" scrollbarMode="showOnDemand">
				<convert type="TemplatedMultiContent">
					{"template": [
									MultiContentEntryPixmapAlphaBlend(pos=(30,5), size=(40,40), png=0),
									MultiContentEntryText(pos=(200,0), size=(400,50), text=1, 	flags=RT_HALIGN_LEFT|RT_VALIGN_CENTER),														
					],
					"fonts": [gFont("Regular",25)],
					"itemHeight": 50
					}
				</convert>
			</widget>	
		
		    <widget name="ButtonRed" pixmap="skin_default/buttons/red.png" position="20,850" size="225,65" alphatest="on" />
    		<widget name="ButtonGreen" pixmap="skin_default/buttons/green.png" position="265,850" size="225,65" alphatest="on" />
	    	<widget name="ButtonYellow" pixmap="skin_default/buttons/yellow.png" position="510,850" size="225,65" alphatest="on" />
	     	<widget name="ButtonBlue" pixmap="skin_default/buttons/blue.png" position="755,850" size="225,65" alphatest="on" />
	    	<widget name="ButtonRedText" position="20,850" size="225,65" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
	    	<widget name="ButtonGreenText" position="265,850" size="225,65" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
    		<widget name="ButtonYellowText" position="510,850" size="225,65" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
	    	<widget name="ButtonBlueText" position="755,850" size="225,65" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
	    	<widget name="ButtonOk" position="1000,864" size="50,37" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#A9A9A9" foregroundColor="#ffffff" transparent="0" />	
	    	<widget name="ButtonMenu" position="1070,864" size="80,37" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#A9A9A9" foregroundColor="#ffffff" transparent="0" />	
		</screen>
	"""
	
	def __init__(self, session, bouquet=None, **args):
		self.session = session
		Screen.__init__(self, session)
		HelpableScreen.__init__(self)
		
		self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions",
		{
			"ok":		(self.changeSelection, _("Select service")),
			"cancel":	(self.close, _("Close")),
		}, -1)
		
		self["ColorActions"] = HelpableActionMap(self, "ColorActions",
		{
			"red":		(boundFunction(self.changeAllSelection, False), _("Deselect all")),
			"green":	(boundFunction(self.changeAllSelection, True), _("Select all")),
			"yellow":	(self.openBouquetSelector, _("Select bouquet")),
			"blue":		(self.askConversionType, _("Convert service to/from Stream Relay")),
		}, -1)
		
		self["MenuActions"] = HelpableActionMap(self, "MenuActions",
		{
			"menu":		(self.showSettings, _("Show Stream Relay settings")),
		}, -1)		
		
		self["icamtext"] = Label("iCam")
		self["channeltext"] = Label(_("Service"))
		self["ButtonRed"] = Pixmap()
		self["ButtonRedText"] = Label()		
		self["ButtonGreen"] = Pixmap()
		self["ButtonGreenText"] = Label()
		self["ButtonYellow"] = Pixmap()
		self["ButtonYellowText"] = Label(_("Select bouquet"))
		self["ButtonBlue"] = Pixmap()
		self["ButtonBlueText"] = Label()
		self["ButtonOk"] = Label("OK")
		self["ButtonMenu"] = Label("MENU")

		self.selectedServices = []			
		self.list = []
		self["list"] = List(self.list)
		self.setButtonText()
		if bouquet is None:
			self.srservicelist = self.session.infobar.servicelist
		self.serviceCenter = eServiceCenter.getInstance()
		self.srservices = None
		self.selectedBouquet = None
		self.bouquetSelectorScreen = None
		self.setWindowTitle()
		self.channelSelectionMode = False
		if bouquet is not None:
			self.channelSelectionMode = True
			self.bouquetSelectorClosed(bouquet)

	def setWindowTitle(self, bouquet=_("No bouquet selected")):
		self.setTitle(_("Stream Relay Manager - %s") %(bouquet))

	def setButtonText(self):
		if len(self.list):
			self["ButtonRedText"].setText(_("Deselect all"))
			self["ButtonGreenText"].setText(_("Select all"))
			self["ButtonOk"].show()
			self["icamtext"].show()
			self["channeltext"].show()
		else:
			self["ButtonRedText"].setText("")
			self["ButtonGreenText"].setText("")
			self["ButtonOk"].hide()
			self["icamtext"].hide()
			self["channeltext"].hide()
			
		if len(self.selectedServices):
			self["ButtonBlueText"].setText(_("Convert"))
		else:
			self["ButtonBlueText"].setText("")

	def showSettings(self):
		self.session.open(StreamRelayManagerSettings)

	def askConversionType(self):
		self.session.openWithCallback(self.conversionTypeSelected, ChoiceBox, _("Please select type of conversion"), list=[( _("Convert to Stream Relay service"), True), (_("Convert to regular service"), False)])
		
	def conversionTypeSelected(self, answer):
		if answer is not None:
			if self.selectedBouquet is not None:
				mutableList = self.getMutableList(self.selectedBouquet)
				if mutableList is not None:
					# idx is required because addService with before does not work if only flags are different...
					for service, idx in self.selectedServices:
						new_service = service
						if answer[1] and new_service.flags != 512:
							new_service.flags = 512
						elif not answer[1] and new_service.flags != 0:
							new_service.flags = 0
						else:
							continue
							
						# delete the service from list because it's not possible to have the same service with different flags in the same list
						mutableList.removeService(service)
						# add the service with correctly set flags to the list
						result = mutableList.addService(new_service)
						# move the service back to the original position
						mutableList.moveService(new_service, idx)
						if not result:
							mutableList.flushChanges()
					eDVBDB.getInstance().reloadBouquets()
					self.selectedServices = []
					self.srservices = self.getBouquetServices(self.selectedBouquet)

	def getMutableList(self, bouquetref):
		return self.serviceCenter.list(bouquetref).startEdit()

	def changeSelection(self):
		cur = self["list"].getCurrent()
	
		if cur:
			tempservice = [x[0] for x in self.selectedServices]
			if cur[0] in tempservice:
				self.selectedServices = [x for x in self.selectedServices if x[0] != cur[0]]
				#self.selectedServices.remove(cur[0])
			else:
				self.selectedServices.append((cur[0], cur[3]))
		
		self.setButtonText()
		self["list"].updateList(self.list)

	def changeAllSelection(self, select):
		if select:
			self.selectedServices = [ (x[0], x[3]) for x in self.list]
		else:
			self.selectedServices = []
		
		self.setButtonText()
		self["list"].updateList(self.list)

	def openBouquetSelector(self):
		self.srbouquets = self.srservicelist.getBouquetList()
		if self.srbouquets is not None:
			self.bouquetSelectorScreen = self.session.openWithCallback(self.closeBouquetSelectorScreen, BouquetSelector, self.srbouquets, self.bouquetSelectorClosed, True)
			
	def closeBouquetSelectorScreen(self, recursive=False):
		self.bouquetSelectorScreen = None
		
	def bouquetSelectorClosed(self, bouquet):
		if bouquet:
			self.selectedBouquet = bouquet
			info = self.serviceCenter.info(bouquet)
			if info:
					bouquetname = info.getName(bouquet).replace('\xc2\x86', '').replace('\xc2\x87', '')
					self.setWindowTitle(bouquetname)
			if self.bouquetSelectorScreen is not None:
				self.bouquetSelectorScreen.close(True)
				self.selectedServices = []
				self.srservices = self.getBouquetServices(bouquet)
			elif self.channelSelectionMode:
				self.selectedServices = []
				self.srservices = self.getBouquetServices(bouquet)				
			else:
				self.close()

	def getBouquetServices(self, bouquet):
		self.list = []
		servicelist = self.serviceCenter.list(bouquet)
		if servicelist is not None:
			idx = 0
			while True:
				service = servicelist.getNext()
				if not service.valid():
					break
				if service.flags & (eServiceReference.isDirectory | eServiceReference.isMarker):
					continue
				isStreamRelay = self.session.nav.streamrelay.isStreamRelay(service)
				
				info = self.serviceCenter.info(service)
				servicename = "n/a"
				if info:
					servicename = info.getName(service).replace('\xc2\x86', '').replace('\xc2\x87', '')
				self.list.append((service, servicename, isStreamRelay, idx))
				idx += 1
		
		self.setButtonText()
		self["list"].setBuildFunc(self.buildServiceEntry)
		self["list"].setList(self.list)
		
	def buildServiceEntry(self, service, servicename, isStreamRelay, idx):
		state = "on" if isStreamRelay else "off"
		selected = ""
		if service in [x[0] for x in self.selectedServices]:
			selected = "_selected"
		checkbox = LoadPixmap(cached=False, path="/usr/share/enigma2/Merlin/checkbox_round_%s%s.svg" %(state, selected))
				
		return [checkbox, servicename]
		
class StreamRelayManagerSettings(Screen, HelpableScreen, ConfigListScreen):
	skin = """
		<screen name="StreamRelayManagerSettings" size="1000,900" position="center,100" title="Stream Relay Manager Settings" >
			<widget name="config" position="10,10" size="980,800" scrollbarMode="showOnDemand" />
			<widget name="ButtonRed" pixmap="skin_default/buttons/red.png" position="20,815" size="225,65" alphatest="on" />
    		<widget name="ButtonGreen" pixmap="skin_default/buttons/green.png" position="265,815" size="225,65" alphatest="on" />
	    	<widget name="ButtonRedText" position="20,815" size="225,65" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
	    	<widget name="ButtonGreenText" position="265,815" size="225,65" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
		</screen>
		"""	
	def __init__(self, session):
		Screen.__init__(self, session)
		HelpableScreen.__init__(self)
		self.session = session

		self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions",
		{
			"ok":			(self.save, _("Save")),
			"cancel":		(self.cancel, _("Cancel")),
		}, -1)
		
		self["ColorActions"] = HelpableActionMap(self, "ColorActions",
		{
			"green":		(self.save, _("Save")),
			"red": 			(self.cancel, _("Cancel")),
		}, -1)

		self["ButtonRed"] = Pixmap()
		self["ButtonRedText"] = Label(_("Cancel"))		
		self["ButtonGreen"] = Pixmap()
		self["ButtonGreenText"] = Label(_("Save"))
	
		self.list = []
		self.list.append(getConfigListEntry(_("Stream Relay Server"),))
		self.list.append(getConfigListEntry(_("Stream Relay IP"), config.merlin2.streamrelayip))
		self.list.append(getConfigListEntry(_("Stream Relay Port"), config.merlin2.streamrelayport))
		
		ConfigListScreen.__init__(self, self.list, session = session)
		
	def save(self):
		ConfigListScreen.saveAll(self)
		self.session.nav.streamrelay.updateServerSettings()
		self.close(True)
		
	def cancel(self):
		ConfigListScreen.keyCancel(self)