
argos.classes = new (function() {
	
	// Global JS Classes to be used across the site.
	var _classes = this;


	/* ELEMENT (Creates an extended Object with access to jQuery/HTML element)
	**************************************************************************/
	function Element(htmlOrDomElement) {
		// Used by classes to inherit jQueryElement and HTML.extended functionality.
		// See tv.js and scroller.js for working examples.
		var _properties = {};
		if(htmlOrDomElement) {
			// Avoid errors when inheriting prototype (e.g. MyClass.prototype = new Element())
			this.$node = $(htmlOrDomElement);
			this.node = this.$node.get(0);
			this.node.Element = this;
		}
		
		this.property = function(prop, value) {
			if(arguments.length > 1) {
				_properties[prop] = value;
			}
			return _properties[prop];
		}
		this.properties = function() {	
			var properties = new Array();
			for(var property in _properties) {
				properties.push(property);
			}
			return properties;
		}
 	}
	Element.prototype = {
		setStatus : function(status) {
			// Passing  empty (or undefined) to .remove causes delete all classes.
			var current = this.property("status");
			this.$node.removeClass(current ? current : "none");
			this.$node.addClass(status);
			this.property("status", status);
		},
		resetInlineStyle : function() {
			this.$node.attr("style", "");
		}
	}
	

	/* BUTTON (standard reusable button)
	************************************/
	function Button(properties) {
		var disabledClass = properties.cssClass + (properties.cssClassDisabled ? properties.cssClassDisabled : properties.cssClass + "Disabled"); // doing this way to compensate for IE6 lack of multiple class support.
		Element.call(this, "<button class=\"" + properties.cssClass + "\" title=\"" + properties.title + "\" type=\"button\"><span>" + properties.text + "</span></button>");

		// Apply events.
		for(var event in properties.events) {
			this.$node.bind(event, properties.events[event]);
		}
		
		// Work out disabled status.
		this.property("disabledClass", disabledClass);
		if(properties.disabled) {
			this.property("disabled", true);
			this.$node.addClass(disabledClass);
		}
		
		// Compensation for lack of :hover support in IE6
		if(properties.supportIE6HoverOnButtons && jQuery.browser.msie && Math.floor(jQuery.browser.version) <= 6) {
			this.$node.bind("mouseover mouseout", function() { $(this).toggleClass(properties.cssClass + "Hover"); });
		}
	}
	Button.prototype.clickable = function(enable) {
		var disabledClass = this.property("disabledClass");
		if(enable) {
			this.property("disabled", false);
			this.$node.removeClass(disabledClass);
		}
		else {
			this.property("disabled", true);
			this.$node.addClass(disabledClass);
		}
	}


	/* COLLECTION (jQuery Collection allowing for old version)
	***********************************************************/
	function Collection() {
		// Compensate for differences in jQuery versions.
		jQuery.extend(this, (this.jquery < 1.4) ? $() : $().slice(1));
	}
	Collection.prototype.reverse = function() {
		// This won't exist if you use jQuery collection.add because that returns a new jQuery object.
		var $reversed =  new _classes.Collection();
		for(var i=this.length; i>=0; --i) {
			$reversed = $reversed.add(this.eq(i));
		}
		return $reversed;
	} 
	

	/* POLLING FUNCTION
	**************************************************************/
	function Ping(config) {
		// Allows you to setup a function to run when finally done.
		var _delay = config["delay"] ? config.delay : 500;
		var _limit = config["limit"] ? config.limit : 60000; // 1000 = 1 second.
		var _whenReadyTries = 0;
		var _config = config ? config : {};

		function _whenReady() {
			var repeat = _config["onEach"] ? _config.onEach.apply(this, _config["argumentsOnEach"]) : false;
			if(!repeat || (_limit && _whenReadyTries++ * _delay > _limit)) {
				// Fires when limit is reached.

				if(_config["onEnd"]) {
					_config.onEnd.apply(this, _config["argumentsOnEnd"]);
				} 
			}
			else {
				// Fires onEach ping.
				window.setTimeout(_whenReady, _delay);
			}
		}
	}
	

	// Make the classes public and available to all.
	this.Element = Element;
	this.Button = Button;
	this.Collection = Collection;
	this.Ping = Ping;
	

	
});
