/**
 * This file contains the voting scripts used by preditorRE
 * 
 * Requires Prototype JS version 1.6.0 or greater
 * Requires Scriptaculous version 1.8.0 or greater
 *  
 */

var VotingBase = {
	
	/* Use the constants below to change the voting settings */
	
	/**
	 * Constant defining if error messages should be shown using POX
	 * @final
	 */
	POX: false,
	
	/**
	 * Constant defining if results should be animated
	 * @final
	 */
	ANIMATE: true,
	
	/**
	 * Voting class constructor
	 * @constructor
	 */
	initialize: function()
	{
		var forms = $$('form.vote');
		
		for ( var i = 0, length = forms.length; i < length; i++ )
		{
			forms[i].observe('submit', this.vote.bind(this));
		}
	},
	
	/**
	 * Function called on form submittion to process the vote
	 * 
	 * @param {Object} e Event object
	 */
	vote: function(e)
	{
		// Stop the event propagation
		Event.stop(e);
		
		// Get the form where the event was triggered
		var form = Event.findElement(e, 'form');
		
		// Get the submit button
		var button = form.down('input[type=submit]');
		
		// Stop the button's onclick action
		if ( button.onclick )
		{
			button.onclick(null);
		}
		
		// Validate vote data
		var radios = form.getInputs('radio');
		var checked = false;
		
		for ( var i = 0, length = radios.length; i < length; i++ )
		{
			if ( radios[i].checked )
			{
				checked = true;
				break;
			}
		}
		
		// If an option was not selected display a message
		if ( !checked )
		{
			var msg = "Please select an option and submit your vote again.";
			
			if ( this.POX )
			{
				// TODO: Format the HTML message better
				Pox.showHTML(msg);
			}
			else
			{
				alert(msg);
			}
			
			return;
		}
		
		// Make the Ajax request to count the vote
		form.request({
  			onComplete: this.counted.bind(this, form)
		});
	},
	
	/**
	 * Callback function called once the Ajax request to process the vote has completed
	 * 
	 * @param {Object} form The form object containing the vote options
	 * @param {Object} transport The Ajax transport object 
	 */
	counted: function(form, transport)
	{
		try {
		// Get the response from the Ajax transport object
		var response = transport.responseText;
		
		// Insert the response after the form so it can be accessed before removing the form
		form.insert({after: response});
		
		// Get the parent element that is the container of the results
		var results_container = form.next();
		
		// Get the result bars
		var bars = results_container.select('div.vote-result-bar');
		
		if ( this.ANIMATE )
		{
			// Hide the container
			results_container.hide();
			
			var height = Util.getMaxHeight([form, results_container]);
			
			// Make the main vote container's position relative
			form.up().setStyle({
				position: 'relative',
				height: height + 'px'
			});
			
			// Style the form
			form.setStyle({
				position: 'absolute',
				width: '100%',
				height: height + 'px'
			});
			
			results_container.setStyle({
				position: 'absolute',
				width: '100%',
				height: height + 'px'
			});
			
			// Set the bars' initial widths
			for ( var i = 0, length = bars.length; i < length; i++ )
			{
				bars[i].setStyle({width: '1px'});
			}
			
			// Fade the form out and the results in
			new Effect.Parallel([
				new Effect.Fade(form, { sync: true }), 
				new Effect.Appear(results_container, { sync: true }) 
			], {
				duration: 0.5,
				afterFinish: this._growBars.bind(this, bars)
			});
		}
		else
		{
			this._growBars(bars);
			
			// Remove the form
			form.remove();
			
			// Clean up
			form = null;
		}
		} catch ( err ) {
			alert(err.message);
		}
	},
	
	/**
	 * Private function used when animating the results to grow the bars
	 * 
	 * @param {Array} bars Array of bar elements
	 */
	_growBars: function(bars)
	{
		var result_container = bars[0].up();
		var percent_container = bars[0].next();
		
		var width = result_container.getWidth() - percent_container.getBoxWidth();
		
		var bar, title, percent, bar_width;
		
		for ( var i = 0, length = bars.length; i < length; i++ )
		{
			bar = bars[i];
			
			title = bar.readAttribute('title');
			
			// Get the percentage number from the title
			percent = title.substring(title.indexOf(', ') + 2, title.indexOf('%'));
			
			// Type cast the percent string obtained from the title
			percent = parseInt(percent);
			
			bar_width = width * (percent / 100);
			
			if ( this.ANIMATE )
			{
				new Effect.ReSize(bar, {
					direction: 'horz',
					amount: bar_width,
					duration: 1.5,
					transition: Effect.Transitions.slowstop
				});
			}
			else
			{
				bar.setStyle({ width: bar_width + 'px' });
			}
		}
	}
};

var Voting = Class.create(VotingBase);

// Initialize voting once the DOM is loaded
document.observe('dom:loaded', function() { new Voting(); });

var RatingBase = {
	vn_id: null,
	field: null,
	item_id: null,
	
	pox_box: null,
	images: null,
	
	initialize: function(vn_id, field, item_id)
	{
		// Error checking
		if ( isNaN(vn_id) )
		{
			return false;
		}
		
		if ( isNaN(item_id) )
		{
			return false;
		}
		
		this.vn_id = vn_id;
		this.field = field;
		this.item_id = item_id;
		
		// Get any existing results
		var url = "/voting.php?op=rating_results";
		
		if ( this.field == "a_id" )
		{
			var param = {vn_id: this.vn_id, a_id: this.item_id}
		}
		else if ( this.field == "aa_id" )
		{
			var param = {vn_id: this.vn_id, aa_id: this.item_id}
		}
		else if ( this.field == "ai_id" )
		{
			var param = {vn_id: this.vn_id, ai_id: this.item_id}
		}
		
		new Ajax.Request(url, {
			parameters: param,
			onSuccess: this.resultsLoaded.bind(this)
		});
	},
	
	resultsLoaded: function(transport)
	{
		// Reload rating
		$('rating-' + this.field + '-' + this.item_id).replace(transport.responseText);
	},
	show: function()
	{
		Pox.showLoading(document.body);
		
		// Add a listener to the background to close the rating if it is clicked
		$$('.pox-bg')[0].observe('click', this.hide);
		
		// URL to get the form from
		var url = "/voting.php?op=rating_form&vn_id=" + this.vn_id + "&field=" + this.field + "&item_id=" + this.item_id;
		
		// Make the request
		new Ajax.Request(url, {
			onSuccess: this.formLoaded.bind(this)
		});
	},
	
	hide: function()
	{
		Pox.hideHTML(document.body);
	},
	
	formLoaded: function(transport)
	{
		// Get the HTML returned by the Ajax request
		var html = transport.responseText;
		
		// Get the Pox box to insert the HTML into
		var pox_box = $$('.pox-box')[0];
		
		// Get any existing children of the Pox box to remove later
		var children = pox_box.childElements();
		
		// Set the style so that the HTML won't show when it's inserted
		pox_box.setStyle({overflow: 'hidden'});
		
		// Insert the HTML at the bottom
		pox_box.insert({bottom: html});
		
		// Get the main contain of what was just inserted
		var container = pox_box.select('div')[0];
		
		// Hide the container so that it can fade in later
		container.hide();
		
		// Get the container dimensions
		var dimensions_c = container.getDimensions();
		
		// Get the window dimensions
		var window_dimensions = document.viewport.getDimensions();
		
		// Calculate where the Pox box should site once it is resized
		var box_left = Math.floor((window_dimensions.width - dimensions_c.width) / 2) + Pox.scrollLeft;
		var box_top = Math.floor((window_dimensions.height - dimensions_c.height) / 2) + Pox.scrollTop;
		
		// Do the effects to resize the Pox box
		pox_box.morph("width: " + dimensions_c.width + "px; left: " + box_left + "px; height: " + dimensions_c.height + "px; top: " + box_top + "px", {duration: 0.4});
		
		// Remove the Pox box's old childrem 
		children.each(Element.remove);
		
		// Make the new content fade in
		new Effect.Appear(container);
		
		this.pox_box = pox_box;
		
		// Process the form
		this.processForm();
	},
	
	processForm: function()
	{
		// Get the form
		var form = this.pox_box.select('form')[0];
		
		// Get all of the rating images
		this.images = form.select('a img');
		var image;
		
		// Attach the event listeners to the images
		for ( var i = 0, length = this.images.length; i < length; i++ )
		{
			image = this.images[i];
			
			image.observe('mouseover', this.mouseOver.bind(this));
			image.observe('mouseout', this.mouseOut.bind(this));
			image.observe('click', this.click.bind(this));
		}
		
		this.images = images;
	},
	
	mouseOver: function(e)
	{
		// Get the image from the event 
		var image = Event.findElement(e, 'img');
		
		// Change the images to reflect the mouseover
		for ( var i = 0, length = this.images.indexOf(image); i <= length; i++ )
		{
			this.images[i].src = "/images/seventeen/lip_pink.jpg";
		}
	},
	
	mouseOut: function(e)
	{
		// Get the image from the event 
		var image = Event.findElement(e, 'img');
		
		// Change the images to reflect the mouseout
		for ( var i = 0, length = this.images.indexOf(image); i <= length; i++ )
		{
			this.images[i].src = "/images/seventeen/lip_grey.jpg";
		}
	},
	
	click: function(e)
	{
		// Get the image from the event 
		var image = Event.findElement(e, 'img');
		
		// Get the index of the image that was clicked
		var index = this.images.indexOf(image);
		
		$('vo_id_' + index).checked = true;
		
		// Make the Ajax request to count the vote
		image.up('form').request({
  			onComplete: this.counted.bind(this)
		});
	},
	
	counted: function(transport)
	{
		// Show the thank you message
		this.pox_box.update('<div style="text-align: center; margin-bottom: 5px;">Thanks</div><a href="javascript: void(0);" onclick="Pox.hideHTML(document.body);" class="grey-button" style="float: none; width: 26px; font-size: 11px; font-weight: normal; margin: 0 auto;">Close</a>');
		this.pox_box.setStyle({height: ''});
		
		// Reload rating
		$('rating-' + this.field + '-' + this.item_id).replace(transport.responseText);
	}
}
var Rating = Class.create(RatingBase);


 
