/* Global */
/***********/
var minimumDigit=0;
var minimumCharacterCode='A'.charCodeAt(0);
var maximumDigit=9;
var maximumCharacterCode='Z'.charCodeAt(0);
var ticketPrice=2.0;
var daysOfWeek=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
var defaultBlockUITimeout=3000;

/* Stores the widget controllers, where applicable. */
/****************************************************/
var _widgets={basket : new BasketWidget()};

/* Init events - fired on body load */
/************************************/
$(function(){
	// Up/Down arrow controls
	$(".up").data("action",increment).click(modifyFieldValue);
	$(".down").data("action",decrement).click(modifyFieldValue);

	// Ticket number entry boxes
	$("input.number").data("modify",modifyNumericField).data("generate",setRandomNumber).keyup(validateKeypressOnNumericField);
	$("input.character").data("modify",modifyCharacterField).data("generate",setRandomCharacter).keyup(validateKeypressOnCharacterField);

	// Kill default blockUI styling
	$.blockUI.defaults.css={};

	$(".fields input").focus(selectContents);
	$(".pick").click(doPickRandomly);
	$(".clear").click(doClearRow);
	$("#row_1 .pick").click();
	$('.add_to_cart').click(_lottery.addticket);
	$('.play').click(_lottery.play);
	$(".unblock").click(_lottery.unblock);
	$(".quick_play_now").click(_lottery.buyTicketImmediate);
	$(".ticketList .remove").click(_lottery.removeTicket);
	if(0!==uid) _widgets.basket.refresh();
	_lottery.updateJackpotData();
});

function increment(value,minimum,maximum){ return (++value>maximum||isNaN(value))?minimum:value; }
function decrement(value,minimum,maximum){ return (--value<minimum||isNaN(value))?maximum:value; }
function modifyCharacterField(field,process){
	fieldValue=field[0].value.charCodeAt(0);
	newValue=process(fieldValue,minimumCharacterCode,maximumCharacterCode);
	field[0].value=String.fromCharCode(newValue);
}
function modifyNumericField(field,process){
	fieldValue=field[0].value;
	newValue=process(fieldValue,minimumDigit,maximumDigit);
	field[0].value=newValue;
}
function validateLotteryField(field,pattern){ return field.value.match(pattern); }
function focusNext(current){
	node=$(current).parents(".fields li").next();
	if(node[0]) $("input",node).focus();
}
function getRandom(min,max){ return Math.floor(Math.random()*(max-min+1))+min; }
function setRandomNumber(field){ field[0].value=getRandom(minimumDigit,maximumDigit); }
function setRandomCharacter(field){ field[0].value=String.fromCharCode(getRandom(minimumCharacterCode,maximumCharacterCode)); }
function setRandomValue(){
	$(this).data("generate")($(this));
}
function fetchTicketNumber(rowId){
	var tickNo="";
	//        $('#' + rowId + ' .fields input').each(function(){
	//            if (this.value && this.value != "")
	//                tickNo += this.value;
	//        });
	/* 5 digit hack
	 * Reads and appends all numeric fields, appends 0, then reads and appends the letters.*/
	$('#'+rowId+' .fields input.number').each(function(){
		if(this.value&&""!=this.value)
			tickNo+=this.value;
	});
	tickNo+='0';
	$('#'+rowId+' .fields input.character').each(function(){
		if(this.value&&""!=this.value)
			tickNo+=this.value;
	});
	return tickNo;
}
function doPickRandomly(){
	ticket=$(this).parents(".ticket");
	fields=$(".fields",ticket);
	$("input",fields).each(setRandomValue);
}
function doClearRow(){
	ticket=$(this).parents(".ticket");
	fields=$(".fields",ticket);
	$("input",fields).each(function(){ this.value=""; });
}
function selectContents(){ $(this).select(); }
function validateKeypressOnNumericField(e){
	if(validateLotteryField(this,/[0-9]/)){
		if(9!=e.keyCode)
			focusNext(this);
	}
	else
		this.value="";
}
function validateKeypressOnCharacterField(e){
	if(validateLotteryField(this,/[A-Z]/i)){
		if(9!=e.keyCode){
			this.value=this.value.toUpperCase();
			focusNext(this);
		}
	}
	else{
		this.value="";
	}
}
function modifyFieldValue(){
	var control=$(this);
	var field=$("input",control.parent());
	var process=field.data("modify")(field,control.data("action"));
}
/*
 * Provides support for the basket widget.
 * This object currently only manages the count of purchased tickets. The count of tickets in
 * the cart is maintained separately.
 * TODO: Add support for the count of tickets in the cart.
 */
function BasketWidget(){
	var basket=$(".basket");
	var pendingTickets=$(".purchased",basket);
	var pendingTicketCount=$(".count",pendingTickets);

	/**
	 * Prepares and calls the asynch request for updates.
	 */
	function countTicketsForNextLottery(){
		var data={type: "pending", offset: 0, length: 1000000};
		doRequest(data,updateDisplay);
	}

	/**
	 * Populates the number of pending tickets, and hides the count if it is empty.
	 * @param data A JSON array of tickets.
	 */
	function updateDisplay(data){
		var numberOfPendingTickets=data.length;
		pendingTicketCount.text(numberOfPendingTickets);
		if(0<numberOfPendingTickets)
			pendingTickets.show();
		else
			pendingTickets.hide();
	}

	/**
	 * Fires an asynchronous request to player-tickets.
	 * @param data The arguments to pass to player-tickets.
	 * @param callback The method to call on return. This should accept a JSON array of tickets.
	 */
	function doRequest(data,callback){
		$.ajax({
			dataType: "json",
			url: $("base").attr("href")+"/player-tickets",
			type: "GET",
			data: data,
			cache: true,
			success: callback
		});
	}

	/**
	 * Reloads the count of pending tickets (tickets which have been purchased, but not played)
	 * and updates the pending ticket counter.
	 */
	this.refresh=function(){
		pendingTicketCount.text("...");
		countTicketsForNextLottery();
	}
}
var _lottery={

	userBalance : 0,

	play : function(){
		var action=(_lottery.validateForQuickPlay())?_lottery.buyTicketImmediate:_lottery.addticket;
		action();
	},

	request : function(param,callback){
		$.ajax({
			type: "GET",
			url: "/otto-portal/flashdata",
			data: param,
			dataType:'json',
			contentType: "application/json; charset=utf-8",
			success: callback
		});
	},
	validateForQuickPlay:function(){
		if(0===uid)return;
		var tickets=_lottery.getValidTickets();
		var numberOfTickets=tickets.length;
		var basketValue=numberOfTickets*ticketPrice;
		return (0<numberOfTickets&&(
				_player.availableBalance()>=basketValue||_player.freeTicketBalance()>=numberOfTickets));
	},
	updateJackpotData : function(){
		this.request({jackpotcounterdata:1},function(data){
			$('.value').html('&euro; '+data.currentJackpotSizeHtml.replace(/\./g,","));
			var drawingTime=new Date(data.drawingTimeAsLong);
			var now=new Date();
			var difference=drawingTime.getTime()-now.getTime();
			// 1 day (ms * s * min * h)
			var day=1000*60*60*24;
			if(drawingTime.getDate()==now.getDate()&&drawingTime.getMonth()==now.getMonth()&&drawingTime.getYear()==now.getYear())
				$("#next_draw_message").text("Today at 20:00 CET"); else if(difference<=day)
				$("#next_draw_message").text("Tomorrow at 20:00 CET");
			else
				$("#next_draw_message").text(daysOfWeek[drawingTime.getDay()]+" at 20:00 CET");
		});
	},
	getValidTickets : function(){
		var ticket1=fetchTicketNumber("row_1");
		var ticket2=fetchTicketNumber("row_2");
		var ticket3=fetchTicketNumber("row_3");
		var tickets=Array();
		if(8==ticket1.length) tickets.push(ticket1);
		if(8==ticket2.length) tickets.push(ticket2);
		if(8==ticket3.length) tickets.push(ticket3);
		return tickets;
	},
	getValidTicketCount : function(){
		return _lottery.getValidTickets().length;
	},
	addticket : function(){
		// block out user interface
		$.blockUI(".ot_lottery .game_container");

		// check ticket validity
		var tickets=_lottery.getValidTickets();
		if(1>tickets.length){
			$.blockUI({message:"No valid tickets specified!"});
			setTimeout($.unblockUI,defaultBlockUITimeout);
		}
		else{
			_lottery.request({
				uid:uid,
				addticket:true,
				groupid:0,
				groupname:'General OTTO ticket',
				ticketnumber:tickets,
				numberofdrawings:1
			},_lottery.onResponse);
			var popupHtml="";
			var basketHtml="";
			for(var i=0; i<tickets.length; i++){
				popupHtml+="<span class='selection'>"+tickets[i].replace(/^(\d{5})\d([A-Z]{2})$/,"$1$2")+"</span>";
				if(i<tickets.length-1) popupHtml+=", ";
			}
			var ticketsInBasket=parseInt($(".number_of_tickets").text());
			if(isNaN(ticketsInBasket))
				ticketsInBasket=0;
			$(".number_of_tickets").text(ticketsInBasket+tickets.length);
			$(".basket .ticketList ul").data("nextbatch",basketHtml);
			$(".ticketnumber").html(popupHtml);
		}
	},

	buyTicketImmediate : function(){
		$.blockUI({message: "Buying tickets, please wait"});
		var tickets=_lottery.getValidTickets();
		if(1>tickets.length){
			$.blockUI({message:"No valid tickets specified!"});
			setTimeout($.unblockUI,3000);
			return;
		}
		_lottery.request({
			uid:uid,
			oneClickBuy:true,
			ticketnumber:tickets,
			numberofdrawings:1
		},_lottery.onImmediateBuyResponse);
	},

	onImmediateBuyResponse : function(response){
		if(null!==response.result.tickets&&response.result.tickets.constructor==Array){
			$.blockUI({
				message:$("#play_quick_complete").parent().html(), css: {
					border:'2px solid black',
					width:'370px',
					height:'120px'
				}
			});
		}
		else{
			$.blockUI({
				message:$("#play_quick_fail").parent().html(), css: {
					border:'2px solid black',
					width:'370px',
					height:'120px'
				}
			});
		}
		_widgets.basket.refresh();
		refreshMemberDisplay();
		$(".blockUI .unblock").click($.unblockUI);
	},

	onResponse : function(response){

		// If the cart widget is present, update it.
		var ticketsAddedDisplay=$($(".basket .ticketList ul").data("nextbatch"));
		$(ticketsAddedDisplay).append("<span class='remove' title='Remove this ticket from basket'>x</span>");
		$(".remove",ticketsAddedDisplay).click(_lottery.removeTicket);
		$(".basket .ticketList ul").prepend(ticketsAddedDisplay);
		$(".basket .ticketList").show();
		$(".basket .noTickets").hide();
		if("undefined"==typeof(playerBalance))
			playerBalance=0.0;
		$.unblockUI(".ot_lottery .game_container");
		if("OK"==response.result){
			var isSignedIn=0!==uid;
			var panel=isSignedIn?"#play_signed":"#play_not_signed";
			$.blockUI({message:$(panel).parent().html()});
			$(".blockUI .unblock").click($.unblockUI);
		}
		else{
			alert("There has been an error adding your ticket to the basket");
		}
	},

	unblock : function(){
		$.unblockUI();
	},

	removeTicket : function(){
		var row=$(this).parent();
		row.remove();
		if(0===$('.basket .ticketList li').length){
			$(".basket .ticketList").hide();
			$(".basket .noTickets").show();
		}
		$.ajax({
			type: "GET",
			url: "/otto-portal/flashdata",
			data: {
				uid:uid,
				removeticket:true,
				groupid:0,
				groupname:'General OTTO ticket',
				ticketnumber:$(".selection",row).text(),
				numberofdrawings:1
			},
			dataType:'json',
			contentType: "application/json; charset=utf-8",
			success:onRemove
		});
	}
};
function onRemove(data){
	// Add any behaviour to do on server confirmation here.
}
function format(nStr){
	nStr+='';
	x=nStr.split('.');
	x1=x[0];
	x2=1<x.length?'.'+x[1]:'';
	var rgx=/(\d+)(\d{3})/;
	while(rgx.test(x1)){
		x1=x1.replace(rgx,'$1'+','+'$2');
	}
	x2+=((3>x2.length)?'0':'');
	return x1+x2[0]+x2[1]+x2[2];
}
