String.prototype.stripHtml = function() {
	return this.replace(/(<([^>]+)>)/ig,"");
} //toglie i tag html da una stringa

String.prototype.linearize = function() {
	return this.replace(/\n/g,"");
} //toglie gli a capo

String.prototype.smartTruncateAt = function(at) {
	var truncated = this.substring(0, at);
	
	var trunc_arr = truncated.match(/^(.{0,})\s+\S{0,}$/);
	
	if (trunc_arr && trunc_arr.length > 0) {
		truncated = trunc_arr[1];
	} 
	
	return truncated;
} //tronca una stringa lineare allo spazio (\s) più prossimo al valore di at (restituisce quindi frasi intere, tranne che se non viene trovato uno spazio)

function toExpandableAbstract(str, at) {
	if(!str || !at) return;
	
	var trimstrippedstr = str.trim().linearize().stripHtml();
	
	var reducedstr = trimstrippedstr.smartTruncateAt(at);
	
	if(trimstrippedstr.substring(0,at).length == trimstrippedstr.length) {
		return str;
	}
	
	return "<span class=\"truncated_content\">"+reducedstr+" [...] <a href=\"#\" class=\"btn_abstractexpand\" onClick=\"abstractExpand(this);return false;\">Visualizza altro</a></span><span class=\"full_content\">"+str+"</span>";      
} //crea un abstract espandibile da un testo e appende un pulsante per espandere il tutto. Il testo intero rimane in uno span con classe 'truncated_content', il testo in abstract rimane in uno span con classe 'full_content'

function quickPager(from) {
  	var box = $(".quickpaged");
  	if (box.length <= 0) {
    	$(".quickpager a").css("display","none");
    	return;
  	} 
  	box.css("display","none");
  	var prevnext = $(".quickpager a");
  	var btnprev = prevnext.eq(0);
  	var btnnext = prevnext.eq(1);
  
  	var _elementsperpage = $(".quickpager").attr("tnes:elementsperpage");
  	var elementsperpage = (_elementsperpage == null || _elementsperpage == "" ? 4 : 1*_elementsperpage);
  
  
  	//default or beginning of array
  	if (from == null || from == 0) {
  	  from = 0;
  	  btnprev.css("display","none");
  	} 
  	var to = from+elementsperpage;
  	window.status="from:"+from+" to:"+to;
  	//hides buttons in too short arrays
  	if (box.length < to) {
  	  btnnext.css("display","none");
  	  btnprev.css("display","none");
  	}
  	//shows "prev" button when needed
  	if (from >= elementsperpage) {
  	  btnprev.css("display","block");
  	}
  	//prevents highest limit overflow 
  	if (to >= box.length) {
  	  to = box.length;
  	  btnnext.css("display","none");
  	} else {
  	  btnnext.css("display","block");
  	}
  
  	for (var i = from; i < to; i++) {
    	box.eq(i).fadeIn();
  	}
  
  	btnprev.get(0).from = from;
  	btnnext.get(0).from = from;
  
  	btnprev.click(function() {
    	btnprev.unbind();
    	var memofrom = $(this).get(0).from; 
    	quickPager(memofrom-elementsperpage,memofrom);
    	return false;
  	});
  
  	btnnext.click(function() {
  		btnnext.unbind();
    	var memofrom = $(this).get(0).from; 
    	quickPager(memofrom+elementsperpage,memofrom+2*elementsperpage);
    	//quickPager(from+elementsperpage,to+elementsperpage);
    	return false;
  	});   
}


function youThumbs() {
	var youthumbs = $("a.youthumb");
	if (youthumbs.length == 0) return;

	var thumbs = youthumbs.find("div.thumb:first");

	//se esistono dei "div.thumb" interni a un "a.youthumb"...
	if(thumbs.length != 0) {
		//...trova il primo "div.thumb" interno a un "a.youthumb" e gli assegna la classe "actual" (= visibile)...
		thumbs.addClass("actual");
		//...e gestisce l'onmouseover/onmouseout su tutti gli "a.youthumb"
		youthumbs.hover(
		  function() {
		    //mouseOVER: all'onmouseover all'elemento viene legato un interval che chiama ricorsivamente "nextThumb"
		    var element = $(this).get(0);
		    var el = this;
		    clearInterval(element.itt);
		    element.itt = setInterval( function() {
		      nextThumb(el);
		    }, 1000 )
		  },
		  function () {
		    //mouseOUT: all'onmouseout viene killato l'interval specifico di quell'elemento (la funzione "nextThumb" non verrà più chiamata)
		    var element = $(this).get(0);
		    clearInterval(element.itt);
		  }
		)
	} //if
}

function nextThumb(el) {
	var element = $(el);
	 //fa scomparire il thumb che ha classe "actual"
	 var actualthumb = element.find("div.actual");
	 if (actualthumb.length == 0) {
	  actualthumb = element.children("div.thumb").eq(0); 
	 }
	 actualthumb.removeClass("actual");
	 actualthumb.css("display","none");
	 //fa apparire il div immediatamente successivo (se non esiste ricomincia da 0)
	 var nextthumb = actualthumb.next("div.thumb");
	 if (nextthumb.length == 0) {
	  nextthumb = element.find("div.thumb").eq(0);
	 }
	 nextthumb.css("display","block");
	 nextthumb.addClass("actual");
}

function bookMark(el, url) {
	 var jqel = $(el);
	 var related_tab = jqel.attr("bs:tab");
	 var tab = jqel.parents('div.usertab').eq(0)
	 var current_tab = null;
	 if(tab.length > 0) {
		current_tab = tab.attr("bs:id"); 
	 }
	 
	 if(jqel.hasClass("loading")) return;
	 
	 jqel.addClass("loading");
 
 	$.ajax({
  		url: url,
  		type: "POST",
  		//data: parameters,
  		success: function(response){
   			if(response) {
    			jqel.removeClass("loading");
    			jqel.replaceWith(response);
    			//tenterà di fare l'update della tab attività. Giunti ad usertabs.update, se la tab non esiste perchè ad es. siamo in una pagina senza tabs, vi sarà un return.
    			usertabs.update("attivita");
    			if (current_tab && current_tab != related_tab || !current_tab) {
     				usertabs.load(related_tab);
    			} 
   			} else {
    			alert("Si è generato un errore durante il salvataggio dei dati. Si prega di riprovare più tardi");
   			}
  		}, //end of success
  		error: function() {
   			alert("Si è generato un errore durante il salvataggio dei dati. Si prega di riprovare più tardi");
  		}
 	}); //end of ajax call
}

function activateVoter(activator) {
	var voterparent = $(activator).parents("div.votebox");
	var voter = voterparent.find("img")
	var span = voterparent.find("span")
	
	span.css("display","none"); 
	voter.addClass("votable");
	voter.css("backgroundPosition","-120px").css("display","none");
	voter.fadeIn(2000);
	
	initVoters();
}

function loadComments(page) {
	var comments_container = $("#commentswrapper");
	//alert("C'è div.commenti? " + comments_container);
	//alert("Lunghezza comments_container: " + comments_container.length);
 	//if(comments_container.length == 0) return;    
    
	 //var url = comments_container.attr("bs:url");
	 var url = "/social/commenti";
	 	 
	 var parameters = {
		  "id" : comments_container.attr("bs:id"),
		  "class" : comments_container.attr("bs:class")
 	}
 
 	//alert("Pagina: " + page);
 	//se viene passata la page vuol dire che è stato cliccato il paginatore (se no è il loadComments di default all'onDomReady)
	 if(page != null) {
	  	parameters["page"] = page;
	 }
 
	 //se esiste l'attributo bs:hidden viene passato anche il parametro hidden=true (si tratta dei libri fuori catalogo) 
	 if(comments_container.attr("bs:hidden")) {
	  	parameters["hidden"] = comments_container.attr("bs:hidden");
	 }
 
	 //comments_container.css("display","none");
	 comments_container.addClass("loading");
 
	 $.ajax({
		   url: url,
		   type: "POST",
		   data: parameters,
		   success: function(response){
		   
		   		//alert("Risposta " + response);
			    comments_container.html(response);
			     //alert($("div.comment").length);
			     var showmore = comments_container.find("div.comment");
			     //alert(showmore.length);
			     for(var i = 0; i < showmore.length; i++) {
				      var str = showmore.eq(i).html();
				      //alert(str);
				      showmore.eq(i).html( toExpandableAbstract(str, 1000) );
		  		}
		     
		     	comments_container.fadeIn("slow");
		   },
		   error: function() {
		     comments_container.html("<span style='color:#c00'>Si è verificato un errore durante il caricamento dei commenti.<br />Provare a ricaricare la pagina.</span>");
		   },
		   complete: function(){
		     comments_container.removeClass("loading");
		   }
	 });
}

var alternateCommentsBalloons = function() {
	var cballoons = $(".box-comment-utenti b.balloon");
	var classtoadd = ["red","green","blue"]
	var count = 0;
	for(var i = 0; i < cballoons.length; i++) {
	  cballoons.eq(i).addClass(classtoadd[count]);
	  count++;
	  if(count == 3) {
	    count = 0;
	  }
	}
}

var injectComments = function() {
	// Wrapper dei commenti presente nella pagina; all'inizio è vuoto.
  	var commentswrapper = $("#commentswrapper");
  	if(commentswrapper.length == 0) return;
  	
  	var classe = commentswrapper.attr("bs:class");
  	var id = commentswrapper.attr("bs:id");
  	
  	commentswrapper.load("/social/commenti", { "id" : id, "class" : classe }, function(data) {
  		//alert("Dati: " + data);
    	if(data.replace(/\s+/g,"") != "") {
      		//$(".commenti-title").css("display","block");
      		//$(".commenti-btn").css("display","block");
      		commentswrapper.css("background","none");
			//commentswrapper.css("display", "block"); 
      		alternateCommentsBalloons();
    		} else {
      		commentswrapper.css("display","none");
    	}
  	});
}

function initVoters() {
	var votables = $(".votable");
	votables.mousemove(function(e) {
		var votable = $(this);
		var pos = (e.pageX - votable.offset().left);
		var scaledpos = (24*(5+Math.ceil(pos / 24)))-240  
		votable.css("backgroundPosition", scaledpos+"px");
	});
	
	votables.click(function(e) {
		var votable = $(this);
		var votableparent = votable.parent("div.votebox");
		votable.unbind();
		votable.removeClass("votable");
		var scaledpos = votable.css("backgroundPosition");
		var scaledwidth = votable.css("width");
		scaledwidth = 1 * scaledwidth.substr(0, scaledwidth.indexOf("px"));
		var votation = (scaledwidth + (1 * scaledpos.substr(0, scaledpos.indexOf("px")))) / (scaledwidth / (1 * votable.attr("bs:scala")));
		votable.fadeOut();
		var url = votable.attr("bs:url");
		
		var parameters = {
			"to[class]" 				: votable.attr("bs:class"),
			"to[id]" 					: votable.attr("bs:id"),
			"action[data][scala]" 		: votable.attr("bs:scala"),
			"action[data][voto]" 		: votation
		}
		
		$.ajax({
			url: url,
			type: "POST",
			data: parameters,
			success: function(response){
			  
			  votableparent.html(response);
			  votableparent.css("display","none");
			  votableparent.fadeIn(3000);
			  
			},
			error: function() {
			  votableparent.html("Si è verificato un errore nella registrazione del voto.")
			}
		});
	});
	
	votables.mouseout(function() {
		var votable = $(this);
		votable.css("backgroundPosition","-120px");
	});
}

function initLoginForm() {
	if($('#login_card_form').get(0)) {
	
		// Inizializzazione.
	    $('#login_password').hide();
		$('#incorrect_fields').hide();
		$('#user_not_exists').hide();
		$('#after_login').hide();    
	    $('#login_username').val($('#login_username').attr('bs:value'));
	    $('#login_clear_password').val($('#login_clear_password').attr('bs:value'));
	    
	    // Gestione focus e blur del campo username.
		$('#login_username').focus(function() {
			    if($('#login_username').val() == $('#login_username').attr('bs:value')) {
					$('#login_username').val('');	
				}				
			}
		);
		
		$('#login_username').blur(function() {
				if($('#login_username').val() == '') {
					$('#login_username').val($('#login_username').attr('bs:value'));	
				}
			}		
	 	);
		
		// Gestione focus e blur del campo password. 
		$('#login_clear_password').focus(function() {
			    if($('#login_clear_password').val() == $('#login_clear_password').attr('bs:value')) {
					$('#login_clear_password').hide();
					$('#login_password').show();
					$('#login_password').focus();	
				}				
			}
		);
		
		$('#login_clear_password').blur(function(){
		        if($('#login_clear_password').val() == '') {
					$('#login_clear_password').val($('#login_clear_password').attr('bs:value'));	
				}
			}		
		);
		
		$('#login_password').blur(function() {
		      	if($('#login_password').val() == '' || $('#login_password').val() == null) {
					$('#login_password').hide();
					$('#login_clear_password').show();
					$('#login_clear_password').val($('#login_clear_password').attr('bs:value'));
				}
			}
		);	
	}
}

function resetLogin() {
	$('#incorrect_fields').hide();
	$('#before_login').show();
}

function validateLoginForm() {
				    	
		$('#login_card_form').validate({
			rules: {
			
				username: {
					email: true,
					required : true					
				}, 
				
			    password: {
					required: true
				},
			    
			    clear_password: {
					required: true
				}	
			},
			
			onfocusout: false,
			
			onkeyup: false,
	
			invalidHandler: function(form, validator) {
			
				var errors = validator.numberOfInvalids();
				
				if(errors) {
					$('#before_login').hide();
					$('#incorrect_fields').show();
				}
				
				/*$('#reset').click( function() {
					$('#incorrect_fields').hide();
					$('#before_login').show();
					$('label.error').hide();					
				});*/	
			},
			
			submitHandler: function() {
				
				var login = $('#login_card_form');
				var data = $('#login_card_form').serialize();
				
				$.ajax({
					type: 'POST',
				    url: login.attr("action"),
					data: login.serialize(),
					success: function(response) {
						var response_washed = jQuery.trim(response);
						if(response_washed == "login") {
							window.location.reload();
						} else if(response_washed == "password_ko") {
							$('#before_login').hide();
							$('#incorrect_fields').show();
						} else {
							var paragrafo = $(response).children();
							$('#before_login').html(paragrafo);
							Cufon.refresh();
						}
					},
					error: function(response) {
					    alert("Spiacenti: si è verificato un errore durante il login.\nProvare a ricaricare la pagina o riprovare più tardi.");
					} 
				});
				
				
				return false;
			}
	});
}

$(document).ready(function(){

	quickPager();
	
	$("#incorrect_fields").hide();
	
	// Validation
	initLoginForm();
	validateLoginForm();
	
	$("#commentform").validate();
	$("#sayform").validate();
	$('#recuperoform').validate();
		
	initVoters();
	loadComments();
	injectComments();
	youThumbs();
});

