var _activeBalloon = null;

function _balloonWrap(balloonId) {
    return $('#' + balloonId);
}

function _balloonInit(balloon) {
    if (balloon.find('.pointer').length == 0) {
	$('<div class="pointer"></div>').prependTo(balloon);
	var close = balloon.find('.close');
	close.click(balloonHide);
    }
}

function balloonConnect(balloonId, triggerId) {
    $("#"+triggerId).click(function () {
	    balloonShow(balloonId, triggerId, true);
	    return false;
	});
}

function balloonShowErrors(balloonId, triggerId) {
    if (_balloonWrap(balloonId).find('.errorlist').length > 0) {
	balloonShow(balloonId, triggerId, false);
    }
}

function balloonHide() {
    if (_activeBalloon) {
	_activeBalloon.hide();
	_activeBalloon = null;
    }
    return false;
}

function balloonHideByClick(e) {
    if (_activeBalloon && e.originalTarget) {
	if ($(e.originalTarget).parents().index(_activeBalloon) < 0
	    && e.originalTarget != _activeBalloon.get(0)) {
	    balloonHide();
	}
    }
}

function balloonShow(balloonId, nearId, toggle) {
    var near = $('#' + nearId);
    var balloon = _balloonWrap(balloonId);
    _balloonInit(balloon);
    var ptr = balloon.find('.pointer');
    var ptrh = 12;
    var nearo = near.offset();
    var nearw = near.outerWidth();
    var x = nearo.left + nearw - balloon.outerWidth();
    var pageX = $("#page").offset().left + 10;
    if (x < pageX) x = pageX;
    var y = nearo.top + near.outerHeight() + ptrh;
    var px = nearo.left + nearw/2 - x - (24/2);
    var isActive = ((_activeBalloon != null)
		    && (_activeBalloon.attr('id') == balloonId));
    var show = false;
    if (toggle) {
	if (isActive) {
	    balloonHide();
	}
	else {
	    show = true;
	}
    }
    else {
	show = (! isActive);
    }
    if (show) {
	balloonHide();
	balloon.show();
	_activeBalloon = balloon;
	balloon.css({left:x, top: y});
	if (y + balloon.outerHeight() - $(window).scrollTop()
	    > $(window).height()) {
	    $(window).scrollTop(y);
	}
	ptr.css({left:px});
	$(document).bind("click", balloonHideByClick);
    }
}
