﻿var Author = Class.create();
Author.prototype = {
	initialize: function (first, last, url) {
		this.first = first;
		this.last = last;
		this.url = url;
	}
}

var Authors = Class.create();
Authors.prototype = {
	initialize: function (sort_order) {
		this.sortOrder = sort_order;
		this.xml_file = '/kids/stacks/xml/authors.xml';
		this.columnClass = 'browseAuthorColumn';
		this.container = 'browseAuthorsWrapper';
		this.numberOfColumns = 3;
		this.itemsPerColumn = 0;
		this.columnsInserted = 0;
		this.names = new Array();
		this.loadXmlFile();
	},
	
	loadXmlFile: function () {
		new Ajax.Request(this.xml_file, {
			method: 'get',
			onSuccess: this.xmlReady.bind(this),
			onException: this.xmlReadyWrapper.bind(this)
		});
	},
	
	xmlReadyWrapper: function (request, e) {
		this.xmlReady(request.transport);
	},
	
	xmlReady: function (transport) {
		var rEl = transport.responseXML.getElementsByTagName('authors')[0];
		this.nameElements = rEl.getElementsByTagName('name');
		this.sort();
		this.show();
	},
	
	show: function () {
		if (!this.itemsPerColumn)
			this.itemsPerColumn = this.names.length / this.numberOfColumns;
		
		if ($(this.container).innerHTML)
			$(this.container).innerHTML = '';
		
		if (this.sortOrder == 'first') {
			this.currentIndex = this.names[0].first.charAt(0);
		} else {
			this.currentIndex = this.names[0].last.charAt(0);
		}
		
		this.setupNewColumn(this.currentIndex);
		this.names.length.times(this.showIterator.bind(this));
		
		if (this.currentColumn) this.insertColumn();
		$(this.container).insert(this.addClear());
		this.columnsInserted = 0;
	},
	
	insertColumn: function () {
		this.currentColumn.insert(this.currentList);
		$(this.container).insert(this.currentColumn);
		this.columnsInserted++;
		this.currentColumn = null;
		this.currentList = null;
	},
	
	showIterator: function (index) {
		var theAuthor = this.names[index];
		var firstChar = '';
		if (this.sortOrder == 'first') {
			firstChar = theAuthor.first.charAt(0);
		} else {
			firstChar = theAuthor.last.charAt(0);
		}
		
		if (this.currentIndex != firstChar.toUpperCase()) {
			if (index >= ((this.columnsInserted + 1) * this.itemsPerColumn)) {
				this.insertColumn();
				this.setupNewColumn(firstChar);
			} else {
				this.currentColumn.insert(this.currentList);
				this.currentColumn.insert(this.addHeading(firstChar));
				this.currentList = new Element('ul');
			}
		}
		
		if (theAuthor.first == theAuthor.last) {
				var fullname = theAuthor.first;
		} else if (this.sortOrder == 'first') {
			var fullname = theAuthor.first+' '+theAuthor.last;
		} else {
			// who in Last, First format ....
			var fullname = theAuthor.last+', '+theAuthor.first;
		}
		
		var li = new Element('li');
		var a = new Element('a', {href: theAuthor.url}).update(fullname);
		li.insert(a);
		this.currentList.insert(li);
	},
	
	showByFirst: function () {
		this.sort('first');
		this.show();
	},
	
	showByLast: function () {
		this.sort('last');
		this.show();
	},
	
	setupNewColumn: function (letter) {
		this.currentColumn = this.newColumn();
		this.currentColumn.insert(this.addHeading(letter));
		this.currentList = new Element('ul');
	},
	
	sort: function (order) {
		if (!this.names.length) {
			this.convertToArray();
		}
	
		if (order) {
			this.sortOrder = order;
		}
		
		if (this.sortOrder == 'first') {
			this.names.sort(this.sortByFirst);
		} else {
			this.names.sort(this.sortByLast);
		}
	},
	
	sortByLast: function (a, b) {
		var x = a.last.toLowerCase();
		var y = b.last.toLowerCase();
		return ((x<y) ? -1 : ((x>y) ? 1 : 0));
	},
	
	sortByFirst: function (a, b) {
		var x = a.first.toLowerCase();
		var y = b.first.toLowerCase();
		return ((x<y) ? -1 : ((x>y) ? 1 : 0));
	},
	
	convertToArray: function () {
		if (!this.nameElements)
			throw('No name elements found from XML source');
		
		this.nameElements.length.times(this.convertIterator.bind(this));
		delete this.nameElements;
	},
	
	convertIterator: function (index) {
		var item = this.nameElements.item(index);
		this.names[index] = new Author(this.first(item),this.last(item),this.url(item));
	},
	
	nodeValue: function (item, value) {
		return item.getElementsByTagName(value)[0].firstChild.nodeValue;
	},
	
	first: function (item) {
		return this.nodeValue(item, 'first');
	},
	
	last: function (item) {
		return this.nodeValue(item, 'last');
	},
	
	url: function (item) {
		return item.getAttribute('url');
	},
	
	clearContainer: function () {
		$(this.container).innerHTML = '';
	},
	
	newColumn: function () {
		return new Element('div', {'class': this.columnClass});
	},
	
	addClear: function () {
		return new Element('br', {style: 'clear: both;'});
	},
	
	addHeading: function (letter) {
		this.currentIndex = letter.toUpperCase();
		return new Element('h1').update(this.currentIndex);
	}
}

Event.observe(window, 'load', function () {
	var authorsObject = new Authors('last');
	$('authorsByFirst').observe('click', authorsObject.showByFirst.bind(authorsObject));
	$('authorsByLast').observe('click', authorsObject.showByLast.bind(authorsObject));
});