var RTB = function() {
	var baseUrl;
	var emptyResponses = 0;
	var lastGetSnipsFunctionCall = 0;
	var maxNumberOfSnips = 20;
	var pinnedEventId;
	var pinnedEventUpdater;

	var searchClient = new BWIN.SearchClient("https://api.bwinlabs.com/searchtng/", "en", "rtb");

	var urlRegex = new RegExp( "(https?://\\S+)", "gi" );
	var openParanthesesRegex = new RegExp("\\(", "g");
	var closeParanthesesRegex = new RegExp("\\)", "g");
	var paranthesesRegex = new RegExp("\\(.*?\\)","g");

	var snipDirective = {
		".pluginIcon[class]" : function(arg){
			return "pluginIcon " + arg.context.pluginId;
		},
		".content .source" : "source",
		".content .intro" : "intro",
		".content .text" : function(arg){
			var text = arg.context.text;
			
			if(text.length > 300){
				text = text.substring(0, text.indexOf(" ", 290)) + " &hellip;";
			}
			
			if(arg.context.keywords){
				for(var k in arg.context.keywords){
					text = text.replace(new RegExp("(" + arg.context.keywords[k].replace(openParanthesesRegex, "\\(").replace(closeParanthesesRegex, "\\)") + ")", "gi"), "<em>$1</em>");
				}
			}
			text = text.replace(urlRegex,"<a class=\"url\" target=\"_blank\" href=\"$1\">$1</a>");
			return text;
		},
		".details .sportIcon[class]" : function(arg){
			return arg.context.event ? "sportIcon sporticon" + arg.context.event.sport.id : "";
		},
		".sport" : "event.sport.name",
		".sport[href]" : function(arg){
			return arg.context.event ? "https://www.bwin.com/betsnew.aspx?sportid=" + arg.context.event.sport.id + "&ShowDays=2147483647&Sorting=dateleague&ReferrerID=ECBDR2EB3VT9HJGY21" : "";
		},
		".location" : "event.location.name",
		".league" : "event.league.name",
		".league[href]" : function(arg){
			return arg.context.event ? "https://www.bwin.com/betsnew.aspx?leagueids=" + arg.context.event.league.id + "&ShowDays=2147483647&Sorting=dateleague&MarkAll=1&ReferrerID=ECBDR2EB3VT9HJGY21" : "";
		},
		".details .eventName" : "event.name",
		".details .eventName[href]" : function(arg){
			return arg.context.event ? "https://www.bwin.com/betsnew.aspx?EventID=" + arg.context.event.eventIds[0].id + "&ShowDays=2147483647&Sorting=dateleague&ReferrerID=ECBDR2EB3VT9HJGY21" : "";
		},
		".scoreboard .eventName" : "event.name",
		"a.tweet[onclick]" : function(arg){
			return  "rtb.tweet(" + (arg.context.pluginId.indexOf("twitter") >= 0 ? "'" + encode(arg.context.source) + "'" : "null") + ", '" + encode(arg.context.text) + "'); return false;";
		},
		"a.tweet[style]" : function(arg){
			return arg.context.pluginId == "serviceMessage" || arg.context.pluginId == "loadingMessage" ? "display: none;" : "";
		},
		".more[href]" : "url",
		".more[style]" : function(arg){
			return !arg.context.url || !arg.context.url.length > 0 ? "display: none;" : "";
		},
		".bet" : "game <- event.allGames",
		".gameName" : "game.name",
		".result" : "result <- game.results",
		".resultName" : function(arg){
			return arg.item.name.replace(paranthesesRegex, "");
		},
		".odds" : "result.odds",
		".result[onclick]" : function(arg){
			if(arg.context.event){
				return "rtb.placeBet('" + ( arg.context.event.live === true ? "live" : "non_live" ) + "', '" + arg.context.event.eventIds[0].id + "', " + arg.context.event.allGames[0].id + ", " + arg.item.id + ", " + arg.item.odds + "); return false;";
			}
		},
		".scoreboard[id]" : function(arg){
			if(arg.context.event){
				return "scoreBoard_" + arg.context.event.eventIds[0].id;
			}
		},
		".bet[id]" : function(arg){
			if(arg.context.event){
				return "bet_" + arg.context.event.eventIds[0].id;
			}
		},
		"a.pin[onclick]" : function(arg){
			if(arg.context.event){
				return "rtb.pin(this.parentNode, " + arg.context.event.eventIds[0].id + "); return false;";
			}
		},
		"a.pin[style]" : function(arg){
			return arg.context.event && arg.context.event.live === true ? "" : "display: none";
		}
	};

	var compiledDirective;
	if($('#templates .snip').length){
		compiledDirective  = $('#templates .snip').compile(snipDirective);
		$('#templates .snip').compile('snip', snipDirective, {});
	}


	var renderSnipResponse = function(response, animate){
		for(var s in response.snips){
			var snip = response.snips[s];
			if(snip.event){
				snip.event.allGames = [];
				snip.event.allGames = snip.event.allGames.concat(snip.event.liveGames);
				snip.event.allGames = snip.event.allGames.concat(snip.event.notLiveGames);
			}

			$("#stream").prepend($p.render('snip', snip));
			var firstSnip = $("#stream .snip:first");
			firstSnip.attr("class", "snip " + snip.pluginId + "Snip " + (snip.sport ? "sport" + snip.sport.id + "Snip" : ""));
			/*if(snip.image){
				var splittedUrl = snip.image.url.split("/");
				splittedUrl.pop();
				firstSnip.css("background-image", "url(" + splittedUrl.join("/") + "/300x" + firstSnip[0].clientHeight + ".jpg?center=0,0" + ")");
				$("#stream .snip:first .imageCredits").css("height", (firstSnip[0].clientHeight - 30) + "px");
				$("#stream .snip:first .imageCredits").attr("title", snip.image.caption + " © " + snip.image.copyright);
				$("#stream .snip:first .imageCredits").click(function(){window.open(snip.image.link);});
			}
			else {*/
				$("#stream .snip:first .imageCredits").remove();
			//}
			if(animate){
				firstSnip.hide();
				firstSnip.slideDown("slow");
			}
		}
	
		var existingSnips = $("#stream .snip");
		if( existingSnips.length > maxNumberOfSnips ) {
			for( var i = maxNumberOfSnips; i < existingSnips.length; i++ ) {
				if(!$(existingSnips[i]).hasClass("disappearing")){
					$(existingSnips[i]).addClass("disappearing");
					$(existingSnips[i]).hide(1000, function(){$(this).remove();});
				}
			}
		}
	};

	var renderImageResponse = function(response){
		for(var s in response.snips){
			var snip = response.snips[s];
			console.log(snip);
			if(snip.image){
				$("#stream").empty();

				var splittedUrl = snip.image.url.split("/");
				splittedUrl.pop();
				var imageUrl = splittedUrl.join("/") + "/1000x.jpg?fit=scale";

				var cacheImg = document.createElement("img");
				cacheImg.src = imageUrl;

				var img = $("<img>");
//				img.attr("height", window.innerHeight);
				img.attr("src", imageUrl);
				img.css("float", "left");
				$("#stream").append(img);
				var h1 = $("<h1>" + snip.text + "</h1>");
				$("#stream").append(h1);
			}
		}
	}

	function encode(string){
		string = encodeURIComponent(string);
		string = string.replace(new RegExp("'", "g"), "%27");
		return string;
	}

	function updateScoreBoard(response){
		if(response.getEventsIterator().hasNext()){
			var event = response.getEventsIterator().next();
			if(event){
				var pinnedEventElement = $("#pinnedStream .snip");
				if(event.live && event.live.games && event.live.games.length) {
					var game = event.live.games[0];
					$(".gameName", pinnedEventElement).html(game.name);
					$(".results", pinnedEventElement).empty();

					if(event.score_board){
						//time
						var formatedTime = "00:00";
						if(event.score_board.time > 0){
							var hours = Math.floor(event.score_board.time / 3600);
							var minutes = Math.floor(event.score_board.time / 60) % 60;
							var seconds = event.score_board.time % 60;
							formatedTime = (hours > 0 ? hours + ":" : "" ) + (minutes < 10 ? "0" : "") + minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
						}
						$(".time", pinnedEventElement).html(formatedTime);

						//period
						$(".period", pinnedEventElement).html(searchClient.getPeriodName(event.details.sports.id, event.score_board.period));
					
						$(".score", pinnedEventElement).html(searchClient.getScore(event.details.sports.id, event.score_board.period, event.score_board.scores));
					}

					//results
					var width;
					if(game.results.length <= 3){
						width = 90 / game.results.length;
					}else {
						width = 30;
					}
					for(var r in game.results){
						var result = game.results[r];
						$("<a/>", {
							href : "#",
							title : "bet on www.bwin.com",
							style : "width: " + width + "%",
							"class" : "result",
							click: function() {
								rtb.placeBet("live", "bwin_" + event.eventIds[0].id, game.id, result.id, result.odds);
								return false;
							}
						}).appendTo($(".results", pinnedEventElement));
						$(".result:last", pinnedEventElement).append($("<span class=\"odds\">" + result.odds + "</span>"));
						$(".result:last", pinnedEventElement).append($("<span class=\"resultName\">" + result.name + "</span>"));
					}
				}
			}
		}
	}

	function tweet(userName, text){
		var decodedText = decodeURIComponent(text);

		var hash = " #rtbwin";
		var rt = "";
		if(userName){
			rt = "RT " + decodeURIComponent(userName) + " ";
		}

		var maxLength = 140 - (hash.length + rt.length);
		if(decodedText.length > maxLength){
			decodedText = decodedText.substring(0, maxLength);
		}
		decodedText = rt + decodedText + hash;
		window.open("http://twitter.com/home?source=rtbwin&status=" + encode(decodedText));

		this.log("tweet", decodedText);
	}

	function placeBet(eventType, eventId, gameId, resultId, resultOdds){
		window.open(eventType != "live" ? "https://www.bwin.com/en/page.aspx?view=partnerfeed&ReferrerID=ECBDR2EB3VT9HJGY21&ResultIDs=" + resultId + "&GameIDs=" + gameId + "&ResultOdds=" + resultOdds + "&Stake=1&zoneid=20017" : "https://www.bwin.com/en/livebets.aspx?ReferrerID=ECBDR2EB3VT9HJGY21&eventID=" + eventId);
		this.log("placeBet", resultId);
	}

	function pin(element, eventId){
		if(element && eventId){
			$("#pinnedStream").empty();
			$("#pinnedStream").append(element);
			$("#pinnedStream .snip").attr("style", "");
			$("#pinnedStream .clear").remove();
			$("#unpin").show();
			pinnedEventId = eventId;
			this.getScoreBoardOfPinnedEvent();
		}
	}

	function unpin(){
		pinnedEventId = null;
		$("#pinnedStream").empty();
		$("#unpin").hide();
	}

	function getScoreBoardOfPinnedEvent(){
		var eventsUrl = "https://labs.bwin.com/rtb/rtb/events/";
		if(pinnedEventId){
			searchClient.search("event:bwin_" + pinnedEventId, {}, function(data){updateScoreBoard(data);setTimeout(function(){rtb.getScoreBoardOfPinnedEvent();}, 1000);});
//			$.ajax({"url":eventsUrl + pinnedEventId,cache:false,success:function(data){updateScoreBoard(data);setTimeout(function(){rtb.getScoreBoardOfPinnedEvent();}, 1000);},dataType:"jsonp"});
		}
	}

	function startSnipStream(){
		var snipsUrl = this.baseUrl + "rtb/snips";

		var successCallback = function(data){
			try{
				renderSnipResponse(data, true);
				if(data.snips && data.snips.length){
					emptyResponses = 0;
					$(".serviceMessageSnip").remove();
					$(".loadingMessageSnip").remove();
				} else {
					emptyResponses++;
					if(emptyResponses == 40){
						var explanations = ["Oh! No more content currently available, please wait a moment.", "Oh! There seems to be nothing going on - just wait a second.", "Oh! There seems to be nothing going on - a good moment to visit www.bwin.com"];
						renderSnipResponse({snips : [{text:explanations[Math.round(Math.random() * explanations.length - 1)], pluginId : "serviceMessage"}]}, true);
					}
				}
			}
			catch(e){
				if(console && console.log){
					console.log(e);
				}
			}
			getSnipsOrWaitFunction();
		};

		var errorCallback = function(){
			setTimeout(getSnipsFunction, 12000);
		};

		var getSnipsFunction = function(){
			if($(window).scrollTop() == 0){
				var data = {};
				$.ajax({"url":snipsUrl,cache:false,error:errorCallback,success:successCallback,dataType:"jsonp","data":data});
				lastGetSnipsFunctionCall = new Date().getTime();
			} else {
				setTimeout(getSnipsOrWaitFunction, 5000);
			}
		};

		var getSnipsOrWaitFunction = function(){
			var snipFetchInterval = 3000;
			if($(window).scrollTop() == 0){
				var timeSinceLastGetSnipsFunctionCall = new Date().getTime() - lastGetSnipsFunctionCall;
				if(lastGetSnipsFunctionCall == 0 || timeSinceLastGetSnipsFunctionCall >= snipFetchInterval){
					getSnipsFunction();
				}else {
					setTimeout(getSnipsFunction, snipFetchInterval - timeSinceLastGetSnipsFunctionCall);
				}
			}
			else {
				setTimeout(getSnipsOrWaitFunction, 5000);
			}
		};

		renderSnipResponse({snips : [{text:"Loading, please wait a second", pluginId : "loadingMessage"}]}, true);

		getSnipsFunction();
	}

	function startImageStream(){
		var snipsUrl = this.baseUrl + "rtb/snips";

		var successCallback = function(data){
			try{
				renderImageResponse(data, true);
			}
			catch(e){
				if(console && console.log){
					console.log(e);
				}
			}
			getImagesOrWaitFunction();
		};

		var errorCallback = function(){
			setTimeout(getImagesFunction, 12000);
		};

		var getImagesFunction = function(){
			if($(window).scrollTop() == 0){
				var data = {};
				$.ajax({"url":snipsUrl,cache:false,error:errorCallback,success:successCallback,dataType:"jsonp","data":data});
				lastGetSnipsFunctionCall = new Date().getTime();
			} else {
				setTimeout(getSnipsOrWaitFunction, 500);
			}
		};

		var getImagesOrWaitFunction = function(){
			var snipFetchInterval = 3000;
			if($(window).scrollTop() == 0){
				var timeSinceLastGetSnipsFunctionCall = new Date().getTime() - lastGetSnipsFunctionCall;
				if(lastGetSnipsFunctionCall == 0 || timeSinceLastGetSnipsFunctionCall >= snipFetchInterval){
					getImagesFunction();
				}else {
					setTimeout(getImagesFunction, snipFetchInterval - timeSinceLastGetSnipsFunctionCall);
				}
			}
			else {
				setTimeout(getSnipsOrWaitFunction, 500);
			}
		};

		getImagesFunction();
	}


	function loadLandingPage(sportId){
		$.ajax({"url":this.baseUrl + "rtb/landingPages/" + sportId,cache:false,success:function(data){renderSnipResponse(data, false);},dataType:"jsonp"});
	}

	return {
		log : function(){//TODO
		},
		init: function(baseUrl) {
			this.baseUrl = baseUrl;
			return this;
		},
		"startSnipStream" : startSnipStream,
		"startImageStream" : startImageStream,
		"tweet" : tweet,
		"placeBet" : placeBet,
		"pin" : pin,
		"unpin" : unpin,
		"getScoreBoardOfPinnedEvent" : getScoreBoardOfPinnedEvent,
		"loadLandingPage" : loadLandingPage
	};
}