$.fn.dhnav = function(opt) {
	if (this.data('dhnav') == true)
		return this;
	this.data('dhnav', true);

	opt = $.extend(true, {
		fade: false,
		global: true,
		autotop: true,
		hideonmouseout: true,
		centered: false
	}, opt);

	var me = this;
	var _root = this.addClass('dhnav');
	var _sub = this.find('ul').addClass('sub');
	var rootWidth = 0;

	this.find('a').focus(function() { $(this).blur(); });

	_sub.each(function() {
		$(this).children('li:first').addClass('first');
		$(this).children('li:last').addClass('last');

		var width = 0;
		var tmp;

		$(this).children('li').each(function() {
			$(this).width($(this).children('a').width());

			width += $(this).width();

			tmp = parseInt(
				$(this).css('margin-left').replace('px', ''));
			if (tmp)
				width += tmp;

			tmp = parseInt(
				$(this).css('margin-right').replace('px', ''));
			if (tmp)
				width += tmp;

			tmp = parseInt(
				$(this).css('padding-left').replace('px', ''));
			if (tmp)
				width += tmp;

			tmp = parseInt(
				$(this).css('padding-right').replace('px', ''));
			if (tmp)
				width += tmp;

			tmp = parseInt(
				$(this).css('border-left-width').replace('px', ''));
			if (tmp)
				width += tmp;

			tmp = parseInt(
				$(this).css('border-right-width').replace('px', ''));
			if (tmp)
				width += tmp;
		});

		$(this).width(width);
	});

	rootWidth = this.outerWidth();

	this.children('li').each(function() {
		$(this).children('a')
		.mouseover(function() {
			var mychild = $(this).parent().children('ul.sub');

			/* determine left */
			var offsetRoot = _root.offset();
			var offsetThis = $(this).offset();
			var left;
			
			if (opt.centered) {
				left =
					(offsetThis.left - offsetRoot.left +
						Math.floor($(this).outerWidth() / 2)) -
					Math.floor(mychild.outerWidth() / 2);
			} else {
				left = offsetThis.left - offsetRoot.left;
			}

			/* fix left */
			if ((offsetThis.left - offsetRoot.left) <
				((offsetRoot.left + rootWidth) -
				 (offsetThis.left + $(this).outerWidth()))) {
				if (left < 0)
					left = 0;
			} else {
				if (left + mychild.outerWidth() > rootWidth)
					left = rootWidth - mychild.outerWidth();
			}

			/* hide other child */
			var _a = opt.global ?
				$('.dhnav').children('li').children('a') :
				me.children('li').children('a');
			_a.not($(this)).each(function() {
				if ($(this).hasClass('hover')) {
					$(this).parent().children('ul.sub')
						.stop(true, true).hide();
					$(this).removeClass('hover');
				}
			});
			$(this).addClass('hover');

			/* set my child */
			var _subs = opt.global ?
				$('.dhnav').find('ul.sub') : _sub;
			_subs.not(mychild).hide();
			if (opt.autotop)
				mychild.css('top', $(this).outerHeight() + 'px')
			mychild.css('left', left);
			if (opt.fade)
				mychild.fadeIn();
			else
				mychild.show();

		})
	});

	_sub.mouseout(function(e) {
		if (!opt.hideonmouseout)
			return;

		if (e.pageX == 0 && e.pageY == 0) {
			/* fix for webkit */
			return;
		}

		var offset = $(this).offset();
		if (e.pageX >= offset.left &&
			e.pageX <= offset.left + $(this).outerWidth() &&
			e.pageY >= offset.top &&
			e.pageY <= offset.top + $(this).outerHeight())
			return;

		if (opt.fade)
			$(this).fadeOut();
		else
			$(this).hide();
		$(this).parent().children('a').removeClass('hover').mouseout();

		/* active */
		_root.find('a.active').mouseover();
	});

	/* set active */
	_sub.find('a').each(function() {
		var pathname = window.location.pathname;
		if (pathname == '/')
			return;
		var pat = new RegExp('^' + $(this).attr('href') + '[.]*');
		if (pathname.match(pat)) {
			$(this).addClass('active');
			$(this).parents('ul').parent().children('a')
				.addClass('active')
				.mouseover();
		}
	});

	_sub.css('visibility', 'visible');
	return this;
};

