/**
 * @class Voyeur.Corpus Corpus encapulates all the metadata of a Trombone corpus class.
 * You should not need to create a Corpus directly.
 * @constructor
 * @param {Object} data The corpus data object, or null to create an empty corpus.  The following are valid object properties:<ul>
 * <li><b>@id</b> : String<div class="sub-desc">The corpus id.</div></li>
 * <li><b>@lastModified</b> : String<div class="sub-desc">A timestamp indicating when the corpus was last modified.</div></li>
 * <li><b>@totalWordTokens</b> : String<div class="sub-desc">The total word tokens in the corpus.</div></li>
 * <li><b>@totalWordTypes</b> : String<div class="sub-desc">The total word types in the corpus.</div></li>
 * <li><b>documents</b> : Ext.util.MixedCollection<div class="sub-desc">The collection of documents contained in this corpus.</div></li>
 */
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 {String} The ID for this corpus.
	 */
	getId : function() {
		return this.record.get('id');
	},
	

	/**
	 * Get the metadata value for the specified key.
	 * @param {String} key The key for the metadata value.
	 * @return {Mixed} 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 {String|Number} key 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 {Ext.util.MixedCollection} The documents for this corpus.
	 */
	getDocuments: function() {
		return this.documents;
	},

	/**
	 * Get an array of short titles for documents in this corpus.
	 * @return {Array}
	 */
	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 {Array}
	 */
	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}
	 */
	,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}
	 */
	,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 {Integer}
	 */
	,getSize: function() {
		return this.documents.getCount();
	}

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

/**
 * @class Voyeur.Document Document encapsulates all the metadata of a Trombone document class.  You should not need to create a Document directly.
 */
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 {String} key The key for the metadata value.
	 * @return {Mixed} The metadata value for the specified key.
	 */
	get : function(key) {
		return this.record.get(key)
	},
	
	/**
	 * Gets a label for this document.
	 * @return {String} The document title, author, and date.
	 */
	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;
	},

	/**
	 * Gets a short label for this document.
	 * @return {String} The short document title, author, and date.
	 */
	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;
	},
	
	/**
	 * Gets the short document title.
	 * @return {String}
	 */
	getShortTitle : function() {
		return this.record.get('shortTitle');
	},
	
	/**
	 * Gets the document author (trimmed if necessary).
	 * @return {String}
	 */
	getShortAuthor : function() {
		var author = this.record.get('author');
		if (author.length > 15) {
			return author.substring(0, author.indexOf(" ", 10)) + "…";
		} else {
			return author
		}
	},
	
	/**
	 * Gets the data associated with the document.
	 * @return {Date}
	 */
	getDate : function() {
		return new Date(this.record.get('timeInMillis')).format("Y-m-d")
	}
	
	/**
	 * Gets the index for this document.
	 * @return {Integer}
	 */
	,getIndex: function() {
		return this.record.get('index');
	}
	
	/**
	 * Gets the ID for this document.
	 * @return {String}
	 */
	,getId: function() {
		return this.record.get('id');
	}

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

	/**
	 * Gets the  total number of tokens in the document.
	 * @return {Integer}
	 */
	,getTotalTokens: function() {
		return this.record.get('totalTokens')
	}
}

