var JsonServices = { //namespace for service wrappers
    defaultName: "service.asmx",
	
	rumote: { // Rumote Client service
		ns: "http://www.rumote.com/export",
		serviceName: "JsonRumoteService.svc/json"
	},
	
    client: { //IVS Client service
        ns: "http://ivsmedia.iptv-distribution.net",
        serviceName: "JsonClientService.svc/json"
    },

    content: { //IVS Content service
        ns: "http://ivsmedia.iptv-distribution.net",
        serviceName: "JsonContentService.svc/json"
    },

    media: { //IVS Media service
        ns: "http://ivsmedia.iptv-distribution.net",
        serviceName: "JsonMediaService.svc/json"
    },
	
	requests: { },
	
	ContentType:  {
		AudioBooks: 0,
		DVR: 1,
		Games: 2,
		Karaoke: 3,
		LiveTV: 4,
		Music: 5,
		Podcast: 6,
		Radio: 7,
		ArcPlus: 8,
		VOD: 9
	},
	
	ContentGenreType: {
		UnknownGenreType: 0,
		TVGenreType: 1,
		VodGenreType: 2,
		ProgramGenreType: 3,
		ArcplusGenreType: 4
	},
	
	OnDemandRequestType: {
		AllItems: -1,
		Today: 0,
		Yesterday: 1,
		BeforeYesterday: 2,
		ThreeDaysAgo: 3,
		FourDaysAgo: 4,
		FiveDaysAgo: 5,
		SixDaysAgo: 6,
		SevenDaysAgo: 7,
		LastWeek: 100,
		JustAdded: 101,
		Featured: 102,
		TopHundredWatched: 103,
		TopHundredRated: 104,
		TopHundredWatchedMonth: 105,
		TopHundredWatchedWeek: 106,
		TopHundredNew: 107,
		SearchByActors: 120,
		SearchByDirectors: 121,
		SearchByName: 122,
		SearchByDescription: 123,
		SearchByDate: 124,
		SearchByDateRange: 125,
		FreeItems: 126,
		SearchByDateRangExpanded: 127,
		SearchByKeywordInChannels: 128
	},
	
	StreamQualityPreset: {
		VQ: 0,
		SQ: 1,
		HQ: 2,
		GQ: 3,
		EQ: 4,
		BQ: 5
	},
	
	RelatedType: {
		children: 1,
		showing: 2,
		similar: 3,
		details: 4,
		IDs: 5
	},
	
	Status: {
		Available: 1,
		Enabled: 2,
		NA: 3,
		PreviewAvailable: 4
	},
	
	RegisterInfoType: {
		NA: 0,
		Activate: 1,
		Confirm: 2,
		Register: 3
	},
	
	Advisory: {
		NR: 0,
		PG1: 1,
		PG2: 2,
		PG3: 3,
		PG4: 4,
		R: 5
	}
};

JsonServices.contentTypeGenreTypeMap = { };
JsonServices.contentTypeGenreTypeMap[JsonServices.ContentType.DVR] = JsonServices.ContentGenreType.ProgramGenreType;
JsonServices.contentTypeGenreTypeMap[JsonServices.ContentType.VOD] = JsonServices.ContentGenreType.VodGenreType;
JsonServices.contentTypeGenreTypeMap[JsonServices.ContentType.ArcPlus] = JsonServices.ContentGenreType.ArcplusGenreType;

JsonServices.invoke = function (data, service, method, callback, errCallback) {
	var url = service.ns + "/" + service.serviceName + "/" + method;
	Logger.write("URL: " +url, "JsonServices", true);
	var json = JSON2.stringify(data);
	var success = function (result) {
		Logger.write("result received: " + result, "JsonServices", true);
		var res;
		if (!result || typeof result !== "string" || result.length == 0) {
			res = null;
		} else {
			res = JSON2.parse(result);
		}
		callback(res);
	};
	Logger.write("Data: " + json, "JsonServices", true);
	$.ajax({
		url: url,
		data: json,
		type: 'POST',
		processData: false,
		contentType: "application/json",
		dataType: 'text',
		success: success,
		error: errCallback,
		statusCode: {
			200: function () {
				Logger.write("Status code: 200", "JsonServices", true);
			}
		}
	});
}

JsonServices.client.ClientLogout = function (sid, appName, duid, callback, errCallback) {

	var url = JsonServices.rumote.ns+"/device/logout.php";
	Logger.write("URL: " + url, "JsonServices.client.ClientLogout", true );

	$.ajax({
            type: "POST",
            url: url,
            dataType: "json",
			data: "duid="+duid+"&source="+appName,
            success: function (data) {
				Logger.write("unregister "+data.toSource(), "JsonServices.client.ClientLogout", true );
				callback();
			},
			error: function (jqXHR, textStatus, error) {
				Logger.write("failed to unregister", "JsonServices.client.ClientLogout", true);
				errCallback(jqXHR, textStatus, error);
			}
	});
}

JsonServices.client.GetMessages = function (sid, callback, errCallback) {
	var data = {
		sessionID: sid
	};
	JsonServices.invoke(data, this, "GetMessages", callback, errCallback);
}

JsonServices.client.GetSettings = function (sid, callback, errCallback) {
	Logger.write("JsonServices.client.GetSettings(" + sid + ")", "JsonServices", true);
	var data = {
		sessionID: sid
	};
	JsonServices.invoke(data, this, "GetSettings", callback, errCallback);
}

JsonServices.client.Login = function (appName, duid, login, password, callback, errCallback) {

	Logger.write("JsonServices1.client.Login(" + duid + ", " + login + ", " + password + ", " + appName + ")", "JsonServices", true);
	var url = JsonServices.rumote.ns+"/device/login.php";
	Logger.write("URL: " + url, "JsonServices.client.Login", true );
	
	AppContext.user.email = "";
	
    $.ajax({
            type: "POST",
            url: url,
            dataType: "json",
			data: "duid="+duid+"&login="+login+"&password="+password+"&source="+appName+"&v=1.10",
            success: function (data) {

				Logger.write("success:" + data.toSource(), "JsonServices.client.Login", true);
				
				var response = [{
					sessionID: [ {Text:data.sid} ], 
					UserLogin: [ {Text:data.login} ], 
					UserPassword: [ {Text:data.password} ], 
					UserSystemPassword: [ {Text:data.systemPassword} ]
				}];
				
				AppContext.user.email = data.email;
				
				callback(response);
				
			},
			error: errCallback
	}); 
	
	Logger.write("ajax complete:" + login + " " + password, "JsonServices.client.Login", true);
	
}

JsonServices.client.RegisterClient = function (registerType, appName, email, phoneNumber, duid, pin, callback, errCallback) {
	if (typeof(registerType) == "string") {
		registerType = JsonServices.RegisterInfoType[registerType];
	}
	var data = {
		cc: {
			appSettings: JsonServices.requests.AppSettings(appName),
			clientCredentials: JsonServices.requests.AccessCredentials(null, null, duid, null)
		},
		info: JsonServices.requests.RegisterInfo(registerType, email, pin, phoneNumber)
	};
	JsonServices.invoke(data, this, "RegisterClient", callback, errCallback);
}

JsonServices.client.SetMessagesRead = function (sid, messageIds, callback, errCallback) {
	var data = {
		sessionID: sid,
		messageIDs: messageIds
	};
	JsonServices.invoke(data, this, "SetMessagesRead", callback, errCallback);
}

JsonServices.client.SetSettings = function (sid, language, timeZoneName, shiftTimeZoneName, qualityPreset, callback, errCallback) {
	if (typeof(qualityPreset) === "string") {
		qualityPreset = JsonServices.StreamQualityPreset[qualityPreset];
	}
	var data = {
		sessionID: sid,
		cs: JsonServices.requests.ClientSettings(language, timeZoneName, shiftTimeZoneName, qualityPreset)
	};
	JsonServices.invoke(data, this, "SetSettings", callback, errCallback);
}

JsonServices.content.AddFavorites = function (sid, contentType, ids, callback, errCallback) {
	if (typeof(contentType) === "string") {
		contentType = JsonServices.ContentType[contentType];
	}
	var items = ids.map(function (id) {
		return {
			id: id,
			contentType: contentType
		};
	});
	var data = {
		sessionID: sid,
		items: items
	};
	JsonServices.invoke(data, this, "AddFavorites", callback, errCallback);
}

JsonServices.content.DeleteFavorites = function (sid, contentType, ids, callback, errCallback) {
	if (typeof(contentType) === "string") {
		contentType = JsonServices.ContentType[contentType];
	}
	var items = ids.map(function (id) {
		return {
			id: id,
			contentType: contentType
		};
	});
	var data = {
		sessionID: sid,
		items: items
	};
	JsonServices.invoke(data, this, "DeleteFavorites", callback, errCallback);
}

JsonServices.content.GetClientChannels = function (sid, type, onPage, pageNumber, callback, errCallback) {
	if (typeof(type) === "string") {
		type = JsonServices.ContentType[type];
	}
	var paging = JsonServices.requests.ItemPaging(onPage, pageNumber);
	var data = {
		sessionID: sid,
		request: new JsonServices.requests.ContentRequest(type, null, paging)
	};
	JsonServices.invoke(data, this, "GetClientChannels", callback, errCallback);
}

JsonServices.content.GetClientContentGenres = function (sid, type, callback, errCallback) {
	if (typeof(type) === "string") {
		type = JsonServices.ContentGenreType[type];
	}
	var data = {
		sessionID: sid,
		type: type
	};
	JsonServices.invoke(data, this, "GetClientContentGenres", callback, errCallback);
}

JsonServices.content.GetClientOnDemandContent = function (sid, requestType, genreId, keyWord, orderBy, onPage, pageNumber, callback, errCallback) {
	requestType = requestType || "AllItems";
	if (typeof(requestType) === "string") {
		requestType = JsonServices.OnDemandRequestType[requestType];
	}
	var contentType = JsonServices.ContentType["VOD"];
	var paging = JsonServices.requests.ItemPaging(onPage, pageNumber);
	var filter = JsonServices.requests.ContentFilter(contentType, true, genreId, null, null, null, orderBy, keyWord);
	var data = {
		sessionID: sid,
		request: JsonServices.requests.OnDemandRequest(contentType, requestType, filter, paging)
	};
	JsonServices.invoke(data, this, "GetClientOnDemandContent", callback, errCallback);
}

JsonServices.content.GetClientProgramGuide = function (sid, contentType, requestType, channelId, genreId, dateFrom, dateTill, keyWord, orderBy, isContainerSearch, onPage, pageNumber, streamZone, watchingZone, callback, errCallback, json) {
	requestType = requestType || "AllItems";
	if (typeof(contentType) === "string") {
		contentType = JsonServices.ContentType[contentType];
	}
	if (typeof(requestType) === "string") {
		requestType = JsonServices.OnDemandRequestType[requestType];
	}
	var paging = JsonServices.requests.ItemPaging(onPage, pageNumber);
	var filter = JsonServices.requests.ContentFilter(contentType, true, genreId, channelId, dateFrom, dateTill, orderBy, keyWord, isContainerSearch);
	var data = {
		sessionID: sid,
		type: contentType,
		request: JsonServices.requests.ProgramGuideRequest(contentType, requestType, dateFrom, dateTill, channelId, filter, paging, streamZone, watchingZone, json)
	};
	JsonServices.invoke(data, this, "GetClientProgramGuide", callback, errCallback);
}

JsonServices.content.GetClientRelatedProgramGuide = function (sid, contentType, relatedType, id, sortBy, onPage, pageNumber, callback, errCallback) {
	if (typeof(contentType) === "string") {
		contentType = JsonServices.ContentType[contentType];
	}
	if (typeof(relatedType) === "string") {
		relatedType = JsonServices.RelatedType[relatedType];
	}
	var paging = JsonServices.requests.ItemPaging(onPage, pageNumber);
	var filter = JsonServices.requests.ContentFilter(contentType, true, null, null, null, null, sortBy, null, null);
	var data = {
		sessionID: sid,
		request: JsonServices.requests.RelatedRequest(contentType, relatedType, id, filter, paging)
	};
	JsonServices.invoke(data, this, "GetClientRelatedProgramGuide", callback, errCallback);
}

JsonServices.content.GetClientRelatedOnDemandContent = function (sid, contentType, relatedType, id, orderBy, onPage, pageNumber, callback, errCallback) {
	if (typeof(contentType) === "string") {
		contentType = JsonServices.ContentType[contentType];
	}
	if (typeof(relatedType) === "string") {
		relatedType = JsonServices.RelatedType[relatedType];
	}
	var paging = JsonServices.requests.ItemPaging(onPage, pageNumber);
	var filter = JsonServices.requests.ContentFilter(contentType, true, null, null, null, null, orderBy);
	var data = {
		sessionID: sid,
		request: JsonServices.requests.RelatedRequest(contentType, relatedType, id, filter, paging)
	};
	JsonServices.invoke(data, this, "GetClientRelatedOnDemandContent", callback, errCallback);
}

JsonServices.content.GetFavPrograms = function (sid, contentType, onPage, pageNumber, callback, errCallback) {
	if (typeof(contentType) === "string") {
		contentType = JsonServices.ContentType[contentType];
	}
	var data = {
		sessionID: sid,
		type: contentType,
		paging: JsonServices.requests.ItemPaging(onPage, pageNumber)
	};
	JsonServices.invoke(data, this, "GetFavPrograms", callback, errCallback);
}

JsonServices.content.GetFavOnDemandContent = function (sid, contentType, onPage, pageNumber, callback, errCallback) {
	if (typeof(contentType) === "string") {
		contentType = JsonServices.ContentType[contentType];
	}
	var data = {
		sessionID: sid,
		type: contentType,
		paging: JsonServices.requests.ItemPaging(onPage, pageNumber)
	};
	JsonServices.invoke(data, this, "GetFavOnDemandContent", callback, errCallback);
}

JsonServices.content.GetFavOnDemandContentFilter = function (sid, contentType, onPage, pageNumber, callback, errCallback) {
	if (typeof(contentType) === "string") {
		contentType = JsonServices.ContentType[contentType];
	}
	var requestType = JsonServices.OnDemandRequestType["AllItems"];
	var paging = JsonServices.requests.ItemPaging(onPage, pageNumber);
	var data = {
		sessionID: sid,
		vodRequest: JsonServices.requests.OnDemandRequest(contentType, requestType, null, paging)
	};
	JsonServices.invoke(data, this, "GetFavOnDemandContentFilter", callback, errCallback);
}

JsonServices.media.GetClientStreamUri = function (sid, contentType, id, baId, cdnId, qualityPreset, shiftTimeZoneName, callback, errCallback) {
	if (typeof(contentType) === "string") {
		contentType = JsonServices.ContentType[contentType];
	}
	if (typeof(qualityPreset) === "string") {
		qualityPreset = JsonServices.StreamQualityPreset[qualityPreset];
	}
	var data = {
		sessionID: sid,
		mediaRequest: JsonServices.requests.MediaRequest(contentType, id, baId, cdnId, qualityPreset, shiftTimeZoneName)
	};
	JsonServices.invoke(data, this, "GetClientStreamUri", callback, errCallback);
}

JsonServices.media.GetCurrentUtcTime = function (callback, errCallback) {
	JsonServices.invoke({}, this, "GetCurrentUtcTime", callback, errCallback);
}

JsonServices.media.GetMediaZoneInfo = function (callback, errCallback) {
	JsonServices.invoke({}, this, "GetMediaZoneInfo", callback, errCallback);
}

JsonServices.media.MediaImageUrlTemplate = function (siteId, callback, errCallback) {
	siteId = siteId || 1;
	var data = { siteID: siteId };
	JsonServices.invoke(data, this, "MediaImageUrlTemplate", callback, errCallback);
}


/*================================================================*/

/** Requests */

JsonServices.requests.AppSettings = function (appName, siteID) {
	var appSettings = {
		appName: appName,
		siteID: siteID || 0,
		settings: []
	};
	
	return appSettings;
}

JsonServices.requests.AccessCredentials = function (login, password, stbMacAddress, sessionId, clientIp) {
	var accessCredentials = {};
	if (login) {
		accessCredentials.UserLogin = login;
	}
	if (password) {
		accessCredentials.UserPassword = password;
	}
	if (stbMacAddress) {
		accessCredentials.StbMacAddress = stbMacAddress;
	}
	if (sessionId) {
		accessCredentials.sessionID = sessionId;
	}
	if (clientIp) {
		accessCredentials.clientIP = clientIp;
	}
	
	return accessCredentials;
}

JsonServices.requests.ContentFilter = function (contentType, availableOnly, genreId, channelId, date, dateTill, orderBy, keyWord, isContainerSearch) {
	var contentFilter = {
		DontFetchDetails: contentType === JsonServices.ContentType.LiveTV,
		availableOnly: availableOnly,
		contentType: contentType,
		visibleOnly: true
	};
	if (isContainerSearch) {
		contentFilter.IsContainerSearch = isContainerSearch;
	}
	if (genreId) {
		genreId = parseInt(genreId);
		if (genreId) {
			contentFilter.contentGenre = {
				genreType: JsonServices.contentTypeGenreTypeMap[contentType],
				id: genreId
			};
		}
	}
	
	if (date) {
		contentFilter.date = date;
	}
	if (dateTill) {
		contentFilter.dateTill = dateTill;
	}
	if (keyWord) {
		contentFilter.keyWord = keyWord;
	}
	if (orderBy) {
		contentFilter.orderBy = orderBy;
	}
	if (channelId) {
		contentFilter.studioID = channelId;
	}
	
	return contentFilter;
}

JsonServices.requests.ItemPaging = function (itemsOnPage, pageNumber) {
	if (!itemsOnPage && !pageNumber) {
		return null;
	}
	var paging = {
		itemsOnPage: itemsOnPage,
		pageNumber: pageNumber
	};
	
	return paging
}

JsonServices.requests.StreamSettings = function (baId, cdnId, qualityPreset, shiftTimeZoneName) {
	var streamSettings = {};
	if (baId) {
		streamSettings.balancingArea = { id: baId };
	}
	if (cdnId) {
		streamSettings.cdn = { id: cdnId };
	}
	if (qualityPreset) {
		streamSettings.qualityPreset = qualityPreset;
	}
	if (shiftTimeZoneName) {
		streamSettings.shiftTimeZoneName = shiftTimeZoneName
	}
	
	return streamSettings;
}

JsonServices.requests.ClientSettings = function (language, timeZoneName, shiftTimeZoneName, qualityPreset) {
	var clientSettings = {};
	if (language) {
		clientSettings.language = language;
	}
	if (timeZoneName) {
		clientSettings.timeZoneName = timeZoneName;
	}
	if (shiftTimeZoneName || qualityPreset) {
		clientSettings.streamPreference = JsonServices.requests.StreamSettings(null, null, qualityPreset, shiftTimeZoneName);
	}
	
	return clientSettings;
}

JsonServices.requests.RegisterInfo = function (type, email, pin, phoneNumber) {
	if (typeof(type) == "string") {
		type = JsonServices.RegisterInfoType[type];
	}
	var registerInfo = {};
	if (email) {
		registerInfo.EMail = email;
	}
	if (pin) {
		registerInfo.PIN = pin;
	}
	if (phoneNumber) {
		registerInfo.PhoneNumber = phoneNumber;
	}
	registerInfo.RegisterInfoType = type;
	
	return registerInfo;
}

JsonServices.requests.ContentRequest = function (type, filter, paging) {
	if (typeof(type) === "string") {
		type = JsonServices.ContentType[type];
	}
	var contentRequest = {
		type: type
	};
	if (filter) {
		contentRequest.filter = filter;
	}
	if (paging) {
		contentRequest.paging = paging;
	}
	
	return contentRequest;
}

JsonServices.requests.OnDemandRequest = function (type, requestType, filter, paging) {
	var onDemandRequest = JsonServices.requests.ContentRequest(type, filter, paging);
	if (requestType) {
		onDemandRequest.requestType = requestType;
	}
	return onDemandRequest;
}

JsonServices.requests.ProgramGuideRequest = function (type, requestType, fromTime, tillTime, channelId, filter, paging, streamZone, watchingZone, json) {
	var programGuideRequest = JsonServices.requests.OnDemandRequest(type, requestType, filter, paging);
	if (channelId || channelId === 0) {
		programGuideRequest.channelID = channelId;
	}
	/*if (fromTime && tillTime) {
		programGuideRequest.fromTime = fromTime;
		programGuideRequest.tillTime = tillTime;
	}*/
	if (streamZone) {
		programGuideRequest.streamZone = streamZone;
	}
	if (watchingZone) {
		programGuideRequest.watchingZone = watchingZone;
	}
	
	if (json || parseInt(json) === 0) {
		programGuideRequest.json = json;
	}
	
	return programGuideRequest;
}

JsonServices.requests.MediaRequest = function (contentType, id, baId, cdnId, qualityPreset, shiftTimeZoneName) {
	if (!contentType || !id) {
		return null;
	}
	if (typeof(contentType) === "string") {
		contentType = JsonServices.ContentType[contentType];
	}
	if (typeof(qualityPreset) === "string") {
		qualityPreset = JsonServices.StreamQualityPreset[qualityPreset];
	}
	if (qualityPreset)
	var mediaRequest = {
		item: {
			id: id,
			contentType: contentType
		},
		streamSettings: JsonServices.requests.StreamSettings(baId, cdnId, qualityPreset, shiftTimeZoneName)
	};
	
	return mediaRequest;
}

JsonServices.requests.RelatedRequest = function (contentType, relatedType, id, filter, paging) {
	if (typeof(contentType) === "string") {
		contentType = JsonServices.ContentType[contentType];
	}
	if (typeof(relatedType) === "string") {
		relatedType = JsonServices.RelatedType[relatedType];
	}
	var relatedRequest = JsonServices.requests.ContentRequest(contentType, filter, paging);
	relatedRequest.id = id;
	relatedRequest.relatedType = relatedType;
	
	return relatedRequest;
}

/** /Requests */
