/*
	Config
*/
var votingOptions = {
	// url
	voteUrl: '/dinamiche/Vote',
	//getVotingUrlTemplate: new Template('/dinamiche/GetVote?cti=#{cti}&cii=#{cii}'),
	//getVotingUrlTemplate: new Template('/voting/#{cti}/#{cti}_#{cii}.json'),
	getVotingUrlTemplate: new Template('/dinamiche/cached/getVote.jsp?cti=#{cti}&cii=#{cii}'),
	
	// html ids and classnames
	optionYesClass: 'OptionYes',
	optionNoClass: 'OptionNo',
	textVotingClass: 'text_Voting',
	
	// update voting statistics every N seconds (-1 to disable)
	updateInterval: -1,
	
	// cookie name
	cookieNameTemplate: new Template('cds_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'),
	resultsUrlTemplate: new Template('/Sondaggi/Risultati/#{category}/#{pi}/#{title}'),
	voteUrlTemplate: new Template('/Sondaggi/Vota/#{category}/#{pi}/#{title}'),

	// html ids and classnames
	totaleVotiId: 'poll_totale',
	precentageIdTemplate: new Template('poll_perc_#{ai}'),
	barIdTemplate: new Template('poll_bar_#{ai}'),
	formId: 'formSondaggio',
	radioInputName: 'ai',
	btnVotaId: 'btn_poll_vota',
	
	// bar max length (in pixels)
	barMaxLength: 200,

	// update polling statistics every N seconds (-1 to disable)
	updateInterval: -1,
	
	// cookie name
	cookieNameTemplate: new Template('cds_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, ulElmId, readOnly, mcn) {
		this.options = votingOptions;
		this.updater = null;
		this.overloadedTypeId = null;
		this.overloadedItemId = null;
		
		if (contentTypeId != undefined && contentItemId != undefined && ulElmId != undefined) {
			this.apply(contentTypeId, contentItemId, ulElmId, readOnly, mcn);
		}
	},
	
	overload: function (contentTypeId, contentItemId) {
		this.overloadedTypeId = contentTypeId;
		this.overloadedItemId = contentItemId;
	},
	
	apply: function (contentTypeId, contentItemId, ulElmId, readOnly, mcn) {
		this.contentTypeId = contentTypeId;
		this.contentItemId = contentItemId;
		this.ulElm = $(ulElmId);
		this.mcn = mcn;
		
		if (!this.ulElm) {
			return;
		}
		
		this.liOptionYesElm = this.ulElm.getElementsByClassName(this.options.optionYesClass)[0];
		this.liOptionNoElm = this.ulElm.getElementsByClassName(this.options.optionNoClass)[0];
		
		var elms = this.ulElm.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 () {
		var yesTrg = this.liOptionYesElm;
		var noTrg = this.liOptionNoElm;
		
		if (this.vote == null) {
			if (this.noAnchor) {
				this.liOptionYesElm.innerHTML = '<a href="javascript:;" title="SI"></a>';				
				this.liOptionNoElm.innerHTML = '<a href="javascript:;" title="NO"></a>';
			}
		
			yesTrg = this.liOptionYesElm.firstDescendant();
			noTrg = this.liOptionNoElm.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.liOptionYesElm.firstDescendant(), 'click', this.yesVoteHandler);
				this.yesVoteHandler = null;
			}
			if (this.noVoteHandler != null) {
				Event.stopObserving(this.liOptionNoElm.firstDescendant(), 'click', this.noVoteHandler);
				this.noVoteHandler = null;
			}

			this.liOptionYesElm.innerHTML = '<div></div>';				
			this.liOptionNoElm.innerHTML = '<div></div>';

			yesTrg = this.liOptionYesElm.firstDescendant();
			noTrg = this.liOptionNoElm.firstDescendant();
			
			this.noAnchor = true;
		}
		
		if (this.mcn) {
			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>';
		} else {
			yesTrg.innerHTML =
				'<span class="VotoNumber">' + this.yesCount + '</span>&nbsp;' +
				'<span class="VotoOption">SI</span>';
			noTrg.innerHTML =
				'<span class="VotoOption">NO</span>&nbsp;' +
				'<span class="VotoNumber">' + this.noCount + '</span>';
		}
				
		if (this.vote != null) {
			if (this.liTextElm) {
				if (this.liTextElm.hasClassName('two_lines')) {
					this.liTextElm.innerHTML = this.options.afterVoting2LinesMsg;
					this.liTextElm.setStyle({ 'line-height': '12px' });
				} else {
					this.liTextElm.innerHTML = this.options.afterVotingMsg;
				}
			}
			
			if (this.vote == 'yes') {
				this.liOptionYesElm.addClassName('selected');
				this.liOptionNoElm.removeClassName('selected');
			} else if (this.vote == 'no') {
				this.liOptionNoElm.addClassName('selected');
				this.liOptionYesElm.removeClassName('selected');
			}
		}
	}
}

/*
	Class Poll
*/
var Poll = Class.create();
Poll.prototype = {
	initialize: function (pollId, results, category, title) {
		this.options = pollingOptions;
		this.pollId = pollId;
		
		this.results = results;
		this.updater = null;
		
		this.getPollUrl = this.options.getPollUrlTemplate.evaluate({
			pi: this.pollId
		});
		this.resultsUrl = this.options.resultsUrlTemplate.evaluate({
			pi: this.pollId,
			category: category,
			title: title
		});
		this.voteUrl = this.options.voteUrlTemplate.evaluate({
			pi: this.pollId,
			category: category,
			title: title
		});

		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.options.formId)[this.options.radioInputName]);
			Event.observe(this.options.btnVotaId, 'click', this.doVote.bind(this));
		}
		
		if ($('error_sondaggio')) {
			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({ 
				ai: answer.answerId
			});
			var barId = this.options.barIdTemplate.evaluate({ 
				ai: answer.answerId
			});
			
			try {
				$(percId).innerHTML = answer.perc + '%';
				$(barId).style.width = (answer.perc * this.options.barMaxLength / 100) + 'px';
			}
			catch(ex) {}
		}.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 ($('error_sondaggio')) {
				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) {
			$('error_sondaggio').className = "MessageINFO";
		} else {
			$('error_sondaggio').className = "MessageERROR";
		}
		$('error_sondaggio').innerHTML = msg;
		$('error_sondaggio').show();
		$('error_sondaggio').scrollTo();
	}
};
