

# XBMC modules
import xbmc
import xbmcaddon
import xbmcgui

# STANDARD library modules
import os
import random
import requests
import subprocess
import sys
import threading
import traceback
import xml.etree.ElementTree as ET

sys.path.append(xbmc.translatePath(os.path.join(xbmcaddon.Addon().getAddonInfo('path'), 'resources','lib')))

# Custom Modules
import osmc_timezones
import LICENSE
import WARRANTY

EULA       = LICENSE.license
WARR       = WARRANTY.warranty
DIALOG     = xbmcgui.Dialog()

__addon__  = xbmcaddon.Addon()
scriptPath = __addon__.getAddonInfo('path')


PANEL_MAP = {
	'language': {
				'order'					:			1,
				'panel_menu_item_id'	:			1002,
				'visibility_controller' :			92000,
				'default_control'		:			20010,
				},
	'timezone': {
				'order'					:			2,
				'panel_menu_item_id'	:			1003,
				'visibility_controller' :			93000,
				'default_control'		:			3001,
				},	
	'hostname': {
				'order'					:			3,
				'panel_menu_item_id'	:			10035,
				'visibility_controller' :			125000,
				'default_control'		:			350010,
				},
	'SSH': 		{
				'order'					:			4,
				'panel_menu_item_id'	:			10037,
				'visibility_controller' :			127000,
				'default_control'		:			370010,
				},		
	'TandC': 	{
				'order'					:			5,
				'panel_menu_item_id'	:			1004,
				'visibility_controller' :			94000,
				'default_control'		:			40010,
				},
	'warranty': {
				'order'					:			6,
				'panel_menu_item_id'	:			1007,
				'visibility_controller' :			97000,
				'default_control'		:			70010,
				},	
	'networking':{
				'order'					:			7,
				'panel_menu_item_id'	:			1006,
				'visibility_controller' :			96000,
				'default_control'		:			60010,
				},
	'skin': 	{
				'order'					:			8,
				'panel_menu_item_id'	:			1008,
				'visibility_controller' :			98000,
				'default_control'		:			80010,
				},		
	'newsletter':{				
				'order'					:			9,
				'panel_menu_item_id'	:			1009,
				'visibility_controller' :			99000,
				'default_control'		:			90010,
				},	
	'exit': 	{
				'order'					:			10,
				'panel_menu_item_id'	:			1005,
				'visibility_controller' :			95000,
				'default_control'		:			1005,
				},	
}


def log(message, level=xbmc.LOGDEBUG):

	try:
		message = str(message)
	except UnicodeEncodeError:
		message = message.encode('utf-8', 'ignore' )

	xbmc.log(str(message), level=level)


def lang(id):
	san = __addon__.getLocalizedString(id).encode( 'utf-8', 'ignore' )
	return san 


class mock_Networking_caller(object):

	def __init__(self, parent, net_call):

		self.ftr_running = False
		self.timeout     = 0
		self.parent = parent
		self.parent.internet_connected = True

	def start(self):

		pass

	def setDaemon(self, bool):

		pass


class Networking_caller(threading.Thread):

	def __init__(self, parent, net_call):

		super(Networking_caller, self).__init__()

		self.daemon      = True
		self.cancelled   = False
		self.parent      = parent
		self.net_call    = net_call
		self.ftr_running = True
		self.timeout     = 0


	def run(self):
		"""Calls Barkers method to check for network connection"""

		log('checking internet connection')

		while self.ftr_running and self.timeout < 12:

			self.ftr_running = self.net_call.is_ftr_running()

			# break early if ftr is not running
			if not self.ftr_running: break

			self.timeout += 1

			xbmc.sleep(10000)

		if not self.ftr_running:

			s
elf.parent.internet_connected = self.net_call.check_network(False)

		else:
			# ftr_running has timed out, consider it ended and leave internet_connected as False
			self.ftr_running = False

		log('network connection is %s' % self.parent.internet_connected)
		lo
g('internet connection is %s' % self.net_call.check_network(True))


def close_walkthru_on_error(func):

    def wrapper(parent, *args, **kwargs):

        try:
            return func(parent, *args, **kwargs)
        except Exception, e:

            log('============= Walkthru Error ====================', xbmc.LOGERROR)
            log(traceback.format_exc(), xbmc.LOGERROR)
            log('=================================', xbmc.LOGERROR)

            parent.close()

    return wrapper




class walkthru_gui(xbmcgui.WindowXMLDialog):

	def __init__(	self, 
					strXMLname, 
					strFallbackPath, 
					strDefaultName, 
					networking_instance, 
					lang_rerun, 
					selected_language,
					testing=False):

		self.testing = testing

		# the order of the panels, this list can be changed depending on the specific need
		self.panel_order 	= sorted(PANEL_MAP.keys(), key=lambda x: PANEL_MAP[x]['order'])

		# the specific controlIDs for the main menu items and others, this is used by onFocus and saves recreating the list every time
		self.menu_controls 	= [v['panel_menu_item_id'] for v in PANEL_MAP.values()]
		self.tz_controls 	= [3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009]
		self.skin_controls 	= [80010, 80020]

		# switch that identifies whether the internet is connected, there is also a flag to determine if the
		# networking panel has already been revealed.
		self.internet_connected = False
		self.networking_panel_revealed = False

		#start a new thread that begins checking for an internet connection
		self.start_checking_for_internet(networking_instance)

		# this flag tells us whether the GUI has been reloaded due to language selection
		self.lang_rerun = lang_rerun

		# get the list of timezones in /etc/timezone
		self.timezones = osmc_timezones.get_timezones()

		# this attribute denotes the skin the user wants to have applied when the walkthru closes
		self.selected_skin = 'OSMC'

		# this is the default hostname for the device
		self.device_name = 'current name: osmc'

		# this holds the users desired SSH state (True for enabled)
		self.ssh_state = True

		# this holds the users ssh password
		self.ssh_pass = 'osmc'

		# newsletter email address
		self.email = ''

		# get the languages
		self.languages = self.get_languages()
		self.languages = list(set(self.languages))
		self.languages.sort()

		self.tz_control_map = {
						'Africa'	: 30010,
						'America'	: 30020,
						'Asia'		: 30030,		
						'Atlantic'	: 30040,
						'Australia'	: 30050,
						'Europe'	: 30060,
						'Indian'	: 30070,
						'Pacific'	: 30080,
						'UTC'		: 30090,
						}

		self.selected_language = selected_language
		self.selected_region   = None
		self.selected_country  = None

		# textures for the skin image
		media_path = xbmc.translatePath(os.path.join(xbmcaddon.Addon().getAddonInfo('path'), 'resources', 'skins', 'Default', 'media'))
		self.osmc_skin_image = os.path.join(media_path, 'osmc_preview.jpg')
		self.conf_skin_image = os.path.join(media_path, 'conf_preview.jpg')

		# if the device is not recognised as a vero, then remove the warranty panel from the walkthrough
		if not self.is_Vero():
			self.panel_order.remove('warranty')

		# this attribute is used to determine when the user is allowed to exit the walkthru using the Esc or Back buttons
		self.prevent_escape = True


	def onInit(self):

		global EULA
		global WARR

		self.hide_controls_on_init()

		self.populate_language_controls()
		self.populate_timezone_controls()

		# populate the terms and conditions and the warranty
		self.getControl(555).setText(EULA)
		self.getControl(777).setText(WARR)		

		# set the image for the skin preview control
		self.set_skin_image('OSMC')

		# set the SSH toggle to ON
		self.getControl(370010).setSelected(True)

		self.remove_coversheet()

		# this will only be True, if the language has been selected and the GUI has reloaded
		if self.lang_rerun:
			# set the flag to False so the GUI doesnt reload on exit
			self.lang_rerun = False
			self.reveal_next_panel('language')


	def start_checking_for_internet(self, networking_instance):
		self.net_call = networking_instance

		self.internet_check = False
		if not self.testing:
			self.internet_checker = Networking_caller(self, self.net_call)
		else:
			self.internet_checker = mock_Networking_caller(self, self.net_call)
		self.internet_checker.setDaemon(True)
		self.internet_checker.start()


	def remove_coversheet(self):
		''' When the window is first loaded, this coversheet (repeated of the background) covers everything.
			This allows the controls in the backg