/**
*
* @package MoltX Live Post
* @author $Author: moltendorf $
* @version $Id: molten_phpbb_post.js 32 2009-10-01 15:11:04Z moltendorf $
* @latest $URL: https://molten-phpbb-post.googlecode.com/svn/trunk/source/styles/prosilver/template/molten_phpbb_post.js $
* @copyright (c) 2005-2009 Matthew Oltendorf
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/

// JavaScript Document

var molten_phpbb_post, molten_phpbb_post_object;

( function ( $ )
{
	var object;

	/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
	// Name: molten_phpbb_post.
	// Type: Singleton.
	// Title: MoltX Live Post Ajax Object.
	// Description: Communicate efficiently.
	// Variables: rate
	//	1. scan: The file to query for scan information.
	//	1. query: The file to query for the new posts.
	//	1. rate: The rate (in seconds) that Live Post checks for new information.
	//	Default: 15
	// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
	window.molten_phpbb_post_object = object = function ( scan, scanId, scanMode, scanPost, query, sort, guessSort, rate )
	{
		// Bind jQuery to $.
		var $ = this.$ = window.jQuery;

		if ( typeof scan !== 'string' || typeof query !== 'string' )
		{
			return false;
		}

		// Check for valid input.
		if ( typeof rate !== 'number' )
		{
			rate = 15;
		}
		else if ( rate < 1 )
		{
			rate = 15;
		}

		// Set URIs.
		this.scanURI = scan;
		this.queryURI = query;

		// Set data.
		this.scanId = scanId;
		this.scanMode = scanMode;
		this.scanPost = scanPost;

		// Set switches.
		this.sort = sort;
		this.guessSort = guessSort;

		// Set the rate of update.
		this.rate = rate * 1000;

		// Let's begin.
		this.scan ( );

		return true;
	}

	// Prototype it!
	object.prototype = {
		// jQuery!
		$: null,

		// URIs.
		scanURI: '',
		queryURI: '',

		// Data.
		scanId: '',
		scanMode: '',
		scanPost: '',

		// The rate of update.
		rate: 15,

		// Hidden elements.
		hidden: new Array ( ),

		// Switches.
		connected: true,
		receiving: false,
		sort: false,
		guessSort: false,

		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: action
		// Title: Handle action.
		// Variables: action
		//	1. action: The action to run.
		// Description: Run a specific action.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		action: function ( action )
		{
			switch ( action )
			{
				case 'disconnect':
					this.connected = false;
				break;
			}

			return true;
		},

		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: check
		// Title: Check information.
		// Variables: document, status
		//	1. document: The XML document containing the latest post information.
		//	2. status: The status of the request.
		// Description: Check for new posts.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		check: function ( document, status )
		{
			// Bind jQuery to $.
			var $ = this.$, actions, data, i, id, key, post, value;

			actions = $ ( 'action', document );

			for ( i = 0; i < actions.length; ++i )
			{
				this.action ( $ ( actions[ i ] ).attr ( 'type' ) );
			}


			data = $ ( 'data', document );

			for ( i = 0; i < data.length; ++i, key = $ ( data[ i ] ).attr ( 'type' ), value = $ ( data[ i ] ).attr ( 'value' ) )
			{
				switch ( key )
				{
					case 'post':
						post = value;
					break;
				}
			}

			if ( post > this.scanPost )
			{
				this.query ( );
			}
			else
			{
				this.scan ( 2 );
			}

			// Update local counter.
			this.scanPost = post;

			return true;
		},

		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: query
		// Title: Query server.
		// Variables: None.
		// Description: Get new posts from the server.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		query: function ( )
		{
			if ( ! this.connected )
			{
				return false;
			}

			// Bind jQuery to $.
			var $ = this.$, options;

			this.receiving = true;

			options = {
				cache: false,
				dataType: 'html',
				error: function ( document, status ) // Use anonymous function to prevent it from screwing up "this."
				{
					alert (status);
					return window.molten_phpbb_post.scan ( 2 ); // Discard arguments.
				},
				global: false,
				success: function ( document, status ) // Use anonymous function to prevent it from screwing up "this."
				{
					return window.molten_phpbb_post.response ( document, status );
				},
				timeout: 30000,
				url: this.queryURI
			};

			// Get the info.
			$.ajax ( options );

			return true;
		},

		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: response
		// Title: Handle response.
		// Variables: document
		//	1. document: The current XHTML or XML version of this page.
		//	2. status: The status of the request.
		// Description: Registers a chat client instance.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		response: function ( document, status )
		{
			// Bind jQuery to $.
			var $ = this.$, current, hidden = new Array ( ), i, last, local = new Array ( );

			// Get post containers.
			current = $ ( '#molten_phpbb_post > *', document );
			local = $ ( '#molten_phpbb_post > *' );

			if ( current.length < 1 || local.length < 1 || current.length < local.length )
			{
				// Something is messed up with the setup. Bye bye!
				this.action ( 'disconnect' );

				return false;
			}

			if ( current.length != local.length )
			{
				// Alright, we gotta add stuff now...
				if ( ! this.guessSort )
				{
					// Standard sorting modes: posts are either appended, or prepended.
					if ( ! this.sort )
					{
						// Ascending.
						for ( i = (current.length - (current.length - local.length)); i < current.length; ++i )
						{
							$ ( current[ i ] ).hide (  ); // Hide element.
							hidden.push ( current[ i ] ); // Add element to hidden array for later showing.
						}

						$ ( '#molten_phpbb_post' ).append ( hidden );
					}
					else
					{
						// Descending.
						for ( i = (current.length - local.length - 1); i >= 0; --i )
						{
							$ ( current[ i ] ).hide (  ); // Hide element.
							hidden.unshift ( current[ i ] ); // Add element to hidden array for later showing.
						}

						$ ( '#molten_phpbb_post' ).prepend ( hidden );

						// Flip it.
						hidden.reverse ( );
					}
				}
				else
				{
					// Unknown sorting mode: posts are added in the places they appear, and shown in the order they appear; not done!
				}
			}

			// We make it fancy-like.
			this.hidden = this.hidden.concat ( hidden );

			if ( this.hidden.length == hidden.length )
			{
				this.unhide ( );
			}

			this.scan ( 2 );

			return true;
		},

		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: scan
		// Title: Get information.
		// Variables: check
		//	1. check: Whether or not to check for new information.
		//	Default: false
		// Description: Check for new posts.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		scan: function ( check )
		{
			if ( ! this.connected )
			{
				return false;
			}

			// Bind jQuery to $.
			var $ = this.$, options, scan;

			// "None shall pass!"
			// "What?"
			// "None shall pass!"
			// "I have no quarrel with you good sir knight, but I must cross this bridge."
			// "Then you shall die!"
			// "I command you, as King of the Britains, to stand aside!"
			// "I move for no man."
			// "So be it!"
			if ( check != 2 && this.receiving )
			{
				return false;
			}
			else if ( check == 2 )
			{
				this.receiving = false;
			}

			if ( ! check || check == 2 )
			{
				scan = function ( ) // Use anonymous function to prevent it from screwing up "this."
				{
					return window.molten_phpbb_post.scan ( 1 );
				};

				// Rescan.
				setTimeout ( scan, this.rate );
			}
			else
			{
				this.receiving = true;

				options = {
					cache: false,
					data: {
						id: this.scanId,
						mode: this.scanMode,
						post: this.scanPost
					},
					dataType: 'xml',
					error: function ( document, status ) // Use anonymous function to prevent it from screwing up "this."
					{
						return window.molten_phpbb_post.scan ( 2 ); // Discard arguments.
					},
					global: false,
					success: function ( document, status ) // Use anonymous function to prevent it from screwing up "this."
					{
						return window.molten_phpbb_post.check ( document, status );
					},
					timeout: 30000,
					url: this.scanURI
				};
				
				// Get the info.
				$.ajax ( options );
			}

			return true;
		},

		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: unhide
		// Title: Unhide posts.
		// Variables: None.
		// Description: Unhide hidden posts one-at-a-time.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		unhide: function ( )
		{
			// Bind jQuery to $.
			var $ = this.$, element, unhide;

			element = this.hidden.shift ( );

			if ( this.hidden.length > 0 )
			{
				unhide = function ( )
				{
					return window.molten_phpbb_post.unhide ( );
				}

				$ ( element ).show ( 'slow', unhide );
			}
			else
			{
				$ ( element ).show ( 'slow' );
			}
		}
	}
}
) ( window.jQuery );