Voyeur.Corpus = function(data) {
	var store = new Ext.data.JsonStore( {
		fields : Voyeur.data.Corpus.fields,
		data : data ? [data] : [{'@id': new Date().getTime()+'.'+parseInt(Math.random()*10000)}]
	})
	this.record = store.getAt(0);
	this.documents = new Ext.util.MixedCollection();
	if (data && data.documents) {
		var doc;
		var dates = new Ext.util.MixedCollection();
		var authors = new Ext.util.MixedCollection();
		for ( var i = 0; i < data.documents.length; i++) {
			doc = new Voyeur.Document(data.documents[i]);
			this.documents.add(doc.get('id'), doc);
		}
		if (this.getAuthors().length<2) {
			this.documents.each(function(doc) {doc.isAllSameAuthor=true;})
		}
		if (this.getDates().length<2) {
			this.documents.each(function(doc) {doc.isAllSameDate=true;})
		}
			
	}
}
Voyeur.Corpus.prototype = {

	/**
	 * Get the ID for this corpus.
	 * @return the ID for this corpus
	 */
	getId : function() {
		return this.record.get('id');
	},
	

	/**
	 * Get the metadata value for the specified key
	 * @param key the key for the metadata value
	 * @return the metadata value for the specified key
	 */
	get : function(key) {
		return this.record.get(key)
	},
	
	/**
	 * Get the document specified by the key (number for index, string for id)
	 * @param key {String|Number} the key to use (number for index, string for id)
	 * @return {Voyeur.Document} the document specified by the key
	 */
	getDocument: function(key) {
		return this.documents.get(key);
	},

	/**
	 * Get the documents for this corpus, as a {@link Ext.util.MixedCollection}.
	 * @return the documents for this corpus, as a {@link Ext.util.MixedCollection}
	 */
	getDocuments: function() {
		return this.documents;
	},

	/**
	 * Get an array of short titles for documents in this corpus.
	 * 
	 * @return an array of short titles for documents in this corpus
	 */
	getShortTitles : function() {
		var titles = [];
		this.documents.each(function(item) {
			titles.push(item.get('title'))
		})
		return titles;
	}

	/**
	 * Get an array of short labels for documents in this corpus.
	 * 
	 * @return an array of short titles for documents in this corpus
	 */
	,
	getShortLabels : function() {
		var labels = [];
		this.documents.each(function(item) {
			labels.push((parseInt(item.get('index')) + 1) + ") "
					+ item.getShortTitle())
		}, this);
		return labels;
	}
	
	/**
	 * Get an array of the unique authors in this corpus.
	 * @return {Array} an array of the unique authors in this corpus
	 */
	,getAuthors: function() {
		var auth = {};
		this.documents.each(function(doc) {auth[doc.get('author')]=true;});
		var authors = [];
		for (var k in auth) {authors.push(k);}
		return authors;
	}

	/**
	 * Get an array of the unique dates in this corpus.
	 * @return {Array} an array of the unique authors in this corpus
	 */
	,getDates: function() {
		var dats = {};
		this.documents.each(function(doc) {dats[doc.getDate()]=true;});
		var dates = [];
		for (var k in dats) {dates.push(k);}
		return dates;
	}
	
	/**
	 * Gets the number of documents in the current corpus.
	 * @return {Number} an integer representing the number of documents in the current corpus;
	 */
	,getSize: function() {
		return this.documents.getCount();
	}

	/**
	 * Determine if the corpus contains any documents.
	 * @return {boolean} whether or not the corpus contains any documents
	 */
	,isEmpty: function() {
		return this.documents.getCount==0;
	}
	
	/**
	 * Get total number of words in the corpus.
	 * @return {Number} the number of words in the corpus
	 */
	,getTotalWordTokens: function() {
		return this.record.get('totalWordTokens')
	}
}

Voyeur.Document = function(data) {
	var store = new Ext.data.JsonStore( {
		fields : Voyeur.data.Document.fields,
		data : data ? [ data ] : []
	})
	this.record = store.getAt(0);
	
	// private – we'll make the short label shorter if all dates are the same
	this.isAllSameDate = false;
	
	// private – we'll make the short label shorter if all authors are the same
	this.isAllSameAuthor = false;
}

Voyeur.Document.prototype = {

	/**
	 * Get the metadata value for the specified key
	 * @param key the key for the metadata value
	 * @return the metadata value for the specified key
	 */
	get : function(key) {
		return this.record.get(key)
	},
	
	getLabel : function() {
		var label = (parseInt(this.record.get('index')) + 1) + ") ";
		label += this.get('title');
		if (!this.isAllSameAuthor) {
			var author = this.getShortAuthor();
			label += author.length > 0 ? ' (' + author + ')' : ''
		}
		if (!this.isAllSameDate) {label += ' '+this.getDate() + " "}
		return label;
	},

	getShortLabel : function() {
		var label = (parseInt(this.record.get('index')) + 1) + ") ";
		label += this.getShortTitle();
		if (!this.isAllSameAuthor) {
			var author = this.getShortAuthor();
			label += author.length > 0 ? ' (' + author + ')' : ''
		}
		if (!this.isAllSameDate) {label += ' '+this.getDate() + " "}
		return label;
	},
	getShortTitle : function() {
		return this.record.get('shortTitle');
	},
	getShortAuthor : function() {
		var author = this.record.get('author');
		if (author.length > 15) {
			return author.substring(0, author.indexOf(" ", 10)) + "&hellip;";
		} else {
			return author
		}
	},
	getDate : function() {
		return new Date(this.record.get('timeInMillis')).format("Y-m-d")
	}
	
	/**
	 * Get the index for this document.
	 * @return the index for this document
	 */
	,getIndex: function() {
		return this.record.get('index');
	}
	
	/**
	 * Get the ID for this document.
	 * @return the ID for this document
	 */
	,getId: function() {
		return this.record.get('id');
	}

	/**
	 * Get total number of words in the corpus.
	 * @return {Number} the number of words in the corpus
	 */
	,getTotalWordTokens: function() {
		return this.record.get('totalWordTokens')
	}
}
