(function($, F){
	/**
	 * The direction to sort if the {@link FooTable.Column#sorted} property is set to true. Can be "ASC", "DESC" or NULL. Added by the {@link FooTable.Sorting} component.
	 * @type {string}
	 * @default null
	 */
	F.Column.prototype.direction = null;
	/**
	 * Whether or not the column can be sorted. Added by the {@link FooTable.Sorting} component.
	 * @type {boolean}
	 * @default true
	 */
	F.Column.prototype.sortable = true;
	/**
	 * Whether or not the column is sorted. Added by the {@link FooTable.Sorting} component.
	 * @type {boolean}
	 * @default false
	 */
	F.Column.prototype.sorted = false;

	/**
	 * This is supplied two values from the column for a comparison to be made and the result returned. Added by the {@link FooTable.Sorting} component.
	 * @param {*} a - The first value to be compared.
	 * @param {*} b - The second value to compare to the first.
	 * @returns {number}
	 * @example <caption>This example shows using pseudo code what a sort function would look like.</caption>
	 * "sorter": function(a, b){
	 * 	if (a is less than b by some ordering criterion) {
	 * 		return -1;
	 * 	}
	 * 	if (a is greater than b by the ordering criterion) {
	 * 		return 1;
	 * 	}
	 * 	// a must be equal to b
	 * 	return 0;
	 * }
	 */
	F.Column.prototype.sorter = function(a, b){
		if (typeof a === 'string') a = a.toLowerCase();
		if (typeof b === 'string') b = b.toLowerCase();
		if (a === b) return 0;
		if (a < b) return -1;
		return 1;
	};

	/**
	 * This is supplied either the cell value or jQuery object to parse. A value must be returned from this method and will be used during sorting operations.
	 * @param {(*|jQuery)} valueOrElement - The value or jQuery cell object.
	 * @returns {*}
	 * @this FooTable.Column
	 */
	F.Column.prototype.sortValue = function(valueOrElement){
		// if we have an element or a jQuery object use jQuery to get the value
		if (F.is.element(valueOrElement) || F.is.jq(valueOrElement)){
			var data = $(valueOrElement).data('sortValue');
			return F.is.defined(data) ? data : this.parser(valueOrElement);
		}
		// if options are supplied with the value
		if (F.is.hash(valueOrElement) && F.is.hash(valueOrElement.options)){
			if (F.is.string(valueOrElement.options.sortValue)) return valueOrElement.options.sortValue;
			if (F.is.defined(valueOrElement.value)) valueOrElement = valueOrElement.value;
		}
		if (F.is.defined(valueOrElement) && valueOrElement != null) return valueOrElement;
		return null;
	};

	// this is used to define the sorting specific properties on column creation
	F.Column.prototype.__sorting_define__ = function(definition){
		this.sorter = F.checkFnValue(this, definition.sorter, this.sorter);
		this.direction = F.is.type(definition.direction, 'string') ? F.Sorting.dir(definition.direction) : null;
		this.sortable = F.is.boolean(definition.sortable) ? definition.sortable : true;
		this.sorted = F.is.boolean(definition.sorted) ? definition.sorted : false;
		this.sortValue = F.checkFnValue(this, definition.sortValue, this.sortValue);
	};

	// overrides the public define method and replaces it with our own
	F.Column.extend('define', function(definition){
		this._super(definition);
		this.__sorting_define__(definition);
	});

})(jQuery, FooTable);