window.PComponents = {}

$(function()
{
	$('div.message dt a').click(function(e)
	{
		e.preventDefault();
		$(this).parents('div.message').slideUp('slow');
	});
});

// For the nav
$(function()
{
	$('div.nav li.has_dropdown').hover(function()
	{
		$(this).addClass('over');
	}, function()
	{
		$(this).removeClass('over');
	});
});

// Toggleable element
// Options:
// target - the element that should toggle (String-selector or element)
// controller - the element that initiates the slide (String-selector or element)
// (it is assumed controller has .opened and .closed elements inside it - these will toggle automatically)
// when_closed - transformation when closed (Object)
// when_opened - transformation when opened (Object)
// force_open - optional. if true, opens the panel automatically (no animation)
// duration - optional. the duration for the animation
// easing - optional. easing string
window.Toggleable = function(opts)
{
	var target = $(opts.target)[0],
		controller = $(opts.controller)[0];
	
	target.is_open = false;
	
	$(controller).click(function(e, d)
	{
		e.preventDefault();
		
		if (d && d.force_open && d.force_open == true)
		{
			opts.old_duration = opts.duration;
			opts.duration = 1;
		}
		
		do_trans();
	});
	
	if (opts.force_open) $(controller).click();
	
	function do_trans()
	{
		$(target).animate(
			target.is_open? opts.when_closed : opts.when_opened,
			opts.duration || 500,
			opts.easing || 'easeInOutQuart',
			post_trans
		);
	}
	
	function post_trans()
	{
		target.is_open = !target.is_open;
		$('.opened', controller)[target.is_open? 'hide' : 'show']();
		$('.closed', controller)[target.is_open? 'show' : 'hide']();
		
		if (opts.duration == 1)
			opts.duration = opts.old_duration;
	}
}

// pfh:layout:w100
$(function()
{
	$('[class*=pfh:layout:]').each(function()
	{
		var m = this.className.match(/pfh:layout:m(t|r|b|l)(\d+)/),
			d = this.className.match(/pfh:layout:(w|h)(\d+)/),
			a = {w: 'width', h: 'height', t: 'top', r: 'right', b: 'bottom', l: 'left'};
		
		if (m) $(this).css('margin-' + a[m[1]], m[2] + 'px');
		if (d) $(this).css(a[d[1]], d[2] + 'px');
	});
});

// pfh:in_field default:Foo_Bar
$(function()
{
	function createInFieldField()
	{
		this.default_value = this.className.match(/default:(.[^ ]+)/)[1].replace(/\_/g, ' ');
		
		if (!$(this).val().match(/.+/)) $(this).val(this.default_value);
		
		$(this).focus(function()
		{
			if ($(this).val() == this.default_value)
				$(this).val('');
			
			$(this).removeClass('off').addClass('on');
		})
		.blur(function()
		{
			if (!$(this).val().match(/.+/))
				$(this).val(this.default_value);
			
			if ($(this).val() == this.default_value) $(this).removeClass('on').addClass('off');
		})
		.blur();
	}
	
	$('[class*=pfh:in_field]').each(createInFieldField);
	
	$(window).bind('paginator:components', function()
	{
		$('span.prompt_container').find('[class*=pfh:in_field]').each(createInFieldField);
	});
});

// input field focus
$(function()
{
	function input_focus()
	{
		$(this).css({
			borderColor: '#d1e1e8',
			backgroundColor: '#e5f7fd'
		});
	}
	
	function input_blur()
	{
		$(this).css({
			borderColor: this.revert.border,
			backgroundColor: this.revert.background
		});
	}
	
	jQuery.fn.colorize = function()
	{
		return this.each(function()
		{
			this.revert = { border: $(this).css('borderColor'), background: $(this).css('backgroundColor') };
			
			$(this)
				.bind('focus', input_focus)
				.bind('blur', input_blur)
				.triggerHandler('blur');
		});
	}
	
	$(':input[type!=image][type!=submit]:not(.nocolorize)').colorize();
	$(window).bind('paginator:components', function()
	{
		$(':input[type!=image][type!=submit]:not(.nocolorize)').colorize();
	});
});

// button press
$(function()
{
	function press()
	{
		$(this).attr('src', this.down_img.src);
	}
	
	function release()
	{
		$(this).attr('src', this.up_img);
	}
	
	$('.has_press').each(function()
	{
		var down = $(this).attr('src').replace(/.(jpg|png)/, '_down.$1');
		
		this.up_img = $(this).attr('src');
		this.down_img = new Image();
		this.down_img.src = down;
		
		$(this)
			.bind('mousedown', press)
			.bind('mouseup', release)
			.bind('mouseout', release)
			.bind('blur', release);
	});
});

// side_label for:class
$(function()
{
	var label_click = function()
	{
		var m = this.className.match(/for:([\w|\d]+)/);
		
		if (!m && !this.className.match(/side_label/) && $(this).attr('for') != '') m = [null, $(this).attr('for')];
		
		if (m)
		{
			var o = $('.' + m[1] + ':first');
			
			if (o[0].disabled == true) return;
			
			if (o.attr('type') == 'radio' || o.attr('type') == 'checkbox')
			{
				if (o.attr('type') == 'checkbox') o[0].checked = !o[0].checked
				else o[0].checked = true;
				
				o.change();
			}
			else o.focus();
		}
		else
		{
			var inputs = $(this).siblings(':input');
			
			for (var i = 0, l = inputs.length; i<l; i++)
			{
				var input = inputs[i];
				
				if (input.disabled) continue;
				
				if ($(input).attr('type') == 'checkbox') input.checked = !input.checked;
				else if ($(input).attr('type') == 'radio') input.checked = true;
				
				$(input).change().focus();
			}
		}
	};
	
	$('.top_label,.side_label,label[for]').click(label_click);
	$(window).bind('paginator:components', function()
	{
		$('.top_label,.side_label,label[for]').click(label_click);
	});
	jQuery.fn.addSideLabel = function(o)
	{
		return this.click(label_click);
	}
});

// disables other form elements
$(function()
{
	$('input[class*=disables]').each(function()
	{
		var els = '.' + this.className.match(/disables:(.[^ ]+)/)[1].replace(/,/g, ',.');
		
		$(this).change(function()
		{
			var d = !this.checked;
			
			$(els).each(function()
			{
				this.disabled = d;
			});
			
		}).change();
	});
});

jQuery.fn.swapClass = function(old_class, new_class)
{
	return this.removeClass(old_class).addClass(new_class);
};

// Forces an update on an element that might not have gotten the measurements right the first time.
// Useful for when you unhide an element.
jQuery.fn.forceUpdate = function()
{
	this.each(function()
	{
		var c = this.className;
		
		if (c.match(/pfh:expando/))
		{
			if (this.do_resize)
				this.do_resize(true);
			else
				window.PComponents.createResizableTextarea.apply(this, [true]);
		}
	});
	
	return this;
}

// Prevents the enter key in a prompt form
$(function()
{
	$('li.card_content span.prompt_container').parent()
		.submit(function(e, should_submit)
		{
			if (!should_submit)
				e.preventDefault();
		});

	$('li.card_content ul.post_button input')
		.mouseup(function(e)
		{
			e.preventDefault();
			
			if (Paginator.getFormValues(true).length == 0)
				return;
			
			window.onbeforeunload = null;
			$('li.card_content span.prompt_container').parent().trigger('submit', true);
		})
		.click(function(e)
		{
			e.preventDefault();
		});
});

// max length textarea
$(function()
{
	$('textarea[class*=maxlength]').each(function()
	{
		var m = Number(this.className.match(/maxlength:([0-9][^ ]*)/)[1]);
		$(this).keypress(function(e)
		{
			if ($(this).val().length >= m && e.keyCode != 8 && e.keyCode != 9 && !e.metaKey && !e.ctrlKey)
				e.preventDefault();
		});
	});
});

// Replaces headers that should be images
$(function()
{
	$('span.replaceable').each(function()
	{
		var src = '/images/layout/%f/%i%s.png',
			img = $('<img />'),
			folder = $(this).attr('class').split(' ')[1],
			image = $(this).text().replace(/\!|\,|\.|\?|\'|\:/g, '').replace(/ /g, '_'),
			suffix = $(this).attr('class').split(' ')[2];
		
		if (image == '') return;
		
		src = src.replace('%f', folder).replace('%i', image);
		
		if (suffix) src = src.replace('%s', '_' + suffix);
		else src = src.replace('%s', '');
		
		img.attr({
			src: src
		});
		
		$(this).replaceWith(img);
	});
});

// Modal window
(function()
{
	var before_close = function() { return true },
		after_close = function() {};
	
	$(function()
	{
		$('a.opens_modal').click(function(e)
		{
			e.preventDefault();
			open();
		});
		
		$('div.modal_content .header').each(function()
		{
			var img = jQuery.trim($(this).text()).replace(/ /g, '_').replace(/!|\.|\?|'|"/g, '');
			$(this).html('<img src="/images/components/modal/headers/' + img + '.png" />').show();
		});
		
		$('div.modal_blocker,div.modal_content a.close,a.closes_modal').click(function(e)
		{
			e.preventDefault();
			$(this).blur();
			close();
		});
		
		$('div.modal_content a.modal_button').click(function()
		{
			$(this).blur();
		});
	});
	
	function open()
	{
		$('div.modal_container')
			.show()
			.find('div.modal_blocker')
				.show()
			.end()
			.find('div.border.tl')
				.fadeIn('fast');
		
		$(window).bind('resize', reposition).triggerHandler('resize');
		$('body').bind('keyup', esc_key);
	}
	
	function close()
	{
		if (before_close())
			$('div.modal_container')
				.find('div.border.tl')
					.fadeOut('fast', function()
					{
						$(this).parent()
							.find('div.modal_blocker')
								.fadeOut('fast', function()
								{
									$('div.modal_container').hide();
								});
						
						$(window).unbind('resize', reposition);
						$('body').unbind('keyup', esc_key);
						setTimeout(after_close, 500);
					});
	}
	
	function setBeforeClose(to)
	{
		before_close = to;
	}
	
	function setAfterClose(to)
	{
		after_close = to;
	}
	
	function reposition()
	{
		var t = ($(window).height() / 3) - ($('div.modal_container div.border.tl').height() / 2),
			l = ($(window).width() / 2) - ($('div.modal_container div.border.tl').width() / 2);
		
		$('div.modal_container div.border.tl')
			.css('top', t < 50? 50 : t)
			.css('left', l < 50? 50 : l);
	}
	
	function esc_key(e)
	{
		if (e.keyCode == 27)
		{
			e.preventDefault();
			close();
		}
	}
	
	window.Modal = {
		open: open,
		close: close,
		beforeClose: setBeforeClose,
		afterClose: setAfterClose
	}
})();

// AutoComplete
(function()
{
	// the list 
	window.AutoCompleteDisplayList = {
		_list: null,
		_selected_index: -1,
		_hovering: false,
		_can_show: false,
		
		init: function()
		{
			if (this._list) return;
			
			this._list = $('<ul />')
						.css({
							position: 'absolute',
							zIndex: 500,
							overflow: 'auto',
							listStyle: 'none',
							display: 'none'
						})
						.prependTo('body')
						.attr('class', 'ac_display_list')
						.append('<li class="ac_display_list_close" />')
						.find('li.ac_display_list_close')
							.css('float', 'right')
							.append('<a />')
							.find('a')
								.html('close')
								.css({
									fontSize: 11
								})
							.end()
						.end();
			
			return this;
		},
		
		addItems: function(node, data, get_data_list, display_key, highlight)
		{
			var list = this._list,
				data = jQuery.removeDuplicates(data, display_key);
			
			list.find('li.ac_display_list_item').remove();
			this._selected_index = -1;
			
			$.each(get_data_list(data), function(i)
			{
				$('<li class="ac_display_list_item" />')
					.html(
						(display_key == null? this : this[display_key])
							.replace(
								highlight, '<strong>' + highlight + '</strong>'
							)
						)
					.css('cursor', 'pointer')
					.click(function(e)
					{
						e.preventDefault();
						
						var item_data = this.ac_data
							val = item_data.display_key == null? item_data.data : item_data.data[item_data.display_key];
						
						node[0].ac_data = item_data;
						
						node.val(val.replace('&amp;', '&')).change()[0].focus();
					})
					.hover(function()
					{
						window.AutoCompleteDisplayList._hover = true;
						$(this).addClass('selected');
					}, function()
					{
						window.AutoCompleteDisplayList._hover = false;
						$(this).removeClass('selected');
					})
					.insertBefore(list.find('li.ac_display_list_close'))
					.get(0).ac_data = { data: this, display_key: display_key };
			});
			
			return this;
		},
		
		// snaps to a jQuery'd element
		snapTo: function(el)
		{
			var el_o = el.offset(),
				top = el_o.top + el.innerHeight() + 1;
			
			this._list.css({
				top: top,
				left: el_o.left,
				width: el.innerWidth()
			}).get(0).ac_field_top = top;
			
			return this;
		},
		
		// shows the list
		showList: function()
		{
			this._list.stop().slideDown('fast', function()
			{
				$(this).css('height', 'auto');
			});
			
			return this;
		},
		
		hideList: function()
		{
			if (this._hover) return;
			
			this._selected_index = -1;
			this._list.stop().slideUp('fast', function()
			{
				$(this).css('height', 'auto');
				$(this).find('li.ac_display_list_item').remove();
			});
			
			return this;
		},
		
		isOpen: function()
		{
			return this._list.css('display') == 'block';
		},
		
		selectIndex: function(node, new_index)
		{
			var items = this._list.find('li.ac_display_list_item'),
				item_data = null,
				val = null,
				old_index = this._selected_index;
			
			if (items.length == 0) return;
			
			this._selected_index += new_index;
			this._selected_index %= items.length;
			if (this._selected_index < 0) this._selected_index = items.length - 1;
			
			$(items[old_index]).removeClass('selected');
			$(items[this._selected_index]).addClass('selected');
			
			item_data = items[this._selected_index].ac_data;
			val = item_data.display_key == null? item_data.data : item_data.data[item_data.display_key];
			
			node[0].ac_data = item_data;
			node.val(val.replace('&amp;', '&')).change();
			
			return this;
		}
	};
	
	// a field that AutoCompletes
	$.fn.enableAutoComplete = function(opts)
	{
		return;
		var node = $(this),
			query_in_progress = false,
			current_query_response = null,
			current_query_keyword = null;
		
		if (typeof opts.displayKey == 'undefined')
			opts.displayKey = 'name';
		
		if (!opts.wantsDataList)
			opts.wantsDataList = function(d)
			{
				return d;
			};
		
		function parseQuery()
		{
			if (current_query_response == null)
				return;
			
			AutoCompleteDisplayList
				.snapTo($(this))
				.addItems(
					node,
					current_query_response,
					opts.wantsDataList,
					opts.displayKey,
					$(this).val()
				)
				.showList();
		}
		
		node
			.keyup(function(e)
			{
				if (e.which == 38 || e.which == 40)
				{
					e.preventDefault();
					
					AutoCompleteDisplayList.selectIndex($(this), e.which == 38? -1 : 1);
					
					if (AutoCompleteDisplayList.isOpen())
						return;
				}
				
				if (e.which == 27 || e.which == 13 && AutoCompleteDisplayList.isOpen())
				{
					$(this).triggerHandler('blur');
					return;
				}
				
				if (current_query_keyword == $(this).val()) return;
			
				if (query_in_progress) return;
				
				if ($.trim($(this).val()) == '')
				{
					AutoCompleteDisplayList.hideList();
					return;
				}
				
				query_in_progress = true;
				
				new FreebaseQuery(opts.wantsQuery.apply(node, []), function(d)
				{
					current_query_response = d.result;
					current_query_keyword = node.val();
					parseQuery.apply(node, [])
					query_in_progress = false;
				});
			})
			.keydown(function(e)
			{
				if (e.which == 13 && AutoCompleteDisplayList.isOpen())
				{
					e.preventDefault();
					return;
				}
			})
			.blur(function(e)
			{
				AutoCompleteDisplayList.hideList();
				current_query_response = null;
				current_query_keyword = null;
			})
			.focus(function()
			{
				if ($.trim($(this).val()) == '') return;
				
				$(this).keyup();
			})
			.change(function()
			{
				current_query_keyword = $(this).val();
			});
	};
	
	jQuery.removeDuplicates = function(arr, field)
	{
		var duplicate_free = [],
			is_uniq = true;
		
		for (var i = 0; i<arr.length; i++)
		{
			is_uniq = true;
			for (var j = 0; j<duplicate_free.length; j++)
			{
				if (field)
				{
					if (arr[i][field] == duplicate_free[j][field])
					{
						is_uniq = false;
						break;
					}
				} else
				{
					if (arr[i] == duplicate_free[j])
					{
						is_uniq = false;
						break;
					}
				}
			}
			if (is_uniq)
				duplicate_free.push(arr[i]);
		}
		
		return duplicate_free;
	}
	
	// a concise way to query freebase
	// @param query JSON string
	// @param callback function on success
	window.FreebaseQuery = function(query, callback)
	{
		var ENDPOINT = 'http://www.freebase.com/api/service/mqlread?query=%s';
		
		$.ajax({
			url: ENDPOINT.replace('%s', $.toJSON({query: query})),
			dataType: 'jsonp',
			success: callback
		});
	};
	
	window.FreebaseUtil = {
		// deletes 'sort' from obj if str > (len || 3)
		deleteSort: function(str, obj, len)
		{
			if (str.length < (len? len : 3))
			{
				if (obj.length)
					delete obj[0].sort;
				else
					delete obj.sort;
			}
			
			return obj;
		}
	};
	
})();

// dismiss buttons
$(function()
{
	var els = $('a[class*=dismiss]'),
		on = null;
	
	if (els.length > 0)
	{
		on = document.createElement('img');
		on.src = '/images/layout/loaders/icon_close_on.png';
		
		els.each(function()
		{
			var position = this.className.match(/dismiss:(right|left)/);
			position = position? position[1] : 'center';
			
			$(this).css({
				height: 16,
				'float': 'left',
				lineHeight: '18px',
				background: 'url(/images/layout/loaders/icon_close_off.png) no-repeat center ' + position
			});
			
			if (position != 'center')
				$(this).css(('padding' + (position == 'left'? 'Left' : 'Right')), 20);
			else
				$(this).css('width', 16);
			
			$(this).hover(function()
			{
				$(this).css('backgroundImage', 'url(' + on.src + ')');
			}, function()
			{
				$(this).css('backgroundImage', 'url(/images/layout/loaders/icon_close_off.png)');
			});
		});
	}
});


