/*
	Config
*/
var votingOptions = {
	// url
	voteUrl: '/dinamiche/Vote',
	//getVotingUrlTemplate: new Template('/dinamiche/GetVote?cti=#{cti}&cii=#{cii}'),
	getVotingUrlTemplate: new Template('/dinamiche/cached/getVote.jsp?cti=#{cti}&cii=#{cii}'),
	
	// html ids and classnames
	optionYesClass: 'out_Vote_Si',
	optionNoClass: 'out_Vote_No',
	countYesClass: 'count_Vote_Si',
	countNoClass: 'count_Vote_No',
	textVotingClass: 'txt_Thanks',
	optionYesClassMcn: 'OptionYes',
	optionNoClassMcn: 'OptionNo',
	
	// update voting statistics every N seconds (-1 to disable)
	updateInterval: -1,
	
	// cookie name
	cookieNameTemplate: new Template('ts_voto_#{cti}_#{cii}'),
	
	// cookie expire time in milliseconds
	cookieExpireTime: 5 * 60 * 1000,
	
	// messages
	afterVotingMsg: "Grazie per aver votato",	
	afterVoting2LinesMsg: "Grazie per<br/>aver votato"	
};

var pollingOptions = {
	// url
	pollUrl: '/dinamiche/Poll',
	getPollUrlTemplate: new Template('/sondaggi/ris_#{pi}.json'),

	// html ids and classnames
	totaleVotiId: 'poll_totale',
	precentageIdTemplate: new Template('poll_perc_#{pi}_#{ai}'),
	barIdTemplate: new Template('poll_bar_#{pi}_#{ai}'),
	formIdTemplate: new Template('form_sondaggio_#{pi}'),
	errorIdTemplate: new Template('error_sondaggio_#{pi}'),
	btnVotaIdTemplate: new Template('btn_poll_vota_#{pi}'),
	radioInputName: 'ai',
	
	// bar max length (in pixels)
	barMaxLength: 310,

	// update polling statistics every N seconds (-1 to disable)
	updateInterval: 60,
	
	// cookie name
	cookieNameTemplate: new Template('ts_poll_#{pi}'),
	
	// cookie expire time in milliseconds
	cookieExpireTime: 5 * 60 * 1000,
	
	// messages
	thanksForVotingMsg: "Grazie per aver votato.<br/>Il tuo voto sar\u00e0 conteggiato entro 3 minuti",
	noAnswerSelectedMsg: "Selezionare una risposta del sondaggio",
	alreadyVotedMsg: "Attenzione! Hai gi\u00e0 votato per questo sondaggio"
};

/*
	Class Voting
*/
var Voting = Class.create();
Voting.prototype = {
	initialize: function (contentTypeId, contentItemId, divElmId, readOnly, mcn) {
		this.options = votingOptions;
		this.updater = null;
		this.overloadedTypeId = null;
		this.overloadedItemId = null;
		
		if (contentTypeId != undefined && contentItemId != undefined && divElmId != undefined) {
			this.apply(contentTypeId, contentItemId, divElmId, readOnly, mcn);
		}
	},
	
	overload: function (contentTypeId, contentItemId) {
		this.overloadedTypeId = contentTypeId;
		this.overloadedItemId = contentItemId;
	},
	
	apply: function (contentTypeId, contentItemId, divElmId, readOnly, mcn) {
		this.contentTypeId = contentTypeId;
		this.contentItemId = contentItemId;
		this.divElm = $(divElmId);
		this.mcn = mcn;
		
		if (!this.divElm) {
			return;
		}
		
		this.optionYesElm = this.divElm.getElementsByClassName(this.mcn ? this.options.optionYesClassMcn : this.options.optionYesClass)[0];
		this.optionNoElm = this.divElm.getElementsByClassName(this.mcn ? this.options.optionNoClassMcn : this.options.optionNoClass)[0];
		this.countYesElm = this.divElm.getElementsByClassName(this.options.countYesClass)[0];
		this.countNoElm = this.divElm.getElementsByClassName(this.options.countNoClass)[0];
		
		var elms = this.divElm.getElementsByClassName(this.options.textVotingClass);
		if (elms.length > 0) {
			this.liTextElm = elms[0];
		} else {
			this.liTextElm = null;
		}
		
		this.getVotingUrl = this.options.getVotingUrlTemplate.evaluate({
			cti: this.contentTypeId,
			cii: this.contentItemId
		});
				
		this.noAnchor = true;
		this.voting = false;
		this.yesCount = 0;
		this.noCount = 0;
		this.yesVoteHandler = null;
		this.noVoteHandler = null;
		
		// min vote count = at the time when user votes (we add one for his vote, should not decrease)
		this.minYesCount = 0;
		this.minNoCount = 0;
		
		if (readOnly) {
			this.vote = 'n/a';
		} else {
			this.vote = null;
		}
		this.getUserVote();		
		this.updateVoting(true);
		
		if (this.options.updateInterval > 0 && this.updater == null) {
			this.updater = 
				new PeriodicalExecuter(this.updateVoting.bind(this), this.options.updateInterval);
		}
	},
	
	updateVoting: function (initialize) {
		if (this.voting) return;
		
		new Ajax.Request(this.getVotingUrl, {
			method: 'get',
			onSuccess: function (transport) {
				eval(transport.responseText); // defines votes
				if (votes.ok) {
					if (votes.yesCount > this.minYesCount) {
						this.yesCount = votes.yesCount;
					}
					if (votes.noCount > this.minNoCount) {
						this.noCount = votes.noCount;
					}
					this.draw();
				}
			}.bind(this),
			onFailure: function () {
				if (initialize) {
					this.draw();
				}
			}.bind(this)
		});
	},
	
	doVote: function (userVote) {
		if (this.voting) return;		
		this.voting = true;
		
		var params = $H({
			cti: this.contentTypeId,
			cii: this.contentItemId,
			vote: userVote
		});

		if (this.overloadedTypeId) {
			params = params.merge({
				cti2: this.overloadedTypeId,
				cii2: this.overloadedItemId
			}); 
		}
		
		new Ajax.Request(this.options.voteUrl, {
			parameters: params,
			onSuccess: function (transport) {
				eval(transport.responseText); // defines votes
				if (votes.ok) {
					this.vote = userVote
					if (this.vote == 'yes') {
						this.minYesCount = this.yesCount + 1;
						this.yesCount = this.yesCount + 1;
					} else if (this.vote == 'no') {
						this.minNoCount = this.noCount + 1;
						this.noCount = this.noCount + 1;
					}
					this.draw();
					this.setCookie();
				} else if (votes.duplicate) {
					this.vote = 'n/a';
					this.draw();
				}
			}.bind(this),
			onComplete: function () {
				this.voting = false;
			}.bind(this)
		}); 
	},
	
	getUserVote: function () {
		var cookieName = this.options.cookieNameTemplate.evaluate({
			cti: this.contentTypeId,
			cii: this.contentItemId
		});
		
		var regexp = new RegExp(cookieName + '=([^ ;]+)');
		var result = regexp.exec(document.cookie);
		
		if (result == null) {
			return null;
		}
		
		var temp = result[1].split("_");

		if (temp.length >= 1) {
			this.vote = temp[0];
			
			var voteCount = 1;
			try {
				voteCount = parseInt(temp[1]);
			} catch (e) {}
			
			if (this.vote == 'yes') {
				this.yesCount = voteCount;
				this.minYesCount = voteCount;
			} else if (this.vote == 'no') {
				this.noCount = voteCount;
				this.minNoCount = voteCount;
			}
		}
	},
	
	setCookie: function () {
		var cookieName = this.options.cookieNameTemplate.evaluate({
			cti: this.contentTypeId,
			cii: this.contentItemId
		});
		
		var expireDate = new Date();
		expireDate.setTime(expireDate.getTime() + this.options.cookieExpireTime);
		
		var cookieValue = this.vote;
		if (this.vote == 'yes') {
			cookieValue += '_' + this.yesCount;
		} else if (this.vote == 'no') {
			cookieValue += '_' + this.noCount;
		} 
		
		document.cookie = cookieName + '=' + cookieValue + '; expires=' + expireDate.toGMTString();  
	},
	
	draw: function () {
		if (this.mcn) {
			var yesTrg = this.optionYesElm;
			var noTrg = this.optionNoElm;
			
			if (this.vote == null) {
				if (this.noAnchor) {
					this.optionYesElm.innerHTML = '<a href="javascript:;" title="SI"></a>';				
					this.optionNoElm.innerHTML = '<a href="javascript:;" title="NO"></a>';
				}
			
				yesTrg = this.optionYesElm.firstDescendant();
				noTrg = this.optionNoElm.firstDescendant();
				
				if (this.noAnchor) {
					this.yesVoteHandler = this.doVote.bind(this, 'yes');
					this.noVoteHandler = this.doVote.bind(this, 'no');
					Event.observe(yesTrg, 'click', this.yesVoteHandler);
					Event.observe(noTrg, 'click', this.noVoteHandler);
				}
				
				this.noAnchor = false;
			} else {
				if (this.yesVoteHandler != null) {
					Event.stopObserving(this.optionYesElm.firstDescendant(), 'click', this.yesVoteHandler);
					this.yesVoteHandler = null;
				}
				if (this.noVoteHandler != null) {
					Event.stopObserving(this.optionNoElm.firstDescendant(), 'click', this.noVoteHandler);
					this.noVoteHandler = null;
				}

				this.optionYesElm.innerHTML = '<div></div>';				
				this.optionNoElm.innerHTML = '<div></div>';

				yesTrg = this.optionYesElm.firstDescendant();
				noTrg = this.optionNoElm.firstDescendant();
				
				this.noAnchor = true;
			}
			
			yesTrg.innerHTML =
				'<span class="box_Ico">S\u00ec</span> <span>' + this.yesCount + '</span>';
			noTrg.innerHTML =
				'<span class="box_Ico">No</span> <span>' + this.noCount + '</span>';
					
			if (this.vote != null) {
				if (this.liTextElm) {
					if (this.liTextElm.hasClassName('two_lines')) {
						this.liTextElm.innerHTML = this.options.afterVoting2LinesMsg;
					} else {
						this.liTextElm.innerHTML = this.options.afterVotingMsg;
					}
				}
				
				if (this.vote == 'yes') {
					this.optionYesElm.addClassName('selected');
					this.optionNoElm.removeClassName('selected');
				} else if (this.vote == 'no') {
					this.optionNoElm.addClassName('selected');
					this.optionYesElm.removeClassName('selected');
				}
			}
		} else {
			if (this.vote == null) {
				if (this.noAnchor) {
					this.optionYesElm.innerHTML = '<a href="javascript:;" class="link_Vote_Si" title="Si">Si</a>';				
					this.optionNoElm.innerHTML = '<a href="javascript:;" class="link_Vote_No" title="No">No</a>';
					this.yesVoteHandler = this.doVote.bind(this, 'yes');
					this.noVoteHandler = this.doVote.bind(this, 'no');
					Event.observe(this.optionYesElm.firstDescendant(), 'click', this.yesVoteHandler);
					Event.observe(this.optionNoElm.firstDescendant(), 'click', this.noVoteHandler);
					this.noAnchor = false;
				}
			} else {
				if (!this.noAnchor) {
					if (this.yesVoteHandler != null) {
						Event.stopObserving(this.optionYesElm.firstDescendant(), 'click', this.yesVoteHandler);
						this.yesVoteHandler = null;
					}
					if (this.noVoteHandler != null) {
						Event.stopObserving(this.optionNoElm.firstDescendant(), 'click', this.noVoteHandler);
						this.noVoteHandler = null;
					}
					this.optionYesElm.innerHTML = '<span class="link_Vote_Si">Si</span>';				
					this.optionNoElm.innerHTML = '<span class="link_Vote_No">No</span>';
					this.noAnchor = true;
				}

				if (this.liTextElm) {
					if (this.liTextElm.hasClassName('two_lines')) {
						this.liTextElm.innerHTML = this.options.afterVoting2LinesMsg;
					} else {
						this.liTextElm.innerHTML = this.options.afterVotingMsg;
					}
				}
				
				if (this.vote == 'yes') {
					this.optionYesElm.firstDescendant().addClassName('vote_Selected');
					this.optionNoElm.firstDescendant().removeClassName('vote_Selected');
				} else if (this.vote == 'no') {
					this.optionNoElm.firstDescendant().addClassName('vote_Selected');
					this.optionYesElm.firstDescendant().removeClassName('vote_Selected');
				}
			}
			
			this.countYesElm.innerHTML = this.yesCount;
			this.countNoElm.innerHTML = this.noCount;
		}
	}
}

/*
	Class Poll
*/
var Poll = Class.create();
Poll.prototype = {
	initialize: function (pollId, results, voteUrl, resultsUrl) {
		this.options = pollingOptions;
		this.pollId = pollId;
		
		this.results = results;
		this.updater = null;
		
		this.getPollUrl = this.options.getPollUrlTemplate.evaluate({
			pi: this.pollId
		});
		this.resultsUrl = resultsUrl;
		this.voteUrl = voteUrl;

		this.formId = this.options.formIdTemplate.evaluate({
			pi: this.pollId
		});
		this.errorId = this.options.errorIdTemplate.evaluate({
			pi: this.pollId
		});
		this.btnVotaId = this.options.btnVotaIdTemplate.evaluate({
			pi: this.pollId
		});
		
		if (this.results) {
			this.updatePoll();
			
			if (this.options.updateInterval > 0) {
				this.updater = 
					new PeriodicalExecuter(this.updatePoll.bind(this), this.options.updateInterval);
			}
		} else {		
			this.radioInput = $A($(this.formId)[this.options.radioInputName]);
			Event.observe(this.btnVotaId, 'click', this.doVote.bind(this));
		}
		
		if ($(this.errorId)) {
			var params = document.location.href.toQueryParams();
			if (params.ok) {
				this.showError(this.options.thanksForVotingMsg, true);
			} else if (params.na) {
				this.showError(this.options.noAnswerSelectedMsg);
			} else if (params.sv) {
				this.showError(this.options.alreadyVotedMsg);
			}
		}
	},
	
	updatePoll: function () {
		new Ajax.Request(this.getPollUrl, {
			onSuccess: function (transport) {
				eval(transport.responseText); // defines polls
				this.polls = polls;
				this.draw();
			}.bind(this)
		});
	},
	
	draw: function () {
		var totalVotes = 0;
		this.polls.answers.pluck('count').each(function (count) {
			totalVotes += count;
		});
		
		$(this.options.totaleVotiId).innerHTML = "" + totalVotes;
		
		this.polls.answers.each(function (answer) {
			if (totalVotes == 0) {
				answer.perc = 0;
			} else {
				answer.perc = Math.round(1000 * answer.count / totalVotes) / 10;
			}
			
			var percId = this.options.precentageIdTemplate.evaluate({ 
				pi: this.pollId,
				ai: answer.answerId
			});
			var barId = this.options.barIdTemplate.evaluate({ 
				pi: this.pollId,
				ai: answer.answerId
			});
			
			$(percId).innerHTML = answer.perc + '%';
			$(barId).style.width = (answer.perc * this.options.barMaxLength / 100) + 'px';
		}.bind(this));		
	},

	setCookie: function (value) {
		var cookieName = this.options.cookieNameTemplate.evaluate({
			pi: this.pollId
		});
		
		var expireDate = new Date();
		expireDate.setTime(expireDate.getTime() + this.options.cookieExpireTime);
		
		document.cookie = cookieName + '=' + value + '; expires=' + expireDate.toGMTString();  
	},

	// return true on ok (no cookie)
	checkCookie: function () {
		var cookieName = this.options.cookieNameTemplate.evaluate({
			pi: this.pollId
		});
		
		var regexp = new RegExp(cookieName + '=([^ ;]+)');
		var result = regexp.exec(document.cookie);
		
		return result == null;
	},
	
	doVote: function () {
		if (this.voting) return;		
		this.voting = true;
		
		var vote = this.radioInput.find(function (radio) { return radio.checked; });

		if (!vote) {
			if ($(this.errorId)) {
				this.showError(this.options.noAnswerSelectedMsg);
			} else {
				document.location.href = this.voteUrl + "?na=true";
			}
			this.voting = false;
			return;
		}
		
		if (!this.checkCookie()) {
			document.location.href = this.resultsUrl + "?sv=true";
			this.voting = false;
			return;
		}
		
		new Ajax.Request(this.options.pollUrl, {
			parameters: {
				pi: this.pollId,
				ai: vote.value
			},
			onSuccess: function (transport) {
				eval(transport.responseText); // defines poll
				if (poll.ok || poll.duplicate) {
					this.setCookie(vote.value);
					document.location.href = this.resultsUrl + "?ok=true";
				}
			}.bind(this),
			onComplete: function () {
				this.voting = false;
			}.bind(this)
		});
	},
	
	showError: function (msg, ok) {
		if (ok) {
			$(this.errorId).className = "txt_Info";
		} else {
			$(this.errorId).className = "txt_Error";
		}
		$(this.errorId).innerHTML = msg;
		$(this.errorId).show();
		$(this.errorId).scrollTo();
	}
};
