/*
 * Metadata - jQuery plugin for parsing metadata from elements
 *
 * Copyright (c) 2006 John Resig, Yehuda Katz, Jörn Zaefferer, Paul McLanahan
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Revision: $Id$
 *
 */

/**
 * Sets the type of metadata to use. Metadata is encoded in JSON, and each property
 * in the JSON will become a property of the element itself.
 *
 * There are three supported types of metadata storage:
 *
 *   attr:  Inside an attribute. The name parameter indicates *which* attribute.
 *          
 *   class: Inside the class attribute, wrapped in curly braces: { }
 *   
 *   elem:  Inside a child element (e.g. a script tag). The
 *          name parameter indicates *which* element.
 *          
 * The metadata for an element is loaded the first time the element is accessed via jQuery.
 *
 * As a result, you can define the metadata type, use $(expr) to load the metadata into the elements
 * matched by expr, then redefine the metadata type and run another $(expr) for other elements.
 * 
 * @name $.metadata.setType
 *
 * @example <p id="one" class="some_class {item_id: 1, item_label: 'Label'}">This is a p</p>
 * @before $.metadata.setType("class")
 * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
 * @desc Reads metadata from the class attribute
 * 
 * @example <p id="one" class="some_class" data="{item_id: 1, item_label: 'Label'}">This is a p</p>
 * @before $.metadata.setType("attr", "data")
 * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
 * @desc Reads metadata from a "data" attribute
 * 
 * @example <p id="one" class="some_class"><script>{item_id: 1, item_label: 'Label'}</script>This is a p</p>
 * @before $.metadata.setType("elem", "script")
 * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
 * @desc Reads metadata from a nested script element
 * 
 * @param String type The encoding type
 * @param String name The name of the attribute to be used to get metadata (optional)
 * @cat Plugins/Metadata
 * @descr Sets the type of encoding to be used when loading metadata for the first time
 * @type undefined
 * @see metadata()
 */

(function($) {

$.extend({
	metadata : {
		defaults : {
			type: 'class',
			name: 'metadata',
			cre: /({.*})/,
			single: 'metadata'
		},
		setType: function( type, name ){
			this.defaults.type = type;
			this.defaults.name = name;
		},
		get: function( elem, opts ){
			var settings = $.extend({},this.defaults,opts);
			// check for empty string in single property
			if ( !settings.single.length ) settings.single = 'metadata';
			
			var data = $.data(elem, settings.single);
			// returned cached data if it already exists
			if ( data ) return data;
			
			data = "{}";
			
			if ( settings.type == "class" ) {
				var m = settings.cre.exec( elem.className );
				if ( m )
					data = m[1];
			} else if ( settings.type == "elem" ) {
				if( !elem.getElementsByTagName ) return;
				var e = elem.getElementsByTagName(settings.name);
				if ( e.length )
					data = $.trim(e[0].innerHTML);
			} else if ( elem.getAttribute != undefined ) {
				var attr = elem.getAttribute( settings.name );
				if ( attr )
					data = attr;
			}
			
			if ( data.indexOf( '{' ) <0 )
			data = "{" + data + "}";
			
			data = eval("(" + data + ")");
			
			$.data( elem, settings.single, data );
			return data;
		}
	}
});

/**
 * Returns the metadata object for the first member of the jQuery object.
 *
 * @name metadata
 * @descr Returns element's metadata object
 * @param Object opts An object contianing settings to override the defaults
 * @type jQuery
 * @cat Plugins/Metadata
 */
$.fn.metadata = function( opts ){
	return $.metadata.get( this[0], opts );
};

})(jQuery);

/*
 ### jQuery Star Rating Plugin v3.13 - 2009-03-26 ###
 * Home: http://www.fyneworks.com/jquery/star-rating/
 * Code: http://code.google.com/p/jquery-star-rating-plugin/
 *
	* Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 ###
*/

/*# AVOID COLLISIONS #*/
;if (window.jQuery) (function ($) {
	/*# AVOID COLLISIONS #*/

	// IE6 Background Image Fix
	if ($.browser.msie) try { document.execCommand("BackgroundImageCache", false, true) } catch (e) { };
	// Thanks to http://www.visualjquery.com/rating/rating_redux.html

	// plugin initialization
	$.fn.rating = function (options) {
		if (this.length == 0) return this; // quick fail

		// Handle API methods
		if (typeof arguments[0] == 'string') {
			// Perform API methods on individual elements
			if (this.length > 1) {
				var args = arguments;
				return this.each(function () {
					$.fn.rating.apply($(this), args);
				});
			};
			// Invoke API method handler
			$.fn.rating[arguments[0]].apply(this, $.makeArray(arguments).slice(1) || []);
			// Quick exit...
			return this;
		};

		// Initialize options for this call
		var options = $.extend(
			{}/* new object */,
			$.fn.rating.options/* default options */,
			options || {} /* just-in-time options */
		);

		// Allow multiple controls with the same name by making each call unique
		$.fn.rating.calls++;

		// loop through each matched element
		this
		 .not('.star-rating-applied')
			.addClass('star-rating-applied')
		.each(function () {

			// Load control parameters / find context / etc
			var control, input = $(this);
			var eid = (this.name || 'unnamed-rating').replace(/\[|\]/g, '_').replace(/^\_+|\_+$/g, '');
			var context = $(this.form || document.body);

			// FIX: http://code.google.com/p/jquery-star-rating-plugin/issues/detail?id=23
			var raters = context.data('rating');
			if (!raters || raters.call != $.fn.rating.calls) raters = { count: 0, call: $.fn.rating.calls };
			var rater = raters[eid];

			// if rater is available, verify that the control still exists
			if (rater) control = rater.data('rating');

			if (rater && control)//{// save a byte!
			// add star to control if rater is available and the same control still exists
				control.count++;

			//}// save a byte!
			else {
				// create new control if first star or control element was removed/replaced

				// Initialize options for this raters
				control = $.extend(
					{}/* new object */,
					options || {} /* current call options */,
					($.metadata ? input.metadata() : ($.meta ? input.data() : null)) || {}, /* metadata options */
					{count: 0, stars: [], inputs: [] }
				);

				// increment number of rating controls
				control.serial = raters.count++;

				// create rating element
				rater = $('<div class="star-rating-control"/>');
				input.before(rater);

				// Mark element for initialization (once all stars are ready)
				rater.addClass('rating-to-be-drawn');

				// Accept readOnly setting from 'disabled' property
				if (input.attr('disabled')) control.readOnly = true;

				// Create 'cancel' button

				rater.append(
						control.cancel = $('<div class="rating-cancel"><a title="' + control.cancel + '">' + control.cancelValue + '</a></div>')
						.mouseover(function () {
							$(this).rating('drain');
							$(this).addClass('star-rating-hover');
							//$(this).rating('focus');
						})
						.mouseout(function () {
							$(this).rating('draw');
							$(this).removeClass('star-rating-hover');
							//$(this).rating('blur');
						})
						.click(function () {
							$(this).rating('select');
						})
						.data('rating', control)
					);

			}; // first element of group

			// insert rating star
			// GF:2011.11.18 Con testo
			//			var star = $('<div class="star-rating rater-'+ control.serial +'"><a title="' + (this.title || this.value) + '">' + this.value + '</a></div>');
			//			var star = $('<div class="star-rating rater-' + control.serial + '"><a>' + this.value + '</a></div>');
			var star = "";
			if (control.showTitle)
				star = $('<div class="star-rating rater-' + control.serial + '"><a>' + (this.title || this.value) + '</a></div>');
			else
				star = $('<div class="star-rating rater-' + control.serial + '"><a>&nbsp;&nbsp;</a></div>');

			rater.append(star);

			// inherit attributes from input element
			if (this.id) star.attr('id', this.id);
			if (this.className) star.addClass(this.className);

			// Half-stars?
			if (control.half) control.split = 2;

			// Prepare division control
			if (typeof control.split == 'number' && control.split > 0) {
				var stw = ($.fn.width ? star.width() : 0) || control.starWidth;
				var spi = (control.count % control.split), spw = Math.floor(stw / control.split);
				star
				// restrict star's width and hide overflow (already in CSS)
					.width(spw)
				// move the star left by using a negative margin
				// this is work-around to IE's stupid box model (position:relative doesn't work)
					.find('a').css({ 'margin-left': '-' + (spi * spw) + 'px' });
			};

			// readOnly?
			if (control.readOnly)//{ //save a byte!
			// Mark star as readOnly so user can customize display
				star.addClass('star-rating-readonly');
			//}  //save a byte!
			else//{ //save a byte!
			// Enable hover css effects
				star.addClass('star-rating-live')
			// Attach mouse events
					.mouseover(function () {
						$(this).rating('fill');
						$(this).rating('focus');
					})
					.mouseout(function () {
						$(this).rating('draw');
						$(this).rating('blur');
					})
					.click(function () {
						$(this).rating('select');
					})
				;
			//}; //save a byte!

			// set current selection
			if (this.checked) control.current = star;

			// hide input element
			input.hide();

			// backward compatibility, form element to plugin
			input.change(function () {
				$(this).rating('select');
			});

			// attach reference to star to input element and vice-versa
			star.data('rating.input', input.data('rating.star', star));

			// store control information in form (or body when form not available)
			control.stars[control.stars.length] = star[0];
			control.inputs[control.inputs.length] = input[0];
			control.rater = raters[eid] = rater;
			control.context = context;

			input.data('rating', control);
			rater.data('rating', control);
			star.data('rating', control);
			context.data('rating', raters);
		}); // each element

		// Initialize ratings (first draw)
		$('.rating-to-be-drawn').rating('draw').removeClass('rating-to-be-drawn');

		return this; // don't break the chain...
	};

	/*--------------------------------------------------------*/

	/*
	### Core functionality and API ###
	*/
	$.extend($.fn.rating, {
		// Used to append a unique serial number to internal control ID
		// each time the plugin is invoked so same name controls can co-exist
		calls: 0,

		focus: function () {
			var control = this.data('rating'); if (!control) return this;
			if (!control.focus) return this; // quick fail if not required
			// find data for event
			var input = $(this).data('rating.input') || $(this.tagName == 'INPUT' ? this : null);
			// focus handler, as requested by focusdigital.co.uk
			if (control.focus) control.focus.apply(input[0], [input.val(), $('a', input.data('rating.star'))[0]]);
		}, // $.fn.rating.focus

		blur: function () {
			var control = this.data('rating'); if (!control) return this;
			if (!control.blur) return this; // quick fail if not required
			// find data for event
			var input = $(this).data('rating.input') || $(this.tagName == 'INPUT' ? this : null);
			// blur handler, as requested by focusdigital.co.uk
			if (control.blur) control.blur.apply(input[0], [input.val(), $('a', input.data('rating.star'))[0]]);
		}, // $.fn.rating.blur

		fill: function () { // fill to the current mouse position.
			var control = this.data('rating'); if (!control) return this;
			// do not execute when control is in read-only mode
			if (control.readOnly) return;
			// Reset all stars and highlight them up to this element
			this.rating('drain');
			this.prevAll().andSelf().filter('.rater-' + control.serial).addClass('star-rating-hover');
		}, // $.fn.rating.fill

		drain: function () { // drain all the stars.
			var control = this.data('rating'); if (!control) return this;
			// do not execute when control is in read-only mode
			if (control.readOnly) return;
			// Reset all stars
			control.rater.children().filter('.rater-' + control.serial).removeClass('star-rating-on').removeClass('star-rating-hover');
		}, // $.fn.rating.drain

		draw: function () { // set value and stars to reflect current selection
			var control = this.data('rating'); if (!control) return this;
			// Clear all stars
			this.rating('drain');
			// Set control value
			if (control.current) {
				control.current.data('rating.input').attr('checked', 'checked');
				control.current.prevAll().andSelf().filter('.rater-' + control.serial).addClass('star-rating-on');
			}
			else
				$(control.inputs).removeAttr('checked');
			// Show/hide 'cancel' button
			control.cancel[control.readOnly || control.required ? 'hide' : 'show']();
			// Add/remove read-only classes to remove hand pointer
			this.siblings()[control.readOnly ? 'addClass' : 'removeClass']('star-rating-readonly');
		}, // $.fn.rating.draw





		select: function (value, wantCallBack) { // select a value

			// ***** MODIFICATION *****
			// Thanks to faivre.thomas - http://code.google.com/p/jquery-star-rating-plugin/issues/detail?id=27
			//
			// ***** LIST OF MODIFICATION *****
			// ***** added Parameter wantCallBack : false if you don't want a callback. true or undefined if you want postback to be performed at the end of this method'
			// ***** recursive calls to this method were like : ... .rating('select') it's now like .rating('select',undefined,wantCallBack); (parameters are set.)
			// ***** line which is calling callback
			// ***** /LIST OF MODIFICATION *****

			var control = this.data('rating'); if (!control) return this;
			// do not execute when control is in read-only mode
			if (control.readOnly) return;
			// clear selection
			control.current = null;
			// programmatically (based on user input)
			if (typeof value != 'undefined') {
				// select by index (0 based)
				if (typeof value == 'number')
					return $(control.stars[value]).rating('select', undefined, wantCallBack);
				// select by literal value (must be passed as a string
				if (typeof value == 'string')
				//return
					$.each(control.stars, function () {
						if ($(this).data('rating.input').val() == value) $(this).rating('select', undefined, wantCallBack);
					});
			}
			else
				control.current = this[0].tagName == 'INPUT' ?
				 this.data('rating.star') :
					(this.is('.rater-' + control.serial) ? this : null);

			// Update rating control state
			this.data('rating', control);
			// Update display
			this.rating('draw');
			// find data for event
			var input = $(control.current ? control.current.data('rating.input') : null);
			// click callback, as requested here: http://plugins.jquery.com/node/1655

			// **** MODIFICATION *****
			// Thanks to faivre.thomas - http://code.google.com/p/jquery-star-rating-plugin/issues/detail?id=27
			//
			//old line doing the callback :
			//if(control.callback) control.callback.apply(input[0], [input.val(), $('a', control.current)[0]]);// callback event
			//
			//new line doing the callback (if i want :)
			if ((wantCallBack || wantCallBack == undefined) && control.callback) control.callback.apply(input[0], [input.val(), $('a', control.current)[0]]); // callback event
			//to ensure retro-compatibility, wantCallBack must be considered as true by default
			// **** /MODIFICATION *****

		}, // $.fn.rating.select





		readOnly: function (toggle, disable) { // make the control read-only (still submits value)
			var control = this.data('rating'); if (!control) return this;
			// setread-only status
			control.readOnly = toggle || toggle == undefined ? true : false;
			// enable/disable control value submission
			if (disable) $(control.inputs).attr("disabled", "disabled");
			else $(control.inputs).removeAttr("disabled");
			// Update rating control state
			this.data('rating', control);
			// Update display
			this.rating('draw');
		}, // $.fn.rating.readOnly

		disable: function () { // make read-only and never submit value
			this.rating('readOnly', true, true);
		}, // $.fn.rating.disable

		enable: function () { // make read/write and submit value
			this.rating('readOnly', false, false);
		} // $.fn.rating.select

	});

	/*--------------------------------------------------------*/

	/*
	### Default Settings ###
	eg.: You can override default control like this:
	$.fn.rating.options.cancel = 'Clear';
	*/
	$.fn.rating.options = { //$.extend($.fn.rating, { options: {
		cancel: 'Cancella selezione',   // advisory title for the 'cancel' link
		cancelValue: '',           // value to submit when user click the 'cancel' link
		split: 0,                  // split the star into how many parts?

		// Width of star image in case the plugin can't work it out. This can happen if
		// the jQuery.dimensions plugin is not available OR the image is hidden at installation
		starWidth: 16,

		showTitle: false

		//NB.: These don't need to be pre-defined (can be undefined/null) so let's save some code!
		//half:     false,         // just a shortcut to control.split = 2
		//required: false,         // disables the 'cancel' button so user can only select one of the specified values
		//readOnly: false,         // disable rating plugin interaction/ values cannot be changed
		//focus:    function(){},  // executed when stars are focused
		//blur:     function(){},  // executed when stars are focused
		//callback: function(){},  // executed when a star is clicked
	}; //} });

	/*--------------------------------------------------------*/

	/*
	### Default implementation ###
	The plugin will attach itself to file inputs
	with the class 'multi' when the page loads
	*/
	$(function () {
		//$('input[type=radio].star').rating();
		//TS:AM:2011-08-31: radiobuttonlist non permette lo styling degli input nè l'hide delle label
		$('.starList').find('input[type=radio]').rating();
		$('.starListTitle').find('input[type=radio]').rating({ showTitle: true });
		$('.starList').find('label').hide();
		$('.starListTitle').find('label').hide();
	});



	/*# AVOID COLLISIONS #*/
})(jQuery);
/*# AVOID COLLISIONS #*/

