CouchStorage = function() {
	this.issues = [];
	this.issueById = {};
	this.projects = [];
	this.projectName = this['projectName']; // undefined
	this._globalIdSequence = 1;
	CouchStorage.superclass.constructor.call(this, arguments);
};

Ext.extend(CouchStorage, Ext.util.Observable, {

	addProject: function(data) {
		this.projects[this.projects.length] = data;
		this.fireEvent('load-projects', this);
	},
	
	deleteProjectById: function(projId) {
		var arr = [];
		each(this.projects, function(project) {
			if (project._id !== projId) {
				arr[arr.length] = project;
			}
		});
		this.projects = arr;
		this.fireEvent('load-projects', this);
	},

	generateId: function() {
		this._globalIdSequence = this._globalIdSequence + 1;
		return this._globalIdSequence;
	},
	
	generateUUID: function() {
		var S4 = function () {
		   return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
		};
		return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
	},
	
	getProjectById: function(projId) {
		var result = null
		each(this.projects, function(project) {
			if (project._id === projId) {
				result = project;
				return false;
			}
		});
		return result;
	},
	
	getProjects: function() {
		return this.projects;
	},
	
	getProjectName: function() {
		return this.projectName;
	},
	
	getIssueById: function(issueId) {
		return this.issueById[issueId];
	},
	
	getIssues: function() {
		return this.issues;
	},
	
	loadIssues: function(projectName) {
		this.projectName = projectName;
		var store = this;
		Ext.Ajax.request({
			method: 'GET',
			disableCaching: false,
			url: "/issues/_design/issues/_view/byProject",
			params: {
				key: '"' + projectName + '"',
				include_docs: true
			},
			success: function(response) {
				var data = eval('(' + response.responseText + ')');
				store.setIssues(data);
			}
		});
	},
	
	setProjects: function(data) {
		var projects = [];
		if (data.total_rows > 0) {
			each(data.rows, function(row) {
				projects[projects.length] = row.value;
			});
		}
		this.projects = projects;
		this.fireEvent('load-projects', this);
	},
	
	setIssues: function(data) {
		var issues = [];
		if (data.total_rows > 0) {
			each(data.rows, function(row) {
				var issue = row.value;
				issues[issues.length] = issue;
			});
		}
		issues = this._postProcessFields(issues);
		this.issues = this._sortData(issues);
		this.fireEvent('load-project', this);
	},
	
	// converts to ints etc
	_postProcessFields: function(issues) {
		each(issues, function(issue) {
			each(['businessPoints', 'id', 'storyPoints'], function(key) {
				var value = parseInt(issue[key]);
				if (isNaN(value)) {
					value = 0;
				}
				issue[key] = value;
			});
		});
		return issues;
	},
	
	_sortData: function(data) {
		this.issueById = {};
		each(data, function(issue) {
			issue.score = Math.round(issue.businessPoints / issue.storyPoints);
			this.issueById[issue.id] = issue;
		}, this);
	
		var current = 0;
		var run = true;
		while (run) {
			run = false;
			current = 0;
			while (current < data.length - 1) {
				var that = data[current];
				var next = data[current+1];
				if (next.status < that.status) {
					data[current] = next;
					data[current+1] = that;
					run = true;
				} else if (next.status == that.status) {
					if (next.businessPoints > that.businessPoints || (next.businessPoints == that.businessPoints && next.score > that.score)) {
						data[current] = next;
						data[current+1] = that;
						run = true;
					}
				}
	
				// fix globalId
				if (that.id > this._globalIdSequence) {
					this._globalIdSequence = 0 + that.id;
				}
				
				current++;
			}
		}
		return data;
	},
	
	/* ---- Move to issueController.js --- */
		
	// saves only new ones
	save: function(issue, successFn) {
		var store = this;
		issue._id = this.generateUUID();
		Ext.Ajax.request({
			method: 'PUT',
			disableCaching: false,
			url: '/issues/' + issue._id,
			jsonData: issue,
			success: function(response) {
				var data = eval('(' + response.responseText + ')');
				issue._rev = data.rev;
				store._save(issue);
				if (successFn) {
					successFn.call(this, data);
				}
				store.fireEvent('update', store);
			},
			failure: function(response) {
				alert('fail ' + response.responseText);
			}
		});
	},
	
	_save: function(issue) {
		this.issues[this.issues.length] = issue;
		this.issues = this._sortData(this.issues);
	},
	
	update: function(issue, successFn) {
		var store = this;
		Ext.Ajax.request({
			method: 'PUT',
			disableCaching: false,
			url: '/issues/' + issue._id,
			jsonData: issue,
			success: function(response) {
				var data = eval('(' + response.responseText + ')');
				issue._rev = data.rev;
				store._update(issue);
				if (successFn) {
					successFn.call(this, data);
				}
				store.fireEvent('update', store);
			},
			failure: function(response) {
				alert('fail ' + response.responseText);
			}
		});
	},
	
	_update: function(data) {
		var issue = this.issueById[data.id];
		for (var key in data) {
			issue[key] = data[key];
		}
		this.issues = this._sortData(this.issues);
	}
});

