define('application/models/epg/item', [
'product-layer/models/epg/item',
'application/managers/channel',
'antie/runtimecontext',
'application/managers/api',
'rofl/lib/utils',
'application/managers/session',
'antie/storageprovider',
'application/managers/feature',
'rofl/lib/l10n'
], function (
EPGItem,
ChannelManager,
RuntimeContext,
ApiManager,
Utils,
SessionManager,
StorageProvider,
FeatureManager,
L10n
) {
'use strict';
var application = RuntimeContext.getCurrentApplication(),
imageFormat = application && application.getLayout().imageFormat,
imageEndpoint = ApiManager.getImageAPI('epg/') + '{{imageId}}/{{size}}.jpg',
getDetailsAction = function (actions) {
var i,
j,
detailsAction;
for (i = 0, j = actions.length; i < j; i++) {
if (actions[i].targetType === 'DETAILS_PAGE') {
detailsAction = actions[i].uri;
break;
}
}
return detailsAction;
},
CONTENT_OPTIONS = {
TRICKPLAY: 'TRICKPLAY',
STARTOVER: 'STARTOVER',
CATCHUP: 'CATCHUP',
RECORDABLE: 'RECORDABLE'
},
l10n = L10n.getInstance();
return EPGItem.extend({
/**
* Initialises the EPG Item.
*
* @param {Object} data - The data.
* @param {Object} channel - The channel the epg item belongs to.
*/
init: function (data, channel) {
var metadata;
data = Utils.isEmpty(data) ? this._createInfoNotAvailable(channel, data) : data;
metadata = data.metadata;
this._id = parseInt(metadata.contentId);
this._title = metadata.title;
this._titleBrief = metadata.titleBrief;
this._startTime = metadata.airingStartTime / 1000;
this._endTime = metadata.airingEndTime / 1000;
this._channelName = metadata.channelName;
this._channelId = channel.getId();
this._assetId = channel.getAssetId();
this._contentOptions = metadata.contentOptions;
this._duration = metadata.duration;
this._imageUrl = metadata.pictureUrl;
this._videoRatings = metadata.pcExtendedRatings;
this._channel = channel;
this._detailsAction = getDetailsAction(data.actions || []);
this._seriesId = parseInt(metadata.seriesId);
this._pcLevel = parseInt(metadata.pcLevel);
this._parentalGenres = metadata.pcExtendedRatings.length ? metadata.pcExtendedRatings : [];
this._parentalWhitelisted = false;
this._noEpgData = data.noEpgData;
this._contentType = metadata.contentType || 'PROGRAM';
this._contentType = metadata.contentType;
this._contentSubtype = metadata.contentType;
if (!imageFormat) {
imageFormat = RuntimeContext.getCurrentApplication().getLayout().imageFormat;
}
if (this._pcLevel === 99) {
this._pcLevel = 0;
}
this._streamOffset = 5 * 60; // Hardcode the stream offset.
},
/**
* Creates epgData when missing.
*
* @param {Object} channel - The channel the epg item belongs to.
* @param {Object} data - The data.
* @returns {Object} - Epg item metadata.
*/
_createInfoNotAvailable: function (channel, data) {
var metadata = {},
dataChannel = [],
now = application.getDate(),
duration = 3600000; // 1hr
if (!Utils.isEmpty(data)) {
metadata = data.metadata || {};
dataChannel = data.channel || [];
}
return {
id: data.id || '0',
layout: data.layout || 'CONTENT_ITEM',
actions: data.actions || [],
metadata: {
contentId: metadata.contentId,
contentType: metadata.contentType || 'PROGRAM',
contentSubtype: metadata.contentSubtype || 'VOD',
title: l10n.get('asset.noinfoavailable'),
titleBrief: l10n.get('asset.noinfoavailable'),
pcExtendedRatings: metadata.pcExtendedRatings || [],
pcLevel: metadata.pcLevel || 99,
duration: metadata.duration || duration / 1000,
pictureUrl: metadata.pictureUrl || '',
season: metadata.season || 0,
externalId: metadata.externalId || '',
airingStartTime: metadata.airingStartTime || now,
airingEndTime: metadata.airingEndTime || now + duration,
contentOptions: metadata.contentOptions || []
},
technicalPackageIds: data.technicalPackageIds || [],
channel: {
channelId: dataChannel.channelId || channel.getId && channel.getId(),
externalChannelId: dataChannel.externalChannelId || channel.getExternalId && channel.getExternalId(),
channelName: dataChannel.channelName || channel.getName && channel.getName(),
type: dataChannel.type || 'LIVE'
},
assets: data.assets || [],
noEpgData: true
};
},
/**
* Returns the id.
*
* @returns {number} - The id.
*/
getId: function () {
return this._id;
},
/**
* Returns the asset id.
*
* @returns {number} - The asset id.
*/
getAssetId: function () {
return this._assetId;
},
/**
* Returns the title.
*
* @returns {string} - The title.
*/
getTitle: function () {
return this._title;
},
/**
* Returns the title brief (short title).
*
* @returns {string} - The title brief.
*/
getTitleBrief: function () {
return this._titleBrief;
},
/**
* Returns if EPG data is available.
*
* @returns {boolean} - True if noEpgData is set.
*/
hasEpgData: function () {
return !this._noEpgData;
},
/**
* Returns the start time.
*
* @returns {number} - The start time.
*/
getStartTime: function () {
return this._startTime;
},
/**
* Returns the end time.
*
* @returns {number} - The end time.
*/
getEndTime: function () {
return this._endTime;
},
/**
* Returns the duration.
*
* @returns {number} - The duration.
*/
getDuration: function () {
return this._duration;
},
/**
* Returns the channel name.
*
* @returns {string} - The channel name.
*/
getChannelName: function () {
return this._channelName;
},
/**
* Returns the channel id.
*
* @returns {string} - The channel id.
*/
getChannelId: function () {
return this._channelId;
},
/**
* Returns the content options.
*
* @returns {Object} - The content options.
*/
getContentOptions: function () {
return this._contentOptions;
},
/**
* Returns the channel.
*
* @returns {Object} - The channel.
*/
getChannel: function () {
return this._channel;
},
/**
* Returns the background.
*
* @param {string} orientation - Orientation.
* @param {Object} [dimensions] - The dimensions. Should contain width and height.
* @returns {string|null} - The background url or null if not available.
* @private
*/
getImage: function (orientation, dimensions) {
var format,
size;
if (!this._imageUrl) {
return null;
}
orientation = orientation || 'landscape'; // Default to landscape image.
if (orientation === 'manual') {
size = dimensions.width + 'x' + dimensions.height;
} else {
format = imageFormat[orientation];
size = Math.round(format.width) + 'x' + Math.round(format.height);
}
return Utils.formatTemplate(imageEndpoint, {
imageId: this._imageUrl,
size: size
});
},
/**
* Returns URL of preview image.
*
* @param {string} size - Size of the image.
* @returns {string} - URL of preview image.
*/
getImageUrl: function (size) {
size = size || imageFormat.landscape.width + 'x' + imageFormat.landscape.height;
// Prevents unnecessary calls to image api when there's no imageUrl.
if (!this._imageUrl) {
return this._imageUrl;
}
return Utils.formatTemplate(imageEndpoint, {
imageId: this._imageUrl,
size: size
});
},
/**
* Returns the video ratings.
*
* @returns {Array} - The video ratings.
*/
getVideoRatings: function () {
return this._videoRatings;
},
/**
* Returns the details action.
*
* @returns {string} - The details action url.
*/
getDetailsAction: function () {
return this._detailsAction;
},
/**
* Returns the channel logo.
*
* @returns {string} - The channel logo.
*/
getChannelLogo: function () {
return this.getChannel().getImage(128);
},
/**
* Returns true if the video can be played.
*
* @returns {boolean} - True if the video can be played.
*/
canPlay: function () {
if (this.isLive()) {
// Program is currently playing and can be restarted.
return true;
} else if (this.isReplayItem()) {
// Program is finished and can be caught up.
return this.canCatchup();
}
// Program is in the future and can't be watched.
return false;
},
/**
* Returns true if the video is currently playing.
*
* @returns {boolean} - True if the video is currently playing.
*/
isLive: function () {
var now = application.getDate() / 1000;
return this.getStartTime() < now && this.getEndTime() > now;
},
/**
* Returns true if the item is a replay item.
*
* @returns {boolean} - True if the item is a replay item.
*/
isReplayItem: function () {
var now = application.getDate() / 1000;
return this.getEndTime() < now;
},
/**
* Returns true if the video can be caught up.
*
* @returns {boolean} - True if can be caught up.
*/
canCatchup: function () {
return this._contentOptions.indexOf(CONTENT_OPTIONS.CATCHUP) >= 0;
},
/**
* Returns true if seeking is allowed.
*
* @returns {boolean} - True if seeking is allowed.
*/
canSeek: function () {
return this._contentOptions.indexOf(CONTENT_OPTIONS.TRICKPLAY) >= 0;
},
/**
* Returns true if recording is allowed.
*
* @returns {boolean} - True if recording is allowed.
*/
canRecord: function () {
return this._contentOptions.indexOf(CONTENT_OPTIONS.RECORDABLE) >= 0;
},
/**
* Returns the series id.
*
* @returns {number} - The series id.
*/
getSeriesId: function () {
return this._seriesId;
},
/**
* Returns parental control level.
*
* @returns {number} - Parental control level.
*/
getPCLevel: function () {
return this._pcLevel;
},
/**
* Returns parental genres.
*
* @returns {Array} - Parental genres.
*/
getParentalGenres: function () {
return this._parentalGenres;
},
/**
* Sets program to be parental whitelisted.
*/
setParentalWhitelisted: function () {
this._parentalWhitelisted = true;
},
/**
* Gets if program is whitelisted.
*
* @returns {boolean} - If is whitelisted.
*/
getParentalWhitelisted: function () {
return this._parentalWhitelisted;
},
/**
* Returns the recording starttime.
*
* @returns {number|null} - The stream offset.
*/
getStreamOffset: function () {
return this._streamOffset;
},
/**
* Returns true if the broadcast is locked.
*
* @returns {boolean} - True if the broadcast is locked.
*/
isLocked: function () {
var parentalControlParams = SessionManager.getInstance().getUserPCParams(),
parentalControlOn = SessionManager.getInstance().isParentalOn(),
parentalControlLevel = parseInt(Utils.getNested(parentalControlParams, 'parentalControlLevel')),
parentalControlGenres = Utils.getNested(parentalControlParams, 'parentalGenres'),
i,
self = this,
isGenreProtected = function () {
if (parentalControlGenres.length) {
for (i = 0; i < parentalControlGenres.length; i++) {
if (self.getParentalGenres().indexOf(parentalControlGenres[i]) > -1) {
return true;
}
}
}
return false;
},
isLocked = false,
VODContentTypes = ['VOD', 'GROUP_OF_BUNDLES', 'BUNDLE'];
if (VODContentTypes.indexOf(this.getContentType()) >= 0) {
parentalControlLevel = parseInt(Utils.getNested(parentalControlParams, 'parentalVODControlLevel'));
}
if (!FeatureManager.getInstance().isParentalEnabled() || !parentalControlOn) {
isLocked = false;
} else {
isLocked = !(parentalControlLevel >= this.getPCLevel()) || isGenreProtected();
}
return isLocked;
},
/**
* Returns true if the stream requires to be requested with pin.
*
* @returns {boolean} - True if stream requires pin.
*/
streamRequiresPin: function () {
var parentalControlParams = SessionManager.getInstance().getUserPCParams(),
parentalControlLevel = parseInt(Utils.getNested(parentalControlParams, 'parentalControlLevel')),
parentalControlGenres = Utils.getNested(parentalControlParams, 'parentalGenres'),
genres = this.getParentalGenres(),
isGenreProtected,
VODContentTypes = ['VOD', 'GROUP_OF_BUNDLES', 'BUNDLE'];
if (VODContentTypes.indexOf(this.getContentType()) >= 0) {
parentalControlLevel = parseInt(Utils.getNested(parentalControlParams, 'parentalVODControlLevel'));
}
isGenreProtected = function () {
var i;
if (parentalControlGenres.length) {
for (i = 0; i < parentalControlGenres.length; i++) {
if (genres.indexOf(parentalControlGenres[i]) > -1) {
return true;
}
}
}
return false;
};
return !(parentalControlLevel >= this.getPCLevel()) || isGenreProtected();
},
/**
* Returns true if the item is playable.
*
* @returns {boolean} - True if the item is playable.
*/
isPlayable: function () {
var now = application.getDate().getTime(),
endTime = this.getEndTime() * 1000,
replayBuffer = 15 * 60 * 1000;
return (now - endTime > replayBuffer);
},
/**
* Returns the content type.
*
* @returns {string} - The content type.
*/
getContentType: function () {
return this._contentType;
},
/**
* Returns the content type.
*
* @returns {string} - The content type.
*/
getContentSubtype: function () {
return this._contentSubtype;
}
});
});