function SceneLiveTv(options) {
	this.options = options;
}

SceneLiveTv.prototype.initialize = function () {
	Logger.write("SceneLiveTv.initialize()", "LiveTv");
	// this function will be called only once when the scene manager show this scene first time
	// initialize the scene controls and styles, and initialize your variables here 
	// scene HTML and CSS will be loaded before this function is called
	
	ErrorHandler.NeedToRefresh["LiveTv"] = true;
	SceneLiveTv.dataLoaded = false;
	SceneLiveTv.initData();
	$("#scrollLiveTv").css({
		'visibility': 'hidden'
	});
	$('#btnChannel1').sfButton({
		text: '',
		width: '100px'
	});
	$('#btnChannel2').sfButton({
		text: '',
		width: '100px'
	});
	$('#btnChannel3').sfButton({
		text: '',
		width: '100px'
	});
	$('#btnChannel6').sfButton({
		text: '',
		width: '100px'
	});
	$('#btnChannel4').sfButton({
		text: '',
		width: '100px'
	});
	$('#btnChannel5').sfButton({
		text: '',
		width: '100px'
	});
	$('#btnChannel7').sfButton({
		text: '',
		width: '100px'
	});
	$('#lblProgramDescription').sfLabel({
		text: ''
	});
	$('#lblProgramName').sfLabel({
		text: ''
	});
	$('#lblProgramGenreTime').sfLabel({
		text: ''
	});
	SceneLiveTv.setHelpBar();
	$('#lblTvGuide').sfLabel({
		text: Resources.getResources().LabelTvGuide,
		width: '130px'
	});
	$('#epgLiveTv').css('visibility', 'hidden');
	ScenePlayer.channelPicker = null;
	SceneLiveTv.channelPicker = null;
	this.elemToFocus = null;
}

SceneLiveTv.getTimeByUserTimeZone = function (callback) {
	var getTimeCallback = function (result) {
		Logger.write("=====Current time getted: " + result, "LiveTv", true);
		var tmpDate = result;
		Logger.write("tmpDate: " + tmpDate, "LiveTv", true);
		var shift = AppContext.getTimeZoneUtcOffset();
		Logger.write("Shift: " + shift, "LiveTv", true);
		tmpDate.setMinutes(tmpDate.getMinutes() + shift);
		SceneLiveTv.startTime = new Date(tmpDate);
		SceneLiveTv.startTime.setHours(SceneLiveTv.startTime.getHours(), SceneLiveTv.startTime.getMinutes() >= 30 ? 30 : 0, 0, 0);
		SceneLiveTv.currentTime = new Date(SceneLiveTv.startTime);
		
		var now = new Date();
		SceneLiveTv.timeDiff = tmpDate - now;
		if (callback) {
			callback();
		}
	};

	var errCallback = function (jqXHR, textStatus, error) {
		ErrorHandler.HandleError(error, "LiveTv", true, textStatus, jqXHR);
	};
	
	JsonServices.media.GetCurrentUtcTime(getTimeCallback, errCallback);
}

SceneLiveTv.setHelpBar = function () {
	if (ScenePlayer.isPlaying) {
		$('#keysLiveTv').sfKeyHelp({
			'red': Resources.getResources().LabelSettings,
			'green': Resources.getResources().Search,
			'blue': Resources.getResources().Player,
			'stop': Resources.getResources().Stop,
			'updown': '',
			'leftright': Resources.getResources().MoveCursor,
			'enter': Resources.getResources().ViewChannel,
			'return': Resources.getResources().BackToMainMenu
		});
	} else {
		$('#keysLiveTv').sfKeyHelp({
			'red': Resources.getResources().LabelSettings,
			'green': Resources.getResources().Search,
			'updown': '',
			'leftright': Resources.getResources().MoveCursor,
			'enter': Resources.getResources().ViewChannel,
			'return': Resources.getResources().BackToMainMenu
		});
	}
}

/*
    Initialize default variables
*/
SceneLiveTv.initData = function () {
	//this.firstChannel = 1;
	this.maxChannels = 7;
	this.channels = [];
	this.initTime = new Date();
	this.channelsPager = null;

	this.timeInterval = 2 * 60 * 60 * 1000; //in ms
	this.checkInterval = 3; //in hours
	this.epgTimeInterval = 48 * 60 * 60 * 1000;

	this.minimumTime = new Date(this.startTime);
	this.maximumTime = new Date(this.minimumTime);
	this.maximumTime.setDate(this.maximumTime.getDate() + 2);

	this.currentFocus = '#btnChannel1';

	this.channelButtons = [];
	this.programButtons = [];

	this.timeDiff = 0; //difference between tv time and real time in ms
	this.offset = AppContext.getNaEstUtcOffset();
}

/*
    Refreshes data on scene
*/
SceneLiveTv.refresh = function () {
	setInterval("SceneLiveTv.clock()", 3000);
	$("#SceneLiveTv .sceneContainer").css("opacity", "0");
	SceneLiveTv.focusChannels();
	this.blur(this.currentFocus);
	SceneLiveTv.initData();
	$('#btnChannel1').sfButton({
		text: '',
		width: '148px'
	});
	$('#btnChannel2').sfButton({
		text: '',
		width: '148px'
	});
	$('#btnChannel3').sfButton({
		text: '',
		width: '148px'
	});
	$('#btnChannel6').sfButton({
		text: '',
		width: '148px'
	});
	$('#btnChannel4').sfButton({
		text: '',
		width: '148px'
	});
	$('#btnChannel5').sfButton({
		text: '',
		width: '148px'
	});
	$('#btnChannel7').sfButton({
		text: '',
		width: '148px'
	});
	$('#lblProgramDescription').sfLabel({
		text: '',
		width: '710px'
	});
	SceneLiveTv.setHelpBar();
	$('#lblTvGuide').sfLabel({
		text: Resources.getResources().LabelTvGuide,
		width: '130px'
	});
	
	SceneLiveTv.getTimeByUserTimeZone(function () {
		SceneLiveTv.loadChannelsPage(SceneLiveTv.maxChannels, 1);
	});
	ErrorHandler.NeedToRefresh["LiveTv"] = false;
}

SceneLiveTv.clock = function () {
	var time = new Date();
	if ((time - this.initTime) > 1800000) {
		SceneLiveTv.refresh();
	}

	var realTime = new Date(time);
	realTime.setMilliseconds(realTime.getMilliseconds() + SceneLiveTv.timeDiff);
	realTime = Helpers.getUtcTime(realTime);
	$("#clock").empty();
	$("#clock").append(realTime.toLocaleFormat("%H:%M"));

	var curDate = DateHelper.getShortDay(realTime) + ", " + DateHelper.getShortMonth(realTime) + " " + realTime.getDate();

	$('#currentDate').empty();
	$('#currentDate').append(curDate);
}

/*
    Loads times
*/
SceneLiveTv.loadTimes = function () {
	var time = new Date(this.currentTime);
	time.setHours(time.getUTCHours());
	time.setMinutes(time.getUTCMinutes());
	time.setHours(time.getHours(), time.getMinutes() - 30, time.getSeconds(), time.getMilliseconds());
	Logger.write("======Times load begins!..." + time, "LiveTv");
	for (var i = 1; i < 6; i++) {
		time.setHours(time.getHours(), time.getMinutes() + 30, time.getSeconds(), time.getMilliseconds());
		var text = time.toLocaleFormat("%H:%M");
		$('#lblTime' + i.toString()).sfLabel({
			text: text
		});
	}
}

/*
 * Focuses channel button by number
 */
SceneLiveTv.focusChannelCallback = function (number) {
	Logger.write("Focus channel callback", "LiveTv");
	SceneLiveTv.programsFocused = false;
	
	var onPage = SceneLiveTv.channelsPager.paging.itemsOnPage;
	var pageNumber = SceneLiveTv.channelsPager.paging.pageNumber;
	var page = Math.ceil(number / onPage);
	Logger.write("Page: " + page + ", pageNumber: " + pageNumber, "LiveTv", true);
	if (page == pageNumber) {
		var channelNumber = number - (onPage * (pageNumber - 1));
		SceneLiveTv.channelsPager.paging.index = channelNumber - 1;
		SceneLiveTv.focusElement("#btnChannel" + channelNumber);
	} else {
		var idx = number - (page - 1) * onPage - 1;
		Logger.write("Page: " + page + "; index: " + idx, "LiveTv", true);
		SceneLiveTv.channelsPager.setPageNumber(page, idx);
	}
}

/*
 * Shows loading image
 */
SceneLiveTv.showLoading = function () {
	SceneLiveTv.dataLoaded = false;
	SceneLiveTv.isLoading = true;
	$('#imgFocus').css('visibility', 'hidden');
	$('#imgFocus').prependTo($('#epgLiveTv'));
	if (AppContext.CurrentScene == "LiveTv") {
		Helpers.showLoading();
	}
}

SceneLiveTv.hideLoading = function () {
	SceneLiveTv.isLoading = false;
	if (AppContext.CurrentScene == "LiveTv") {
		Helpers.hideLoading();
	}
}

SceneLiveTv.onPagerPageChanging = function (onPage, newPageNumber, pageChangedCallback) {
	Logger.write("Page changing, new page: " + newPageNumber, "LiveTv", true);
	var start = (newPageNumber - 1) * onPage;
	var channelsLoaded = true;
	for (var i = start; i < (start + onPage); i++) {
		if (!SceneLiveTv.channels[i]) {
			channelsLoaded = false;
			break;
		}
	}
	
	Logger.write("Channels loaded: " + channelsLoaded, "LiveTv", true);
	if (channelsLoaded) {
		pageChangedCallback(true);
		if (!SceneLiveTv.programsFocused) {
			SceneLiveTv.elemToFocus = "#btnChannel" + (SceneLiveTv.channelsPager.paging.index + 1);
		}
		SceneLiveTv.bindChannels();
	} else {
		SceneLiveTv.loadChannelsPage(onPage, newPageNumber, pageChangedCallback);
	}
	
	
}

SceneLiveTv.onPagerOutOfBounds = function (num) {
	
}

SceneLiveTv.onChannelsPageLoaded = function (channels, paging) {
	if (!SceneLiveTv.channelsPager) {
		SceneLiveTv.channelsPager = new Pager(paging, SceneLiveTv.onPagerPageChanging, SceneLiveTv.onPagerOutOfBounds, true);
		Logger.write("Scroll pages count: " + Math.ceil(paging.totalItems / paging.itemsOnPage), "LiveTv", true);
		$("#scrollLiveTv").sfScroll({
			page: Math.ceil(paging.totalItems / paging.itemsOnPage)
		});
	}
	
	if (!SceneLiveTv.channels || SceneLiveTv.channels.length == 0) {
		SceneLiveTv.channels = [];
		SceneLiveTv.channelPicker = new ChannelPicker(paging.totalItems, SceneLiveTv.focusChannelCallback);
		ScenePlayer.channelPicker = new ChannelPicker(paging.totalItems, SceneLiveTv.getStreamByNumberCallback);
	}
	
	var startIndex = paging.itemsOnPage * (paging.pageNumber - 1);
	Logger.write("On channels page loaded, startIndex: " + startIndex, "LiveTv", true);
	for (var i = startIndex; i < startIndex + SceneLiveTv.maxChannels; i++) {
		SceneLiveTv.channels[i] = channels.shift();
	}
	
}

SceneLiveTv.loadChannelsPage = function (onPage, pageNumber, pageChangedCallback, loadOnly) {
	SceneLiveTv.showLoading();
	var loadedCallback = function (result) {
		if (result.items.length > 0) {
			$("#liveTvNoData").hide();
			SceneLiveTv.onChannelsPageLoaded(result.items, result.paging);
			if (pageChangedCallback) {
				pageChangedCallback(true);
			}
			Logger.write("Loaded, Index: " + SceneLiveTv.channelsPager.paging.index, "LiveTv", true);
			if (!loadOnly) {
				if (!SceneLiveTv.programsFocused) {
					SceneLiveTv.elemToFocus = "#btnChannel" + (SceneLiveTv.channelsPager.paging.index + 1);
				}
				SceneLiveTv.bindChannels();
			} else {
				SceneLiveTv.hideLoading();
			}
		} else if (SceneLiveTv.channels.length == 0) {
			$("#liveTvNoData").show();
			SceneLiveTv.hideLoading();
		}
	};
	
	var errorCallback = function (jqXHR, textStatus, error) {
		ErrorHandler.HandleError(error, "LiveTv", true, textStatus, jqXHR);
	};
	
	JsonServices.content.GetClientChannels(AppContext.user.sid, "LiveTV", onPage, pageNumber, loadedCallback, errorCallback);
}

SceneLiveTv.bindChannels = function () {
	SceneLiveTv.showLoading();
	var firstChannel = SceneLiveTv.channelsPager.paging.itemsOnPage * (SceneLiveTv.channelsPager.paging.pageNumber - 1);
	var moveTo = Math.ceil(firstChannel / SceneLiveTv.channelsPager.paging.itemsOnPage);
	Logger.write("Move to: " + moveTo, "LiveTv", true);
	$("#scrollLiveTv").sfScroll('move', moveTo);
	SceneLiveTv.programButtons = [];
	var buttons = [];
	var maxChannels = SceneLiveTv.channelsPager.paging.getUpperBound();
	
	for (var i = firstChannel; i < firstChannel + maxChannels; i++) {
		SceneLiveTv.loadPrograms(i, maxChannels, firstChannel);
		
		var num = i - firstChannel + 1;
		var channelName = "#btnChannel" + num.toString();
		$(channelName).sfButton("blur");
		$(channelName).sfButton({
			text: [SceneLiveTv.channels[i].name]
		});
		
		$(channelName).attr('channelId', SceneLiveTv.channels[i].id);
		var src = AppContext.ImageUrlTemplate.replace("{0}", SceneLiveTv.channels[i].id).replace("{1}", 4).replace("{2}", 1) + "&width=32";
		$("#imgLiveTvLogo" + num.toString() + " img").sfImage({
			src: src
		});
		buttons.push(channelName);
	}
	SceneLiveTv.channelButtons = buttons;
}

SceneLiveTv.channnelTables = new Array;
/*
    Loads programs async
*/
SceneLiveTv.loadPrograms = function (chIndex, maxChannels, firstChannel) {
	Logger.write("=====SceneLiveTv.loadPrograms(" + chIndex + ", " + maxChannels + ")", "LiveTv");
	SceneLiveTv.showLoading();

	var startTime = new Date(this.currentTime);
	Logger.write("offset: " + SceneLiveTv.offset, "LiveTv", true);
	startTime.setHours(startTime.getHours() - SceneLiveTv.offset);
	var endTime = new Date(startTime);
	var channelId = SceneLiveTv.channels[chIndex].id;

	startTime.setHours(startTime.getHours()/* - this.checkInterval*/);
	endTime.setTime(endTime.getTime() + this.timeInterval);
	
	var callback = function (result) {
		try {
			if (!result || !result.items) {
				SceneLiveTv.hideLoading();
				return;
			}
			Logger.write("====SceneLiveTv GetChannelEPG callback", "LiveTv");
			var num = chIndex - firstChannel + 1;
			var currentPrograms = [];
			var result = result.items;
			var table = EpgHelper.createChannelTable(SceneLiveTv.channels[chIndex].id, result, startTime, SceneLiveTv.timeInterval, currentPrograms);
			SceneLiveTv.programButtons[num - 1] = currentPrograms;
			SceneLiveTv.channnelTables[num] = table;
			var loaded = true;
			var channelCount = maxChannels - SceneLiveTv.firstChannel;
			for (var i = 0; i < maxChannels; i++) {
				if (typeof (SceneLiveTv.programButtons[i]) == "undefined") {
					loaded = false;
				}
			}
			if (loaded) {
				SceneLiveTv.showChannels();
				SceneLiveTv.onLoadDataCompleted();
				$("#scrollLiveTv").css({
					'visibility': 'visible'
				});
			}
		} catch (error) {
			ErrorHandler.HandleError(error, "LiveTv");
		}
	};
	
	var errCallback = function (jqXHR, textStatus, error) {
		ErrorHandler.HandleError(error, "LiveTv", true, textStatus, jqXHR);
	};
	
	JsonServices.content.GetClientProgramGuide(AppContext.user.sid, "LiveTV", "AllItems", channelId, 
			null, startTime, endTime, null, null, null, 50, 1, AppContext.ClientSettings.shiftTimeZoneName, 
			AppContext.ClientSettings.timeZoneName, callback, errCallback, 1);
}

/*
Sets channels visibility
*/
SceneLiveTv.showChannels = function () {
	Logger.write("====SceneLiveTv.showChannels()", "LiveTv")

	$(".channelButton").css({
		"visibility": "hidden"
	});
	$(".channelCell").empty();
	$(".imgLiveTvLogo").css({
		"visibility": "hidden"
	});
	
	$(".channelButton").find(".sf-ui-button-c").css({'width': '86px'});
	var upperBound = SceneLiveTv.channelsPager.paging.getUpperBound();
	for (var i = 1; i <= upperBound; i++) {
		if (SceneLiveTv.channnelTables[i]) {
			$('#tdChannel' + i.toString()).append(SceneLiveTv.channnelTables[i]);
		}
		
		$('#btnChannel' + i).css({
			"visibility": "visible"
		});
		$('#imgLiveTvLogo' + i).css({
			"visibility": "visible"
		});
	}
	
	SceneLiveTv.channnelTables = new Array;
}

/*
    Occurs when data is loaded
*/
SceneLiveTv.onLoadDataCompleted = function () {
	if (SceneLiveTv.programsFocused) {
		$('#imgFocus').css('visibility', 'visible');
	}
	$("#SceneLiveTv .sceneContainer").css("opacity", "1");
	$('#epgLiveTv').css('visibility', 'visible');
	this.loadTimes();
	//this.loadScrolls();

	if (this.channelsPager.paging.totalItems > 0) {
		var currentRow = this.channelsPager.paging.index;
		if (typeof ($(this.currentFocus).attr('id')) != "undefined") {
			this.focusElement(this.currentFocus);
		} else if (SceneLiveTv.movingLeft == true) {
			SceneLiveTv.movingLeft = false;
			var lastElId = this.programButtons[currentRow][this.programButtons[currentRow].length - 1];
			this.focusElement(lastElId);
		} else {
			var firstElId = this.programButtons[currentRow][0];
			this.focusElement(firstElId);
		}
	} else {
		$('#epgLiveTv').css({
			'visibility': 'hidden'
		});
	}
	
	SceneLiveTv.dataLoaded = true;
	
	SceneLiveTv.hideLoading();
	if (this.elemToFocus != null) {
		this.focusElement(this.elemToFocus);
		this.elemToFocus = null;
	}
}

/*
    Current image's url
*/
SceneLiveTv.currentImage = "";

/*
    Focus element with selected name
    
    *elementName - name of the element
*/
SceneLiveTv.focus = function (elementName) {
	Logger.write("====SceneLiveTv.focus(" + elementName + ")", "LiveTv");
	if (elementName.indexOf("btnChannel") != -1) {
		$(elementName).sfButton('focus');
		var buttons = this.programButtons[this.channelsPager.paging.index]
		if (buttons && buttons.length > 0) {
			this.showDescription(buttons[0]);
		}
		SceneLiveTv.showCounter();
	} else {
		$('#imgFocus').prependTo($(elementName));

		var focusParentWidth = $('#imgFocus').parent().width();

		var offset = (focusParentWidth > EpgHelper.tableMaxWidth) ? 0 : EpgHelper.tablePadding;
		$('#imgFocus').width(focusParentWidth + offset);

		$('#imgFocus').css('visibility', 'visible');

		this.showDescription(elementName);
		var programTvGuideId = $(elementName).attr('ProgramTvGuideID');
		SceneLiveTv.showCounter();
	}
}

SceneLiveTv.showDescription = function (elementName) {
	Logger.write("====SceneLiveTv.showDescription(" + elementName + ")", "LiveTv");
	var name = $(elementName).text();
	var timeFromParse = DateHelper.parseDate($(elementName).attr('startTime'));
	if (timeFromParse != null) {
		Logger.write("offset: " + SceneLiveTv.offset, "LiveTv", true);
		timeFromParse.setHours(timeFromParse.getUTCHours() + SceneLiveTv.offset);
		timeFromParse.setMinutes(timeFromParse.getUTCMinutes());
	}
	var time = (timeFromParse != null) ? timeFromParse.toLocaleFormat("%H:%M") : "undefined";
	//  var description = $(elementName).attr('programDescription');
	if (name.indexOf("Unavailable") != -1) {
		$('#lblProgramName').sfLabel({
			text: "&nbsp;&nbsp;No Data Available"
		});
		$('#lblProgramGenreTime').sfLabel({
			text: ""
		});
		$('#lblProgramDescription').sfLabel({
			text: ""
		});
	} else {
		$('#lblProgramName').sfLabel({
			text: name.toString()
		});
		$('#lblProgramGenreTime').sfLabel({
			text: time
		});
	}
}

/*
    Shows channels counter
*/
SceneLiveTv.showCounter = function () {
	Logger.write("====SceneLiveTv.showCounter()", "LiveTv");
	var countStr = "";
	var channel = 0;
	var firstChannel = SceneLiveTv.channelsPager.paging.itemsOnPage * (SceneLiveTv.channelsPager.paging.pageNumber - 1);
	if (!SceneLiveTv.programsFocused) {
		channel = firstChannel + parseInt(this.currentFocus.replace("#btnChannel", ""), 10);
	} else {
		channel = firstChannel + parseInt($(this.currentFocus).parents('.channelCell').first().attr('id').replace("tdChannel", ""), 10);
	}
	countStr = channel.toString() + " | " + SceneLiveTv.channelsPager.paging.totalItems.toString();
	$("#lblLiveTvChannelCounter").empty();
	$("#lblLiveTvChannelCounter").append(countStr);
}

/*
    Blurs element with selected name
    
    *elementName - name of the element
*/
SceneLiveTv.blur = function (elementName) {
	Logger.write("====SceneLiveTv.blur(" + elementName + ")", "LiveTv");
	if (elementName.indexOf("btnChannel") != -1) {
		$(elementName).sfButton('blur');
	} else {
		$('#imgFocus').css('visibility', 'hidden');
	}
}

/*
    Focus new element with selected name and blurs old one
    
    *newFocus - name of the new element
*/
SceneLiveTv.focusElement = function (newFocus) {
	Logger.write("====SceneLiveTv.focusElement(" + newFocus + ")", "LiveTv");
	this.blur(this.currentFocus);
	this.currentFocus = newFocus;
	this.focus(this.currentFocus);
}

SceneLiveTv.findString = function (arr, str) {
	for (var i = 0; i < arr.length; i++) {
		if (arr[i] == str) {
			return i;
		}
	}
	return -1;
}

/*
    Moves cursor left
*/
SceneLiveTv.moveLeft = function () {
	try {
		if (!SceneLiveTv.dataLoaded) return;

		if (this.currentFocus.indexOf("btnChannel") != -1) return;

		var idx = this.findString(this.programButtons[this.channelsPager.paging.index], this.currentFocus) - 1;
		var left = idx > -1 ? this.programButtons[this.channelsPager.paging.index][idx] : null;
		if (left != null) {
			this.focusElement(left);
		} else if (this.currentTime > this.startTime) {
			this.currentTime.setTime(this.currentTime.getTime() - this.timeInterval);
			this.bindChannels();
			SceneLiveTv.movingLeft = true;
		} else {
			SceneLiveTv.focusChannels();
		}
	} catch (error) {
		ErrorHandler.HandleError(error, "LiveTv");
	}
}

/*
    Moves cursor right
*/
SceneLiveTv.moveRight = function () {
	try {
		if (!SceneLiveTv.dataLoaded) return;

		if (this.currentFocus.indexOf("btnChannel") != -1) {
			this.focusPrograms();
			return;
		}

		var idx = this.findString(this.programButtons[this.channelsPager.paging.index], this.currentFocus) + 1;
		var right = idx < this.programButtons[this.channelsPager.paging.index].length ? this.programButtons[this.channelsPager.paging.index][idx] : null;
		if (right != null) {
			this.focusElement(right);
		} else {
			var tmpEndTime = new Date(this.currentTime);
			tmpEndTime.setTime(tmpEndTime.getTime() + this.timeInterval);
			var tmpMaxTime = new Date(this.startTime);
			tmpMaxTime.setTime(tmpMaxTime.getTime() + this.epgTimeInterval);
			if (tmpEndTime < tmpMaxTime) {
				this.currentTime.setTime(this.currentTime.getTime() + this.timeInterval);
				this.bindChannels();
			}
		}
	} catch (error) {
		ErrorHandler.HandleError(error, "LiveTv");
	}
}

/*
    Moves cursor up
*/
SceneLiveTv.moveUp = function () {
	try {
		if (!SceneLiveTv.dataLoaded) return;
		
		if (this.channelsPager.prev()) {
			var toFocus;
			if (this.currentFocus.indexOf("btnChannel") != -1) {
				toFocus = "#btnChannel" + (this.channelsPager.paging.index + 1).toString();
			} else {
				toFocus = this.findElementToFocus(this.programButtons[this.channelsPager.paging.index]);
			}
			SceneLiveTv.focusElement(toFocus);
		}
	} catch (error) {
		ErrorHandler.HandleError(error, "LiveTv");
	}
}

/*
    Moves cursor down
*/
SceneLiveTv.moveDown = function () {
	try {
		if (!SceneLiveTv.dataLoaded) return;

		if (this.channelsPager.next()) {
			var toFocus;
			if (this.currentFocus.indexOf("btnChannel") != -1) {
				toFocus = "#btnChannel" + (this.channelsPager.paging.index + 1).toString();
			} else {
				toFocus = this.findElementToFocus(this.programButtons[this.channelsPager.paging.index]);
			}
			SceneLiveTv.focusElement(toFocus);
		}
	} catch (error) {
		ErrorHandler.HandleError(error, "LiveTv");
	}
}

/*
    Finds element to focus
*/
SceneLiveTv.findElementToFocus = function (programs) {
	var elToFocus = this.currentFocus;
	var btnLeft = $(this.currentFocus).offset().left + 1;
	for (var i = 0; i < programs.length; i++) {
		left = $(programs[i]).offset().left;
		if (left > btnLeft) {
			elToFocus = programs[i - 1];
			break;
		} else if (i == (programs.length - 1)) {
			elToFocus = programs[i];
			break;
		}
	}
	return elToFocus;
}

/*
    Focuses programs panel
*/
SceneLiveTv.focusPrograms = function () {
	try {
		SceneLiveTv.programsFocused = true;
		if (this.currentFocus.indexOf("btnChannel") != -1) {
			var program = $('.channelCell table div', $(this.currentFocus).parent().parent()).first().attr('id');
			this.focusElement("#" + program);
		}
	} catch (error) {
		ErrorHandler.HandleError(error, "LiveTv");
	}
}

/*
    Focuses channels panel
*/
SceneLiveTv.focusChannels = function () {
	try {
		SceneLiveTv.programsFocused = false;
		if (this.currentFocus.indexOf("btnProgram") != -1 || this.currentFocus.indexOf("btnUnavail") != -1) //btnUnavail
		{
			var channel = $('td div', $(this.currentFocus).parents('.channelCell').first().parent()).first().attr('id');
			this.focusElement("#" + channel);
		}
	} catch (error) {
		ErrorHandler.HandleError(error, "LiveTv");
	}
}

/*
    Getting button number from its name
*/
SceneLiveTv.getButtonNumber = function (btnName) {
	var rx = /^\#\w{2,}(\d)$/;
	var res = rx.exec(btnName);
	if (res.length == 2) {
		return parseInt(res[1]);
	}
	return -1;
}

/*
 * Gets and plays channel's stream by it's number
 */
SceneLiveTv.getStreamByNumberCallback = function (number, successCallback) {
	Logger.write("SceneLiveTv.getStreamByNumberCallback("+number+")");
	var index = number - 1;
	SceneLiveTv.newChannelIdx = index;
	Logger.write("Changing channel (in player)", "LiveTv", true);
	if (SceneLiveTv.channels[index]) {
		Logger.write("Channel is in cache", "LiveTv", true);
		var advisory = SceneLiveTv.channels[index].advisory;
		var cb = function () {
			successCallback();
			SceneLiveTv.getStreamCallback(index);
			SceneLiveTv.focusChannelCallback(number);
		};
		if (advisory == JsonServices.Advisory.R) {
			var scene = ScenePlayer.isFocused ? "Player" : "LiveTv";
			SceneLiveTv.checkPinCode(cb, scene);
		} else {
			cb();
		}
	} else {
		Logger.write("Channel isn't in cache", "LiveTv", true);
		var onPage = SceneLiveTv.channelsPager.paging.itemsOnPage;
		var page = Math.ceil(number / onPage);
		var callback = function (result) {
			Logger.write("Channels loaded", "LiveTv", true);
			if (result) {
				var advisory = SceneLiveTv.channels[index].advisory;
				var cb = function () {
					successCallback();
					SceneLiveTv.getStreamCallback(index);
					SceneLiveTv.focusChannelCallback(number);
				};
				if (advisory == JsonServices.Advisory.R) {
					var scene = ScenePlayer.isFocused ? "Player" : "LiveTv";
					SceneLiveTv.checkPinCode(cb, scene);
				} else {
					cb();
				}
			}
		};
		SceneLiveTv.loadChannelsPage(onPage, page, callback, true);
	}
}

/*
 * Gets and plays stream by channel id
 */
SceneLiveTv.getStreamCallback = function (index) {
	Logger.write("SceneLiveTv.getStreamCallback("+index+")", "LiveTv", true);
	var channel = SceneLiveTv.channels[index];
	var id = channel.id;
	if (!channel.streamData || !channel.streamData.timeStamp || channel.streamData.isExpired()) {
		if (channel.streamData && channel.streamData.isExpired()) {
			Logger.write("Stream data expired", "LiveTv");
		}
		var callback = function (result) {
			try {
				ASXLoader.loadProgramsDuration([]);
				Logger.write("Player is playing: " + ScenePlayer.isPlaying, "LiveTv", true);
				Logger.write("Player is focused: " + ScenePlayer.isFocused, "LiveTv", true);
				Logger.write("Open player condition: " + (!ScenePlayer.isPlaying || ScenePlayer.isFocused), "LiveTv", true);
				if (!ScenePlayer.isPlaying || ScenePlayer.isFocused) { //ситуация, когда переключают канал enter-ом из сетки лайва
					$.sfScene.hide(AppContext.CurrentScene);
					$.sfScene.show('Player');
					$.sfScene.focus('Player');
				}
				var streamData = {
					url: result.URL,
					playlist: result.Playlist,
					ar: {
						x: channel.arX,
						y: channel.arY
					},
					contentType: "LiveTV"
				};
				if (AppContext.ClientSettings.shiftTimeZoneName == "EU_RST") {
					Logger.write("Adding stream data to cache", "LiveTv");
					Helpers.addTimeStamp(streamData, 60);
					channel.streamData = streamData;
				}
				ScenePlayer.setContent(streamData, "LiveTv");
			} catch (error) {
				ErrorHandler.HandleError(error, "LiveTv");
			}
		};
		var errCallback = function (jqXHR, textStatus, error) {
			ErrorHandler.HandleError(error, "LiveTv", true, textStatus);
		};
		JsonServices.media.GetClientStreamUri(
			AppContext.user.sid, "LiveTV", id,
			AppContext.ClientSettings.bAId, AppContext.ClientSettings.cdnId,
			AppContext.ClientSettings.qualityPreset, AppContext.ClientSettings.shiftTimeZoneName,
			callback, errCallback
		);
	} else {
		Logger.write("Getting stream data from cache", "LiveTv", true);
		Logger.write("Player is playing: " + ScenePlayer.isPlaying, "LiveTv", true);
		Logger.write("Player is focused: " + ScenePlayer.isFocused, "LiveTv", true);
		Logger.write("Open player condition: " + (!ScenePlayer.isPlaying || ScenePlayer.isFocused), "LiveTv", true);
		if (!ScenePlayer.isPlaying || ScenePlayer.isFocused) {
			$.sfScene.focus('Player');
		}
		ScenePlayer.setContent(channel.streamData, "LiveTv");
	}
}

SceneLiveTv.checkPinCode = function (callback, sender) {
	if (!AppContext.isAdultPasswordEntered()) {
		SceneLiveTv.showPinWindow(callback, sender);
	} else {
		callback();
	}
}

SceneLiveTv.showPinWindow = function (callback, sender) {
	sender = sender || "LiveTv";
	var okFunc = function (result) {
			Logger.write("User system password: " + AppContext.user.userSystemPassword, "LiveTv", true);
			Logger.write("Result: " + result, "LiveTv", true);
			if (result == AppContext.user.userSystemPassword) {
				callback();
				AppContext.user.adultPasswordTimestamp = new Date();
			} else {
				Logger.write("Sender: " + sender, "LiveTv", true);
				if (sender.toLowerCase() == "player") {
					SceneErrorPopUp.backTo = "Player";
				}
				ErrorHandler.HandleError(new Error(Resources.getResources().InvalidPinError), "LiveTv", false, "", null, true);
			}
		}
	SceneTextboxPopUp.setCallbacks(okFunc, sender, Resources.getResources().EnterPin);
	SceneTextboxPopUp.show(true);
}

/*
    Handles enter button press
*/
SceneLiveTv.handleEnterButton = function () {
	try {
		if (!SceneLiveTv.dataLoaded) return;

		var channelId = 0;
		if (this.currentFocus.indexOf("btnChannel") != -1) {
			channelId = $(this.currentFocus).attr('channelId');
		} else {
			channelId = $(this.currentFocus).parents('.channelTr').first().find('td div').first().attr('channelId');
		}

		var channelNumber = SceneLiveTv.channelsPager.paging.getTotalIndex() + 1;
		Logger.write("Channel number: " + channelNumber, "LiveTv", true);
		var playerChannel = parseInt(ScenePlayer.channelPicker.settedChannel);
		if (ScenePlayer.isPlaying) {
			if (playerChannel == channelNumber) {
				$.sfScene.hide('LiveTv');
				$.sfScene.show('Player');
				$.sfScene.focus('Player');
			} else {
				$.sfScene.hide(AppContext.CurrentScene);
				$.sfScene.show('Player');
				$.sfScene.focus('Player');
				ScenePlayer.channelPicker.setChannelManual(channelNumber, ScenePlayer.channelPicker);
			}
		} else {
			ScenePlayer.channelPicker.setChannelManual(channelNumber, ScenePlayer.channelPicker);
		}
	} catch (error) {
		ErrorHandler.HandleError(error, "LiveTv");
	}
}

/*
    Moves focus back to MainMenu scene
*/
SceneLiveTv.backToMainMenu = function () {
	try {
		$.sfScene.hide('LiveTv');
		SceneMainMenu.show();
	} catch (error) {
		ErrorHandler.HandleError(error, "LiveTv");
	}
}

SceneLiveTv.handleExit = function () {
	var resultCallback = function (result) {
		if (result) {
			AppEvents.Exit();
		}
	};
	SceneDialogPopUp.showExitDialog("LiveTv", resultCallback);
}

SceneLiveTv.prototype.handleShow = function () {
	Logger.write("SceneLiveTv.handleShow()", "LiveTv");
	// this function will be called when the scene manager show this scene 
	SceneLiveTv.setHelpBar();
	$('#lblTvGuide').sfLabel({
		text: Resources.getResources().LabelTvGuide,
		width: '130px'
	});
	$("#liveTvNoData").html(Resources.getResources().NoData);
}

SceneLiveTv.prototype.handleHide = function () {
	Logger.write("SceneLiveTv.handleHide()", "LiveTv");
	// this function will be called when the scene manager hide this scene  
	Helpers.hideLoading();
}

SceneLiveTv.prototype.handleFocus = function () {
	Logger.write("SceneLiveTv.handleFocus()", "LiveTv");
	// this function will be called when the scene manager focus this scene
	AppContext.CurrentScene = "LiveTv";
	if (ScenePlayer.isPlaying == true) {
		Helpers.setBackgroundOpacity();
	}
	SceneLiveTv.setHelpBar();
	if (ErrorHandler.NeedToRefresh["LiveTv"]) {
		SceneLiveTv.refresh();
	} else if (SceneLiveTv.isLoading) {
		Logger.write("Scene is loading");
		Helpers.showLoading();
	}
}

SceneLiveTv.prototype.handleBlur = function () {
	Logger.write("SceneLiveTv.handleBlur()", "LiveTv");
	// this function will be called when the scene manager move focus to another scene from this scene
}

/*
 * Handles num button pressing
 */
SceneLiveTv.handleNumPress = function (num) {
	if (SceneLiveTv.channelPicker != null) {
		SceneLiveTv.channelPicker.numPressed(num);
		var currentChannel = SceneLiveTv.channelPicker.getCurrentChannel();
		var countStr = currentChannel + " | " + SceneLiveTv.channelsPager.paging.totalItems.toString();
		$("#lblLiveTvChannelCounter").empty();
		$("#lblLiveTvChannelCounter").append(countStr);
	}
}

SceneLiveTv.prototype.handleKeyDown = function (keyCode) {
	Logger.write("SceneLiveTv.handleKeyDown(" + keyCode + ")", "LiveTv");
	// TODO : write an key event handler when this scene get focued
	if (Helpers.handleGlobalKeys(keyCode)) {
		return;
	}
	switch (keyCode) {
		case $.sfKey.N0:
			SceneLiveTv.handleNumPress("0");
			break;
		case $.sfKey.N1:
			SceneLiveTv.handleNumPress("1");
			break;
		case $.sfKey.N2:
			SceneLiveTv.handleNumPress("2");
			break;
		case $.sfKey.N3:
			SceneLiveTv.handleNumPress("3");
			break;
		case $.sfKey.N4:
			SceneLiveTv.handleNumPress("4");
			break;
		case $.sfKey.N5:
			SceneLiveTv.handleNumPress("5");
			break;
		case $.sfKey.N6:
			SceneLiveTv.handleNumPress("6");
			break;
		case $.sfKey.N7:
			SceneLiveTv.handleNumPress("7");
			break;
		case $.sfKey.N8:
			SceneLiveTv.handleNumPress("8");
			break;
		case $.sfKey.N9:
			SceneLiveTv.handleNumPress("9");
			break;

		case $.sfKey.LEFT:
			SceneLiveTv.moveLeft();
			break;
		case $.sfKey.RIGHT:
			SceneLiveTv.moveRight();
			break;
		case $.sfKey.UP:
			SceneLiveTv.moveUp();
			break;
		case $.sfKey.DOWN:
			SceneLiveTv.moveDown();
			break;
		case $.sfKey.ENTER:
			SceneLiveTv.handleEnterButton();
			break;
		case $.sfKey.RETURN:
			widgetAPI.blockNavigation(event);
			SceneLiveTv.backToMainMenu();
			break;
		case $.sfKey.STOP:
			if (ScenePlayer.isPlaying == true) {
				ScenePlayer.stop();
				SceneLiveTv.setHelpBar();
			}
			break;
		case $.sfKey.BLUE:
			if (ScenePlayer.isPlaying == true) {
				$.sfScene.hide('LiveTv');
				$.sfScene.show('Player');
				$.sfScene.focus('Player');
			}
			break;
		case $.sfKey.GREEN:
			try {
				var okFunc = function (result) {
						$.sfScene.hide('LiveTv');
						SceneSearchChannels.show();
						SceneSearchChannels.loadResults(result, "LiveTv");
					}
				SceneTextboxPopUp.setCallbacks(okFunc, "LiveTv");
				SceneTextboxPopUp.show();
			} catch (error) {
				ErrorHandler.HandleError(error, "LiveTv");
			} finally {
				break;
			}
		case $.sfKey.RED:
			try {
				$.sfScene.hide('LiveTv');
				$.sfScene.show('Settings');
				$.sfScene.focus('Settings');
				SceneSettings.selectAccount();
			} catch (error) {
				ErrorHandler.HandleError(error, "LiveTv");
			}
			break;
		case $.sfKey.EXIT:
			try {
				widgetAPI.blockNavigation(event);
				SceneLiveTv.handleExit();
			} catch (error) {
				ErrorHandler.HandleError(error, "LiveTv");
			}
			break;
		default:
			widgetAPI.blockNavigation(event);
			break;
	}
}