if (typeof(ADC) == 'undefined') ADC = {};




ADC.Sort = Class.create({

	initialize: function(table, options) {
		// we need something there buck-o
		if (!table) return false;
		
		this.table = table;
		this.table.header = table.down('thead');
		this.table.bodies = table.select('tbody');

		this.options = options || {};
		this.initial = { by:this.options.initial || 'name' }
		this.initial.header = this.table.header.down('.'+this.initial.by);
		
		this.setHeaderLinks();

		if (this.options.initialDirection) this.initial.header.addClassName(this.options.initial.direction);
		this.handleSort(null, this.initial.header);

		this.setFilter();
	},

	setHeaderLink: function(header) {
		if (header.hasClassName('nosort')) return;

		var link = new Element('a').update(header.innerHTML);
		link.observe('click', this.handleSort.bindAsEventListener(this, header));
		header.update(link);
	},

	setHeaderLinks: function() {
		this.table.headers = this.table.header.select('tr th');
		this.table.headers.each(this.setHeaderLink.bind(this));
	},

	resetHeader: function(header) {
		header.className = header.className.replace(/[^\s]*scending/, '').strip();
	},

	resetHeaders: function(header) {
		var headers = this.table.headers.without(header);
		headers.each(this.resetHeader.bind(this));
	},

	handleSort: function(evt, header) {
		if (evt) Event.stop(evt);
		this.resetHeaders(header);

		var by = header.className.replace(/[^\s]*scending/, '').strip();
		var className = by;
		var classes = className.split(' ');
		if (classes.length>0) by = classes[0];

		var direction = this.options.direction || 'descending';
		if (header.className.match(/[^\s]*scending/)) direction = header.className.match(/[^\s]*scending/)[0];
		direction = (direction == 'ascending') ? 'descending' : 'ascending';

		header.className = className +' '+ direction;
		this.sort(by, direction);
	},

	sort: function(by, direction) {
		this.table.bodies.each(function(table) {
			var rows = table.select('tr');
			rows.sort(this.compare.bind(null, this.compare.bind(null, null, this.initial.by), by, direction));
			table.update('');

			rows.each(function(row) {
				table.insert(row);
			});
		}.bind(this))
	},

	compare: function(callback, by, direction, a, b) {
		if ($(a).down('th')) return -1;
		if ($(b).down('th')) return 1;

		if ($(a).down('.'+by)) var aStr = $(a).down('.'+by).innerHTML.stripTags().strip();
		if ($(b).down('.'+by)) var bStr = $(b).down('.'+by).innerHTML.stripTags().strip();

		var date = /(\d\d)\/(\d\d)\/(\d\d\d\d) (\d\d):(\d\d) ([AP]M)/;
		var aDate = aStr.match(date);
		var bDate = bStr.match(date);

		if (aStr && bStr) {
			if (aDate || bDate) {
				if ((direction=='ascending' && !aDate) || (direction=='descending' && !bDate)) return -1;
				if ((direction=='ascending' && !bDate) || (direction=='descending' && !aDate)) return 1;

				// year
				if ((direction=='ascending' && parseInt(aDate[3])>parseInt(bDate[3])) || (direction=='descending' && parseInt(aDate[3])<parseInt(bDate[3]))) return -1;
				if ((direction=='ascending' && parseInt(aDate[3])<parseInt(bDate[3])) || (direction=='descending' && parseInt(aDate[3])>parseInt(bDate[3]))) return 1;
				
				// month
				if ((direction=='ascending' && parseInt(aDate[1])>parseInt(bDate[1])) || (direction=='descending' && parseInt(aDate[1])<parseInt(bDate[1]))) return -1;
				if ((direction=='ascending' && parseInt(aDate[1])<parseInt(bDate[1])) || (direction=='descending' && parseInt(aDate[1])>parseInt(bDate[1]))) return 1;
				
				// day
				if ((direction=='ascending' && parseInt(aDate[2])>parseInt(bDate[2])) || (direction=='descending' && parseInt(aDate[2])<parseInt(bDate[2]))) return -1;
				if ((direction=='ascending' && parseInt(aDate[2])<parseInt(bDate[2])) || (direction=='descending' && parseInt(aDate[2])>parseInt(bDate[2]))) return 1;
				
				// am/pm
				if ((direction=='ascending' && aDate[6]>bDate[6]) || (direction=='descending' && aDate[6]<bDate[6])) return -1;
				if ((direction=='ascending' && aDate[6]<bDate[6]) || (direction=='descending' && aDate[6]>bDate[6])) return 1;
				
				// hour
				if ((direction=='ascending' && parseInt(aDate[4])>parseInt(bDate[4])) || (direction=='descending' && parseInt(aDate[4])<parseInt(bDate[4]))) return -1;
				if ((direction=='ascending' && parseInt(aDate[4])<parseInt(bDate[4])) || (direction=='descending' && parseInt(aDate[4])>parseInt(bDate[4]))) return 1;
				
				// minute
				if ((direction=='ascending' && parseInt(aDate[5])>parseInt(bDate[5])) || (direction=='descending' && parseInt(aDate[5])<parseInt(bDate[5]))) return -1;
				if ((direction=='ascending' && parseInt(aDate[5])<parseInt(bDate[5])) || (direction=='descending' && parseInt(aDate[5])>parseInt(bDate[5]))) return 1;
			} else {
				if ((direction=='ascending' && aStr>bStr) || (direction=='descending' && aStr<bStr)) return 1;	
				if ((direction=='ascending' && aStr<bStr) || (direction=='descending' && aStr>bStr)) return -1;
			}

			if (callback) return callback(direction, a, b);
		}

		return 0;
	},
	
	setFilter: function() {
		var table = this.table;
		var select = $(document.body).down('div.filter select');
		if (select) {
			var tableClass = this.table.className;

			select.observe('change', function() {
				var value = ($F(select));

				table.className = tableClass +' '+ value;

				// causing issues with the overlay trigger, after sorting. might be related to scrollable content area?
				// var reset = table.innerHTML;
				// table.update('').update(reset);
			});
		}
	}
	
});




ADC.Truncate = Class.create({

	initialize: function(items, truncateTo) {
		// we need something there buck-o
		if (!items) return false;
		
		this.items = [];
		this.to = truncateTo;
		
		items.each(this.setUp.bind(this));
	},

	setUp: function(item) {
		if (item.innerHTML.length>this.to) {
			this.items.push(item);
			this.truncate(item);
		}
	},

	truncate: function(item) {
		var content = item.innerHTML;
		if (item.down('.replaced')) content = item.down('.replaced').innerHTML;

		// finder style
		// var start = content.substring(0, this.to-5);
		// var end = content.substring(content.length-5, content.length);
		// item.innerHTML = start+'...'+end;

		// end truncation
		var substring = content.substring(0, this.to);
		item.innerHTML = substring+'...';

		item.title = content;
	}

});
