(function($){
    
    var config = {
        triggers: 'a.balloon, a.glossarlink'
    };
    
    $(document).ready(function(){
        var Helpballoon = function(selectors){
            var balloon = this;
            
            var $template = $('\n\
                <div class="helpballoon">\n\
                    <a href="#" class="closebutton"></a>\n\
                    <div class="helpballooncontent"></div>\n\
                    <div class="helpballoontip"></div>\n\
                </div>\n\
            ');
            
            var lastPosition    = null;
            var top             = null;
            var right           = null;
            
            var $body           = $('body');
            var $html           = $('html');

            var $closeButton    = $template.find('.closebutton');
            var $content        = $template.find('.helpballooncontent');
            var isOpen          = false;

            $template.hide();
            $body.append($template);
            
            $closeButton.click(function(event){
                $template.fadeOut();
                
                event.preventDefault();
            });
            
            this.hide = function(){
                $template.hide();
                $(document).unbind('keyup.helpballoon click.helpballoon');
                isOpen = false;
                
                return this;
            };
            
            this.reposition = function(x, y){
                var scrollTop = $html.scrollTop();
                var pos;
                
                // decide top / bottom
                if(y - $template.height() >= scrollTop){
                    pos = 'top';
                    top = true;
                }else{
                    pos = 'bottom';
                    top = false;
                }
                
                // decide left / right
                
                if(x + $template.width() < $body.width()){
                    pos += '-right' ;
                    right = true;
                }else{
                    pos += '-left' ;
                    right = false;
                }
                
                if(lastPosition !== pos){
                    if(lastPosition){
                        $template.removeClass(lastPosition);
                    }

                    $template.addClass(pos);
                }
                
                lastPosition = pos
                
                return this;
            };

            this.show = function(url, x, y){
                $content.empty();
                
                $.ajax({
                    url:   url,
                    // disable caching, otherwise the full page might appear in
                    // the ballon if viewed in the browser before
                    cache: false,
                    
                    success: function(msg){
                        // if we are in the offline version remove all links in the balloon
                        if(window['KLIMAATLAS'] && window['KLIMAATLAS'].isOfflineVersion()){
                            var $msg = $(msg);
                            var $link;
                            
                            $msg.find('a').each(function(index, link){
                                $link = $(link);
                                $link.replaceWith($link.html());
                            });
                            
                            $content.html($msg);
                            
                        }else{
                            $content.html(msg);  
                        }
                    },
                    
                    error: function(){
                        balloon.hide();
                        if(!(window['KLIMAATLAS'] && window['KLIMAATLAS'].isOfflineVersion())){
                            window.location.href = url;
                        }
                    }
                });
                
                this.reposition(x, y);

                $template.css({
                    left: right ? (x - 9)                         : (x + 9 - $template.width()),
                    top:  top   ? (y - ($template.height() + 10)) : (y + 9 + 10)
                }).fadeIn();
                
                if(!isOpen){
                    $(document).bind('keyup.helpballoon', function(event){
                        switch(event.keyCode){
                            // cancel current tool action
                            case $.ui.keyCode.ESCAPE:
                                balloon.hide();
                                event.preventDefault();
                                break;  
                        };
                    });
                    
                    $(document).bind('click.helpballoon', function(event){
                        // only call hide if the trigger is not one to open a new balloon
                        // or the balloon itself
                        if(!($(event.currentTarget).is(config.triggers) || $(event.target).closest('.helpballoon').length == 1)){
                            balloon.hide();
                        }
                    });
                }
                
                isOpen = true;

                return this;
            };
            
            
            $(selectors).live('click', function(event){
                var $trigger = $(this);   

                balloon.show($trigger.attr('href'),
                             event.pageX,
                             event.pageY);

                event.preventDefault();
            });
        }; 
        
        new Helpballoon(config.triggers);
    }); 
})(jQuery);

