var myProjectList = null;
var myTaskTypeMap = {'0':'Task', '1':'Bug', '2':'Feature Request'};
var myTaskTypeList = ['Task', 'Bug', 'Feature Request'];

var myPriorities = {'0':'0', '1':'1', '2':'2', '3':'3', '4':'4', '5':'5'};
//var myTaskStates = {'0':'Open', '1':'Closed', '2':'Blocked', '3':'Delete', '4':'Resolved'};
var myTaskStates = {'0':'Open', '1':'Resolved', '2':'Blocked', '3':'Closed', '4':'Delete'};
var myGuestTaskStates = {'0':'Open', '1':'Resolved'};

var myProjectSelector = null;

var mySubProjectSelector = null;

var myTaskTypeSelector = null;
var myfUseOnBlurSubmission = false;

// change the error object -> to String so we get verbosive information
Error.prototype.toString = function() {
	return objectToString(this);
}

// a  wrapper around normal errors so we can generate emails with them
var BMIError = Class.create();
BMIError.prototype = {
	initialize: function(error, desc) {
		this.error = error;
		this.desc = desc;
		this.page = window.location.href;
	},
	
	toREST: function() {
		return "error="+escape(this.error)+"&extra="+escape(this.desc)+"&page="+escape(this.page);
	}
};

// debug func
function objectToString(obj) {
	// ignore any functions, just save 
	var str = "{\n"
	for(var keys in obj) {
		str += "\t" + keys + ":";
		if(typeof(obj[keys]) == 'function') {
			str += "function \n";
		}
		else {
			str += "'"+obj[keys] + "'\n";
		}
	}
	return str + "}\n";
}

function reportException(ajaxObject, error) {
	if (error == null) {
		return;
	}
	// create additional description detail that will help debug
	var description = "func: mentat-browser::reportException";
	description += "\ncurrent: " + window.location.href;
	description += "\nrequesting: " + ajaxObject.url;
	if ("options" in ajaxObject) {
		description += "\nparams:\n" + objectToString(ajaxObject.options.parameters);
	}
	var lightbox = createErrorReportingLightbox(new BMIError(error, description));
	
	lightbox.show();
}

function reportFailure(ajaxObject, error) {
	if (error == null) {
		return;
	}
	// create additional description detail that will help debug
	var description = "func: mentat-browser::reportFailure";
	description += "\ncurrent: " + window.location.href;
	description += "\nrequesting: " + ajaxObject.url;
	if ("options" in ajaxObject) {
		description += "\nparams:\n" + objectToString(ajaxObject.options.parameters);
	}
	var lightbox = createErrorReportingLightbox(new BMIError(error, description));
	
	lightbox.show();
}

function isIE() {
	return navigator.appName == "Microsoft Internet Explorer";
}

function usePersonalTaskTypes() {
	myTaskTypeMap = {'0':'Task', '1':'Notes', '2':'Lists'};
	myTaskTypeList = ['Task', 'Notes', 'Lists'];
}

function useCustomTaskTypes(projectID) {
 	var mentatProj = TaskDataStore.getProjectById(projectID);
	myTaskTypeMap = mentatProj.getTaskTypesMap();
	myTaskTypeList = mentatProj.getTaskTypesList();
}

function isDefined(globalVar) {
	return (window[globalVar] != undefined);
}

// this is a nice function, lets use it everywhere :D
function buildAjax(pair, func, paramName) {
	var id = pair.control.getAttribute('taskId');
	var task = TaskDataStore.getTask(id);
	var project_id = task.project_id;
	
	var url = '/projects/'+func+'/'+project_id;
	var param=paramName+'='+pair.control.value  + "&taskId="+task.id;
	
	ajaxGet(url, param, updateTaskData);
}

function showNewTaskOnBlurForm() {
	
	var newTaskDiv = clearDiv('newTaskDiv');
	var taskForm = document.createElement("form");
	taskForm.id='newTaskForm';
	newTaskDiv.appendChild(taskForm);
	var summary = document.createElement('input');
	summary.type='text';
	summary.id='newTaskSummary';
	summary.name='summary';
	summary.onblur=submitNewTask;
	taskForm.onsubmit=submitNewTask;
	taskForm.appendChild(summary);
	
	/** Oh sweet sweet three hours of my life just to know that you belonged BENEATH the appendChild */
	summary.focus();
	summary.select();	
	return false;
}

/** 
 *	DLP: This needs to be consolidated into common new task control code
 * that gcole is working on.
 *
 * gcole: this is only called in the agenda view. perhaps it should go there?
 */
function showRegularNewTaskForm() {
	var newTaskDiv = clearDiv('newTaskDiv');

	var taskForm = document.createElement("form");
	newTaskDiv.appendChild(taskForm);
	var summary = document.createElement('input');
	summary.type='text';
	summary.id='newTaskSummary';
	summary.name='summary';
	taskForm.onsubmit=submitNewTask;
	taskForm.appendChild(summary);
	taskForm.appendChild(myProjectSelector);
	taskForm.appendChild(myTaskTypeSelector);
	var submit = document.createElement('input');
	submit.type = 'submit';
	submit.value = 'submit';
	taskForm.appendChild(submit);
	myProjectSelector.onchange = updateTaskTypeSelector;
	updateTaskTypeSelector(); // update before we show
	
	/** Oh sweet sweet three hours of my life just to know that you belonged BENEATH the appendChild */
	summary.focus();
	summary.select();	
	return false;
}


function updateTaskTypeSelector () { 
	var index = myProjectSelector.value;
	var types = TaskDataStore.getProjectById(index).getTaskTypesMap();
	var tempSelector = createBasicSelector(types, 0);
	myTaskTypeSelector.innerHTML = tempSelector.innerHTML;	// SWAP content and drop tempSelector
}


function showNewTaskForm() {
	var ret = null;
	if(myfUseOnBlurSubmission) {
		ret = showNewTaskOnBlurForm();
	}
	else {
		ret = showRegularNewTaskForm();
	}
	return ret;
}

/** 
 *	DLP: This needs to be consolidated into common new task control code
 * that gcole is working on.
 */
function loadNewTaskForm() {
	
	var newTaskDiv = clearDiv('newTaskDiv');
	var taskForm = document.createElement("div");
	taskForm.id='createNewTaskForm';
	taskForm.className='createNewTaskForm';
	taskForm.onclick=showNewTaskForm;
	taskForm.innerHTML = 'Click to create new task';
	newTaskDiv.appendChild(taskForm);
}

function requestUsersProjectTaskList(project_id) {
	try {
		var url = '/projects/list_user_tasks/'+project_id;
		new Ajax.Request(url, {method: 'post', onException: reportFailure, onSuccess: handleProjectTaskListData, onFailure: reportFailure});
	}
	catch(E) {
		alert("ERROR: requestTaskData - " + E);
		printError(E);
	}		
}

function requestUsersContextTaskList(context_id) {
	try {
		var url = '/contexts/list_user_context_tasks/'+context_id;
		new Ajax.Request(url, {method: 'post', onException: reportFailure, onSuccess: handleContextTaskListData, onFailure: reportFailure});
	}
	catch(E) {
		alert("ERROR: requestTaskData - " + E);
		printError(E);
	}		
}


function requestTaskData() {
	try {
		var url = '/home/list_tasks/';
		new Ajax.Request(url, {method: 'post', onException: reportFailure, onSuccess: updateTaskData, onFailure: reportFailure});
	}
	catch(E) {
		alert("ERROR: requestTaskData - " + E);
		printError(E);
	}
}

function requestShortListData() {
	try {
		var url = '/home/short_list/';
		new Ajax.Request(url, {method: 'post', onException: reportFailure, onSuccess: handleShortListData, onFailure: reportFailure});
	}
	catch(E) {
		alert("ERROR: requestTaskData - " + E);
		printError(E);
	}
}

/** 
 *	DLP: This needs to be consolidated into common new task control code
 * that gcole is working on.
 */
function submitNewTask() {
	if(myfUseOnBlurSubmission) {
		var taskForm = document.getElementById("newTaskForm");
		var summary = document.getElementById('newTaskSummary');
		taskForm.onsubmit=null;
		summary.onblur=null;
	}
	var type = myTaskTypeSelector.value;
	if(type == -1) {
		// grab the first key.  there's probably a more elegant way to do this.
		for(var key in myTaskTypeMap) {
			type = key;
			if(type != -1) {
				break;
			}
		}
	}
	var summary = escape( document.getElementById('newTaskSummary').value);
	var url = '/projects/new_task/'+myProjectSelector.value;
	
	/** G.K. I am adding this check so that you can't accidentally add a blank task */
	if (summary != "") { 
		var param="summary="+summary+"&type="+type;
		new Ajax.Request(url, {method: 'post', parameters: param, onException: reportFailure, onSuccess: updateTaskData, onFailure: reportFailure});
	}
	loadNewTaskForm();
	return false;
}
	
function requestProjectList(userId) {
	var url = '/projects/list_user_projects/'+userId;
	new Ajax.Request(url, {method: 'post', onException: reportFailure, onSuccess: updateProjectList, onFailure: reportFailure});
}	

function clearDiv(divName) {
	var taskTableDiv = document.getElementById(divName);
	if (taskTableDiv != null) {
		while (taskTableDiv.hasChildNodes()) {
			taskTableDiv.removeChild(taskTableDiv.lastChild);
		}
	}
	return taskTableDiv;
}

function clearAndInitializeJSONDiv(json, divName) {
	var func = new Function("return " + json);
	/** Parse JSON response.  THIS WILL EXPLODE IF WE HAVE NEWLINES, QUOTES, ETC. */
	var objt = func();
	/** If we're here, we lived through it */
	clearDiv(divName)
	return objt;
}

function parseJSON(response) {
	var func = new Function("return " + response.responseText);
 	/** Parse JSON response.  THIS WILL EXPLODE IF WE HAVE NEWLINES, QUOTES, ETC. */
 	var objt = func();
 	return objt;
}


function concealEditor(id) {
	new Effect.SlideUp('editPanel' + id, { afterFinish: removeEditPane, duration:0.2}); 
	var dat = document.getElementById(' expandOview'+id);
	dat.onclick= new Function("return revealEditor('" + id +"');");
	dat.innerHTML="v";
}

// gcole: is this being called?
function revealEditor(id) {
	var taskRow = document.getElementById("taskRow"+id);
	var nextTaskRow = taskRow.nextSibling;
	var taskDetails = myTaskDetails[id];
	/** Create the next row */								
	var editRow = document.createElement("tr");
	var td = document.createElement("td");
	td.colSpan = 9;
	editRow.appendChild(td);
	editRow.id='trEdit'+id;
	editRow.style.backgroundColor="#05a";
	
	var editPanel = document.createElement("div");
	td.appendChild(editPanel);

	editPanel.id="editPanel"+id;
	editPanel.setAttribute('parentRowId', "trEdit"+id);
	
	var textControl = document.createElement('textArea');
	textControl.setAttribute("rows", 8);
	textControl.setAttribute("cols", 180);
	textControl.setAttribute('taskId', id);
	textControl.className='quick-edit-control';
	var temp = document.createElement("div");
	temp.className='quick-edit tasklist-description-div';
	editPanel.appendChild(temp);	
	
	temp.innerHTML= taskDetails.description;
	var controlPair = new ControlPair(temp,textControl,editPanel, handleDescriptionPropertyChange);
	controlPair.width = '450';
	addControlPair("description"+id, controlPair);

	var taskTypeSelector = document.createElement('div');
	taskTypeSelector.className='quick-edit taskTypeSelector';
	editPanel.appendChild(taskTypeSelector);
	controlPair = createSelector(taskTypeSelector, 'tasktype', id, myTaskTypeList, taskDetails.type_id, handleTaskTypeChange);
	taskTypeSelector.appendChild(controlPair.div);	
	editPanel.style.display='none';
	taskRow.parentNode.insertBefore(editRow, nextTaskRow);
	new Effect.SlideDown('editPanel' + id, {duration:0.2}); 
	var dat = document.getElementById(' expandOview'+id);
	dat.onclick= new Function("return concealEditor('" + id +"');");
	dat.innerHTML="^";
}

function testPlatform() {
	if(navigator.appName=="Microsoft Internet Explorer") {
		alert("Internet Explorer");
	}
	else {
		alert("Not Internet Explorer");
	}
}

function startTable(parentDiv, headingList) {
	var taskTable = document.createElement("table");
	taskTable.id="data-table";
	taskTable.className = 'sortable';
	parentDiv.appendChild(taskTable);
	var tbody = document.createElement("tbody");
	taskTable.appendChild(tbody);
	taskTable.style.borderCollapse = 'collapse';
	/** 
	 * Make our header row 
	 */
	var tr = createHeaderRow(headingList);
   	tbody.appendChild(tr);
	return tbody;
}

/** 
 * Creates a table with the id specified and adds it to the
 * supplied parent
 */
function createTableRow(id, tbody, className) {
	var tr = document.createElement("tr");
	if(tbody != null) {
		tbody.appendChild(tr);
	}
	tr.id = id;
	if(className != null) {
		tr.className = className;
	}
	return tr;
}

function createElement(type, id, parent, className, innerHTML, onclickfunc)  {
	var dat = document.createElement(type);	
	if(id != null) {
		dat.id = id;
	}	
	if(className != null) {
		dat.className=className;
	}
	if(innerHTML != null) {
		dat.innerHTML = innerHTML;
	}
	if(parent != null) {
		parent.appendChild(dat);
	}
	if(onclickfunc != null) {
		dat.onclick = onclickfunc;
	}
	return dat;
}

function createBasicSelector(labels, index) {
	var sel = document.createElement('select');
	for(var key in labels){
		sel.appendChild(createOption(labels[key], key, (index == key)));
	}
	return sel;
}

function createTableCell(id, parent, className, innerHTML, onclickfunc) {
	return createElement("td",id, parent, className, innerHTML, onclickfunc);
}

function createShowNewTaskControl(callback, parent) {
	var taskForm = document.createElement("form");
	taskForm.id='createNewTaskForm';
	taskForm.onsubmit=callback;
	parent.appendChild(taskForm);
	var button = document.createElement('input');
	button.type='submit';
	button.className = 'createNewTaskForm';
	button.value='Create new task';		
	taskForm.appendChild(button);	
}

function ajaxGet(url, param, successcallback) {
	try {
		new Ajax.Request(url, {method: 'post', parameters: param, onException: reportFailure, onSuccess: successcallback, onFailure: reportFailure});
	}
	catch(E) {
		alert("ERROR: ajaxGet - " + E);
		printError(E);
	}
}

function createCookie(name,value) {
	var expires = new Date();	    //set new date object	
	expires.setTime(expires.getTime() + (1000 * 60 * 60 * 24 * 30));     //set it 30 days ahead
	var expires = "; expires="+expires.toGMTString();
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}