var desktop_drag_state = {};
var desktop_step_listing = {};
var desktop_step_ids = {};
var desktop_completed = {};
var desktop_step_preventing = false;
var desktop_ignore_step_complete = false;

function desktop_step_do_deepcopy(props)
{
	if (!props)
		return false;

	var obj = new props.constructor();

	for (var k in props)
	{
		if (typeof(props[k]) == "object" && props[k] != null)
			obj[k] = desktop_step_do_deepcopy(props[k]);
		else
			obj[k] = props[k];
	}

	return obj;
}

function desktop_step_save_state(el)
{
	var divs = el.getElementsByTagName("div");
	var id_goal = null;

	for (var i = 0; i < divs.length; i++)
		if (divs[i].id.indexOf("step-list-holder-") == 0)
		{
			id_goal = divs[i].id.replace("step-list-holder-", "");
			break;
		}

	var state = {id_goal: id_goal, completed: id_goal in desktop_completed};
	state.steps = desktop_step_do_deepcopy(desktop_step_listing[id_goal]);

	return state;
}

function desktop_step_restore_state(state)
{
	var id_goal = state.id_goal;

	if (state.completed)
		desktop_completed[id_goal] = 1;

	desktop_step_listing[id_goal] = desktop_step_do_deepcopy(state.steps);

	desktop_step_redraw(id_goal, 'view');
}

function desktop_step_cmp_state(state1, state2)
{
	if (state1.id_goal != state2.id_goal)
		return false;
	if (state1.completed != state2.completed || state1.steps.length != state2.steps.length)
		return false;

	for (var i = 0; i < state1.steps.length; i++)
	{
		var parts = ["title", "id", "id_step", "direction", "completed"];
		for (var j = 0; j < parts.length; j++)
		{
			if (state1.steps[i][parts[j]] != state2.steps[i][parts[j]])
				return false;
		}
	}

	return true;
}

function desktop_step_init(id_goal)
{
	if (!(id_goal in desktop_step_listing))
		desktop_step_listing[id_goal] = [];
	if (!(id_goal in desktop_step_ids))
		desktop_step_ids[id_goal] = 0;
}

var desktop_step_prevent_redraw_fixup_t = null;
function desktop_step_prevent_redraw(toggle)
{
	var save = desktop_step_preventing;

	desktop_step_preventing = toggle ? {} : false;

	if (save !== false)
	{
		for (var id_goal in save)
			desktop_step_redraw(id_goal, save[id_goal], true);

		if (!desktop_step_prevent_redraw_fixup_t)
			desktop_step_prevent_redraw_fixup_t = setTimeout(desktop_step_prevent_redraw_fixup, 50);
	}
}

function desktop_step_prevent_redraw_fixup()
{
	desktop_step_prevent_redraw_fixup_t = null;

	site_first_load();
}

function desktop_step_add_custom(id_goal, str, skip_focus)
{
	desktop_step_init(id_goal);

	if (str == '')
	{
		alert('Please enter a step description above.');
		return false;
	}

	if (!skip_focus)
	{
		window.setTimeout(function ()
		{
			$('new_step_' + id_goal).value = $('new_step_' + id_goal).defaultValue;
			$('new_step_' + id_goal).focus();
			$('new_step_' + id_goal).select();
			$('new_step_' + id_goal).style.display = "block";
			$add_class($('new_step_' + id_goal), "new-step-focus");
		}, 0);
	}

	desktop_step_add_existing(id_goal, str, 0);
	return true;
}

function desktop_step_add_existing(id_goal, str, id_step, done, direction)
{
	desktop_step_init(id_goal);

	if (!direction)
		direction = "";

	desktop_step_listing[id_goal].push({title: str, id: 'goal' + id_goal + '-step-item-' + desktop_step_ids[id_goal]++, id_step: id_step, completed: !!done, direction: direction});
	desktop_step_redraw(id_goal, 'view');
}

function desktop_step_clear_existing(id_goal)
{
	desktop_step_init(id_goal);

	desktop_step_listing[id_goal] = [];
	desktop_step_redraw(id_goal, 'view');
}

function desktop_step_detect_enter(id_goal, el, ev)
{
	if (ev.keyCode == 13)
	{
		desktop_step_add_custom(id_goal, el.value);
		return false;
	}
	else
		return true;
}

function desktop_step_new_show(id_goal)
{
	var prompt = $("new_step_prompt_" + id_goal);
	var container = $("new_step_container_" + id_goal);
	var new_step = $("new_step_" + id_goal);

	if (prompt)
	{
		prompt.style.display = "none";
		container.style.display = "block";
	}

	new_step.value = new_step.defaultValue;
	new_step.focus();
	new_step.select();

	return false;
}

function desktop_step_new_save(id_goal)
{
	var new_step = $("new_step_" + id_goal);

	desktop_step_add_custom(id_goal, new_step.value);

	desktop_step_new_show(id_goal);
}

function desktop_step_new_close(id_goal)
{
	var prompt = $("new_step_prompt_" + id_goal);
	var container = $("new_step_container_" + id_goal);

	prompt.style.display = "block";
	container.style.display = "none";
}

function desktop_dragger_help(ev, link)
{
	var image = new Image();

	if (typeof(desktop_drag_state.marker) != "undefined")
		return;

	function remove()
	{
		if (image && image.parentNode)
			document.body.removeChild(image);

		return false;
	}

	var cancel = false;
	function cancel_set()
	{
		cancel = true;
	}

	function show()
	{
		if (cancel)
			return;

		var pos = get_element_pos(link);
		var pos2 = get_element_pos(link.parentNode.parentNode);

		// This fixes a bug in IE7 getting the correct pos.
		pos.x = pos2.x - 18;

		image.src = static_url + "/images/desktop/help-drag.png";
		image.style.position = "absolute";
		image.style.top = (pos.y - 54) + "px";
		image.style.left = (pos.x - 11) + "px";
		image.style.zIndex = 102;

		obj_event_queue(link, "onclick", remove);
		obj_event_queue(link, "onmousedown", remove);
		obj_event_queue(link, "onmouseout", remove);

		document.body.appendChild(image);
	}

	obj_event_queue(link, "onmouseout", cancel_set);
	setTimeout(show, 0);
}

function desktop_step_redraw(id_goal, mode, prevent_fixup)
{
	if (desktop_step_preventing !== false)
	{
		desktop_step_preventing[id_goal] = mode;
		return;
	}

	var html = '';
	var completed = id_goal in desktop_completed;

	function is_marker(i)
	{
		if (typeof(desktop_drag_state.id_goal) == "undefined" || desktop_drag_state.id_goal != id_goal)
			return false;
		if (typeof(desktop_drag_state.marker) != "undefined" && desktop_drag_state.marker == i)
			return true;
		return false;
	}

	desktop_step_init(id_goal);
	var step_listing = desktop_step_listing[id_goal];

	for (var i = 0; i < step_listing.length; i++)
	{
		var step = step_listing[i];

		if (is_marker(i))
			html += '\
	<div class="drag-marker"></div>';

		var classNames = 'step';
		if (typeof(desktop_drag_state.id) != 'undefined' && desktop_drag_state.id == step.id)
			classNames = 'step-hover ' + classNames + ' step-dragging';

		if (step.completed)
			classNames += ' step-completed';
		if (completed)
			classNames += ' step-goal-completed';

		html += '\
	<div id="' + step.id + '" class="' + classNames + '"' + (completed ? '' : ' onmouseover="this.className += \' step-hover\';" onmouseout="this.className = this.className.replace(\' step-hover\', \' \');"') + '>\
		<div class="step-box">\
			<a href="javascript://"' + (completed || desktop_ignore_step_complete ? '' : ' onclick="desktop_step_toggle_done(' + id_goal + ', \'' + step.id + '\'); return false;"') + ' class="checkmark"></a>\
			<input type="hidden" name="step_completed[]" value="' + (step.completed ? 1 : 0) + '" />\
			<input type="hidden" name="step_id[]" value="' + step.id_step + '" />\
			<textarea name="step[]" spellcheck="true" onfocus="this.select();" onchange="desktop_step_modify_desc(' + id_goal + ', \'' + step.id + '\', this.value);" class="field-textbox"' + (completed ? ' readonly="readonly"' : '') + ' rows="1">' + html_escape(step.title) + '</textarea>\
			<a href="javascript://" class="trash" onclick="desktop_step_remove(' + id_goal + ', \'' + step.id + '\'); return false;" onmouseover="site_toggle_inside_img(this, true);" onmouseout="site_toggle_inside_img(this, false);"><img src="' + static_url + '/images/elements/icons/trash-off.png" alt="Delete" /></a>\
		</div>\
		<div class="progress">\
			<img src="' + static_url + '/images/tracking/' + (step.direction == "positive" ? "light" : "off") + '-green.png" alt="" id="' + step.id + '-progress-positive" />\
			<img src="' + static_url + '/images/tracking/' + (step.direction == "neutral" ? "light" : "off") + '-yellow.png" alt="" id="' + step.id + '-progress-neutral" />\
			<img src="' + static_url + '/images/tracking/' + (step.direction == "negative" ? "light" : "off") + '-red.png" alt="" id="' + step.id + '-progress-negative" />\
		</div>\
		' + (completed ? '' : '<a href="javascript://" class="dragger" onclick="return false;" onmousedown="return desktop_step_start_drag(event, this, ' + id_goal + ', ' + i + ');" onmouseover="desktop_dragger_help(event, this);"></a>') + '\
		<div style="clear: left;"></div>\
	</div>';
	}

	if (is_marker(step_listing.length))
		html += '\
	<div class="drag-marker"></div>';

	var holder = $('step-list-holder-' + id_goal);
	holder.style.position = "relative";
	holder.innerHTML = html;

	function later()
	{
		if (!prevent_fixup)
			site_first_load();

		if (!holder.loopPrevent && holder.scrollHeight > 0 && holder.clientHeight == 0 && desktop_item_last_opened)
		{
			holder.loopPrevent = true;
			desktop_item_close(desktop_item_last_opened);
			desktop_item_open(desktop_item_last_open_link);
		}
	}
	window.setTimeout(later, 0);

	if (!holder.has_events)
	{
		holder.has_events = true;

		obj_event_queue(holder, "onmouseover", desktop_step_progress_mouseover);
		obj_event_queue(holder, "onmouseout", desktop_step_progress_mouseout);
		obj_event_queue(holder, "onclick", desktop_step_progress_click);
	}

	var textareas = holder.getElementsByTagName("textarea");
	for (var i = 0; i < textareas.length; i++)
		step_textarea_autoheight(textareas[i]);

	if ($('new_step_' + id_goal))
		step_textarea_autoheight($('new_step_' + id_goal));
}

function step_textarea_autoheight(o)
{
	o.resize_last_length = -1;

	function set_height(o, add)
	{
		// Hack: aside from height, there's padding + border, but Safari 3 only does border.
		add += 8 - (o.offsetHeight - o.clientHeight);

		var new_h = o.scrollHeight - o.clientHeight + add;
		if (new_h < 5)
		{
			new_h = 17;
			o.style.height = "1.2em";
		}
		else
			o.style.height = new_h + "px";
		return new_h;
	}

	o.resize = function ()
	{
		if (o.resize_last_length == o.value.length || (o.parentNode && o.parentNode.clientWidth == 0))
			return;

		o.style.height = "1px";
		set_height(o, set_height(o, 1));
	}

	obj_event_queue(o, "onclick", o.resize);
	obj_event_queue(o, "onkeyup", o.resize);
	obj_event_queue(o, "onfocus", o.resize);
	obj_event_queue(o, "onblur", o.resize);

	o.resize();
	window.setTimeout(o.resize, 0);
}

function desktop_step_progress_mouseover(ev)
{
	var target = "target" in ev ? ev.target : ev.srcElement;

	if (target.tagName.toLowerCase() == "img")
	{
		target.real_src = target.src;
		target.src = target.src.replace("off-", "light-");

		var type = target.src.match(/(light|off)\-(green|red|yellow)\./);
		if (type && type[2])
		{
			if (this.prompt && this.prompt.parentNode)
				this.prompt.parentNode.removeChild(this.prompt);

			this.prompt = new Image();
			this.prompt.src = static_url + "/images/tracking/bubble-" + type[2] + ".png";
			this.prompt.style.position = "absolute";
			this.prompt.style.left = (target.offsetLeft + 6) + "px";
			this.prompt.style.top = (target.offsetTop - 42) + "px";
			this.prompt.style.zIndex = 20;

			target.parentNode.appendChild(this.prompt);
		}
	}
}

function desktop_step_progress_mouseout(ev)
{
	var target = "target" in ev ? ev.target : ev.srcElement;

	if (target.tagName.toLowerCase() == "img")
	{
		target.src = target.real_src;

		if (this.prompt && this.prompt.parentNode)
			this.prompt.parentNode.removeChild(this.prompt);
		this.prompt = null;
	}
}

function desktop_step_progress_click(ev)
{
	var target = "target" in ev ? ev.target : ev.srcElement;

	if (target.tagName.toLowerCase() == "img")
	{
		var id_goal = this.id.replace('step-list-holder-', '');
		var id_match = target.id.match(/^(.+)\-progress\-(.+)$/);

		if (id_match)
		{
			var step = desktop_step_get(id_goal, id_match[1]);
			step.direction = id_match[2];

			if (this.prompt && this.prompt.parentNode)
				this.prompt.parentNode.removeChild(this.prompt);
			this.prompt = null;
			desktop_step_redraw(id_goal, 'edit');
		}
	}
}

function desktop_step_start_drag(ev, el, id_goal, i)
{
	if (ev.button == 2)
		return true;

	var pos = get_mouse_pos(ev);

	function finish()
	{
		if (el.parentNode == null)
			return;

		if (el.id)
			desktop_drag_state.id = el.id;
		else
			desktop_drag_state.id = el.parentNode.id;
		desktop_drag_state.id_goal = id_goal;
		desktop_drag_state.yOffset = pos.y - (get_element_pos(el).y - get_element_pos(el.offsetParent.offsetParent).y);
		desktop_drag_state.old_i = i;
		desktop_drag_state.marker = i;

		document.body.style.cursor = 'move';
		document.body.onmousemove = desktop_step_continue_drag;
		document.body.onmouseup = desktop_step_stop_drag;

		var inputs = $('step-list-holder-' + id_goal).getElementsByTagName("textarea");
		for (var j = 0; j < inputs.length; j++)
			inputs[j].onchange();

		desktop_step_redraw(id_goal, 'reorder');

		desktop_step_continue_drag(ev);
	}

	finish();

	return true;
}

function desktop_step_continue_drag(ev)
{
	if (!ev)
		ev = event;
	var pos = get_mouse_pos(ev);

	desktop_step_init(desktop_drag_state.id_goal);
	var step_listing = desktop_step_listing[desktop_drag_state.id_goal];

	var old_marker = desktop_drag_state.marker;
	desktop_drag_state.marker = step_listing.length;
	for (var i = 0; i < step_listing.length; i++)
	{
		if (step_listing[i].id == desktop_drag_state.id)
			continue;

		var y = get_element_pos($(step_listing[i].id)).y;
		if (pos.y - 11 < y)
		{
			desktop_drag_state.marker = i;
			break;
		}
	}

	if (desktop_drag_state.marker != old_marker)
		desktop_step_redraw(desktop_drag_state.id_goal, 'reorder');

	var new_y = pos.y - desktop_drag_state.yOffset;
	$(desktop_drag_state.id).style.top = new_y + 'px';
}

function desktop_step_stop_drag()
{
	desktop_step_init(desktop_drag_state.id_goal);
	var step_listing = desktop_step_listing[desktop_drag_state.id_goal];

	if (typeof(desktop_drag_state.marker) != 'undefined')
	{
		var new_step_list = [];
		for (var i = 0; i < step_listing.length; i++)
		{
			if (step_listing[i].id == desktop_drag_state.id)
				continue;
			if (desktop_drag_state.marker == i)
				new_step_list[new_step_list.length] = step_listing[desktop_drag_state.old_i];

			new_step_list[new_step_list.length] = step_listing[i];
		}

		if (desktop_drag_state.marker == step_listing.length)
			new_step_list[new_step_list.length] = step_listing[desktop_drag_state.old_i];

		desktop_step_listing[desktop_drag_state.id_goal] = new_step_list;
	}

	document.body.style.cursor = '';
	document.body.onmousemove = null;
	document.body.onmouseup = null;

	var id_goal = desktop_drag_state.id_goal;
	desktop_drag_state = {};
	desktop_step_redraw(id_goal, 'reorder');
}

function desktop_step_remove(id_goal, id)
{
	desktop_step_init(id_goal);
	var step_listing = desktop_step_listing[id_goal];

	if (step_listing.length <= 1)
	{
		alert("Sorry, you have to have at least one step.");
		return;
	}

	var new_step_list = [];
	for (var i = 0; i < step_listing.length; i++)
	{
		if (step_listing[i].id == id)
			continue;

		new_step_list[new_step_list.length] = step_listing[i];
	}

	desktop_step_listing[id_goal] = new_step_list;

	desktop_step_redraw(id_goal, 'edit');
	window.setTimeout(function ()
	{
		try
		{
			$('new_step_' + id_goal).focus();
			$('new_step_' + id_goal).select();
		}
		catch (e)
		{
		}
	}, 0);
}

function desktop_step_toggle_done(id_goal, id, title)
{
	var step = desktop_step_get(id_goal, id);
	step.completed = !step.completed;

	desktop_step_redraw(id_goal, 'edit');
}

function desktop_step_modify_desc(id_goal, id, title)
{
	if (title == "")
	{
		desktop_step_remove(id_goal, id);
	}
	else
	{
		var step = desktop_step_get(id_goal, id);
		step.title = title;

		if (!("id" in desktop_drag_state))
			desktop_step_redraw(id_goal, 'edit');
	}
}

function desktop_step_get(id_goal, id)
{
	desktop_step_init(id_goal);

	for (var i = 0; i < desktop_step_listing[id_goal].length; i++)
	{
		if (desktop_step_listing[id_goal][i].id == id)
			return desktop_step_listing[id_goal][i];
	}

	return false;
}

function desktop_step_save_changes(type, id_goal)
{
	var params = {goal: id_goal};

	var add_step = $("new_step_" + id_goal);
	if (add_step.value != "" && add_step.value != add_step.defaultValue)
	{
		if (!desktop_step_add_custom(id_goal, add_step.value))
			return;
	}

	desktop_step_init(id_goal);

	for (var i = 0; i < desktop_step_listing[id_goal].length; i++)
	{
		var step = desktop_step_listing[id_goal][i];
		var key = "steps[" + i + "]";

		params[key + "[id_step]"] = step.id_step;
		params[key + "[title]"] = step.title;
		params[key + "[completed]"] = step.completed ? "1" : "0";
		params[key + "[direction]"] = step.direction;
	}

	function show_complete(title)
	{
		var item = $("goal-last-updated-" + id_goal);
		while (item && !$has_class(item, "item-bottom"))
			item = item.parentNode;

		var item_holder = item;
		while (item_holder && !$has_class(item_holder, "item-open"))
			item_holder = item_holder.parentNode;

		function complete_archive()
		{
			item_holder.style.display = "none";
			item_holder.permanentGone = true;
			return false;
		}

		function complete_delete()
		{
			item_holder.style.display = "none";
			item_holder.permanentGone = true;
			desktop_save_update("delete", {type: type, id: id_goal}, null, true);
			return false;
		}

		function complete_again()
		{
			item_holder.style.display = "none";
			item_holder.permanentGone = true;
			this.href += id_goal;
			return true;
		}

		item.goal_complete_undo = item.cloneNode(true);
		item.innerHTML = "";
		item_holder.resetOnCloseState = false;

		var dialog = $("desktop-confirm-complete-" + type).cloneNode(true);
		dialog.style.display = "block";
		item.appendChild(dialog);

		fix_height_reflow();

		var children = dialog.getElementsByTagName("*");
		for (var i = 0; i < children.length; i++)
		{
			if (children[i].className == "title")
				children[i].innerHTML = title;
			else if (children[i].className == "archive-it")
				children[i].onclick = complete_archive;
			else if (children[i].className == "delete-it")
				children[i].onclick = complete_delete;
			else if (children[i].className == "again-it")
				children[i].onclick = complete_again;
		}
	}

	function save_finish()
	{
		var item = $("goal-last-updated-" + id_goal);
		while (item && !$has_class(item, "item-bottom"))
			item = item.parentNode;

		var item_holder = item;
		while (item_holder && !$has_class(item_holder, "item-open"))
			item_holder = item_holder.parentNode;

		item_holder.resetOnCloseState = false;

		var save = $("save-changes-" + id_goal);

		var save_button = save.firstChild;
		while (save_button && !$has_class(save_button, "button"))
			save_button = save_button.nextSibling;

		var save_message = save.firstChild;
		while (save_message && !$has_class(save_message, "message"))
			save_message = save_message.nextSibling;

		Animation(save_button).duration(100).to("opacity", 0.01).hide().go();
		Animation(save_message).duration(100).to("opacity", 1.0).show().go();

		function revert()
		{
			Animation(save_button).duration(3000).checkpoint().duration(250).to("opacity", 1.0).show().go();
			Animation(save_message).duration(3000).checkpoint().duration(250).to("opacity", 0.01).hide().go();
		}
		setTimeout(revert, 3000);
	}

	function finish(request)
	{
		var response = eval(request.responseText);

		$("goal-last-updated-" + id_goal).innerHTML = "just now";

		$("goal-progress-bar-" + id_goal).style.display = response.steps.length > 1 ? "block" : "none";
		$("goal-progress-bar-" + id_goal + "-percent").innerHTML = response.percent + "%";
		$("goal-progress-bar-" + id_goal + "-bar").style.width = response.percent + "%";

		desktop_step_clear_existing(id_goal);
		for (var i = 0; i < response.steps.length; i++)
		{
			var step = response.steps[i];
			desktop_step_add_existing(id_goal, step.title, step.id_step, step.completed, step.direction);
		}

		if (response.is_complete)
			show_complete(response.title);
		else
			save_finish();
	}

	desktop_save_update("save_goal", params, finish, true);
}
