var Vote = {
	
	ajaxPath 			: '/ajax/vote.php',
	loadingIndicator	: '/media/images/ajax-loader-mini.gif',
	loadingIndicatorBig	: '/media/images/loading_64px.gif',
	displayLoading		: true,	
	commitSelector 		: 'div.vote_commit',
	resultSelector 		: 'div.vote_result',
	hashPattern			: /[a-z_]+([a-zA-Z0-9]{32})/,
	zIndex				: 100,
	
	/**
	* Initialisiert die Vote
	*/
	init : function()
	{
		this.update();
		
		// Nur bei der ersten Initialisierung, die Ladeanimation anzeigen
		this.displayLoading = false;
	},
	
	/**
	* Aktualisiert alle noetigen Bereiche, mit den aktuellen Daten
	* @param string|null hash (Optional) Nur einen bestimmten Hash updaten
	*/
	update : function ()
	{
		var hash = null; 
		if (Vote.update.arguments.length > 0) {
			hash = Vote.update.arguments[0]; 	
		}
		
		this.checkCommitContainer(hash);
		this.checkResultContainer(hash);		
	},
	
	/**
	* Gibt den naechsten zIndex fuer die Votingpanels zurueck.
	* @return int zIndex
	*/
	getNextZIndex : function()
	{
		this.zIndex++;
		return this.zIndex;
	},
	
	/**
	* Zeigt an den Stellen, wo Voringinhalte geladen werden, eine kleine Ladeanmitation an.
	* @param string selector CSS-Selektor
	*/
	showLoading : function (selector) 
	{
		if (this.displayLoading) {
			jQuery(selector).html("<img src=\"" + this.loadingIndicator + "\" />");
		}	
	},
	
	/**
	* Zeigt an den Stellen, wo Voringinhalte geladen werden, eine kleine Ladeanmitation an.
	* @param string selector CSS-Selektor
	*/
	showLoadingBig : function (selector) 
	{
		if (jQuery('.voteLoadingBig').length == 0) {
			var div = jQuery('<div>')
					. addClass('voteLoadingBig');
			
			div.html("<table border=\"0\"><tr><td><img src=\"" + Vote.loadingIndicatorBig + "\" /></td></tr></table>");
			
			jQuery('body').append(div);
		}
		
		var pos = jQuery(selector).offset();
		var w	= jQuery(selector).width();
		var h	= jQuery(selector).height();
		
		jQuery('.voteLoadingBig').css({
			left 	: pos.left - jQuery(window).scrollLeft() + 10 + 'px',
			top  	: pos.top - jQuery(window).scrollTop() + 10 + 'px',	
			width  	: w + 'px',	
			height  : h + 'px'	
		});
		
		jQuery('.voteLoadingBig table').css({	
			width  	: w + 'px',	
			height  : h + 'px'	
		});
		
		jQuery('.voteLoadingBig').show();
				
	},
	
	hideLoadingBig : function()
	{
		jQuery('.voteLoadingBig').hide();
	},
	 
	/**
	* Holt den Hash aus einer Reihe von Klassennamen
	* @param array|string classes
	* @return string|null Wird der Hash gefunden, wird dieser zurueckgegeben
	*/
	getHash : function(classes) 
	{
		var hash = null;
		
		if (typeof classes == "string") {
			classes = classes.split(" ");
		}
		jQuery(classes).each(function(key, val) {
			if (val.search(Vote.hashPattern) > -1) {
				hash = val.match(Vote.hashPattern);
				if (hash.length >= 2) hash = hash[1];
			}	
		});
		
		return hash;		
	},
	
	/**
	* Prueft das HTML Dokument nach etwaigen Containern, zum Abgeben einer Bewertung
	* @param string|null hash (Optional) Nur einen bestimmten Hash updaten  
	*/
	checkCommitContainer : function() 
	{
		var desiredHash = null;
		if (Vote.checkCommitContainer.arguments.length > 0) {
			desiredHash = Vote.checkCommitContainer.arguments[0]; 	
		}
		
		var hashes = new Array();
		
		jQuery(this.commitSelector).each(function(n, o) {
			hash = Vote.getHash(jQuery(this).attr('class').split(" "));
			if (hash != null && (desiredHash == null || desiredHash == hash)) {
				hashes.push(hash);
				Vote.showLoading(Vote.commitSelector + '_' + hash);
			}	
		});
		
		if (hashes.length > 0) {
			jQuery.getJSON(this.ajaxPath, {
					action 	: 'loadCommits',
					hash 	: hashes.join(",")
				}, function(data) {
					if (data.success == true) {
						Vote.createCommitElements(data);	
					} else {
						jQuery(Vote.commitSelector).hide();	
					}	
				}
			);
		}	
	},
	
	/**
	* Prueft das HTML Dokument nach etwaigen Containern, zum Abgeben einer Bewertung
	* @param string|null hash (Optional) Nur einen bestimmten Hash updaten  
	*/
	checkResultContainer : function() 
	{
		var desiredHash = null;
		if (Vote.checkResultContainer.arguments.length > 0) {
			desiredHash = Vote.checkResultContainer.arguments[0]; 	
		}
		
		var hashes = new Array();
		
		jQuery(this.resultSelector).each(function(n, o) {
			hash = Vote.getHash(jQuery(this).attr('class').split(" "));
			if (hash != null && (desiredHash == null || desiredHash == hash)) {
				hashes.push(hash);
				Vote.showLoading(Vote.resultSelector + '_' + hash);
			}	
		});
		
		if (hashes.length > 0) {
			jQuery.getJSON(this.ajaxPath, {
					action 	: 'loadResults',
					hash 	: hashes.join(",")
				}, function(data) {
					if (data.success == true) {
						Vote.createResultElements(data);
					} else {
						jQuery(Vote.resultSelector).hide();	
					}	
				}
			);
		}	
	},
	
	/**
	* Erstellt die notwendigen Elemente um eine Bewertung abgeben zu koennen.
	* @param object data Die Daten des Ajax Requests
	*/
	createCommitElements : function(data) 
	{
		if (typeof data.data != "undefined") {
			jQuery(data.data).each(function(key, val) {				
				if (val.valid == true) {
					// Link genrieren
					var link = jQuery("<a>")
							 . attr("href", "javascript:;")
							 . addClass("vote")
							 . addClass("vote_link")
							 . html(val.link_label);
							 
					jQuery(link).click(function() {
						Vote.showPanel(val.hash);	
					});
					
					jQuery(Vote.commitSelector + '_' + val.hash).html(link);				
					jQuery(Vote.commitSelector + '_' + val.hash).show();
					
					// Panel genrieren
					if (jQuery('#votePanel_' + val.hash).length == 0) {
						Vote.createPanel(val.hash, val.headline, val.content);
					}
				} else {
					jQuery(Vote.commitSelector + '_' + val.hash).hide();	
				}					
			});
		}	
	},
	
	/**
	* Erstellt die notwendigen Elemente um ein Resultat darzustellen.
	* @param object data Die Daten des Ajax Requests
	*/
	createResultElements : function(data)
	{
		if (typeof data.data != "undefined") {
			jQuery(data.data).each(function(key, val) {				
				if (val.valid == true) {
					jQuery(Vote.resultSelector + '_' + val.hash).html(val.content);
					jQuery(Vote.resultSelector + '_' + val.hash).show();
				} else {
					jQuery(Vote.resultSelector + '_' + val.hash).hide();	
				}
			});
		}		
	},
	
	/**
	* Erstellt ein neues Fenster, um eine Bewertung abzugeben
	* @param string hash		Der Hash fuer den das Fenster erstellt werden soll.
	* @param string headline	Die Ueberschrift, die zu der Bewertung angezeigt werden soll.
	* @param string content		Der Inhalt, der im Fenster angezeigt werden soll.
	*/
	createPanel : function(hash, headline, content)
	{
		//Panel erstellen
		var divOuter 	= jQuery("<div>")
						. attr("id", "votePanel_" + hash)
						. addClass("vote")
						. addClass("vote_panel_outer");
		var divInner 	= jQuery("<div>")
						. addClass("vote")
						. addClass("vote_panel_inner");
		var divHeadline = jQuery("<div>")
						. addClass("vote")
						. addClass("vote_panel_headline");
		var imgClose	= jQuery("<img>")
						. addClass("vote_panel_close")
						. attr("align", "right")
						. attr("src", "/media/misc/gb_close.png");
		var divContent 	= jQuery("<div>")
						. addClass("vote")
						. addClass("vote_panel_content");
		
		imgClose.click(function() {
			Vote.hidePanel(hash);		
		});
						
		divContent.html(content);
		divHeadline.html(headline).append(imgClose);
		divInner.append(divHeadline).append(divContent);
		divOuter.append(divInner);
		divOuter.hide();
		
		// Mouseover und Clickhandler fuer die Bewertung hinzufuegen
		jQuery(divContent).find("div.vote_rating_icons > div")
			.mouseover(function() {				
				jQuery(this).prevAll().addClass("vote_rating_icon_active");
				jQuery(this).nextAll().removeClass("vote_rating_icon_active");
				jQuery(this).addClass("vote_rating_icon_active");					
			})
			.mouseout(function() {				
				obj = jQuery(divContent).find("div.vote_rating_icons > div")
				cnt = obj.length;
				rating = jQuery(divContent).find("input[name='rating']").val();
				
				for (i = rating; i < cnt; i++) {
					jQuery(obj[i]).removeClass("vote_rating_icon_active");	
				}				
			})
			.click(function() {
				jQuery(divContent).find("input[name='rating']").val(jQuery(this).attr('rating'));		
			});
		
		// Form action
		jQuery(divContent).find("form").submit(function() {
			Vote.saveRating(hash);
		});
		
		jQuery("body").append(divOuter);
		
		
	},
	
	/**
	* Speichert die Bewertung zu einem Vote.
	* @param string hash Der Hashwert, auf den sich die Bewertung bezieht
	*/
	saveRating : function(hash) 
	{
		var p_rating = jQuery('#voteForm_' + hash).find("input[name='rating']").val();
		var p_comment = jQuery('#voteForm_' + hash).find("textarea[name='comment']").val();
		 
		// Fehler fuer keine Bewertung anzeigen
		if (p_rating <= 0) { 
			jQuery('#voteForm_' + hash).find(".vote_error_response").show();	
		} else {
			Vote.showLoadingBig('#votePanel_' + hash);
			jQuery('#voteForm_' + hash).find(".vote_error_response").hide();
			
			// Request durchfuehren
			jQuery.post(this.ajaxPath, {
					action	: 'saveRating',
					hash	: hash,
					rating	: p_rating,
					comment	: p_comment
				}, function(data) {
			 		Vote.hideLoadingBig();
			 		
			 		// Response verarbeiten
			 		if (data.success == true) {
						jQuery('#votePanel_' + hash).find(".vote_ajax_response")
													.html("<span class=\"confirm\">" + data.message + "</span>")
													.show();
						// Daten updaten
						Vote.update(hash);
			 		} else {
						jQuery('#votePanel_' + hash).find(".vote_ajax_response")
													.html("<span class=\"error\">" + data.message + "</span>")
													.show();	
			 		}
				}
			);	
		}
	},
	
	/**
	* Zeigt einen Bewertungspanel an
	*/
	showPanel : function(hash)
	{		
		// Positionierung
		jQuery('div#votePanel_' + hash).show();
		Vote.positioning();
		jQuery('div#votePanel_' + hash).hide();
		jQuery('div#votePanel_' + hash).fadeIn(300);
		jQuery('#votePanel_' + hash).find(".vote_ajax_response").hide();		
	},
	
	/**
	* Versteckt den Panel
	*/
	hidePanel : function(hash)
	{
		jQuery('div#votePanel_' + hash).fadeOut(200);	
	},
	
	/**
	* Positioniert die Vote-Elemente
	*/
	positioning : function()
	{ 		
		// Panels neu positionieren
		jQuery('div.vote_panel_outer:visible').each(function(key, obj) {			
			var xpos 	= jQuery(window).width() / 2
						- jQuery(this).width() / 2;
					
			var ypos 	= jQuery(window).height() / 2
						- jQuery(this).height() / 2;
			
			jQuery(this).css({
				zIndex 	: Vote.getNextZIndex(),
				left	: xpos + 'px',
				top		: ypos + 'px'		
			});	
		})
	}
}

// Vote initialisieren
jQuery(document).ready(function() {
	Vote.init();
});

// Ggfls. Vote Objekte umpositionieren
jQuery(window).resize(function() {
	Vote.positioning();
});




