ProjectView = function(model) {
	this.model = model;
	
	this.model.on('load-projects', this.showProjectList, this);
	debug('ProjectView(' + couchStore + ")");
}

ProjectView.prototype = {
	showProjectList: function(store) {
		debug('ProjectView.showProjectList');
		var result = "<div class='header'>Project List</div>";
		each(store.getProjects(), function(project) {
			result += "<div class='project' id='project-" + project._id + "'>" +
				"<span class='project-name' onClick='showIssueListView(\"" + project.name + "\")'>" + project.name + "</span>" +
				"<div class='project-actions' id='project-actions-" + project._id + "'>" +
				"<span class='project-action' onClick='projectController.edit(\"" + project._id + "\")'>Edit</span>" +
				"</div>" +
				"</div>";
		});
		list = Ext.get('projectList');
		this._preDestroyProcess();
		list.replaceWith({
			id: 'projectList',
			tag: 'div',
			cls: 'fluffContent',
			html: result
		});
		showView('projectListView');
		list.setVisible(true, true);
		this._postProcessProjects();
	},
	
	_preDestroyProcess: function() {
		// IMPROVEMENT: this should really work on the DOM, not the projects since that list might be longer/shorter
		debug("ProjectView._preDestroyProcess");
		var projects = this.model.getProjects();
		each(projects, function(project) {
			var element = Ext.get('project-' + project._id);
			if (element && element.purgeListeners) {
				element.purgeListeners();
			}
		});
	},
	
	_postProcessProjects: function() {
		debug("ProjectView._postProcessProjects");
		var projects = this.model.getProjects();
		each(projects, function(project) {
			var element = Ext.get('project-' + project._id);
			element.hover(this._showActions, this._hideActions, this);
			debug("ProjectView._postProcessProjects " + project.name + " " + project._id);
		}, this);
	},
	
	_showActions: function(event, target, options) {
		if (target.nodeName === "SPAN" || target.parentNode.className === 'project') {
			return this._showActions(event, target.parentNode, options);
		}
		var id = target.id.substr(target.className.length);
		var div = "project-actions" + id;
		Ext.get(div).addClass('fluff-show');
	},
	
	_hideActions: function(event, target, options) {
		if (target.nodeName === "SPAN" || target.parentNode.className === 'project') {
			return this._hideActions(event, target.parentNode, options);
		}
		var id = target.id.substring(target.className.length);
		var div = "project-actions" + id;
		Ext.get(div).removeClass('fluff-show');
	},
	
	_getId: function(element) {
		return {
			id: element._id
		};
	}
}

ProjectController = function(couchStore) {
	this.store = couchStore;
	this.formView = {
		show: function() {
			Ext.get('editProjectForm').addClass('fluff-show');
			document.getElementById('editProjectForm_name').select();
			document.getElementById('editProjectForm_name').focus();
		},
		hide: function() {
			Ext.get('editProjectForm').removeClass('fluff-show');
		}
	};
	debug('ProjectController(' + couchStore + ")");
};

ProjectController.prototype = {
	
	cancelEdit: function() {
		this.formView.hide();
	},

	deleteProject: function() {
		if (confirm('Vill du verkligen ta bort projektet?')) {
			this._deleteProject(this.formView.hide);
		}
	},
	
	edit: function(projectId) {
		if (!projectId) {
			this.updateFormValues({
				_id: -1,
				name: ''
			});
		} else {
			this.updateFormValues(this.store.getProjectById(projectId));
		}
		this.formView.show();
	},
	
	generateUUID: function() {
		var S4 = function () {
		   return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
		};
		return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
	},
	
	getFormValue: function(key) {
		var field = document.getElementById('editProjectForm_' + key);
		return field.value;
	},

	// saves only new ones
	saveEdit: function() {
		var id = this.getFormValue('_id');
		var project = {
			type: 'project',
			name: this.getFormValue('name')
		};
		
		if (id == -1) {
			project._id = this.generateUUID();
		} else {
			project._id = id;
			project._rev = this.getFormValue('_rev');
		}
		
		this._saveObject(project, this.formView.hide.createDelegate(this.formView));
	},
	
	setFormValue: function(key, value) {
		var field = document.getElementById('editProjectForm_' + key);
		field.value = value;
	},
	
	showProjectList: function() {
		debug('ProjectController.showProjectList()');
		this._loadProjects();
	},
	
	updateFormValues: function(project) {
		for (key in project) {
			this.setFormValue(key, project[key]);
		}
	},

	
	_deleteProject: function(callBackFn) {
		debug('ProjectController._deleteProject()');
		var _id = this.getFormValue('_id');
		var _rev = this.getFormValue('_rev');
		if (_id == -1) {
			alert('Kan inte ta bort projekt som inte sparats.');
			return;
		}
		
		var store = this.store;
		Ext.Ajax.request({
			method: 'DELETE',
			disableCaching: false,
			url: '/issues/' + _id + "?rev=" + _rev,
			success: function(response) {
				var data = eval('(' + response.responseText + ')');
				store.deleteProjectById(_id);
				if (callBackFn) {
					callBackFn.call(this, data);
				}
			}
		});
	},
	
	_loadProjects: function() {
		debug('ProjectController._loadProjects()');
		var store = this.store;
		Ext.Ajax.request({
			method: 'GET',
			disableCaching: false,
			url: '/issues/_design/projects/_view/byName/',
			success: function(response) {
				var data = eval('(' + response.responseText + ')');
				store.setProjects(data);
			}
		});
	},
	
	_saveObject: function(obj, successFn) {
		var store = this.store;
		Ext.Ajax.request({
			method: 'PUT',
			disableCaching: false,
			url: '/issues/' + obj._id,
			jsonData: obj,
			success: function(response) {
				var data = eval('(' + response.responseText + ')');
				obj._rev = data.rev;
				store.addProject(obj);
				if (successFn) {
					successFn.call(this, data);
				}
			},
			failure: function(response) {
				alert('fail ' + response.responseText);
			}
		});
	},
	
	_updateObject: 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);
	}
};

Project = function() {
	this.name = 'n/a';
	this.issues = [];
	this.issueMapById = {};
};

Project.prototype = {
	getIssues: function() {
		return this.issues;
	},
	
	getIssue: function(id) {
		return this.issueMapById[id];
	},
	
	setName: function(name) {
		this.name = name;
	},
	
	getName: function() {
		return this.name;
	}
};

var projectController = new ProjectController(couchStore);
var projectView = new ProjectView(couchStore);


