//get lighthttp domain from script tag to reuse on loading other static resources like flash elements
//has to be global and before document ready
_webPath = 'http://'+$('#kronehit-global-js').attr('src').split('/')[2];

$(document).ready(function(){

    //make jquery animations less cpu-heavy (possible as of 1.4.3)
    jQuery.fx.interval = 50; //default: 13

    //init blockUI
    $.blockUI.defaults.overlayCSS.opacity = 0.0;
    $.blockUI.defaults.message = null;
    $.blockUI.defaultsfadeIn = 0;
    $.blockUI.defaultsfadeOut = 0;

    //global ajax loading indicator
    $("#loading").ajaxStart(function() {
        $(this).show();
    }).ajaxStop(function() {
        $(this).hide();
    });

    //catch global ajax error
    $(document).ajaxError(function(event, request, options, error){
        //hide possibly opened dialogs
        $('.ui-dialog:visible').each(function(){
            $(this).find('.ui-dialog-content').dialog('destroy');
        });

        if(request.status == 401) { // Unauthorized
            var strSpecialParam = '';
            //inform user and show login page
            if($('#login').data('logged-in')) { //user was already logged-in
                $.KH.error("Session abgelaufen - bitte neu einloggen!");
            }
            if (request.responseText.indexOf('votetrack') != -1) {
                $('#player').get(0).ratingComplete({type:'error', msg:'Bitte zuerst einloggen'});
                strSpecialParam = '/special/votetrack';
            }
            if (request.responseText.indexOf('addtrack') != -1) {
                $('#player').get(0).addtoplaylistComplete({type:'error', msg:'Bitte zuerst einloggen'});
                strSpecialParam = '/special/addtrack';
            }
            $.KH.refreshPage('/auth/pleaselogin' + strSpecialParam);
        } else if(request.status == 403) { // Forbidden
            //show forbidden page
            $.KH.refreshPage('/auth/forbidden');
        } else if(request.status == 404) { // Not Found
            //show not found page
            $.KH.refreshPage('/index/notfound');
        } else if(request.status == 405) { // Privacy Error
            var data = eval("(" + request.responseText + ")");
            if (data['comerr']) {
                $.KH.error(data["errmsg"]);
            }
            else {
                //open info Box (need to be a friend)
/*
                $('<p>' + data["errmsg"] + '</p>').dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 300,
                    height: 150,
                    modal: true,
                    title: 'Nicht freigeschaltenes UserProfil',
                    buttons: {
                        'SCHLIESSEN': function() {
                            $(this).dialog('destroy');
                        }
                    }
                });
*/
                var $diaRec = $('#405_addFriend');
                var $message = $diaRec.find('textarea[name=message]');
                $diaRec.dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 400,
                    height: 300,
                    modal: true,
                    title: 'Nicht freigeschaltenes UserProfil',
                    buttons: {
                        'ANFRAGE SENDEN': function() {
                            var $diaContent = $(this);
                            $form = $('form', $diaRec);
                            $diaRec.find('.error').hide();
                            $.KH.ajax({
                                url: $form.attr('action'),
                                data: $form.serialize(),
                                type: $form.attr('method'),
                                dataType: 'json',
                                element: $diaRec,
                                success: function(data){
                                    if(data.success) {
                                        $diaRec.find('.error').hide();
                                        $diaRec.find('.step:eq(0)').hide();
                                        $diaRec.find('.step:eq(1)').show();
                                        $diaRec.data('origButtons', $diaRec.dialog('option', 'buttons'));
                                        $diaRec.dialog('option', 'buttons', {'SCHLIESSEN': function() { $(this).dialog("destroy"); } });
                                    } else {
                                        if (data.error) {
                                            $diaRec.find('.error[name=error]').html(data.error);
                                            $diaRec.find('.error[name=error]').show();
                                        }
                                        if (data.errmsg) {
                                            $diaRec.find('.error[name=errormessage]').html(data.errmsg);
                                            $diaRec.find('.error[name=errormessage]').show();
                                        }
                                    }
                                }
                            });
                        },
                        'LIEBER NICHT': function() {
                            $(this).dialog('destroy');
                        }
                    },
                    open: function(){
                        if($diaRec.data('origButtons')) $diaRec.dialog('option', 'buttons', $diaRec.data('origButtons'));
                        $diaRec
                            .find('.step').hide().end()
                            .find('.error').hide().end()
                            .find('[name=message]').val('');
                        if (data['alreadysent']) {
                            $diaRec.find('.step:eq(2) .info').html(data["errmsg"]);
                            $diaRec.find('.step:eq(2)').show();
                            $diaRec.data('origButtons', $diaRec.dialog('option', 'buttons'));
                            $diaRec.dialog('option', 'buttons', {'SCHLIESSEN': function() { $(this).dialog("destroy"); } });
                        }
                        else {
                            $diaRec.find('.step:eq(0)').show();
                            $message.val($message.attr('title'));

                            //$diaRec.find('#recip').val(data["id"]);
                            $diaRec.find('.step:eq(0)').find('input[name=recip]').val(data["id"]);
                            $diaRec.find('.step:eq(0) .info').html(data["errmsg"]);
                            $diaRec.find('.step:eq(1)').find('p').find('.usrname').html(data["name"]);
                        }
                    },
                    close: function() { //always destroy on close
                        $diaRec.dialog('destroy');
                    }
                });
                return false;
            }
        } else {
            $.KH.error("Es ist ein Fehler aufgetreten. Lade bitte die Seite neu");
        }
    });

    //binds click events to ajax links
    $("a.KH-link").live("click", function() {
        var href = $(this).attr('href');
        //ie makes links absolute when the anchor-tag is loaded via ajax, so strip the absolute path out
        if(href.indexOf('/') != 0) { //url isn't starting with '/' - we got you, ie bastard
            href = href.replace(/http:\/\//, '');
            href = href.replace(href.slice(0, href.indexOf('/')), '');
        }
        var oElem = false;
        var strContainerId = $(this).attr('target');
        if (strContainerId != '') {
            oElem = $("#"+strContainerId);
        }
        $.KH.ajax({
            url: href,
            element: oElem,
            keepInHistory: keepInHistoryFromClass($(this).attr('class')), //see local functions below
            block: blockElementFromClass($(this).attr('class'))
        });
        //with KH-noHistory as CSS Class, you can prevent a link from getting into the history
        function keepInHistoryFromClass (css_classes) {
            return css_classes.match(/KH-noHistory/g) ? false : true;
        }
        //filter and prepare any further page elements, that should get blocked
        //html with classes like "KH-block-#myid" or "KH-block-.myclass" will get picked out and returned as jquery objects to the $.KH.ajax method, where they will get handled in beforeSend and complete
        function blockElementFromClass (css_classes){
            var match = css_classes.match(/KH-block-[#|.]\w+/g); //filter out block css class
            if (match)
                return $(match.join(", ").replace(/KH-block-/g,"")); //return jquery array
        }
        return false;
    });

    //history management via jquery address plugin
    _historyLive = true; //provide a global toggle to disable ajax requests on location.change (=$.address.change), required as $.address.value triggers location.change too
    $.address.change(function(e){
        var targetUrl;
        //backend delivers layout only, so decide what to load into #pageContent here:
        //if a hash url is present (e.path != '/') load the part after the hash, otherwise load the full href
        if(_historyLive) {
            if(e.path != '/') targetUrl = e.path;
            else targetUrl = location.href;
            //load #pageContent contents
            $.KH.ajax({
                url: targetUrl,
                isHistory: true
            });
        }
    });

    //init ajax queue manager
    $.manageAjax.create('kronehit', {
        queue: 'clear', //The clear option clears the queue, before it adds a new ajax-task to the queue (last in first out)
        abortOld: true, //aborts all "older" requests, if there is a response to a newer request
        maxRequests: 2, //limits the number of simultaneous request in the queue
        preventDoubbleRequests: true, //prevents multiple equal requests (compares url, data and type)
        cacheResponse: false, //do not cache response
        jsonp: null, //jquery 1.5 fix! see http://bugs.jquery.com/ticket/8084
        jsonpCallback: null
    });

    //init 'copy url to clipboard' tool
    swfobject.embedSWF("/swf/copy2clip.swf", "copy2clip", "80", "19", "9.0.0", null, null, {wmode:'opaque'});
    $('#urlcopy .arrow').click(function(){
        $main = $('#urlcopy .main');
        if($main.data('origWidth') == undefined) {
            $main.data('origWidth', $main.width());
            $main.animate({width:425});
        } else {
            $main.animate({width:$main.data('origWidth')});
            $main.data('origWidth', null);
        }
    });

    //_webplayerFlashVars defined in layout
    swfobject.embedSWF("/swf/webplayer.swf", "player", "310", "378", "9.0.0", null, _webplayerFlashVars, {wmode:'opaque'}, null,
        function(e){
            if(!e.success) {
                $('#artistcarousel').hide();
                $('#player').html('<p style="padding:10px;">Sie benötigen eine aktuelle Version des Adobe Flash Players.<br/><br/><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>');
            }
        });

    //ie6-friendly 'position:fixed' for alert messages
    if($.browser.msie && $.browser.version == '6.0') {
        $('#alert').css('position', 'absolute');
        $(window).scroll(function() {
            $('#alert').css('top', $(this).scrollTop() + 'px');
        });
    }

    //init google analytics
    try{
        _pageTracker = _gat._getTracker("UA-3459334-1");
    } catch(err) {}
    //inital tracking (all subsequent http requests are tracked in 'complete' handler of $.KH.ajax)
    //no longer required as every page request leads to an ajax request now (backend delivers only layout)
    //$.KH.tracking();

    //fun!
    $(document).konami(function(){
        $.KH.swfBridge.switchChannel({carousel:'image',carouselImg:_webPath+'/images/konami.jpg',carouselImgLink:'http://www.wunderweiss.com'});
    });
});

(function($) { //closure allows us to define functions visible to all plugins
    $.fn.extend({

        //init homepage
        KH_home: function() {
            if($("#usermessage", this).length) $.KH.error($("#usermessage", this).html()); //fallback error message, passed by other pages when forwarded to homepage
            //load artist carousel
            var flashvars = {
                xmlPlaylist: "" //default: "data/playlist.xml", set this to empty string for live mode (where webplayer triggers playlist loading via localconnection)
            };
            swfobject.embedSWF("/swf/artistcarousel.swf", "artistcarousel", "670", "286", "9.0.0", null, flashvars, {wmode:'opaque'});
            //load artist box (logged-in)
            var flashvars = {
                xmlPlaylist: "" //default: "data/playlist.xml", set this to empty string for live mode (where webplayer triggers playlist loading via localconnection)
            };
            swfobject.embedSWF("/swf/artistbox.swf", "artistbox", "500", "134", "9.0.0", null, flashvars, {wmode:'opaque'});
            //new modbox in js
            $('.boxModbox', this).KH_modbox();
            $('#KH-activityStream').KH_activityStream();
        },

        KH_modbox: function() {
            var $box = $(this);
            var $slides = $('.slide', $box);
            if($slides.length > 1) {

                var currSlide = 0;
                var totalSlides = $slides.length;
                var $slider = $('.slider', $box);
                var $border = $('.border', $box);
                var $caption = $('.caption', $box);
                var blocked = false; //block buttons while animating

                $('.next', $box).click(function(e){
                    if(e.originalEvent != undefined) window.clearInterval(autopilotInt); //user clicked, not autopilot!
                    if(!blocked) {
                        blocked = true;
                        var nextSlide = currSlide + 1;
                        if(nextSlide == totalSlides) nextSlide = 0;
                        $slides.hide(); //prevent overlapping
                        $slider.css({left:0});
                        $slides.eq(currSlide).show().css({position:'absolute',left:0});
                        $slides.eq(nextSlide).show().css({position:'absolute',left:490});
                        $slider.animate({left:-490},{duration:500,complete:function(){slideComplete();}});
                        currSlide = nextSlide;
                    }
                    return false;
                });
                $('.prev', $box).click(function(e){
                    if(e.originalEvent != undefined) window.clearInterval(autopilotInt); //user clicked, not autopilot!
                    if(!blocked) {
                        blocked = true;
                        var nextSlide = currSlide - 1;
                        if(nextSlide == -1) nextSlide = totalSlides-1;
                        $slides.hide();
                        $slider.css({left:-490});
                        $slides.eq(currSlide).show().css({position:'absolute',left:490});
                        $slides.eq(nextSlide).show().css({position:'absolute',left:0});
                        $slider.animate({left:0},{duration:500,complete:function(){slideComplete();}});
                        currSlide = nextSlide;
                    }
                    return false;
                });
                var slideComplete = function() {
                    //update link on border (clicks won't be received by slides as border is on top of them!)
                    var href = $slides.eq(currSlide).attr('href');
                    //disable for invalid links
                    if(href == '#' || href == '') {
                        $border.bind('click', returnFalse).css('cursor', 'default');
                    } else {
                        $border.unbind('click', returnFalse).css('cursor', 'pointer');
                    }
                    //for regular links...
                    $border.attr('href', href);
                    var target = $slides.eq(currSlide).attr('target');
                    $border.attr('target', target);
                    if(target == 'pageContent') $border.addClass('KH-link');
                    else $border.removeClass('KH-link');
                    //set caption
                    $caption.html($slides.eq(currSlide).attr('title'));
                    //re-enable buttons
                    blocked = false;
                }
                var returnFalse = function() {
                    return false;
                }
                var autopilot = function() {
                    if($box.parents('body').length) { //box still exists in dom?
                        $('.next', $box).click();
                    } else {
                        window.clearInterval(autopilotInt);
                    }
                }
                slideComplete(); //init

                //autopilot. cleared in ajax functions
                var autopilotInt = window.setInterval(function(){autopilot();}, 7000);
            }

        },

        //login box
        KH_login: function() {
            var element = this; //cache
            $("form .textButton", element).click(login); //loginbutton
            $("input", element).formclear(); //formclear plugin
            $("input[name=password]", element).keypress(function(e){ if (e.which == 13) $("form .textButton", element).trigger('click');});
            element.data('logged-in', false);

            $('a.fb_button', element).live('click', function() {
                $.KH.facebook.login(
                    function() {
                        $.KH.error('Facebook-Login fehlgeschlagen!');
                    },
                    function() {
                        $.KH.FacebookLoginHandler();
                    }
                );
            });

            function login() {
                //post to the server
                $.KH.ajax({
                    url: $("form").attr('action'),
                    data: $("form",element).serialize(),
                    type: 'POST',
                    success: function(data){
                        if(!data.error) { //render logged in state on success
                            if (data.special == 'votetrack') {
                                $.KH.info('Du kannst jetzt den Song bewerten');
                            } else if (data.special == 'addtrack') {
                                $.KH.info('Du kannst jetzt den Song zur Playlist hinzufügen');
                            }
                            element.html(data.html);

                            // redirect by backend (eg on facebook connect)
                            if (data.redirect) {
                                $.KH.refreshPage(data.redirect);
                            } else {
                                var currentUrlArr = location.href.split('#');
                                var currentUrl = (currentUrlArr.length>1) ? currentUrlArr[1] : currentUrlArr[0];
                                if (currentUrl.indexOf('auth/') == -1)
                                    $.KH.refreshPage(currentUrl); //refresh pageContent to current page
                                else
                                    $.KH.refreshPage('/user/user'); // if we are on an auth-page redirect to user/user
                            }
                        } else { //render error
                            $.KH.error(data.error);

                            if (data.action === 'reloadlogin') {
                                $.KH.reloadLogin({
                                    onSuccess: function() {
                                        $.KH.refreshPage(null);
                                    }
                                });
                            } else {
                                //shake head
                                var posx = $('#login').offset().left;
                                var dist = 10;
                                var time = 50;
                                $('#login')
                                    .animate({left: posx+dist}, time)
                                    .animate({left: posx-dist}, time)
                                    .animate({left: posx+dist}, time)
                                    .animate({left: posx-dist}, time)
                                    .animate({left: posx+dist}, time)
                                    .animate({left: posx-dist}, time)
                                    .animate({left: posx}, time)
                                ;
                            }
                        }
                    },
                    dataType: 'json',
                    element: element
                });
                return false;
            }
        },

        //logout box
        KH_logout: function(options) {
            if (!options) {
                options = {};
            }

            options.facebookLogout = options.facebookLogout || false;

            var element = this;
            $(".textButton", this).click(function (){
                function doLogout() {
                    $.KH.ajax({
                        url: "/auth/logout",
                        success: function(data){
                            element.html(data); //render logged out state
                            $.KH.refreshPage(); //refresh to index page
                        },
                        element: element
                    });
                }

                if (options.facebookLogout) {
                    $('#pageContent').KH_blockElement();
                    $.KH.facebook.logout(function() {
                        doLogout();
                        $('#pageContent').KH_unblockElement();
                    });
                } else {
                    doLogout();
                }
                return false;
            });
            element.data('logged-in', true);
        },

        KH_register: function(options) {
            if (!options) {
                options = {};
            }

            options.url = options.url || "/auth/register";

            var element = this;
            var form = $("#form_register",element);

            $("#button_register",element).click(function(){
                $.KH.ajax({
                    url: options.url,
                    data: form.serialize(),
                    type: 'POST',
                    success: function(data){
                        if(!data.error) {
                            if(data.success) { //form valid
                                $.KH.refreshPage();
                                $.KH.info(data.success); //display this for longer time
                            } else { //form not valid
                                $("#pageContent").html(data.html); //refresh form with validation errors
                            }
                        } else { //backend error
                            $.KH.error(data.error);
                        }
                    },
                    dataType: 'json',
                    element: element
                });
                return false;
            });
        },

        KH_profile: function(strRedirect) {
            var element = this;
            var avatar = $("input#avatar_id", element); //beware, uploadify does magically only work if an id is set on the dom element
            var modimage = $("input#modimage_id", element);
            var form = $("#form_profile", element);

            $("#dob", element).datepicker({
                yearRange:'-80:0',
                changeMonth: true,
                changeYear: true,
                monthNamesShort: ['Jan','Feb','M&auml;r','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez'],
                dayNamesMin: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
                dateFormat: 'dd.mm.yy'
            });
            $("#button_profile",element).click(function(){
                $.KH.ajax({
                    url: "/user/profile",
                    data: form.serialize(),
                    type: 'POST',
                    success: function(data){
                        if(data.success) { //form valid
                            $.KH.refreshPage(strRedirect);
                            $.KH.info('Änderungen gespeichert', 3);
                        } else { //form not valid
                            $("#pageContent").html(data.html); //refresh form with validation errors
                            $.KH.error(data.error);
                        }
                    },
                    dataType: 'json',
                    element: element
                });
                return false;
            });

            var upfOptions_avatar = $.extend({}, $.KH.uploadifyOptions); //using $.extend($.KH.uploadifyOptions... would change original options!
            avatar.uploadify($.extend(upfOptions_avatar, {
                'fileDesc': 'Bilder (jpg/gif/png)',
                'fileExt': '*.jpg;*.jpeg;*.gif;*.png',
                'onComplete' : function(event, queueID, fileObj, response, data){
                    $("input[id=avatar_filename]", form).val(fileObj.name); //set server filename (response) to hidden field to submit later on
                    $("input[id=avatar_folder]", form).val($.KH.uploadifyOptions.folder); //set server filename (response) to hidden field to submit later on
                    $("input[id=avatar_preview_url]", form).val($.KH.uploadifyOptions.folder + '/' + fileObj.name); //set uploadify-path and server filename (response) to hidden field to submit later on
                    $("#avatar_preview").empty().html('<img src="' + $.KH.uploadifyOptions.folder + '/' + fileObj.name + '" width="64" />'); //show temp image
                }
            }));

            var upfOptions_modimage = $.extend({}, $.KH.uploadifyOptions); //using $.extend($.KH.uploadifyOptions... would change original options!
            modimage.uploadify($.extend(upfOptions_modimage, {
                'fileDesc': 'Bilder (png)',
                'fileExt': '*.png',
                'onComplete' : function(event, queueID, fileObj, response, data){
                    $("input[id=modimage_filename]", form).val(fileObj.name); //set server filename (response) to hidden field to submit later on
                    $("input[id=modimage_folder]", form).val($.KH.uploadifyOptions.folder); //set server filename (response) to hidden field to submit later on
                    $("input[id=modimage_preview_url]", form).val($.KH.uploadifyOptions.folder + '/' + fileObj.name); //set uploadify-path and server filename (response) to hidden field to submit later on
                    $("#modimage_preview").empty().html('<img src="' + $.KH.uploadifyOptions.folder + '/' + fileObj.name + '" width="64" />'); //show temp image
                }
            }));
        },

        KH_settings: function() {
            var element = this;
            var form = $("#form_settings", element);

            $('.fb_button.connect', element).click(function(e) {
                e.preventDefault();
                $.KH.facebook.login(
                    function() {
                        $.KH.error('Facebook-Login fehlgeschlagen!');
                    },
                    function() {
                        $.KH.FacebookConnect({'successUrl' : '/user/settings'});
                    }
                );
                return false;
            });

            $('.fb_button.disconnect', element).click(function() {
                $.KH.FacebookDisconnect();
                return false;
            });

            $("#button_settings",element).click(function(e){
                e.preventDefault();
                if ($('input:radio[name="facebook_publish"]:checked').val() == '1') {
                    $.KH.facebook.getPermissions('publish_stream',
                        function() {
                            $.KH.error('Um Beiträge automatisch auf Facebook posten zu können, musst Du den benötigten Zugriff auf dein Facebook-Profil durch kronehit.at erlauben.');
                        },
                        function() {
                            submit();
                        }
                    );
                } else {
                    submit();
                }
                function submit() {
                    $.KH.ajax({
                        url: "/user/settings",
                        data: form.serialize(),
                        type: 'POST',
                        success: function(data){
                            if(data.success) { //form valid
                                $.KH.refreshPage('/user/settings');
                                $.KH.info('Änderungen gespeichert', 3);
                            } else { //form not valid
                                $("#pageContent").html(data.html); //refresh form with validation errors
                                $.KH.error(data.error);
                            }
                        },
                        dataType: 'json',
                        element: element
                    });
                }
                return false;
            });

            if ($('input:radio[name="facebook_publish"]').length > 0) {
                $.KH.ajax({
                    url: "/user/fbsettings",
                    success: function(data){
                        if(data.success) { //form valid
                            if (data.notSetFacebookPublish) {
                                $.KH.FacebookSettingsDialog(function(settingsSaved) {
                                    // don't refresh if settings aren't saved, otherwise we could run into an loop
                                    if (settingsSaved) {
                                        $.KH.refreshPage('/user/settings');
                                    }
                                });
                            }
                        } // ignore errors
                    },
                    dataType: 'json'
                });
            }
        },

        KH_activate: function() { //activate user (step1)
            var element = this;
            $(".textButton", element).click(function(){
                var form = $("form", element);
                $.KH.ajax({
                    url: "/auth/activate", //token is not submitted, because it resides in the users session
                    data: form.KH_serialize(),
                    type: 'POST',
                    success: function(data){
                        if(!data.error) {
                            $("#pageContent").html(data.html);
                        } else { //backend error
                            $.KH.error(data.error);
                        }
                    },
                    dataType: 'json',
                    element: element
                });
                return false;
            });
        },

        KH_activate_step2: function() { //activate user (step2)
            var element = this;
            $("#zip, #phone, #dob", element).formclear();
            $("#dob", element).datepicker({
                yearRange:'-80:0',
                changeMonth: true,
                changeYear: true,
                monthNamesShort: ['Jan','Feb','M&auml;r','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez'],
                dayNamesMin: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
                dateFormat: 'dd.mm.yy'
            });
            $(".textButton", element).click(function(){
                var form = $("form", element);
                $.KH.ajax({
                    url: "/auth/activate2", //token is not submitted, because it resides in the users session
                    data: form.KH_serialize(),
                    type: 'POST',
                    success: function(data){
                        if(!data.error) { //success
                            if(data.success) { //form valid
                                if (data.action === 'fbconnect') {
                                    $.KH.FacebookLoginHandler({'successUrl' : data.redirect});
                                } else {
                                    $.KH.refreshPage();
                                }
                                $.KH.info(data.success);
                            } else { //form invalid
                                $("#pageContent").html(data.html);
                            }
                        } else { //backend error
                            $.KH.error(data.error);
                        }
                    },
                    dataType: 'json',
                    element: element
                });
                return false;
            });
        },

        KH_forgottenPassword: function(){
            var element = this;
            var form = $("form",element);
            $(".textButton",element).click(function(){
                $.KH.ajax({
                    url: "/auth/password",
                    data: form.serialize(),
                    type: 'POST',
                    success: function(data){
                        if(!data.error) { //success
                            if(data.success) { //form valid
                                if (data.redirect) {
                                    $.KH.refreshPage(data.redirect);
                                }
                                else {
                                    $.KH.refreshPage();
                                    $.KH.info(data.success,10);
                                }
                            } else { //form invalid
                                $("#pageContent").html(data.html);
                            }
                        } else { //backend error
                            if (data.redirect)
                                $.KH.refreshPage(data.redirect);
                            else
                                $.KH.error(data.error);
                        }
                    },
                    dataType: 'json',
                    element: element
                });
                return false;
            });
            if($('#pwdsuccess', element).length) {$.KH.info($('#pwdsuccess', element).html());} //spit out success message
        },

        KH_admin_label_create: function(){
            var element = this;
            var image = $("input#image", element);
            var form = $("form", element);

            var upfOptions_image = $.extend({}, $.KH.uploadifyOptions); //using $.extend($.KH.uploadifyOptions... would change original options!
            image.uploadify($.extend(upfOptions_image, {
                'fileDesc': 'Bilder (jpg/gif/png)',
                'fileExt': '*.jpg;*.jpeg;*.gif;*.png',
                'onComplete' : function(event, queueID, fileObj, response, data){
                    $("input[name=image_filename]", form).val(fileObj.name); //set server filename (response) to hidden field to submit later on
                    $("input[name=image_folder]", form).val($.KH.uploadifyOptions.folder); //set server filename (response) to hidden field to submit later on
                    $("#image_preview", form).empty().html('<img src="' + $.KH.uploadifyOptions.folder + '/' + fileObj.name + '" heigth="64" width="64" />'); //show temp image
                }
            }));

            //form submit button
            $(".textButton", element).click(function(){

                $.KH.ajax({
                    url: "/artist/" + form.attr('action'),
                    data: form.KH_serialize(),
                    type: 'POST',
                    success: function(data){
                        if(!data.error){
                            $.KH.refreshPage('/artist/labellist');
                            $.KH.info(data.success);
                        }
                        else { //backend error
                            $.KH.error(data.error);
                        }
                    },
                    element: element,
                    dataType: 'json'
                });

                return false;
            });
        },

        KH_admin_artist_create: function(){
            var element = this;
            var avatar = $("input#avatar", element); //beware, uploadify does magically only work if an id is set on the dom element
            var image = $("input#image", element);
            var form = $("form", element);

            var upfOptions_avatar = $.extend({}, $.KH.uploadifyOptions); //using $.extend($.KH.uploadifyOptions... would change original options!
            avatar.uploadify($.extend(upfOptions_avatar, {
                'fileDesc': 'Bilder (png)',
                'fileExt': '*.png',
                'onComplete' : function(event, queueID, fileObj, response, data){
                    $("input[name=avatar_filename]", form).val(fileObj.name); //set server filename (response) to hidden field to submit later on
                    $("input[name=avatar_folder]", form).val($.KH.uploadifyOptions.folder); //set server filename (response) to hidden field to submit later on
                    $("#avatar_preview", form).empty().html('<img src="' + $.KH.uploadifyOptions.folder + '/' + fileObj.name + '" heigth="230" width="230" />'); //show temp image
                }
            }));

            var upfOptions_image = $.extend({}, $.KH.uploadifyOptions); //using $.extend($.KH.uploadifyOptions... would change original options!
            image.uploadify($.extend(upfOptions_image, {
                'fileDesc': 'Bilder (jpg/gif/png)',
                'fileExt': '*.jpg;*.jpeg;*.gif;*.png',
                'onComplete' : function(event, queueID, fileObj, response, data){
                    $("input[name=image_filename]", form).val(fileObj.name); //set server filename (response) to hidden field to submit later on
                    $("input[name=image_folder]", form).val($.KH.uploadifyOptions.folder); //set server filename (response) to hidden field to submit later on
                    $("#image_preview", form).empty().html('<img src="' + $.KH.uploadifyOptions.folder + '/' + fileObj.name + '" heigth="64" width="64" />'); //show temp image
                }
            }));

            //form submit button
            $(".textButton", element).click(function(){
                if(!$("input[name=mbid]", element).val()) { //first check for a set musicbrainz id
                    var $dialogCreateMbArtist = $('#dialogCreateMbArtist');

                    $dialogCreateMbArtist.dialog({
                        resizable: false,
                        draggable: false,
                        bgiframe: true,
                        width: 250,
                        height: 100,
                        modal: true,
                        title: 'Musicbrainz Artist',
                        buttons: {
                            'Ja': function() {
                                $dialogCreateMbArtist.dialog('destroy');
                                submit();
                            },
                            'Nein': function() {
                                $dialogCreateMbArtist.dialog('destroy');
                                $.KH.error("Bitte einen Musicbrainz Artist auswählen!");
                            }
                        },
                        close: function() { //always destroy on close
                            $dialogCreateMbArtist.dialog('destroy');
                            $.KH.error("Bitte einen Musicbrainz Artist auswählen!");
                        }
                    });
                    return false;
                } else {
                    submit();
                }

                function submit() {
                    $.KH.ajax({
                        url: "/artist/" + form.attr('action'),
                        data: form.KH_serialize(),
                        type: 'POST',
                        success: function(data){
                            if(!data.error){
                                if(data.artist_id) { //coming from 'create', goto discographie tab so it's initially fetched from amazon
                                    $.KH.refreshPage('/artist/discographie/id/'+data.artist_id);
                                } else { //coming from 'edit'
                                    $.KH.refreshPage('/artist/list');
                                }
                                $.KH.info(data.success);
                            }
                            else { //backend error
                                $.KH.error(data.error);
                            }
                        },
                        element: element,
                        dataType: 'json'
                    });
                }

                return false;
            });

            //autocomplete on Artistnames
            $("input[name=title]", element).autocomplete('/artist/findmusicbrainzartist', {
                delay: 1000,
                minChars: 3,
                max: 20 //show only 20 results
            }).result(function(event, data, formatted) {
                $("input[name=mbid]", element).val(data[1]); //set mb data on result
                $("input[name=mbartist]", element).val(data[0]); //set temporary uploadfolder, so backend knows where to find the uploads
            });

            //autocomplte on artistnames for related artists
            $("input[name=title_ra]", element).autocomplete('/artist/findmusicbrainzartist', {
                delay: 1000,
                minChars: 3,
                max: 20 //show only 20 results
            }).result(function(event, data, formatted) {
                //$("input[name=mbid]", element).val(data[1]); //set mb data on result
                //$("input[name=mbartist]", element).val(data[0]); //set temporary uploadfolder, so backend knows where to find the uploads

                $("#related_artist", element).append(
                        $('<option></option>').val(data[1]).html(data[0]).attr('selected','selected')
                );
                //alert('ID ' + data[1] + ' hinzugefügt');
                $("input[name=title_ra]", element).val(''); // reset autocomplete field
            });

        },

        KH_admin_kronenews_edit: function() {
            var element = this;
            var form = $("form", element);
            //form submit button
            $(".textButton", element).click(function(){
                $.KH.ajax({
                    url: '/content/kronenewsedit',
                    data: form.KH_serialize(),
                    type: 'POST',
                    success: function(data){
                        if(!data.error){
                            $.KH.info(data.success);
                            $.KH.refreshPage('/content/admkronenews');
                        }
                        else { //backend error
                            $.KH.error(data.error);
                        }
                    },
                    element: element,
                    dataType: 'json'
                });

                return false;
            });

            //autocomplte on artistnames for related artists
            $("input[name=title_ra]", element).autocomplete('/artist/findartistpage', {
                delay: 1000,
                minChars: 3,
                max: 20 //show only 10 results
            }).result(function(event, data, formatted) {
                //$("input[name=mbid]", element).val(data[1]); //set mb data on result
                //$("input[name=mbartist]", element).val(data[0]); //set temporary uploadfolder, so backend knows where to find the uploads

                $("#related_artist", element).append(
                        $('<option></option>').val(data[1]).html(data[0]).attr('selected','selected')
                );
                //alert('ID ' + data[1] + ' hinzugefügt');
                $("input[name=title_ra]", element).val(''); // reset autocomplete field
            });
        },

        //lottery questions (simple'n'stupid)
        KH_lottery: function(strPageKey) {
            //first step, answer questions
            $('.boxLotteryQuestion', this).each(function(i){
                var $box = $(this);
                if(i==0) $box.show();
                $('.textButton', $box).click(function(){
                    if (!$(this).hasClass("KH-link")) {
                        var $box = $(this).closest('.box'); //can't use $box from outer closure as it contains the last box of the loop
                        if($('input:checked', $box).hasClass('KH-correct')) {
                            if($box.next().hasClass('boxLotteryQuestion')){
                                $box.hide();
                                $box.next().show();
                            } else {
                                //last question done, render userdata form
                                loadUserdataForm(strPageKey);
                            }
                        } else {
                            var inputID = $('input:checked', $box).attr('id');
                            $('label[for='+inputID+']').css('color','red');
                        }
                    }
                });
            });
            //second step, submit userdata form
            var element = this;
            $('#lotteryUserdata .submit').click(function(){
                var $form = $("form", element);
                $('input[name=pagekey]', $form).attr('value', $('#pagekey').val());
                $('input,select', $form).attr('disabled', '');

                var postData = null;
                // if the user wants to publish and type is share (popup), we don't do it async (adblocker) refs #818
                var doAsync = !($('input[name="allow_facebook_publish"]:checked', $form).length > 0 &&
                                $('input[name="facebook_post_type"]', $form).val() === 'share');

                var successHandler = function(data) {
                    if(data.success) {
                        $.KH.info(data.msg);
                        $('#lottery').html('<p class="message">'+data.msg+'</p>');

                        if (data.facebookData) {
                            // share with fb ui
                            $.KH.facebook.publishPost(
                                data.facebookData,
                                function() {
                                    $.KH.error('Dein Beitrag wurde nicht auf Facebook gepostet');
                                },
                                function(postId) {
                                    $.KH.ajax({
                                        url: data.successUrl,
                                        dataType: 'json',
                                        type: 'post',
                                        data: 'uid='+postId,
                                        success: function(data){
                                            if (!data.error) {
                                                $.KH.info(data.msg);
                                            } else {
                                                $.KH.error(data.error);
                                            }
                                        }
                                    });
                                }
                            );
                        }
                    } else {
                        $('#lottery').html(data.html);
                    }
                };

                $.KH.ajax({
                    url: $form.attr('action'),
                    data: $form.KH_serialize(),
                    async: doAsync,
                    type: 'POST',
                    element: $('#lottery'),
                    success: function(data){
                        if (doAsync) {
                            successHandler(data);
                        } else {
                            postData = data;
                        }
                    },
                    dataType: 'json'
                });

                if (!doAsync) {
                    successHandler(postData);
                }
                return false;
            });
            //fallback: if lottery doesn't have questions (or a 'already done' message), just render the userdata form
            if($('#lottery').children().length == 0) {
                loadUserdataForm(strPageKey);
            }
            //helpers
            function loadUserdataForm(strPageKey) {
                $.KH.ajax({
                    url: '/content/lotterysubmit/pagekey/' + strPageKey,
                    element: $('#lottery'),
                    success: function(data){
                        $('#lottery').html(data);
                    }
                });
            }
        },

        //voting
        KH_voting: function() {
            var $voting = this;
            $('.submit', $voting).click(function(){
                var $form = $("form", $voting);
                //$('input[name=pagekey]', $form).attr('value', $('#pagekey').val());
                $.KH.ajax({
                    url: $form.attr('action'),
                    data: $form.serialize(),
                    type: $form.attr('method'),
                    element: $voting,
                    success: function(data){
                        $voting.replaceWith(data.html);
                    },
                    dataType: 'json'
                });
                return false;
            });
        },

        KH_frequencyFinder: function() {
            var element = this;
            var form = $("form", element);
            var button = $(".textButton", element);
            var input = $("input[name=zip]", form);
            input.keypress(function(e){ if (input.val().length && e.which == 13) button.trigger('click'); else if(e.which == 13) return false;});
            button.click(function(){
                if(input.val()) {
                    $.KH.ajax({
                        url: "/content/frequencies",
                        data: form.serialize(),
                        type: 'POST',
                        success: function(data){
                            if(!data) $.KH.error("Postleitzahl konnte nicht gefunden werden.");
                            else {
                                $("#frequency_result", element).html(data);
                                $.KH.info("Du kannst KRONEHIT unter "+data+" genießen!", 10);
                            }
                        },
                        element: element
                    });
                }
                return false;
            });
            //zoom map
            $('.map', element).click(function(){
                $('.map-zoom')
                    .appendTo('body')
                    .css({position:'absolute', left:88, top:140, cursor:'pointer'})
                    .click(function(){
                        $(this).hide();
                    })
                    .show();
            });
        },

        //musicwish teaser
        KH_musicWish: function() {
            var $box = this;
            var $form = $('form', $box);
            //not logged in? return
            if($box.hasClass('require_login')) {
                $('input[name=artist]', $box).val('Bitte zuerst einloggen!').css('color','red');
                $('input, textarea', $box).attr('disabled','disabled');
                $('.submit', $box).hide();
                return;
            }
            //autocomplete artist/song
            $("input[name=artist]", $box).autocomplete('/content/findartist', {
                delay: 500,
                minChars: 3,
                max: 20 //show only 10 results
            }).result(function(event, data, formatted) {
                //console.log('result artist');
                $("input[name=artist]", $box).data('artistID', data[1]).addClass('chosen');
                $("input[name=track]", $box).removeAttr('disabled').focus();
            }).keydown(function(e){
                if(e.keyCode != 13 && e.keyCode != 9) { //ENTER, TAB
                    $(this).removeClass('chosen');
                    $("input[name=track]", $box).val('').removeClass('chosen').attr('disabled','disabled');
                    toggleValid(false);
                }
            });
            $("input[name=track]", $box).autocomplete('/content/findtrack', {
                extraParams: {
                    artistID: function() { return $("input[name=artist]", $box).data('artistID'); }
                },
                delay: 500,
                minChars: 3,
                max: 20 //show only 10 results
            }).result(function(event, data, formatted) {
                //console.log('result track');
                $("input[name=track]", $box).data('trackID', data[1]).addClass('chosen');
                toggleValid(true);
                $("input[name=dedicate]", $box).focus();
            }).keydown(function(e){
                if(e.keyCode != 13 && e.keyCode != 9) { //ENTER, TAB
                    $(this).removeClass('chosen');
                    toggleValid(false);
                }
            });
            //submit
            $(".submit", $form).click(function(){
                $.KH.ajax({
                    url: $form.attr('action'),
                    data: $form.serialize() + '&trackID=' + $('input[name=track]', $box).data('trackID'),
                    type: $form.attr('method'),
                    success: function(data){
                        if (data.error) {
                            $.KH.error(data.error);
                        } else {
                            $('.content', $box).html(data.html);
                        }
                    },
                    dataType: 'json',
                    element: $box
                });
                return false;
            });
            //if valid song is chosen, allow submit
            function toggleValid(toggle) {
                if(toggle) {
                    $('.dedicate, .whyme', $box).removeAttr('disabled');
                    $('.submit', $box).removeClass('disabled');
                } else {
                    $('.dedicate, .whyme', $box).attr('disabled','disabled');
                    $('.submit', $box).addClass('disabled');
                }
            }
            //init
            $("input[name=track]", $box).attr('disabled','disabled');
            toggleValid(false);
        },

        //block region via jquery BlockUI, also set opacity of region
        KH_blockElement: function() {
            return this.each(function(){
                $(this).css('opacity', 0.5).block();
            });
        },
        KH_unblockElement: function() {
            return this.each(function(){
                $(this).css('opacity', '').unblock();
            });
        },

        //reset jquery formclear plugin values before submit
        //call this, if your form fields are managed by formclear and you need to submit them
        KH_serialize : function () {
            this.each(function(){
                $("input, textarea, select", this).each(function(){
                    var o = $(this);
                    if(o.attr('title') && o.val() == o.attr('title')){ //unset value, if title equals value
                        o.val("");
                    }
                });
            });
            return this.serialize(); //call normal jquery serialize now
        },

        //tabboxes with collapsible content
        KH_tabbox_collapsible: function() {
            return this.each(function(){
                $(this).find('h2.collapsible').each(function(){
                    $(this).click(function(){
                        var $this = $(this);
                        if($this.next().is('.collapseContent')) {
                            $this.toggleClass('expanded');
                            $this.next().slideToggle();
                        }
                    });
                });
            });
        },

        //wikipedia content on artistpage
        KH_wikipedia: function() {
            var $target = $(this);
            if($('.tabBox', $target).length) {
                //content cleanup
                $('.tabBox', $target).not('.KH-shortinfo').each(function(){
                    var $tabBox = $(this);
                    //content cleanup
                    $('a', $tabBox).attr('target', '_blank');
                    $('a[href^=#]', $tabBox).each(function(){ //remove hash links (starting with #)
                        $(this).replaceWith(this.childNodes);
                    });
                    $('tr[bgcolor^=#]', $tabBox).attr('bgcolor','').css('background','white');
                    $('th[bgcolor^=#]', $tabBox).attr('bgcolor','').css('background','white');
                    $('td[bgcolor^=#]', $tabBox).attr('bgcolor','').css('background','white');
                    //collapsible
                    $tabBox.data('origHeight', $tabBox.height());
                    $tabBox.height(17).css('overflow','hidden');
                    $('h2', $tabBox).addClass('collapsible').prepend('<span class="arrow"></span>').click(function(){
                        var $h2 = $(this);
                        if($h2.hasClass('expanded')) {
                            $tabBox.animate({height:17});
                            $h2.removeClass('expanded');
                        } else {
                            $tabBox.animate({height:$tabBox.data('origHeight')});
                            $h2.addClass('expanded');
                        }
                        $.KH.tracking();
                    });
                });
            }
        },

        //tabbed content
        KH_tabbox: function() {
            var $target = $(this);
            var $tabs = $('.tabs', $target);
            var $content = $('.tabContent', $target);
            $('a', $tabs).click(function(){
                $a = $(this);
                $.KH.ajax({
                    url: $a.attr('href'),
                    success: function(data){
                        $content.html(data);
                    },
                    element: $content,
                    keepInHistory: true
                });
                $('a', $tabs).removeClass('current');
                $a.addClass('current');
                return false;
            });
        },

        //tabbed content
        KH_tabboxsub: function() {
            var $target = $(this);
            var $tabs = $('.tabssub', $target);
            var $content = $('.tabContent', $('#tabbox'));
            $('a', $tabs).click(function(){
                $a = $(this);
                $.KH.ajax({
                    url: $a.attr('href'),
                    success: function(data){
                        $content.html(data);
                    },
                    element: $content,
                    keepInHistory: true
                });
                $('a', $tabs).removeClass('current');
                $a.addClass('current');
                return false;
            });
        },

        //artistpage discography
        KH_discography: function() {
            var $target = $(this);
            $('.tabBox ul', $target).each(function(){
                $ul = $(this);
                $ul.data('origHeight', $ul.height());
                //show only the first 3 songs initially
                var shrinkHeight = 0;
                $('li:lt(3)', $ul).each(function(){
                    shrinkHeight += $(this).outerHeight();
                });
                $ul.css('height', shrinkHeight);
            });
            $('.tabBox .showAll', $target).click(function(){
                $ul = $(this).prev();
                $ul.animate({height:$ul.data('origHeight')+'px'}, 500);
                $(this).hide();
                $.KH.tracking();
                return false;
            });
        },

        KH_mediaupload: function(){
            var $target = $(this);
            var $image = $("input#image", $target);
            var $form = $("form", $target);

            $('input[name=youtube_url], input[name=flickr_url], input[name=description]').formclear();

            var upfOptions_image = $.extend({}, $.KH.uploadifyOptions); //using $.extend($.KH.uploadifyOptions... would change original options!
            $image.uploadify($.extend(upfOptions_image, {
                'fileDesc': 'Bilder (jpeg/gif/png)',
                'fileExt': '*.jpg;*.jpeg;*.gif;*.png',
                'onComplete' : function(event, queueID, fileObj, response, data){
                    $("input[name=image_filename]", $form).val(fileObj.name);
                    $("input[name=image_folder]", $form).val($.KH.uploadifyOptions.folder);
                    $(".filename", $form).html(fileObj.name);
                }
            }));
            $('input[name=mediaType]', $target).change(function(){
                var val = $(this).val();
                //disable all
                $('#imageUploader, .filename', $target).css('opacity', 0.5);
                $('input[name=youtube_url], input[name=flickr_url]', $target).attr('disabled','disabled');
                //enable current
                if(val == 'image') {
                    $('#imageUploader, .filename', $target).css('opacity', 1);
                }
                if(val == 'youtube') {
                    $('input[name=youtube_url]', $target).removeAttr('disabled');
                }
                if(val == 'flickr') {
                    $('input[name=flickr_url]', $target).removeAttr('disabled');
                }
            }).eq(0).click().change();
            $('.textButton', $form).click(function(){
                $.KH.ajax({
                    url: $form.attr('action'),
                    data: $form.KH_serialize(),
                    type: $form.attr('method'),
                    success: function(data){
                        if(data.error) {
                            $.KH.error(data.msg, 3);
                        } else {
                            $.KH.info(data.msg, 3);
                            $('#KH-mediaTab').click(); //reload media tab
                            var $amount = $('#KH-mediaTab .slice.main span');
                            var newAmount = parseInt($amount.text().replace(/(\(|\))/g, ''))+1;
                            $amount.html('('+newAmount+')');
                        }
                    },
                    dataType: 'json',
                    element: $target
                });
            });
        },

        KH_mediadetail: function() {
            var $target = $(this);
            var $diaDel = $('#confirmDelete', $target);
            var $aDelete = $('.KH-delete', $target);

            //delete
            $aDelete.click(function(){
                $diaDel.dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 200,
                    height: 150,
                    modal: true,
                    title: 'Löschen bestätigen',
                    buttons: {
                        'Löschen': function() {
                            $.KH.ajax({
                                url: $aDelete.attr('href'),
                                success: function(data){
                                    $('#KH-mediaTab').click(); //reload media
                                    $.KH.info(data.msg, 3);
                                    $diaDel.dialog('destroy');
                                    //update amount in media tab
                                    var $amount = $('#KH-mediaTab .slice.main span');
                                    var newAmount = parseInt($amount.text().replace(/(\(|\))/g, ''))-1;
                                    $amount.html('('+newAmount+')');
                                },
                                dataType: 'json',
                                element: $diaDel
                            });
                        },
                        'Abbrechen': function() {
                            $diaDel.dialog('destroy');
                        }
                    }
                });
                return false;
            });
            //change caption
            $('.KH-changeText', $target).click(function(){
                var $a = $(this);
                var $desc = $('.caption', $target);
                if(!$a.data('save')) {
                    var currentText = $desc.html();
                    $desc.html('<input class="text KH-editText" type="text" value="'+currentText+'" maxlength="100" />');
                    var $editField = $('.KH-editText', $target);
                    $editField.keypress(function(e){
                        var code = (e.keyCode ? e.keyCode : e.which);
                        if(code == 13) { //ENTER
                            saveNewText(currentText);
                        }
                    }).select();
                    $a.data('save',true).html('Text speichern');
                } else {
                    saveNewText('');
                }
                function saveNewText(currentText) {
                    var txt = $('.KH-editText', $target).val();
                    $.KH.ajax({
                        url: $a.attr('href'),
                        type: 'post',
                        data: 'newText='+txt,
                        success: function(data){
                            if (!data.error) {
                                $desc.html(txt);
                                $.KH.info(data.msg, 3);
                            } else {
                                $desc.html(currentText);
                                $.KH.error(data.error);
                            }
                            $a.data('save',false).html('Text ändern');
                        },
                        dataType: 'json',
                        element: $target
                    });
                }
                return false;
            });
            //report media (=comment)
            $('.KH-report', $target).click(function(){
                reportComment($(this), 'media');
                return false;
            });
            //comments
            $('.comments', $target).KH_comments({$outerAddBtn: $('.KH-addComment', $target)});
        },

        //artistpage infobox
        KH_artistinfo: function() {
            var $target = $(this);

            //FANBUTTON
            var $fanbutton = $('.KH-fanbutton', $target);
            $fanbutton.click(function(){
                handleFanOf ($fanbutton, $('#artistname').html(), 'artist', false);
                return false;
            });
            //init
            toggleFanButtonTitle($fanbutton);

            //'EMPFEHLEN'
            var $recommend = $('.KH-recommend', $target);
            var $diaRec = $('#recommend');
            var $message = $diaRec.find('textarea[name=message]');

            $recommend.click(function(){
                $diaRec.dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 300,
                    height: 240,
                    modal: true,
                    title: 'Artist empfehlen',
                    buttons: {
                        'Artist empfehlen': function() {
                            $form = $('form', $diaRec)
                            $.KH.ajax({
                                url: $form.attr('action'),
                                data: $form.serialize(),
                                type: $form.attr('method'),
                                dataType: 'json',
                                element: $diaRec,
                                success: function(data){
                                    if(data.success) {
                                        $diaRec.find('.error').hide();
                                        $diaRec.find('.step:eq(0)').hide();
                                        $diaRec.find('.step:eq(1)').show();
                                        $diaRec.data('origButtons', $diaRec.dialog('option', 'buttons'));
                                        $diaRec.dialog('option', 'buttons', {'Schliessen': function() { $(this).dialog("destroy"); } });
                                    } else {
                                        $diaRec.find('.error').show();
                                    }
                                }
                            });
                        },
                        'Abbrechen': function() {
                            $diaRec.dialog('close');
                        }
                    },
                    open: function(){
                        if($diaRec.data('origButtons')) $diaRec.dialog('option', 'buttons', $diaRec.data('origButtons'));
                        $diaRec
                            .find('.step').hide().end()
                            .find('.step:eq(0)').show()
                                .find('.error').hide().end()
                                .find('[name=email]').val('');
                        $message.val($message.attr('title'));
                    },
                    close: function() { //always destroy on close
                        $diaRec.dialog('destroy');
                    }

                });
                return false;
            });
        },

        //'Titelsuche'
        KH_trackservice: function() {
            var $target = $(this);
            var $form = $('.search form', $target);
            var $result = $('.result', $target);
            $('.search .textButton', $target).click(function() {
                $.KH.ajax({
                    url: $form.attr('action'),
                    type: $form.attr('method'),
                    data: $form.serialize(),
                    element: $result,
                    success: function(data){
                        $result.html(data);
                    }
                });
                return false;
            });
        },

        //userpage
        KH_boxFanOf: function() {
            var $box = $(this);
            var $showAll = $('.KH-showAll', $box);
            $showAll.click(function(){
                $('#tabbox .tabs a').removeClass('current'); //'fan of' has no tab
                $.KH.ajax({
                    url: $(this).attr('href'),
                    type: 'post',
                    element: $('#tabContent'),
                    keepInHistory: true,
                    success: function(data){
                        $('#tabContent').html(data);
                    }
                });
                return false;
            });
        },

        //userpage/artistpage
        KH_boxPostMessage: function($updateTab, errorMessage) { //username required to show in box when disabled
            var $box = $(this);
            var $submit = $('.textButton', $box);
            var $form = $('form', $box);
            var $msg = $('textarea[name=msg]', $form);
            var $url = $('input[name=url]', $form);
            if($box.hasClass('KH-disabled')) { //posting may be disabled in privacy settings
                $msg.attr('disabled','disabled').html(errorMessage);
                $url.attr('disabled','disabled');
                $submit.click(function(){return false;});
            } else {
                $msg.formclear();
                $msg.KH_maxlength();
                $url.formclear();
                $submit.click(function(){
                    var postData = null;
                    // if the user wants to publish and type is share (popup), we don't do it async (adblocker) refs #818
                    var doAsync = !($('input[name="allow_facebook_publish"]:checked', $form).length > 0 &&
                                    $('input[name="facebook_post_type"]', $form).val() === 'share');

                    var successHandler = function(data) {
                        if(data.error) {
                            $.KH.error(data.msg, 3);
                            $msg.blur();
                            $url.blur();
                        } else {
                            $.KH.info(data.msg, 3);
                            $msg.val('').formclear();
                            $url.val('').formclear();
                            if ($updateTab.attr('id') == 'KH-storiesTab') {
                                var $amount = $('#KH-storiesTab .slice.main span');
                                var newAmount = parseInt($amount.text().replace(/(\(|\))/g, ''))+1;
                                $amount.html('('+newAmount+')');
                                $('#KH-storiesTabComments').click();
                            } else {
                                $updateTab.click(); //reload tab where message should appear
                            }

                            // if publish checkbox is checked we post it directly or share it with fb ui
                            if (data && data.facebookData) {
                                // share with fb ui
                                $.KH.facebook.publishPost(
                                    data.facebookData,
                                    function() {
                                        $.KH.error('Dein Beitrag wurde nicht auf Facebook gepostet');
                                    },
                                    function(postId) {
                                        $.KH.ajax({
                                            url: data.successUrl,
                                            dataType: 'json',
                                            type: 'post',
                                            data: 'uid='+postId,
                                            success: function(data){
                                                if (!data.error) {
                                                    $.KH.info(data.msg);
                                                } else {
                                                    $.KH.error(data.error);
                                                }
                                            }
                                        });
                                    }
                                );
                            }
                        }
                    };

                    $.KH.ajax({
                        url: $form.attr('action'),
                        type: $form.attr('method'),
                        data: $form.KH_serialize(),
                        dataType: 'json',
                        element: $box,
                        async: doAsync,
                        success: function(data){
                            if (doAsync) {
                                successHandler(data);
                            } else {
                                postData = data;
                            }
                        }
                    });

                    if (!doAsync) {
                        successHandler(postData);
                    }
                    return false;
                });
            }
        },

        //userpage
        KH_boxAdmin: function() {
            var $box = $(this);
            //delete user
            var $userDel = $('.KH-delete_user', $box);
            $userDel.click(function(){
                $('<p>User wirklich löschen?</p>').dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 200,
                    height: 150,
                    modal: true,
                    title: 'Löschen bestätigen',
                    buttons: {
                        'Löschen': function() {
                            var $diaContent = $(this);
                            $.KH.ajax({
                                url: $userDel.attr('href'),
                                dataType: 'json',
                                element: $box,
                                success: function(data){
                                    if (!data.error) {
                                        $.KH.info(data.success)
                                    } else {
                                        $.KH.error(data.error);
                                    }
                                    $diaContent.dialog('destroy');
                                },
                                element: $diaContent.closest('.ui-dialog')
                            });
                        },
                        'Abbrechen': function() {
                            $(this).dialog('destroy');
                        }
                    }
                });
                return false;
            });
            //delete artistpage
            var $artistpageDel = $('.KH-delete_artistpage', $box);
            $artistpageDel.click(function(){
                $('<p>Artistpage wirklich löschen?</p>').dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 200,
                    height: 150,
                    modal: true,
                    title: 'Löschen bestätigen',
                    buttons: {
                        'Löschen': function() {
                            var $diaContent = $(this);
                            $.KH.ajax({
                                url: $artistpageDel.attr('href'),
                                dataType: 'json',
                                element: $box,
                                success: function(data){
                                    if (!data.error) {
                                        $.KH.info(data.success);
                                        $.KH.refreshPage('/artist/list');
                                    } else {
                                        $.KH.error(data.error);
                                    }
                                    $diaContent.dialog('destroy');
                                },
                                element: $diaContent.closest('.ui-dialog')
                            });
                        },
                        'Abbrechen': function() {
                            $(this).dialog('destroy');
                        }
                    }
                });
                return false;
            });
        },

        KH_activityStream: function() {
            var $stream = $(this);
            //slide thumbnails for attached images
            $('p.slideThumb', $stream).click(function(){
                $(this).next().slideToggle();
            });
            //toggle 'delete' icon (event delegation - attach to stream only)
            //dont't use 'hover' as of event bubbling, see http://www.learningjquery.com/2009/12/simple-tooltip-for-huge-number-of-elements
            $stream.bind('mouseover mouseout', function(e) {
                var $li = $(e.target).closest('li');
                if($li.hasClass('KH-canDelete')) {
                    var $delIcon = $li.find('.btnSX:eq(0)');
                    if(e.type == 'mouseover') $delIcon.show();
                    else $delIcon.hide();
                }
            });
            $stream.bind('click', function(e) {
                var $target = $(e.target);
                //'delete' icon
                if($target.is('.btnSX')) {
                    $('<p>Eintrag wirklich löschen?</p>').dialog({
                        resizable: false,
                        draggable: false,
                        bgiframe: true,
                        width: 200,
                        height: 150,
                        modal: true,
                        title: 'Löschen bestätigen',
                        buttons: {
                            'Löschen': function() {
                                var $diaContent = $(this);
                                $.KH.ajax({
                                    url: $target.attr('href'),
                                    success: function(data){
                                        if(data.success) {
                                            $.KH.info(data.success, 3);
                                            $target.closest('li').fadeOut(function(){ $(this).remove(); });
                                        } else {
                                            $.KH.error(data.error, 3);
                                        }
                                        $diaContent.dialog('destroy');
                                    },
                                    dataType: 'json',
                                    element: $diaContent.closest('.ui-dialog')
                                });
                            },
                            'Abbrechen': function() {
                                $(this).dialog('destroy');
                            }
                        }
                    });
                    return false;
                }
                //'report' link
                if($target.is('.report')) {
                    reportComment($target);
                    return false;
                }
            });
            //prepare comments
            $('.comments', $stream).each(function(){
                var $comments = $(this);
                var $activity = $comments.closest('li');
                $comments.KH_comments({$outerAddBtn: $('.comment', $activity)});
            });
            //prepare toolbar if exists (atm for artistpage only)
            var $toolbar = $('#KH-activityToolbar');
            if($toolbar.length) {
                var $select = $('select', $toolbar);
                var $go = $('.go', $toolbar);
                $go.click(function(){
                    var target = $select.val();
                    var $checkboxes = $('.checkbox:checked', $stream);
                    if(!$checkboxes.length) {
                        $.KH.error('Keine Kommentare ausgewählt');
                        return false;
                    }
                    var activities = new Array();
                    $checkboxes.each(function(){
                        activities.push($(this).val());

                    });
                    $.KH.ajax({
                        url: $go.attr('href'),
                        type: 'post',
                        data: 'target='+target+'&activities='+activities.join(','),
                        dataType: 'json',
                        success: function(data){
                            if(data.success) {
                                $.KH.info(data.msg);
                                $checkboxes.each(function(){
                                    $(this).closest('li').fadeOut(function(){ $(this).remove(); });
                                });
                                var tabs = {
                                    'AP_STORIES': '#KH-storiesTabStories',
                                    'AP_LINKS': '#KH-storiesTabLinks',
                                    'AP_COMMENTS': '#KH-storiesTabComments'
                                }
                                //update amount on current tab
                                var $amountCurr = $('#tabboxsub a.current .slice.main span');
                                var newAmountCurr = parseInt($amountCurr.text().replace(/(\(|\))/g, ''))-$checkboxes.length;
                                $amountCurr.html('('+newAmountCurr+')');
                                //update amount on target tab
                                var $amountTar = $(tabs[target]+' .slice.main span');
                                var newAmountTar = parseInt($amountTar.text().replace(/(\(|\))/g, ''))+$checkboxes.length;
                                $amountTar.html('('+newAmountTar+')');
                            } else {
                                $.KH.error(data.msg);
                            }
                        }
                    });
                    return false;
                })
            }
        },

        KH_comments: function(options) {
            var $comments = $(this);
            var $addBtn, $addBox;
            init(); //also called on paging
            //toggle 'add' buttons (inside content / after comments) and comments container
            if($('li', $comments).length > 1) { //at least 1 li always exists (the addBox item)
                options.$outerAddBtn.hide();
            } else {
                $comments.hide(); //make sure the container doesn't waste space (margin, empty ul)
                $addBtn.hide();
            }
            //bind outer add button (in content area, outside comments)
            options.$outerAddBtn.click(function(){ showAddBox($(this)); return false; });
            //use event delegation (so we can reload the complete comments section without re-applying the events)
            $comments.bind('click', function(e) {
                var $target = $(e.target);
                //'delete' icon
                if($target.is('.btnSX')) {
                    var $delBtn = $target;
                    $('<p>Kommentar wirklich löschen?</p>').dialog({
                        resizable: false,
                        draggable: false,
                        bgiframe: true,
                        width: 200,
                        height: 150,
                        modal: true,
                        title: 'Löschen bestätigen',
                        buttons: {
                            'Löschen': function() {
                                var $diaContent = $(this);
                                $.KH.ajax({
                                    url: $delBtn.attr('href'),
                                    success: function(data){
                                        if(data.success) {
                                            $.KH.info(data.success, 3);
                                            $delBtn.closest('li').fadeOut(function(){ $(this).remove(); });
                                        } else {
                                            $.KH.info(data.error, 3);
                                        }
                                        $diaContent.dialog('destroy');
                                    },
                                    dataType: 'json',
                                    element: $diaContent.closest('.ui-dialog')
                                });
                            },
                            'Abbrechen': function() {
                                $(this).dialog('destroy');
                            }
                        }
                    });
                    return false;
                }
                //'add comment' box
                if($target.is('.addComment')) {
                    showAddBox($target);
                }
                //addBox buttons
                if($target.closest('.addBox').length) { //clicked inside addBox
                    if($target.closest('.textButton').length) {  //submit button
                        if(!$addBox.hasClass('KH-disabled')) {
                            var postData = null;
                            // if the user wants to publish and type is share (popup), we don't do it async (adblocker) refs #818
                            var doAsync = !($('input[name="allow_facebook_publish"]:checked', $addBox).length > 0 &&
                                            $('input[name="facebook_post_type"]', $addBox).val() === 'share');

                            var successHandler = function(data) {
                                if(data.error) {
                                    $.KH.error(data.msg, 3);
                                } else {
                                    $.KH.info(data.msg, 3);
                                    $addBox.before(data.comment).hide().find('textarea[name=body]').val('');
                                    $addBtn.show();

                                    // if publish checkbox is checked we post it directly or share it with fb ui
                                    if (data !== null && data.facebookData) {
                                        // share with fb ui
                                        $.KH.facebook.publishPost(
                                            data.facebookData,
                                            function() {
                                                $.KH.error('Dein Beitrag wurde nicht auf Facebook gepostet');
                                            },
                                            function(postId) {
                                                $.KH.ajax({
                                                    url: data.successUrl,
                                                    dataType: 'json',
                                                    type: 'post',
                                                    data: 'uid='+postId,
                                                    success: function(data){
                                                        if (!data.error) {
                                                            $.KH.info(data.msg);
                                                        } else {
                                                            $.KH.error(data.error);
                                                        }
                                                    }
                                                });
                                            }
                                        );
                                    }
                                }
                            };

                            $.KH.ajax({
                                url: '/user/addcomment',
                                data: $('form', $addBox).serialize(),
                                type: 'post',
                                async: doAsync,
                                success: function(data){
                                    if (doAsync) {
                                        successHandler(data);
                                    } else {
                                        postData = data;
                                    }
                                },
                                dataType: 'json',
                                element: $addBox
                            });

                            if (!doAsync) {
                                successHandler(postData);
                            }
                        }
                        return false;
                    }
                    if($target.is('.cancel')) {
                        $addBox.hide();
                        $addBox.data('showBtn').show();
                        return false;
                    }
                }
                //paging
                if($target.closest('.browse').length) { //browse nodes have child nodes; .closest starts with the element itself
                    var $li = $target.closest('li');
                    var $link = $target.closest('.browse');
                    $.KH.ajax({
                        url: $link.attr('href'),
                        success: function(data){
                            $comments.html(data);
                            init();
                            //toggle 'comment' link when on last page (= no 'next' link exists)
                            if(!$('.browse.next', $comments).length) {
                                $addBtn.show();
                            } else {
                                $addBtn.hide();
                            }
                        },
                        dataType: 'html',
                        element: $comments
                    });
                    return false;
                }
                //'report' link
                if($target.is('.report')) {
                    reportComment($target);
                    return false;
                }
                //prevent activity stream (in case these comments are inside one) from evaluating the click event too
                //but make sure KH-link ajax links and facebook share (refs #818) still work
                if(!$target.closest('.KH-link').length && !$target.closest('.facebookPublish').length) {
                    e.stopPropagation();
                    return false;
                }
            });
            function showAddBox($showBtn) {
                $addBox.data('showBtn', $showBtn).show();
                $comments.show(); //in case they were initially hidden
                $showBtn.hide();
            }
            function init() {
                $addBtn = $('.addComment', $comments);
                $addBox = $('.addBox', $comments);
                //toggle 'delete' icon
                $('ul', $comments).bind('mouseover mouseout', function(e) {
                    var $li = $(e.target).closest('li');
                    if($li.hasClass('KH-canDelete')) {
                        var $delIcon = $li.find('.btnSX');
                        if(e.type == 'mouseover') $delIcon.show();
                        else $delIcon.hide();
                    }
                    e.stopPropagation(); //in case the comments are inside i.e. the activity stream, make sure it's event handler isn't affected
                });
                //textarea maxlength
                $('textarea', $addBox).KH_maxlength();
                //check if posting via addbox is enabled (see also click handler for submit button in addbox)
                if($addBox.hasClass('KH-disabled')) {
                    var message = $addBox.attr('rel');
                    $('textarea', $addBox).attr('disabled','disabled').val(message);
                }
            }
        },

        KH_playlist: function() {
            var $box = this;
            var $playlist = $('#KH-playlist');
            $playlist.sortable({
                update: function(event, ui) {
                    var dataString = $playlist.sortable('serialize');
                    $.KH.ajax({
                        url: '/user/updateplaylist',
                        data: dataString,
                        type: 'post',
                        success: function(data){
                            $('#KH-playlistTab').click();
                        },
                        dataType: 'json',
                        element: $box
                    });
                }
            });
            //delete buttons
            $playlist.find('.btnSX').click(function(){
                var $li = $($(this).parents('li')[0]);
                var track_id = $li.attr('id').split('_')[1];
                $.KH.ajax({
                    url: '/user/deletetrack',
                    data: 'track_id='+track_id,
                    type: 'post',
                    success: function(data){
                        $('#KH-playlistTab').click();
                    },
                    dataType: 'json',
                    element: $box
                });
                return false;
            });
        },

        KH_playlistAddTrack: function() {
            var $box = this;
            //autocomplete artist/song
            $("input[name=artist]", $box).autocomplete('/content/findartist', {
                delay: 500,
                minChars: 3,
                max: 20 //show only x results
            }).result(function(event, data, formatted) {
                $("input[name=artist]", $box).data('artistID', data[1]).addClass('chosen');
                $("input[name=track]", $box).removeAttr('disabled').focus();
            }).keydown(function(e){
                if(e.keyCode != 13 && e.keyCode != 9) { //ENTER, TAB
                    $(this).removeClass('chosen');
                    $("input[name=track]", $box).val('').removeClass('chosen').attr('disabled','disabled');
                    toggleValid(false);
                }
            });
            $("input[name=track]", $box).autocomplete('/content/findtrack', {
                extraParams: {
                    artistID: function() { return $("input[name=artist]", $box).data('artistID'); }
                },
                delay: 500,
                minChars: 3,
                max: 20 //show only x results
            }).result(function(event, data, formatted) {
                $("input[name=track]", $box).data('trackID', data[1]).addClass('chosen');
                toggleValid(true);
                $("input[name=dedicate]", $box).focus();
            }).keydown(function(e){
                if(e.keyCode != 13 && e.keyCode != 9) { //ENTER, TAB
                    $(this).removeClass('chosen');
                    toggleValid(false);
                }
            });
            //submit
            $(".KH-submit", $box).click(function(){
                if(!$(this).hasClass('disabled')) {
                    var trackId = $('input[name=track]', $box).data('trackID')
                    $.KH.addToPlaylist(trackId, false);
                }
                return false;
            });
            //if valid song is chosen, allow submit
            function toggleValid(toggle) {
                if(toggle) {
                    $('.KH-submit', $box).removeClass('disabled');
                } else {
                    $('.KH-submit', $box).addClass('disabled');
                }
            }
            //init
            $("input[name=track]", $box).attr('disabled','disabled');
            toggleValid(false);
        },

        //maxlength for textareas
        KH_maxlength: function() {
            var $textarea = $(this);
            var maxlength = parseInt($textarea.attr('maxlength'));
            var $remaining = $textarea.next('.remaining');
            $textarea.keyup(function(e){
                var currLength = $textarea.val().length;
                var remainLength = maxlength - currLength;
                if(currLength > maxlength) {
                    $textarea.val($textarea.val().substr(0, maxlength));
                } else {
                    $remaining.html('noch '+remainLength+' Zeichen');
                }
            });
        },

        //invite button in left sidebar
        KH_boxInvite: function() {
            var $box = $(this);
            var $dialog = $('#dialog_invite');
            var $form = $('form', $dialog);
            $box.click(function(){
                $dialog.dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 300,
                    height: 240,
                    modal: true,
                    title: 'Freund einladen',
                    buttons: {
                        'Einladung senden': function() {
                            $.KH.ajax({
                                url: $form.attr('action'),
                                data: $form.serialize(),
                                type: $form.attr('method'),
                                dataType: 'json',
                                element: $dialog.closest('.ui-dialog'),
                                success: function(data){
                                    if(data.error) {
                                        $('.error', $dialog).html(data.msg);
                                    } else {
                                        $dialog.dialog('close');
                                        $.KH.info(data.msg);
                                    }
                                }
                            });
                        },
                        'Lieber nicht': function() {
                            $dialog.dialog('close');
                        }
                    },
                    close: function() {
                        $dialog.dialog('destroy');
                        $form.get(0).reset();
                        $('.error', $dialog).empty();
                    }
                });
                return false;
            });
        },

        //search box in left sidebar
        KH_boxSearch: function() {
            var $box = $(this);
            var $form = $('form', $box);
            var $target = $('#colMainRight');
            var $submit = $('.textButton', $box);
            $form.submit(submit);
            $submit.click(submit);
            function submit(){
                $.KH.ajax({
                    url: $form.attr('action')+'/type/'+$('input[name=type]:checked', $form).val()+'/keyword/'+$('input[name=keyword]', $form).val(),
                    dataType: 'html',
                    element: $target,
                    keepInHistory: true,
                    success: function(data){
                        $target.html(data);
                    }
                });
                return false;
            };
        },

        // Mailbox newmail
        KH_newmail: function() {
            var $box = $(this);
            //add recipients
            var $addBtn = $('.addRecip', $box);
            var $pool = $('.recipPool', $box);
            var $list = $('.recipList', $box);
            var $idList = $('input[name=recip]', $box);
            var recipArr = new Array();
            $('option', $pool).each(function(index){
                var $option = $(this);
                if($option.val() != "") recipArr.push({id:$option.val(), name:$option.text(), selected:false});
            });
            $addBtn.click(function(){
                var recipId = $pool.val();
                if(recipId != '') {
                    var recipObj = findRecip('id', recipId);
                    recipObj.selected = true;
                }
                updateRecips();
                return false;
            });
            function updateRecips() {
                //serialize to idList and build recipient items
                $idList.val('');
                $list.empty();
                $.each(recipArr, function(index, item) {
                    if(item.selected) {
                        $idList.val($idList.val() + item.id + ';');
                        $('<p><span>'+item.name+'</span><a class="actionBtnSmall btnSX" href="#"></a></p>')
                            .data('id', item.id)
                            .appendTo($list)
                            .find('a').click(function(){
                                var $item = $(this).parent();
                                var id = $item.data('id');
                                var recipObj = findRecip('id', id);
                                recipObj.selected = false;
                                updateRecips();
                                return false;
                            });
                    }
                });
                //update dropdown
                $pool.find('option:gt(0)').remove();
                $.each(recipArr, function(index, item) {
                    if(!item.selected) $pool.append('<option value="'+item.id+'">'+item.name+'</option>');
                });
                //MULTI RESTRICTION for now, restrict recipients to 1
                if($list.find('p').length) { $addBtn.hide(); $pool.hide(); }
                else { $addBtn.show(); $pool.show(); }
            }
            function findRecip(prop, val) {
                var result;
                $.each(recipArr, function(index, item) {
                    if(item[prop] == val) result = item;
                });
                return result;
            }
            //initial un-serialization of recipients (refresh after error)
            var initialRecipIds = $idList.val().split(';');
            initialRecipIds.pop(); //string was ending with a ; so remove last (empty) element
            $.each(initialRecipIds, function(index, item) {
                var recipObj = findRecip('id', item);
                recipObj.selected = true;
                updateRecips();
            });
            //submit
            var $submit = $('.submit', $box);
            var $form = $('#form_newmail', $box);
            $submit.click(function(){
                $.KH.ajax({
                    url: $form.attr('action'),
                    type: $form.attr('method'),
                    data: $form.KH_serialize(),
                    dataType: 'json',
                    element: $box,
                    success: function(data){
                        if(data.error) {
                            $.KH.error(data.error, 3);
                            $("#tabContent").html(data.html); //refresh form with validation errors
                        }
                        else {
                            $.KH.info(data.msg, 3);
                            $('#KH-outboxTab').click();
                        }
                    }
                });
                return false;
            });
        },

        // Mailbox newmail
        KH_maildetail: function(strId, strBaseUrl) {
            var $box = $(this);
            var $submit = $('a[name=postAction]', $box);
            var $submitState = $('a[name=stateAction]', $box);
            var strFormName = $submitState.attr('rel');
            var $formpost = $('form#form_post', $box);
            var $formstate = $('form#'+strFormName, $box);
            var $idfield = $('form#'+strFormName + ' input[name=msgs]');
            var $msg = $('textarea[name=message]', $formpost);
            $msg.formclear();
            $submit.click(function(){
                $.KH.ajax({
                    url: $formpost.attr('action'),
                    type: $formpost.attr('method'),
                    data: $formpost.KH_serialize(),
                    dataType: 'json',
                    element: $box,
                    success: function(data){
                        if(data.error) {
                            $.KH.error(data.msg, 3);
                            $msg.blur();
                        }
                        else {
                            $.KH.info(data.msg, 3);
                            $msg.val('').formclear();
                            $.KH.refreshPage('/user/inbox');
                        }
                    }
                });
                return false;
            });
            $submitState.click(function(){
                $idfield.val(strId);
                $.KH.ajax({
                    url: $formstate.attr('action'),
                    type: $formstate.attr('method'),
                    data: $formstate.KH_serialize(),
                    dataType: 'json',
                    element: $box,
                    success: function(data){
                        if(data.error) {
                            $.KH.error(data.msg, 3);
                            $submit.blur();
                        }
                        else {
                            $.KH.info(data.msg, 3);
                            $idfield.val('').formclear();
                            $.KH.refreshPage(strBaseUrl);
                        }
                    }
                });
                return false;
            });
        },

        // Mailbox inbox/outbox
        KH_mailbox: function(strBaseUrl) {
            var $box = $(this);
            var $submit = $('a[name=stateAction]', $box);
            var $markall = $('a[name=markall]', $box);
            $submit.click(function(){
                var $btn = $(this); //there are 2 different submit buttons + forms (at top and bottom)
                var strFormName = $btn.attr('rel');
                var $form = $('#'+strFormName, $box);
                var $idfield = $('#'+strFormName + ' input[name=msgs]');
                var strIds = '';
                $('input[name=cbMark]:checked', $box).map( function () {if (strIds != '') strIds += ';'; strIds += $(this).val();});
                if (strIds == '') {
                    $.KH.error('Bitte wählen Sie eine Nachricht aus', 3);
                    return false;
                }
                $idfield.val(strIds);

                $.KH.ajax({
                    url: $form.attr('action'),
                    type: $form.attr('method'),
                    data: $form.KH_serialize(),
                    dataType: 'json',
                    element: $box,
                    success: function(data){
                        if(data.error) {
                            $.KH.error(data.msg, 3);
                            $btn.blur();
                        }
                        else {
                            $.KH.info(data.msg, 3);
                            $idfield.val('').formclear();
                            $.KH.refreshPage(strBaseUrl);
                        }
                    }
                });
                return false;
            });
            $markall.click( function(){
                if ($(this).html() == 'Alle markieren') {
                    $bCheck = true;
                    $markall.each( function () {
                        $(this).html('Alle demarkieren');
                    });
                } else {
                    $bCheck = false;
                    $markall.each( function () {
                        $(this).html('Alle markieren');
                    });
                }
                $('input[name=cbMark]', $box).each( function() {
                    $(this).attr('checked', $bCheck);
                });
                return false;
            });
        },

        // Mailbox inbox/outbox
        KH_boxOtherInfo: function(strName, strId) {
            var $box = $(this);
            var $sendMsg = $('a.btnMail', $box);
            var $addFriend = $('a.btnPlus', $box);
            var $sendHeart = $('a.btnHeart', $box);
            //action buttons
            $sendMsg.click(function(){
                sendMessage ($(this), strName, strId);
                return false;
            });
            $addFriend.click(function(){
                handleFriendship ($(this), strName, strId, '/user/user');
                return false;
            });
            $sendHeart.click(function(){
                sendHeart ($(this), strName, strId);
                return false;
            });
            //'report user'
            var $report = $('.report', $box);
            var $diaReport = $('#reportUser');
            $report.click(function(){
                $diaReport.dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 300,
                    height: 210,
                    modal: true,
                    title: 'User melden',
                    buttons: {
                        'User melden': function() {
                            $form = $('form', $diaReport)
                            $.KH.ajax({
                                url: $form.attr('action'),
                                data: $form.serialize(),
                                type: $form.attr('method'),
                                dataType: 'json',
                                element: $diaReport,
                                success: function(data){
                                    if(!data.error) {
                                        $.KH.info(data.msg)
                                    } else {
                                        $.KH.error(data.msg);
                                    }
                                    $diaReport.dialog('destroy');
                                }
                            });
                        },
                        'Abbrechen': function() {
                            $diaReport.dialog('destroy');
                        }
                    }
                });
                return false;
            });

       },

        // Friends-Requests
        KH_friendrequestBox: function() {
            var $box = $(this);
            var $annehmen = $('a[name=annehmen]', $box);
            var $ablehnen = $('a[name=ablehnen]', $box);

            $annehmen.click(function(){
                $button = $(this);
                $('<p>Freundschaftsanfrage wirklich annehmen?</p>').dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 350,
                    height: 100,
                    modal: true,
                    title: 'Anfrage annehmen',
                    buttons: {
                        'ANNEHMEN': function() {
                            var $diaContent = $(this);
                            $.KH.ajax({
                                url: $button.attr('href'),
                                success: function(data){
                                    if(data.success) {
                                        $.KH.info(data.success, 3);
                                        $.KH.refreshPage('/user/friendrequests');
                                    } else {
                                        $.KH.error(data.error, 3);
                                    }
                                    $diaContent.dialog('destroy');
                                },
                                dataType: 'json',
                                element: $diaContent.closest('.ui-dialog')
                            });
                        },
                        'LIEBER NICHT': function() {
                            $(this).dialog('destroy');
                        }
                    }
                });
                return false;
            });

            $ablehnen.click(function(){
                $button = $(this);
                $('<p>Freundschaftsanfrage wirklich ablehnen?</p>').dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 350,
                    height: 100,
                    modal: true,
                    title: 'Anfrage ablehnen',
                    buttons: {
                        'ABLEHNEN': function() {
                            var $diaContent = $(this);
                            $.KH.ajax({
                                url: $button.attr('href'),
                                success: function(data){
                                    if(data.success) {
                                        $.KH.info(data.success, 3);
                                        $.KH.refreshPage('/user/friendrequests');
                                    } else {
                                        $.KH.error(data.error, 3);
                                    }
                                    $diaContent.dialog('destroy');
                                },
                                dataType: 'json',
                                element: $diaContent.closest('.ui-dialog')
                            });
                        },
                        'LIEBER NICHT': function() {
                            $(this).dialog('destroy');
                        }
                    }
                });
                return false;
            });
        },

        // Friends Tab
        KH_friendsListBox: function(bMypage) {
            var $box = $(this);
            var $sendMsg = $('a.btnMail', $box);
            var $addFriend = $('a.btnPlus', $box);
            var $sendHeart = $('a.btnHeart', $box);

            $sendMsg.click(function(){
                sendMessage ($(this), $(this).attr('rel'), $(this).attr('href'));
                return false;
            });

            $addFriend.click(function(){
                handleFriendship ($(this), $(this).attr('rel'), $(this).attr('href'), bMypage);
                return false;
            });

            $sendHeart.click(function(){
                sendHeart ($(this), $(this).attr('rel'), $(this).attr('href'));
                return false;
            });
        },

        KH_userFanOfBox: function(bMyPage) {
            var $box = $(this);
            var $fanbutton = $('.KH-fanbutton', $box);

            $fanbutton.click(function(){
                handleFanOf ($(this), $(this).parent().find('.name').find('a').html(), 'user', bMyPage);
                return false;
            });
            $fanbutton.each (function(){
                toggleFanButtonTitle($(this));
            });
        },

        KH_giap: function() {
            var $box = $(this);
            var $suggestionbutton = $('a[name=giapsugfromlist]', $box);
            var $migratebutton = $('a[name=miapfromlist]', $box);
            var $deletebutton = $('a[name=diapfromlist]', $box);

            $migratebutton.click(function(){
                var $diaRec = $('#migrateoverlay');
                $button = $(this);
                strID = $button.attr('href').substr($button.attr('href').lastIndexOf('/') + 1);
                $diaRec.dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 300,
                    height: 100,
                    modal: true,
                    title: 'Artistpage migrieren?',
                    buttons: {
                        'Migrieren': function() {
                            if (confirm("Bist du dir sicher?")) {
                                var $diaContent = $(this);
                                $form = $('form', $diaRec);
                                $.KH.ajax({
                                    url: $button.attr('href'),
                                    data: $form.serialize(),
                                    type: $form.attr('method'),
                                    dataType: 'json',
                                    success: function(data){
                                        if(!data.error) {
                                            $.KH.info(data.msg, 3);
                                            if ($button.closest('tr').next().attr('id') == 'suggestion_' + strID)
                                                $button.closest('tr').next().fadeOut(function(){ $(this).html(); });
                                            $button.closest('tr').fadeOut(function(){ $(this).html(); });
                                            $diaContent.dialog('destroy');
                                        } else {
                                            $.KH.error(data.msg, 3);
                                        }
                                    },
                                    element: $diaContent.closest('.ui-dialog')
                                });
                            }
                        },
                        'Abbrechen': function() {
                            $(this).dialog('destroy');
                        }
                    },
                    open: function() {
                        $diaRec
                        .find('#artistname').find('span').html($button.attr('rel')).end().end()
                        .find('#oldartistid').find('span').html(strID).end().end()
                        .find('#newartist_id').val('').end();
                   }
                });
                return false;
            });

            $deletebutton.click(function(){
                $button = $(this);
                strID = $button.attr('href').substr($button.attr('href').lastIndexOf('/') + 1);
                $('<p>Bist du dir sicher, dass du diese Artistpage löschen möchtest?</p>').dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 300,
                    height: 100,
                    modal: true,
                    title: 'Song löschen?',
                    buttons: {
                        'Löschen': function() {
                            if (confirm("Bist du dir sicher?")) {
                                var $diaContent = $(this);
                                $.KH.ajax({
                                    url: $button.attr('href'),
                                    type: 'post',
                                    dataType: 'json',
                                    success: function(data){
                                        if(!data.error) {
                                            $.KH.info(data.msg, 3);
                                            if ($button.closest('tr').next().attr('id') == 'suggestion_' + strID)
                                                $button.closest('tr').next().fadeOut(function(){ $(this).html(); });
                                            $button.closest('tr').fadeOut(function(){ $(this).html(); });
                                        } else {
                                            $.KH.error(data.msg, 3);
                                        }
                                        $diaContent.dialog('destroy');
                                    },
                                    element: $diaContent.closest('.ui-dialog')
                                });
                            }
                        },
                        'Abbrechen': function() {
                            $(this).dialog('destroy');
                        }
                    }
                });
                return false;
            });

            $suggestionbutton.click(function(){
                $button = $(this);
                if ($button.closest('tr').next().attr('id') == 'suggestion_' + $button.attr('rel'))
                    $button.closest('tr').next().fadeOut(function(){ $(this).html(); });
                $.KH.ajax({
                    url: $button.attr('href'),
                    type: 'post',
                    dataType: 'json',
                    success: function(data){
                        if(!data.error) {
                            $button.closest('tr').after(data.html);
                        } else {
                            $.KH.error(data.msg, 3);
                        }
                    }
                });

                return false;
            });
        },

        KH_git: function() {
            var $box = $(this);
            var $suggestionbutton = $('a[name=gitsugfromlist]', $box);
            var $migratebutton = $('a[name=mitfromlist]', $box);
            var $deletebutton = $('a[name=ditfromlist]', $box);

            $migratebutton.click(function(){
                var $diaRec = $('#migrateoverlay');
                $button = $(this);
                strID = $button.attr('href').substr($button.attr('href').lastIndexOf('/') + 1);
                $diaRec.dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 300,
                    height: 100,
                    modal: true,
                    title: 'Song migrieren?',
                    buttons: {
                        'Migrieren': function() {
                            if (confirm("Bist du dir sicher?")) {
                                var $diaContent = $(this);
                                $form = $('form', $diaRec);
                                $.KH.ajax({
                                    url: $button.attr('href'),
                                    data: $form.serialize(),
                                    type: $form.attr('method'),
                                    dataType: 'json',
                                    success: function(data){
                                        if(!data.error) {
                                            $.KH.info(data.msg, 3);
                                            if ($button.closest('tr').next().attr('id') == 'suggestion_' + strID)
                                                $button.closest('tr').next().fadeOut(function(){ $(this).html(); });
                                            $button.closest('tr').fadeOut(function(){ $(this).html(); });
                                            $diaContent.dialog('destroy');
                                        } else {
                                            $.KH.error(data.msg, 3);
                                        }
                                    },
                                    element: $diaContent.closest('.ui-dialog')
                                });
                            }
                        },
                        'Abbrechen': function() {
                            $(this).dialog('destroy');
                        }
                    },
                    open: function() {
                        $diaRec
                        .find('#songname').find('span').html($button.attr('rel')).end().end()
                        .find('#oldsongid').find('span').html(strID).end().end()
                        .find('#newsong_id').val('').end();
                   }
                });
                return false;
            });

            $deletebutton.click(function(){
                $button = $(this);
                strID = $button.attr('href').substr($button.attr('href').lastIndexOf('/') + 1);
                $('<p>Bist du dir sicher, dass du diesen Song löschen möchtest?</p>').dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 300,
                    height: 100,
                    modal: true,
                    title: 'Song löschen?',
                    buttons: {
                        'Löschen': function() {
                            if (confirm("Bist du dir sicher?")) {
                                var $diaContent = $(this);
                                $.KH.ajax({
                                    url: $button.attr('href'),
                                    type: 'post',
                                    dataType: 'json',
                                    success: function(data){
                                        if(!data.error) {
                                            $.KH.info(data.msg, 3);
                                            if ($button.closest('tr').next().attr('id') == 'suggestion_' + strID)
                                                $button.closest('tr').next().fadeOut(function(){ $(this).html(); });
                                            $button.closest('tr').fadeOut(function(){ $(this).html(); });
                                        } else {
                                            $.KH.error(data.msg, 3);
                                        }
                                        $diaContent.dialog('destroy');
                                    },
                                    element: $diaContent.closest('.ui-dialog')
                                });
                            }
                        },
                        'Abbrechen': function() {
                            $(this).dialog('destroy');
                        }
                    }
                });
                return false;
            });

            $suggestionbutton.click(function(){
                $button = $(this);
                if ($button.closest('tr').next().attr('id') == 'suggestion_' + $button.attr('rel'))
                    $button.closest('tr').next().fadeOut(function(){ $(this).html(); });
                $.KH.ajax({
                    url: $button.attr('href'),
                    type: 'post',
                    dataType: 'json',
                    success: function(data){
                        if(!data.error) {
                            $button.closest('tr').after(data.html);
                        } else {
                            $.KH.error(data.msg, 3);
                        }
                    }
                });

                return false;
            });
        },

        // Friends Tab
        KH_artistList: function(bMypage) {
            var $box = $(this);
            var $featureArtist = $('a[name=feature_artist]', $box);

            $featureArtist.click(function(){
                $button = $(this);
                strType = $button.html();
                $('<p>Willst du diesen Artist wirklich ' + strType + '?</p>').dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 350,
                    height: 100,
                    modal: true,
                    title: 'Artist ' + strType,
                    buttons: {
                        'JA': function() {
                            var $diaContent = $(this);
                            $.KH.ajax({
                                url: $button.attr('href'),
                                success: function(data){
                                    if(data.success) {
                                        $.KH.info(data.msg);
                                        $.KH.refreshPage('/artist/list/');
                                    } else {
                                        $.KH.error(data.error, 3);
                                    }
                                    $diaContent.dialog('destroy');
                                },
                                dataType: 'json',
                                element: $diaContent.closest('.ui-dialog')
                            });
                        },
                        'LIEBER NICHT': function() {
                            $(this).dialog('destroy');
                        }
                    }
                });
                return false;
            });
        },

        // Friends Tab
        KH_boxUserPageAdmin: function(bShowWarningFeat, bShowWarningSow) {
            var $box = $(this);
            var $featureUser = $('a[name=featureuser]', $box);
            $featureUser.click(function(){
                $button = $(this);
                strType = $button.html();
                iUserId = $button.attr('rel');
                var strWarn = '';
                if (strType == 'Featuren' && bShowWarningFeat) {
                    strWarn = '<span class="error"><br /><br />Es sind bereits 2 User gefeatured. Der am längsten gefeaturete wird automatisch gelöscht</span>';
                }
                $('<p>Willst du diesen User wirklich ' + strType + '?' + strWarn + '</p>').dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 350,
                    height: 100,
                    modal: true,
                    title: 'User ' + strType,
                    buttons: {
                        'JA': function() {
                            var $diaContent = $(this);
                            $.KH.ajax({
                                url: $button.attr('href') + '/type/' + strType,
                                success: function(data){
                                    if(data.success) {
                                        $.KH.info(data.msg);
                                        $.KH.refreshPage('/user/user/id/' + iUserId);
                                    } else {
                                        $.KH.error(data.error, 3);
                                    }
                                    $diaContent.dialog('destroy');
                                },
                                dataType: 'json',
                                element: $diaContent.closest('.ui-dialog')
                            });
                        },
                        'LIEBER NICHT': function() {
                            $(this).dialog('destroy');
                        }
                    }
                });
                return false;
            });

            var $sowUser = $('a[name=sowuser]', $box);
            $sowUser.click(function(){
                $button = $(this);
                strType = $button.html();
                iUserId = $button.attr('rel');
                var strWarn = '';
                if (strType.indexOf('Setze') != -1 && bShowWarningSow) {
                    strWarn = '<span class="error"><br /><br />Es sind bereits 2 User als Single der Woche markiert. Der am längsten markierte Single der Woche wird automatisch gelöscht</span>';
                }
                var strDiag = '<p>Willst du "' + strType + '" bei diesem User durchführen?' + strWarn + '</p>';
                if (strType.indexOf('Setze') != -1) {
                    strDiag = ''
                            + '<form name="sow">'
                            + '<p>Willst du "' + strType + '" bei diesem User durchführen?</p><br/><br/>'
                            + '<p>Optionaler Infotext:<br/><textarea name="sowinfotext" class="text diaSowText" id="sowinfotext"></textarea></p>'
                            + '<p>' + strWarn + '</p>'
                            + '</form>';
                }
                var $diaSow = $(strDiag);
                $diaSow.dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 350,
                    height: 200,
                    modal: true,
                    title: 'User: ' + strType,
                    buttons: {
                        'JA': function() {
                            var $diaContent = $(this);
                            $.KH.ajax({
                                url: $button.attr('href') + '/type/' + strType.substring(0,strType.indexOf(" ")),
                                data: $("form[name='sow']").serialize(),
                                type: 'post',
                                success: function(data){
                                    if(data.success) {
                                        $.KH.info(data.msg);
                                        $.KH.refreshPage('/user/user/id/' + iUserId);
                                    } else {
                                        $.KH.error(data.error, 3);
                                    }
                                    $("#sowinfotext").val("");
                                    $diaContent.dialog('destroy');
                                },
                                dataType: 'json',
                                element: $diaContent.closest('.ui-dialog')
                            });
                        },
                        'LIEBER NICHT': function() {
                            $("#sowinfotext").val("");
                            $(this).dialog('destroy');
                        }
                    }
                });
                return false;
            });

            var $deleteUser = $('a[name=deleteuser]', $box);
            $deleteUser.click(function(){
                $button = $(this);
                $('<p>Willst du diesen User wirklich löschen</p>').dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 350,
                    height: 100,
                    modal: true,
                    title: 'User löschen',
                    buttons: {
                        'JA': function() {
                            var $diaContent = $(this);
                            if (confirm('Sind sie sicher dass sie diesen User löschen wollen?')) {
                                $.KH.ajax({
                                    url: $button.attr('href'),
                                    success: function(data){
                                        if(data.success) {
                                            $.KH.info(data.msg);
                                            $.KH.refreshPage();
                                        } else {
                                            $.KH.error(data.error, 3);
                                        }
                                        $diaContent.dialog('destroy');
                                    },
                                    dataType: 'json',
                                    element: $diaContent.closest('.ui-dialog')
                                });
                            }
                        },
                        'LIEBER NICHT': function() {
                            $(this).dialog('destroy');
                        }
                    }
                });
                return false;
            });

            var $enableUser = $('a[name=enableuser]', $box);
            var $diaEnable = $('#enableUser');
            $enableUser.click(function(){
                $button = $(this);
                iUserId = $button.attr('rel');
                $diaEnable.dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 300,
                    height: 210,
                    modal: true,
                    title: 'User entsperren',
                    buttons: {
                        'User entsperren': function() {
                            if (confirm('Sind sie sicher dass sie diesen User entsperren wollen?')) {
                                $form = $('form', $diaEnable);
                                $.KH.ajax({
                                    url: $form.attr('action'),
                                    data: $form.serialize(),
                                    type: $form.attr('method'),
                                    dataType: 'json',
                                    element: $diaEnable,
                                    success: function(data){
                                        if(!data.error) {
                                            $.KH.info(data.msg);
                                            $.KH.refreshPage('/user/user/id/' + iUserId);
                                        } else {
                                            $.KH.error(data.msg);
                                        }
                                        $diaEnable.dialog('destroy');
                                    }
                                });
                            }
                        },
                        'Abbrechen': function() {
                            $diaEnable.dialog('destroy');
                        }
                    }
                });
                return false;
            });

            var $disableUser = $('a[name=disableuser]', $box);
            var $diaDisable = $('#disableUser');
            $disableUser.click(function(){
                $button = $(this);
                iUserId = $button.attr('rel');
                $diaDisable.dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 300,
                    height: 210,
                    modal: true,
                    title: 'User sperren',
                    buttons: {
                        'User sperren': function() {
                            if (confirm('Sind sie sicher dass sie diesen User sperren wollen?')) {
                                $form = $('form', $diaDisable);
                                $.KH.ajax({
                                    url: $form.attr('action'),
                                    data: $form.serialize(),
                                    type: $form.attr('method'),
                                    dataType: 'json',
                                    element: $diaDisable,
                                    success: function(data){
                                        if(!data.error) {
                                            $.KH.info(data.msg);
                                            $.KH.refreshPage('/user/user/id/' + iUserId);
                                        } else {
                                            $.KH.error(data.msg);
                                        }
                                        $diaDisable.dialog('destroy');
                                    }
                                });
                            }
                        },
                        'Abbrechen': function() {
                            $diaDisable.dialog('destroy');
                        }
                    }
                });
                return false;
            });
        },

        //new members box in left column
        KH_boxNewMembers: function(){
            var $box = $(this);
            var $next = $('.arrow.next', $box);
            var $prev = $('.arrow.prev', $box);
            var disabled = false; //prevent multiple clicks (disturbing the animation)
            var items = new Array();
            //init
            $('li:last', $box).prependTo($('ul', $box)); //so most recent user is in the center
            $('li', $box).each(function(i){
                $li = $(this);
                $li.css('top', 0);
                $li.css('left', 76*i);
                items[i] = $li;
            });
            $.each(items, function(index, value){
                items[index].css('position','absolute');
            });
            updateName();
            //events
            $next.click(function(){
                if(!disabled) {
                    slide(false);
                }
                return false;
            });
            $prev.click(function(){
                if(!disabled) {
                    slide(true);
                }
                return false;
            });
            //helpers
            function slide(forward){
                disabled = true;
                var completeCount = 0;
                $('.name a', $box).hide();
                if(forward){
                    items[items.length-1].css('left', -76);
                    items.unshift(items.pop());
                    $.each(items, function(index, value){
                        items[index].animate({left: '+=76'},{complete:function(){
                            completeCount++;
                            if(completeCount == items.length) { //do this only once (after all items finished animating)
                                updateName();
                                disabled = false;
                            }
                        }});
                    });
                } else {
                    $.each(items, function(index, value){
                        items[index].animate({left: '-=76'},{complete:function(){
                            completeCount++;
                            if(completeCount == items.length) {
                                items[0].css('left', items[items.length-1].position().left + 76);
                                items.push(items.shift());
                                updateName();
                                disabled = false;
                            }
                        }});
                    });
                }
            }
            function updateName(){
                var href = items[1].find('a').attr('href');
                var name = items[1].find('a').attr('title').split(' ').join('<br/>');
                $('.name a', $box).attr('href',href).html(name).show();
            }
        },

        KH_admin_statistic_activityindex: function(){
            var element = this;
            var form = $("form", element);

            //form submit button
            $(".textButton", element).click(function(){
                $.KH.ajax({
                    url: form.attr('action'),
                    data: form.KH_serialize(),
                    type: 'POST',
                    success: function(data){
                        if(!data.error){
                            $("#actResult", element).html(data.html);
                        }
                        else { //backend error
                            $.KH.error(data.error);
                        }
                    },
                    element: element,
                    dataType: 'json'
                });

                return false;
            });
        },

        // Friends Tab
        KH_boxUserAdmin: function() {
            var $box = $(this);
            var $deleteUser = $("a[name='deleteuser']", $box);
            $deleteUser.click(function(){
                $button = $(this);
                $('<p>Willst du diesen User wirklich löschen</p>').dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 350,
                    height: 100,
                    modal: true,
                    title: 'User löschen',
                    buttons: {
                        'JA': function() {
                            var $diaContent = $(this);
                            if (confirm('Sind sie sicher dass sie diesen User löschen wollen?')) {
                                $.KH.ajax({
                                    url: $button.attr('href'),
                                    success: function(data){
                                        if(data.success) {
                                            $.KH.info(data.msg);
                                            $.KH.refreshPage('/useradmin/deletefromcsv');
                                        } else {
                                            $.KH.error(data.error, 3);
                                        }
                                        $diaContent.dialog('destroy');
                                    },
                                    dataType: 'json',
                                    element: $diaContent.closest('.ui-dialog')
                                });
                            }
                        },
                        'LIEBER NICHT': function() {
                            $(this).dialog('destroy');
                        }
                    }
                });
                return false;
            });
            var $deleteAllUser = $('.useradmin_del_fromcsv', $box);
            var $diaConfirm = $('#deleteFromCsv');
            $deleteAllUser.click(function() {
                $button = $(this);
                $diaConfirm.dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 400,
                    height: 100,
                    modal: true,
                    title: 'Alle User löschen',
                    buttons: {
                        'Alle User löschen': function() {
                            if (confirm('Sind sie sicher dass sie alle User in dieser Liste löschen wollen?')) {
                                $form = $('form', $diaConfirm);
                                $.KH.ajax({
                                    url: $form.attr('action'),
                                    data: $form.serialize(),
                                    type: $form.attr('method'),
                                    dataType: 'json',
                                    element: $diaConfirm,
                                    success: function(data){
                                        if(!data.error) {
                                            $.KH.info(data.success);
                                            $.KH.refreshPage('/useradmin/deletefromcsv');
                                        } else {
                                            $.KH.error(data.error);
                                        }
                                        $diaConfirm.dialog('destroy');
                                    }
                                });
                            }
                        },
                        'Abbrechen': function() {
                            $diaConfirm.dialog('destroy');
                        }
                    }
                });
                return false;
            });
        },

        KH_sitemap: function() {
            var $sitemap = $(this);
            var $list = $('.archivelist', $sitemap);
            var $pageContent = $('#pageContent');
            var $archive = $('.archive', $sitemap);
            //the padding of pageContent needs to be adjusted when footer's height changes (as footer is positioned absolute at the page bottom).
            //refresh from last time here.
            var oldPadding = $pageContent.data('padding-bottom');
            if(oldPadding !== undefined) {
                $pageContent.css('padding-bottom', oldPadding);
            } else {
                oldPadding = parseInt($pageContent.css('padding-bottom').replace('px',''));
                $pageContent.data('padding-bottom', oldPadding);
            }
            $archive.click(function(){
                if(!$archive.data('opened')) {
                    $list.show();
                    var newPadding = oldPadding + $list.height();
                    $pageContent.css('padding-bottom', newPadding);
                    $archive.data('opened', true);
                } else {
                    $list.hide();
                    $pageContent.css('padding-bottom', oldPadding);
                    $archive.removeData('opened');
                }
                return false;
            });
        },

        KH_delete: function() {
            $container = $(this);
            $("a.confirm", $container).click(function(){
                $('<p>Willst du deinen KRONEHIT VIP Account wirklick löschen?<br/></p>').dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 350,
                    height: 150,
                    modal: true,
                    title: 'KRONEHIT VIP Account löschen',
                    buttons: {
                        'JA': function() {
                            var $diaContent = $(this);
                            $.KH.ajax({
                                url: '/user/delete/',
                                type: 'post',
                                success: function(data){
                                    if(data.success) {
                                        $.KH.info(data.success);
                                        $("#pageContent").html(data.html);
                                    } else {
                                        $.KH.error(data.error, 3);
                                    }
                                    $diaContent.dialog('destroy');
                                },
                                dataType: 'json',
                                element: $diaContent.closest('.ui-dialog')
                            });
                        },
                        'LIEBER NICHT': function() {
                            $(this).dialog('destroy');
                        }
                    }
                });
                return false;
            });
        },

        KH_deleteconfirm: function() {
            $container = $(this);
            $("select[name='reason']").change(function () {
                if ($(this).val() == '5') {
                    $("textarea", $container).attr('disabled', '');
                } else {
                    $("textarea", $container).attr('disabled', 'disabled');
                }
            });
            $("a.submit", $container).click(function () {
                $('<p>Willst du deinen KRONEHIT VIP Account wirklick löschen?<br/></p>').dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 350,
                    height: 150,
                    modal: true,
                    title: 'KRONEHIT VIP Account löschen',
                    buttons: {
                        'JA': function() {
                            var $diaContent = $(this);
                            $form = $('form', $container);
                            $.KH.ajax({
                                url: '/auth/deleteconfirm/',
                                type: 'post',
                                data: $form.serialize(),
                                success: function(data){
                                    if(data.success) {
                                        $.KH.info(data.success);
                                        $("#login").html(data.loginbox);
                                    } else {
                                        $.KH.error(data.error, 3);
                                    }
                                    $("#pageContent").html(data.html);
                                    $diaContent.dialog('destroy');
                                },
                                dataType: 'json',
                                element: $diaContent.closest('.ui-dialog')
                            });
                        },
                        'LIEBER NICHT': function() {
                            $(this).dialog('destroy');
                        }
                    }
                });
                return false;
            });
            $("select[name='reason']").change();
        },

        KH_boxWeather: function() {
            var $weather = $(this);
            $('select[name="province"]').change(function(){
                $.KH.refreshPage($(this).val());
            });
        },

        KH_lotteryfile: function() {
            var $target = $(this);
            var $diaDel = $('#confirmDelete', $target);
            var $aDelete = $('.KH-delete', $target);
            $('.sort', $target).hide();

            //delete
            $aDelete.click(function(){
                $diaDel.dialog({
                    resizable: false,
                    draggable: false,
                    bgiframe: true,
                    width: 200,
                    height: 150,
                    modal: true,
                    title: 'Löschen bestätigen',
                    buttons: {
                        'Löschen': function() {
                            $.KH.ajax({
                                url: $aDelete.attr('href'),
                                success: function(data){
                                    $('#KH-mediaTab').click(); //reload media
                                    $.KH.info(data.msg, 3);
                                    $diaDel.dialog('destroy');
                                },
                                dataType: 'json',
                                element: $diaDel
                            });
                        },
                        'Abbrechen': function() {
                            $diaDel.dialog('destroy');
                        }
                    }
                });
                return false;
            });
            //change caption
            $('.KH-changeText', $target).click(function(){
                var $a = $(this);
                var $desc = $('.caption', $target);
                if(!$a.data('save')) {
                    var currentText = $desc.html();
                    $desc.html('Text: <input class="text KH-editText" type="text" value="'+currentText+'" maxlength="100" />');
                    var $editField = $('.KH-editText', $target);
                    $editField.keypress(function(e){
                        var code = (e.keyCode ? e.keyCode : e.which);
                        if(code == 13) { //ENTER
                            saveNewText(currentText);
                        }
                    }).select();
                    $a.data('save',true).html('Text speichern');
                } else {
                    saveNewText('');
                }
                function saveNewText(currentText) {
                    var txt = $('.KH-editText', $target).val();
                    $.KH.ajax({
                        url: $a.attr('href'),
                        type: 'post',
                        data: 'newText='+txt,
                        success: function(data){
                            if (!data.error) {
                                $desc.html(txt);
                                $.KH.info(data.msg, 3);
                            } else {
                                $desc.html(currentText);
                                $.KH.error(data.error);
                            }
                            $a.data('save',false).html('Text ändern');
                        },
                        dataType: 'json',
                        element: $target
                    });
                }
                return false;
            });
            //change caption
            $('.KH-changeSort', $target).click(function(){
                var $a = $(this);
                var $desc = $('.sort', $target);
                $desc.show();
                if(!$a.data('save')) {
                    var currentSort = $desc.html();
                    $desc.html('Sortierung: <input class="text KH-editSort" type="text" value="'+currentSort+'" maxlength="3" />');
                    var $editField = $('.KH-editSort', $target);
                    $editField.keypress(function(e){
                        var code = (e.keyCode ? e.keyCode : e.which);
                        if(code == 13) { //ENTER
                            saveNewSort(currentSort);
                        }
                    }).select();
                    $a.data('save',true).html('Sortierung speichern');
                } else {
                    saveNewSort('');
                }
                function saveNewSort(currentText) {
                    var sort = $('.KH-editSort', $target).val();
                    $.KH.ajax({
                        url: $a.attr('href'),
                        type: 'post',
                        data: 'newSort='+sort,
                        success: function(data){
                            if (!data.error) {
                                $desc.html(sort);
                                $desc.hide();
                                $.KH.info(data.msg, 3);
                            } else {
                                $desc.html(currentText);
                                $.KH.error(data.error);
                            }
                            $a.data('save',false).html('Sortierung ändern');
                        },
                        dataType: 'json',
                        element: $target
                    });
                }
                return false;
            });
        },

        KH_gallery: function(data) {

            if(data == undefined || data.images.length == 0) return false;

            var $container = $(this);
            var $gallery = $('<div class="box boxGallery" />').appendTo($container);
            var $thumbs = $('<div class="thumbs" />').appendTo($gallery);
            var $paging = $('<div class="paging" />').appendTo($gallery);
            var page_current = 0;
            var page_items = 16;
            var page_count = Math.ceil(data.images.length/page_items);

            function buildPage(add) {
                var page_next = page_current + add;
                var itemStart = page_next * page_items;
                var itemStop = itemStart + page_items;
                if(itemStop > data.images.length) itemStop = data.images.length;

                var thumbsList = '<ul>';
                for(var i=itemStart; i<itemStop; i++) {
                    var imgSrc = data.options.imgPath + data.images[i];
                    var thumbSrc = data.options.thumbPath + data.images[i];
                    thumbsList += '<li><a href="'+imgSrc+'" rel="'+i+'"><img src="'+thumbSrc+'" /></a></li>';
                }
                thumbsList += '</ul>';
                $thumbs.html(thumbsList);
                page_current = page_next;
                buildPaging();
                $.KH.scrollToTop();
            }
            function buildPaging() {
                //no paging required? hide it
                if(page_count < 2) {
                    $paging.hide();
                    return false;
                }

                var paging = '';
                if(page_current != 0) {
                    paging += '<a class="prev" href="#">zurück</a>';
                }
                paging += '<span>Seite '+(page_current+1)+' von '+page_count+'</span>';
                if(page_current+1 != page_count) {
                    paging += '<a class="next" href="#">weiter</a>';
                }
                $paging.html(paging);
                //bind events
                $('.prev', $paging).click(function(e){
                    buildPage(-1);
                    $.KH.tracking();
                    e.preventDefault();
                });
                $('.next', $paging).click(function(e){
                    buildPage(+1);
                    $.KH.tracking();
                    e.preventDefault();
                });
            }

            //fancybox
            //using a custom jquery collection of *all* images to have a fancybox paging that includes not only the images visible atm (on paging)
            var fancyData = '';
            $.each(data.images, function(index, img) {
                var imgSrc = data.options.imgPath + img;
                var thumbSrc = data.options.thumbPath + img;
                fancyData += '<a href="'+imgSrc+'" data-image="'+img+'"><img src="'+thumbSrc+'" /></a>';
            });
            //open fancybox on click on thumbnails
            $('a', $thumbs[0]).live('click', function(e){ //event context for live! see http://api.jquery.com/live/#event-context
                var $a = $(this);
                var index = parseInt($a.attr('rel'));
                openFancybox(index);
                e.preventDefault();
            });
            
            //open fancybox for image using index in fancyData array
            function openFancybox(index) {
                var config = {
                    index: index,
                    titlePosition: 'inside',
                    titleFormat: formatTitle,
                    onStart: function(){ $.KH.tracking(); } //triggered on every prev/next click
                };
                $.fancybox($(fancyData).toArray(), config);
            }
            //add like button to images
            function formatTitle(title, currentArray, currentIndex, currentOpts) {
                //get path of current image, encode it for use in url
                var currImage = $(currentArray[currentIndex]).data('image');
                //build the url for facebook
                var url = location.protocol + '//' + location.host + '/'+_galleryUrlSegment+'/index/gallery/'+data.options.galleryName+'/image/'+currImage;
                return '' +
                        '<div style="text-align:left;">' +
                        '<iframe src="http://www.facebook.com/plugins/like.php?href='+url+'&amp;layout=button_count&amp;show_faces=false&amp;width=200&amp;action=like&amp;colorscheme=dark&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:200px; height:21px;" allowTransparency="true"></iframe>' +
                        '</div>';
            }

            //init
            buildPage(0);
            //open initial image given in url (.../image/filename.jpg), set in PageContent view script
            if(_galleryImage != '') {
                var imageIndex = $.inArray(_galleryImage, data.images);
                if(imageIndex != -1) {
                    openFancybox(imageIndex);
                }
                _galleryImage = '';
            }
        }
    });


    //define functions available to all plugins
    function toggleFanButtonTitle($btn) {
        if($btn.hasClass('btnFlagOff')) $btn.attr('title', 'nicht mehr Fan sein');
        else $btn.attr('title', 'Fan werden');
    }

    function handleFanOf ($button, strName, strType, bMyPage) {
        if ($button.hasClass('btnFlagOff')) {
            deleteFanOf($button, strName, strType, bMyPage);
            return false;
        } else {
            var saveFan = function(options) {
                if (!options) {
                    options = {};
                }
                if (options.async === undefined) {
                    options.async = true;
                }
                var postData = null;
                $.KH.ajax({
                    url: $button.attr('href'),
                    type: 'post',
                    async: options.async,
                    data: options.data || null,
                    dataType: 'json',
                    success: function(data){
                        postData = data;
                        $button.addClass('btnFlagOff');
                        toggleFanButtonTitle($button);
                        $.KH.info(data.msg, 3);
                        if (strType == 'artist') {
                            // queue triggering (otherwise it fails with sync. requests)
                            setTimeout(function(){$('#KH-fansTab').click();},0); //reload fans tab
                            //update amount in fans tab
                            var $amount = $('#KH-fansTab .slice.main span');
                            var newAmount = parseInt($amount.text().replace(/(\(|\))/g, '')) + 1;
                            $amount.html('('+newAmount+')');
                        }
                    }
                });
                return postData;
            };

            if ($button.hasClass('publish') || $button.hasClass('share')) {
                $.KH.FacebookShareDialog(
                    function() {
                        if ($button.hasClass('share')) {
                            var data = saveFan({
                                async: false,
                                data: 'allow_facebook_publish=1&facebook_post_type=share'
                            });
                            if (data && data.facebookData) {
                                // share with fb ui
                                $.KH.facebook.publishPost(
                                    data.facebookData,
                                    function() {
                                        $.KH.error('Dein Beitrag wurde nicht auf Facebook gepostet');
                                    },
                                    function(postId) {
                                        $.KH.ajax({
                                            url: data.successUrl,
                                            dataType: 'json',
                                            type: 'post',
                                            data: 'uid='+postId,
                                            success: function(data){
                                                if (!data.error) {
                                                    $.KH.info(data.msg);
                                                } else {
                                                    $.KH.error(data.error);
                                                }
                                            }
                                        });
                                    }
                                );
                            }
                        } else {
                            saveFan({
                                data: 'allow_facebook_publish=1&facebook_post_type=publish'
                            });
                        }
                    },
                    function() {
                        saveFan();
                    }
                );
            } else {
                saveFan();
            }
            return false;
        }
    }

    function deleteFanOf ($button, strName, strType, bMyPage) {
        strUrl = $button.attr('href');
        strId = strUrl.substr(strUrl.lastIndexOf('/') + 1);
        $('<p>Bist du dir sicher, dass du kein Fan mehr von "' + strName + '" sein möchtest?</p>').dialog({
            resizable: false,
            draggable: false,
            draggable: false,
            bgiframe: true,
            width: 300,
            height: 100,
            modal: true,
            title: 'Fanschaft beenden!',
            buttons: {
                'Nicht mehr Fan sein': function() {
                    var $diaContent = $(this);
                    $.KH.ajax({
                        url: $button.attr('href'),
                        type: 'post',
                        dataType: 'json',
                        success: function(data){
                        $button.removeClass('btnFlagOff');
                            toggleFanButtonTitle($button);
                            $.KH.info(data.msg, 3);
                            if (strType == 'artist') {
                                $('#KH-fansTab').click(); //reload fans tab
                                //update amount in fans tab
                                var $amount = $('#KH-fansTab .slice.main span');
                                var newAmount = parseInt($amount.text().replace(/(\(|\))/g, '')) - 1;
                                $amount.html('('+newAmount+')');
                            } else if (strType == 'user') {
                            /* skip this for now, may be improved later on, refs #562
                                if (bMyPage) {
                                    $button.closest('td').fadeOut(function(){ $(this).html(); });
                                    $('#boxFanOf .body').find('a[name=fanof_' + strId + ']').fadeOut(function(){ $(this).remove(); });
                                } else {
                                }
                            */
                            }
                            $diaContent.dialog('destroy');
                        },
                        element: $diaContent.closest('.ui-dialog')
                    });
                },
                'Abbrechen': function() {
                    $(this).dialog('destroy');
                }
            }
        });
    }

    function reportComment($target, type) {
        var txt;
        if(type == 'media') {
            txt = {
                body: '<p>Willst Du das Foto/Video wirklich melden?</p>',
                title: 'Foto/Video an KRONE<b>HIT</b> Redaktion melden',
                btn: 'FOTO/VIDEO MELDEN'
            };
        } else {
            txt = {
                body: '<p>Willst Du den Kommentar wirklich melden?</p>',
                title: 'Kommentar an KRONE<b>HIT</b> Redaktion melden',
                btn: 'KOMMENTAR MELDEN'
            };
        }
        var options = {
            resizable: false,
                    draggable: false,
            bgiframe: true,
            width: 320,
            height: 150,
            modal: true,
            title: txt.title
        }
        var buttons = {};
        buttons[txt.btn] = function() {
            var $diaContent = $(this);
            $.KH.ajax({
                url: $target.attr('href'),
                success: function(data){
                    if(!data.error) {
                        $.KH.info(data.msg, 3);
                    } else {
                        $.KH.error(data.msg, 3);
                    }
                    $diaContent.dialog('destroy');
                },
                dataType: 'json',
                element: $diaContent.closest('.ui-dialog')
            });
        }
        buttons['ABBRECHEN'] = function() {
            $(this).dialog('destroy');
        }
        options.buttons = buttons;
        $(txt.body).dialog(options);
    }

    function sendMessage ($button, strName, strId) {
        var $diaRec = $('#newUserMessage');
        var $message = $diaRec.find('textarea[name=message]');
        var $subject = $diaRec.find('text[name=subject]');
        $diaRec.dialog({
            resizable: false,
            draggable: false,
            bgiframe: true,
            width: 400,
            height: 300,
            modal: true,
            title: strName + ' eine Nachricht senden',
            buttons: {
                'NACHRICHT SENDEN': function() {
                    var $diaContent = $(this);
                    $form = $('form', $diaRec);
                    $diaRec.find('.error').hide();
                    $diaRec.find('input[name=recip]').val(strId);
                    $.KH.ajax({
                        url: $form.attr('action'),
                        data: $form.serialize(),
                        type: $form.attr('method'),
                        dataType: 'json',
                        element: $diaRec,
                        success: function(data){
                            if(data.success) {
                                $diaRec.find('.error').hide();
                                $diaRec.find('.step:eq(0)').hide();
                                $diaRec.find('.step:eq(1)').show();
                                $diaRec.data('origButtons', $diaRec.dialog('option', 'buttons'));
                                $diaRec.dialog('option', 'buttons', {'SCHLIESSEN': function() { $(this).dialog("destroy"); } });
                            } else {
                                if (data.error) {
                                    $diaRec.find('#error').html(data.error);
                                    $diaRec.find('#error').show();
                                }
                                if (data.errsubj) {
                                    $diaRec.find('#errorsubject').html(data.errsubj);
                                    $diaRec.find('#errorsubject').show();
                                }
                                if (data.errmsg) {
                                    $diaRec.find('#errormessage').html(data.errmsg);
                                    $diaRec.find('#errormessage').show();
                                }
                            }
                        }
                    });
                },
                'LIEBER NICHT': function() {
                    $(this).dialog('destroy');
                }
            },
            open: function(){
                if($diaRec.data('origButtons')) $diaRec.dialog('option', 'buttons', $diaRec.data('origButtons'));
                $diaRec
                    .find('.step').hide().end()
                    .find('.step:eq(0)').show()
                    .find('.error').hide().end()
                    .find('input[name=message]').val('').end()
                    .find('input[name=subject]').val('').end()
                    .find('input[name=recip]').val('');
                $message.val($message.attr('title'));
                $diaRec.find('.step:eq(1)').find('p').find('.usrname').html(strName);
            },
            close: function() { //always destroy on close
                $diaRec.dialog('destroy');
            }
        });
    }

    function handleFriendship ($button, strName, strId, afteractionarg) {
        if ($button.hasClass('btnPlusOff')) {
            deleteFriend ($button, strName, strId, afteractionarg);
        }
        else {
            addFriend ($button, strName, strId);
        }
    }

    function deleteFriend ($button, strName, strId, afteractionarg) {
        $('<p>Willst du die Freundschaft mit ' + strName + ' wirklich beenden?</p>').dialog({
            resizable: false,
            draggable: false,
            bgiframe: true,
            width: 350,
            height: 100,
            modal: true,
            title: 'Freundschaft löschen',
            buttons: {
                'FREUNDSCHAFT BEENDEN': function() {
                    var $diaContent = $(this);
                    $.KH.ajax({
                        url: '/user/frienddelete/uid/' + strId,
                        success: function(data){
                            if(data.success) {
                                $.KH.info(data.success, 3);
                                $button.closest('a[name=heart]').fadeOut(function(){ $(this).remove(); });
                                $button.removeClass('btnPlusOff');
                                $button.attr('title', 'Als Freund hinzufügen');
                                if (typeof(afteractionarg) == 'string' && afteractionarg != '')
                                    $.KH.refreshPage(afteractionarg);
                                else if (typeof(afteractionarg) == 'boolean' && afteractionarg == true) {
                                    $button.closest('li').fadeOut(function(){ $(this).remove(); });
                                    var $amount = $('#KH-friendsTab .slice.main span');
                                    var newAmount = parseInt($amount.text().replace(/(\(|\))/g, ''))-1;
                                    $amount.html('(' + newAmount + ')');
                                }
                            } else {
                                $.KH.error(data.error, 3);
                            }
                            $diaContent.dialog('destroy');
                        },
                        dataType: 'json',
                        element: $diaContent.closest('.ui-dialog')
                    });
                },
                'LIEBER NICHT': function() {
                    $(this).dialog('destroy');
                }
            }
        });
    }

    function addFriend ($button, strName, strId) {
        var $diaRec = $('#addFriend');
        var $message = $diaRec.find('textarea[name=message]');

        $diaRec.dialog({
            resizable: false,
            draggable: false,
            bgiframe: true,
            width: 400,
            height: 200,
            modal: true,
            title: strName + ' kennenlernen',
            buttons: {
                'NACHRICHT SENDEN': function() {
                    var $diaContent = $(this);
                    $form = $('form', $diaRec);
                    $diaRec.find('.error').hide();
                    $diaRec.find('input[name=recip]').val(strId);
                    $.KH.ajax({
                        url: $form.attr('action'),
                        data: $form.serialize(),
                        type: $form.attr('method'),
                        dataType: 'json',
                        element: $diaRec,
                        success: function(data){
                            if(data.success) {
                                $diaRec.find('.error').hide();
                                $diaRec.find('.step:eq(0)').hide();
                                $diaRec.find('.step:eq(1)').show();
                                $diaRec.data('origButtons', $diaRec.dialog('option', 'buttons'));
                                $diaRec.dialog('option', 'buttons', {'SCHLIESSEN': function() { $(this).dialog("destroy"); } });
                            } else {
                                if (data.error) {
                                    $diaRec.find('.error[name=error]').html(data.error);
                                    $diaRec.find('.error[name=error]').show();
                                }
                                if (data.errmsg) {
                                    $diaRec.find('.error[name=errormessage]').html(data.errmsg);
                                    $diaRec.find('.error[name=errormessage]').show();
                                }
                            }
                        }
                    });
                },
                'LIEBER NICHT': function() {
                    $(this).dialog('destroy');
                }
            },
            open: function(){
                if($diaRec.data('origButtons')) $diaRec.dialog('option', 'buttons', $diaRec.data('origButtons'));
                $diaRec
                    .find('.step').hide().end()
                    .find('.step:eq(0)').show()
                    .find('.error').hide().end()
                    .find('input[name=message]').val('').end()
                    .find('input[name=recip]').val('');
                $message.val($message.attr('title'));
                $diaRec.find('.step:eq(1)').find('p').find('.usrname').html(strName);
            },
            close: function() { //always destroy on close
                $diaRec.dialog('destroy');
            }
        });
    }

    function sendHeart ($button, strName, strId) {
        var $diaRec = $('#sendHeartMsg');
        $diaRec.dialog({
            resizable: false,
            draggable: false,
            bgiframe: true,
            width: 350,
            height: 100,
            modal: true,
            title: strName + ' antupfen',
            buttons: {
                'ANTUPFEN': function() {
                    var $diaContent = $(this);
                    $diaRec.find('.error').hide();
                    $diaRec.find('input[name=uid]').val(strId);
                    $form = $('form', $diaRec);
                    $.KH.ajax({
                        url: $form.attr('action'),
                        data: $form.serialize(),
                        type: $form.attr('method'),
                        dataType: 'json',
                        element: $diaRec,
                        success: function(data){
                            if(data.success) {
                                $diaRec.find('.error').hide();
                                $diaRec.find('.step:eq(0)').hide();
                                $diaRec.find('.step:eq(1)').show();
                                $diaRec.data('origButtons', $diaRec.dialog('option', 'buttons'));
                                $diaRec.dialog('option', 'buttons', {'SCHLIESSEN': function() { $(this).dialog("destroy"); } });
                            } else {
                                $diaRec.find('.error[name=error]').html('<br />' + data.error);
                                $diaRec.find('.error[name=error]').show();
                            }
                        }
                    });
                },
                'LIEBER NICHT': function() {
                    $(this).dialog('destroy');
                }
            },
            open: function(){
                if($diaRec.data('origButtons')) $diaRec.dialog('option', 'buttons', $diaRec.data('origButtons'));
                $diaRec
                    .find('.step').hide().end()
                    .find('.step:eq(0)').show()
                    .find('.error').hide().end()
                    .find('input[name=uid]').val('');
                $diaRec.find('.step:eq(0)').find('p').find('.usrname').html(strName);
                $diaRec.find('.step:eq(1)').find('p').find('.usrname').html(strName);
            },
            close: function() { //always destroy on close
                $diaRec.dialog('destroy');
            }
        });
        return false;
    }

})(jQuery);

/**
 * Facebook Helper
 * @param appId
 * @param options possible options: string loginPermissions, boolean disable
 */
function Facebook(appId, options) {
    if (!options) {
        options = {};
    }

    this.appId = appId;
    this.loginPermissions = options.loginPermissions || '';

    this.onAuthChange = options.onAuthChange;

    var self = this;

    var fbInit = function() {
        FB.init({
          appId   : self.appId,
          status  : true, // check login status
          cookie  : true, // enable cookies to allow the server to access the session
          xfbml   : true, // parse XFBML,
          oauth : true
        });
        // TODO: ie bug with facebook's js, remove those lines if there is a fix
        // refs #1048
        // http://stackoverflow.com/questions/7280007/permission-denied-error-in-all-js
        // temp. fix from http://bugs.developers.facebook.net/show_bug.cgi?id=19042
        FB.UIServer.setActiveNode = function(a,b){FB.UIServer._active[a.id]=b;};
        // temp. fix from http://bugs.developers.facebook.net/show_bug.cgi?id=20168
        FB.UIServer.setLoadedNode = function(a,b){FB.UIServer._loadedNodes[a.id]=b;};
    };

    var loaded = false;

    var _loadedHandler = function() {
        fbInit();

        FB.Event.subscribe('auth.authResponseChange', function(response) {
            if (self.onAuthChange) {
               self.onAuthChange(response);
            }
        });

        // we still need to reinitialize the facebook object (checks for session changes), since
        // FB.Event.subscribe on auth.statusChange only listens for changes in the current window (NO push).
        // TODO: try to avoid the refresh
        //setInterval(self.refresh, 10000);

        loaded = true;
    };

    this.refresh = function() {
        if (loaded) {
            fbInit();
        }
    };

    this.login = function(errorHandler, successHandler) {
        if (loaded) {
            self.getPermissions(self.loginPermissions, errorHandler, successHandler);
        }
    };

    this.logout = function(callback) {
        if (loaded) {
            var session = FB.getAuthResponse();
            if (session && session.accessToken) {
                FB.logout(function(response) {
                    callback(response);
                });
            } else {
                callback(null);
            }
        }
    };

    this.getPermissions = function(scope, errorHandler, successHandler) {
        if (loaded) {
            FB.login(function(response) {
                if (response.authResponse) {
                    successHandler(response);
                } else {
                    errorHandler(response);
                }
            }, {scope: scope});
        }
    };

    /**
     * data fields:
     *  * name
     *  * link
     *  * picture
     *  * caption
     *  * description
     *
     * @param data
     * @param errorHandler
     * @param successHandler
     */
    this.publishPost = function(data, errorHandler, successHandler) {
        if (loaded) {
            var session = FB.getAuthResponse();
            var params = {
                method: 'feed',
                name: data.name,
                link: data.link,
                picture: data.picture,
                caption: data.caption,
                description: data.description
            };
            if (session && session.accessToken) {
                params.access_token = session.accessToken;
                params.display = 'iframe';
            } else {
                params.display = 'popup';
            }
            FB.ui(
                params,
                function(response) {
                    if (response && response.post_id) {
                        successHandler(response.post_id);
                    } else {
                        errorHandler(response);
                    }
                }
            );
        }
    };

    if (!options.disable) {
        // load async which is faster (see https://developers.facebook.com/docs/reference/javascript/)
        window.fbAsyncInit = _loadedHandler;

        var e = document.createElement('script');
        e.async = true;
        // may lead to problems, if one part of page is http and the other https (eg auth)
        e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
        document.getElementById('fb-root').appendChild(e);
    }
}

$.KH = {

    // wrap jquery ajax method to pass further options:
    // element: expects an array of jquery objects: this is the target selector, where data will be filled in. Also gets blocked by blockUI
    // block: if further stuff should get blocked, this is passed via the 'block' option: expects an array of jquery objects
    ajax : function (options) {
        options.origUrl = options.url; //options.url is modified in succession, keep the untouched url here i.e. for the 'url copy' function
        //default options
        options.element = options.element || $("#pageContent");
        options.keepInHistory = options.keepInHistory || false;
        //in case the target page has sub-parts, make sure it's being rendered including the containing grid
        if(options.element.is('#pageContent')) options.isHistory = true;

        //history management
        if(options.keepInHistory) {
            _historyLive = false; //prevent ajax loading as called in $.address.change (which is unfortunately triggered by $.address.value)
            $.address.value(options.url);
            _historyLive = true;
        }

        // Now follows the preparation of the url so Zend can handle it correctly
        // remove every slash and hash from the last character
        do {
            options.url = options.url.replace(/[#|\/]$/, '');
        }
        while (options.url.match(/[#|\/]$/));

        // if we have a normal url call
        if(options.url.substring(0,7) == 'http://') {
            //avoid calling home with ajax parameter (like http://www.kronehit.at/ajax/1), using /index/index instead
            if(options.url.split('/').length == 3) {
                options.url = '/index/index';
            }
            //avoid passing invalid action name (isHistory) to Zend Framework
            //if no action is set in the url, we set it manually here
            else if(options.url.split('/').length == 4) {
                options.url += '/index';
            }
        }
        // if we do have an ajax-call
        else {
            // if Url is empty we call home
            if(options.url == "") {
                options.url = "/index/index";
            }
            // Add slash at first pos if missing
            if (options.url != "" && options.url.indexOf('/') != 0) {
                options.url = "/" + options.url;
            }

            // if just a controller with starting / is given, we extend with an action so
            // Zend can handle the request correctly
            if (options.url.split('/').length == 2) {
                if (options.url.split('/')[1] == "")
                    options.url += "index/index";
                else
                    options.url += "/index";
            }
        }

        // check if the request params have an even count (then add a dummy value)
        // if we do not add default value, the rest of the url gets invalid
        // only works correctly if we do not have a subfolder between the server-dns and the first request param
        if ((options.url.split('/').length % 2) == 0) {
            options.url += '/0';
        }

        //augment url with isHistory if required (when called by $.address.change)
        //calling a url with isHistory tells backend to deliver the complete pageContent instead of content parts only (f.e. parts loaded into colMainRight)
        //this to prevent the following: 1) we don't know which container to load the part into (history gives us the url only!) and 2) the container might not be present any more on the current page
        if(options.isHistory) {
            if(options.url == "") options.url = "/index/index"; //calling [host]/isHistory/1 gives zend errors, therefore using /index/index instead
            options.url += '/isHistory/1';
        }
        //add ajax param (no longer relying on the x-request-with header)
        options.url += '/ajax/1';

        //pass normal options to jquery method
        $.manageAjax.add('kronehit', {
            async: (options.async === undefined || options.async === null) ? true : options.async,
            url: options.url,    //required
            data: options.data, //default is {}
            type: options.type, //default is 'GET'
            dataType: options.dataType, //default is 'html'
            beforeSend: options.beforeSend || function() {
                options.element.KH_blockElement();    //block element (target)
                if(options.block) options.block.KH_blockElement();    //block other given stuff (via css class KH-block-..)
                if(options.element.is('#pageContent')) $.KH.moveLogin(); //reset login position if necessary
            },
            complete: options.complete || function(event, status) {
                options.element.KH_unblockElement();    //unblock element
                if(options.block) options.block.KH_unblockElement(); //unblock other given stuff (via css class KH-block-..)
                //get siteconfig (in case it's a complete new 'page' meaning we got a new footer) and do tracking. if 'complete' function is overriden in call, tracking has to be done there!
                if(status != 'error') {
                    $.KH.siteConfig();
                    $.KH.tracking();
                    //'copy url' on top of page
                    if(options.keepInHistory || options.isHistory) {
                        var copyUrl = options.origUrl;
                        if(copyUrl.substring(0,1) == '/') copyUrl = 'http://' + location.host + copyUrl;
                        $('#urlcopy .url').val(copyUrl);
                    }
                    $.KH.facebook.refresh();
                }
            },
            success: options.success || function(data) {
                options.element.html(data);
                if(options.element.is('#pageContent')) $.KH.scrollToTop();
            } //default behaivour is to change the 'element' html
        });
    },

    //refresh default div
    //defaults to homepage, if no url is passed
    refreshPage : function (url) {
        var url = (url)? url : '/index/index';
        $.KH.ajax({
            url: url
        });
    },

    //show info to user (twitter-like)
    //calls $.KH.alert()
    info : function (msg, timeVisible) {
        $.KH.alert(msg, timeVisible, 'info');
    },

    //show error to user (twitter-like)
    //calls $.KH.alert()
    error : function (msg, timeVisible) {
        $.KH.alert(msg, timeVisible, 'error');
    },

    //renders the info/error alert
    alert : function (msg, timeVisible, type) {
        var $alert = $('#alert');
        var $content = $('.content', $alert);
        var timeVisible = (timeVisible || 5) * 1000;
        var bgColor;
        //hide existing alert message first
        if($alert.data('timer')) {
            clearTimer();
            $content.hide();
        }
        //build new message
        if(type == 'info') bgColor = '#53bec7';
        if(type == 'error') bgColor = '#d7234c';
        $alert.css('background', bgColor); //setting a class for this didn't work in ie6
        $alert.css('opacity', 0.9); //for ie6 too
        $content.html(msg);
        $alert.click(function(){
            clearTimer();
            $content.slideUp('fast');
        });
        $alert.data('timer', window.setTimeout(function(){
            $alert.trigger('click');
        }, timeVisible));
        //finally, show message
        $content.slideDown('fast');

        function clearTimer(){
            window.clearTimeout($alert.data('timer'));
            $alert.data('timer', false);
        }
    },

    scrollToTop: function() { //TODO scroll to container
        $("html").animate({ scrollTop: 0 }, "fast");
    },

    videoPlayer : function(flv, divid) {
        /*
        var flashvars = {
                file: flv
        };
        swfobject.embedSWF("/swf/flvplayer.swf", divid, "425", "350", "9.0.0", "/swf/expressInstall.swf", flashvars);
        */
        var $div = $('#'+divid);
        $div.flowplayer('/swf/flowplayer-3.1.5.swf', {
            clip : {
                autoPlay: false,
                autoBuffering: true,
                url: flv
            },
            canvas: {backgroundColor: "#ffffff"},
            plugins: {
               controls: {
                  sliderColor: '#ffffff',
                  buttonColor: '#000000',
                  progressGradient: 'medium',
                  progressColor: '#000000',
                  borderRadius: '5',
                  bufferColor: '#949494',
                  tooltipTextColor: '#ffffff',
                  durationColor: '#ffffff',
                  tooltipColor: '#000000',
                  backgroundGradient: 'low',
                  volumeSliderGradient: 'none',
                  sliderGradient: 'none',
                  timeBgColor: '#000000',
                  backgroundColor: '#957842',
                  volumeSliderColor: '#000000',
                  bufferGradient: 'none',
                  buttonOverColor: '#292929',
                  timeColor: '#957842',
                  height: 24,
                  opacity: 1.0,
                  fullscreen: false
               }
            }
        }).load();
    },

    audioPlayer : function(mp3, divid) {
        var $div = $('#'+divid);
        $div.flowplayer('/swf/flowplayer-3.1.5.swf', {
            clip : {
                autoPlay: false,
                url: mp3
            },
            canvas: {backgroundColor: "#ffffff"},
            plugins: {
               controls: {
                  sliderColor: '#ffffff',
                  buttonColor: '#000000',
                  progressGradient: 'medium',
                  progressColor: '#000000',
                  borderRadius: '5',
                  bufferColor: '#949494',
                  tooltipTextColor: '#ffffff',
                  durationColor: '#ffffff',
                  tooltipColor: '#000000',
                  backgroundGradient: 'low',
                  volumeSliderGradient: 'none',
                  sliderGradient: 'none',
                  timeBgColor: '#000000',
                  backgroundColor: '#957842',
                  volumeSliderColor: '#000000',
                  bufferGradient: 'none',
                  buttonOverColor: '#292929',
                  timeColor: '#957842',
                  height: 24,
                  opacity: 1.0,
                  fullscreen: false
               }
            }
        }).load();
    },

    // swf<->js bridging to allow webplayer broadcasting a new playlist to other swfs such as artistcarousel
    swfBridge: {
        playlistTargets: Array('artistcarousel','artistbox'), //swf's send corresponding string to 'swfReady'. CAUTION: id's of embed-tags have to be identical to these strings!
        currentPlaylistXmlUrl: '',
        currentChannelData: null,
        broadcastPlaylist: function(xmlUrl) { //called by webplayer to trigger loading of a new playlist xml file in other swfs
            for(index in this.playlistTargets) {
                try { $('#'+this.playlistTargets[index]).get(0).loadPlaylist(xmlUrl); }
                catch(e) {} //swf will call swfReady, so don't worry here
            }
            this.currentPlaylistXmlUrl = xmlUrl;
        },
        swfReady: function(targetString) { //called by target swfs. if a broadcast has already been made, it is sent to the delayed target (also happens on history.back)
            //playlist: check wheter this is a valid target and there is already a xml to load (sent from webplayer)
            var playlistTargetIndex = $.inArray(targetString, this.playlistTargets);
            if(playlistTargetIndex != -1 && this.currentPlaylistXmlUrl != '') {
                $('#'+targetString).get(0).loadPlaylist(this.currentPlaylistXmlUrl);
            }
            //channel data, what to do with artistcarousel
            if(targetString == 'artistcarousel' && this.currentChannelData != null) {
                this.switchChannel(this.currentChannelData);
            }
        },
        switchChannel: function(channelData) { //update screen according to the current channel data
            var $carousel = $('#artistcarousel');
            var $box = $('#artistbox'); //showing this instead of carousel when logged-in
            //logged-out, showing carousel
            if($carousel.length) {
                $carousel.parent().find('a, img').remove(); //reset what last channel did
                if(channelData.carousel) {
                    $carousel.parent().css({'width': '670px', 'height': '286px'});
                    if(channelData.carousel == 'carousel') {
                        $carousel.css({'width': '670px', 'height': '286px'});
                    }
                    if(channelData.carousel == 'image') {
                        $carousel.css({'width':0, 'height':0}); //DON'T do a simple hide(), as firefox unloads swf when hidden
                        if(channelData.carouselImg) {
                            var $image = $('<img src="'+channelData.carouselImg+'" alt="" />');
                            if(channelData.carouselImgLink) {
                                if(channelData.carouselImgLink.substring(0,7) != 'http://') {
                                    $image.wrap('<a href="'+channelData.carouselImgLink+'" class="KH-link" target="pageContent"></a>');
                                } else {
                                    $image.wrap('<a href="'+channelData.carouselImgLink+'" target="_blank"></a>');
                                }
                                $image = $image.parent();
                            }
                            $carousel.parent().append($image);
                        }
                    }
                } else {
                    $carousel.parent().css({'width':0, 'height':0, 'overflow':'hidden'});
                }
            }
            //logged-in, showing box
            if($box.length) {
                if(channelData.carousel == 'carousel') { //we don't care about carousel='image'
                    $box.css({'width':500, 'height':134});
                } else {
                    $box.css({'width':0, 'height':0});
                }
            }
            this.currentChannelData = channelData;
        }
    },

    //called by copy2clip.swf
    getCurrentUrl: function() {
        return $('#urlcopy .url').val();
    },
    urlCopyComplete: function() {
        $('#urlcopy .arrow').click();
        $.KH.info('URL wurde in die Zwischenablage kopiert.');
    },

    //rating called from webplayer
    rating: function(trackId, stars) {
        webplayer = $('#player').get(0);
        $.KH.ajax({
            url: '/user/votetrack/track_id/'+trackId+'/stars/'+stars,
            dataType: 'json',
            success: function(data){
                if(data.success) {
                    webplayer.ratingComplete({type:'success', msg:data.msg, stars:data.voteavg});
                } else {
                    webplayer.ratingComplete({type:'error', msg:data.msg});
                }
            }
        });
    },

    //add to playlist, called on 'playlist' tab or by webplayer
    addToPlaylist: function(trackId, isWebplayer) {
        var url = '/user/addtrack/trackID/'+trackId;
        if(isWebplayer) {
            webplayer = $('#player').get(0);
            $.KH.ajax({
                url: url,
                dataType: 'json',
                success: function(data){
                    if(!data.error) {
                        webplayer.addtoplaylistComplete({type:'success', msg:data.msg});
                        $.KH.refreshPage('/user/playlist');
                    } else {
                        webplayer.addtoplaylistComplete({type:'error', msg:data.msg});
                    }
                }
            });
        } else {
            $.KH.ajax({
                url: url,
                dataType: 'json',
                element: $('#KH-addTrack'),
                success: function(data){
                    if(data.error) {
                        $.KH.error(data.msg, 3);
                    } else {
                        $.KH.info(data.msg, 3);
                        $('#KH-playlistTab').click();
                    }
                }
            });
        }
    },

    reloadLogin: function(options) {
        if (!options) {
            options = {};
        }

        options.param = options.param || '';

        var $login = $('#login');

        $.KH.ajax({
            url: '/auth/index' + options.param,
            element: $login,
            success: function(data){
                $login.html(data);

                if (options.onSuccess) {
                    options.onSuccess();
                }
            }
        });
    },

    //move login box into focus (position under current content)
    moveLogin: function($target, strParam){
        if (typeof(strParam) == 'undefined' || String(strParam) == 'undefined')
            strParam = '';
        var posX, posY;
        var $login = $('#login');
        $loginForm = $('form', $login);
        $loginForm.attr('action', $loginForm.attr('action') + strParam);

        if($target) {
            $login.data('origPos', {x: $login.offset().left, y: $login.offset().top})
            posX = $target.offset().left + 80;
            posY = $target.offset().top + $target.height();
            $login.animate({left: posX, top: posY}, 700, '', function(){
                //was logged-in, but session expired? then reload login form
                if($login.data('logged-in')) {
                    $.KH.reloadLogin({param: strParam});
                }
            });
        } else {
            //return to original position
            loginPos = $('#login').data('origPos');
            if(!loginPos) return; //login box must save it's orig position before moving around. data is removed when returning to original position
            posX = loginPos.x;
            posY = loginPos.y;
            $login.animate({left: posX, top: posY}, 700);
        }
    },

    //options for jquery uploadify, globally defined for reuse
    uploadifyOptions: {
        'uploader'   : '/swf/uploadify.swf', //do not use _webPath here, cause uploadify works only for same Domain (and should so because of security reasons)
        'script'     : '/uploadify/uploadify.php',
        'cancelImg'  : _webPath+'/images/nao.png',
        'folder'     : '/uploadify/uploads',
        'auto'       : true,
        'multi'      : false,
        'sizeLimit'  : 2*1024*1024 //2mb
    },

    //hacking tracking! _oewaTag is set in footer when (re)loading #pageContent
    tracking: function(){
        //ga
        //get current url (_trackPageview doesn't honor hash-urls when called without url param)
        var gaUrl;
        if(location.hash == '') gaUrl = location.pathname;
        else gaUrl = location.hash; //.replace('#','');
        if(window['_trackGA'] !== undefined && _trackGA) {
            _pageTracker._trackPageview(gaUrl);
        }
        //oewa
        //this is a hacked version of the official OEWA Tag, we're just loading the image to track the hit
        if(window['_oewaTag'] !== undefined && _oewaTag != '') {
            var img = new Image();
            img.src = _oewaTag + '?r=' + escape(document.referrer) + '&d=' + (new Date()).getTime();
        }
    },

    //configuration of a 'site' (pageContent contents), such as oewaTag or background image
    siteConfig: function() {
        //get config info from footer
        var config = $('#KH-siteConfig').val().split('|'); //oewaTag|trackGA|themeImg|skyscraperUrl|skyscraperPosY
        _oewaTag = config[0];
        _trackGA = (config[1] == '1')?true:false;
        $('#theme').css('background-image', 'url('+config[2]+')');
        $('#KH-skyscraper').attr('rel', config[3]); //lazy loading of skyscraper iframe via $.KH.loadAdtagIframes
        $('#skyscraper').css('top', config[4]+'px');

        // testing iframe resizing for expandable banners here. working, but missing 'onresize' event atm.
        // maybe we'll implement this later on, refs #726
        /*
        var vpW = $(window).width();
        var vpH = $(window).height();
        var $sky = $('#KH-skyscraper');
        var off = $sky.offset(); console.log(off);
        var newW = vpW - off.left;
        var newH = vpH - off.top;
        $sky.css({width:newW, height:newH, background:'red'});
        */

        $.KH.adtagIframeConditions.skyscraper_ready = true;
        $.KH.loadAdtagIframes();
    },

    //iframes with adtags are 'lazy-loaded', siteConfig sets a 'rel' attribute on them containing the target url
    loadAdtagIframes: function(npbt_ready, skyscraper_ready){
        //as the script loading the npbt variable is executed asynchronous, we wait for alle conditions to be met first
        if($.KH.adtagIframeConditions.npbt_ready && $.KH.adtagIframeConditions.skyscraper_ready) {
            //look for iframes with adtags and load them
            var $fullBanner = $('#KH-fullBanner');
            var $contentAd = $('#KH-contentAd');
            var $skyscraper = $('#KH-skyscraper');
            try{
                //don't simply set attr('src') to the new value, as this would trigger the history and break the backbutton for the overall site
                //ff adblock plugin might crash here, see #488
                if($fullBanner.length) $fullBanner.get(0).contentWindow.location.replace($fullBanner.attr('rel'));
                if($contentAd.length) $contentAd.get(0).contentWindow.location.replace($contentAd.attr('rel'));
                if($skyscraper.length) $skyscraper.get(0).contentWindow.location.replace($skyscraper.attr('rel'));
            } catch(e){}
            //reset conditions
            $.KH.adtagIframeConditions.npbt_ready = false;
            $.KH.adtagIframeConditions.skyscraper_ready = false;
        }

    },

    //conditions for loading of adtags inside iframe
    adtagIframeConditions: {
        npbt_ready: false, //npbt variable is loaded in a nugg.ad script in footer
        skyscraper_ready: false //skyscraper iframe needs a url in the 'rel' attribute, which is set via siteConfig
    },

    /**
     * Default set to disabled Facebook object, later initialized by $.KH.FacebookInit.
     * @type Facebook
     */
    facebook: new Facebook(null, {disable: true}),

    /**
     * Initializes $.KH.facebook.
     * @param appId
     * @param options
     */
    FacebookInit: function (appId, options) {
        $.KH.facebook = new Facebook(appId, options);
        $.KH.facebook.onAuthChange = function(response) {
            $.KH.ajax({
                url: '/auth/fbauthchange',
                type: 'post',
                success: function(data){
                    // TODO: eg refresh page or facebook elements
                },
                dataType: 'json'
            });
        };
    },

    FacebookLoginHandler: function(options) {
        if (!options) {
            options = {};
        }

        options.successUrl = options.successUrl || null;

        var strParam = '';
        if ($("input[name=remember]").attr('checked')) {
            strParam += 'remember/1';
        }

        $.KH.ajax({
            url: '/auth/fblogin/' + strParam,
            type: 'post',
            success: function(data){
                if(data.success) {
                    if (data.special == 'votetrack') {
                        $.KH.info('Du kannst jetzt den Song bewerten');
                    } else if (data.special == 'addtrack') {
                        $.KH.info('Du kannst jetzt den Song zur Playlist hinzufügen');
                    }
                    $('#login').html(data.html);

                    function redirectHandler() {
                        // eg activation -> fblogin -> back to activation
                        if (options.successUrl && options.successUrl !== '') {
                            $.KH.refreshPage(options.successUrl);
                            return;
                        }

                        var currentUrlArr = location.href.split('#');
                        var currentUrl = (currentUrlArr.length>1) ? currentUrlArr[1] : currentUrlArr[0];
                        if (currentUrl.indexOf('auth/') == -1)
                            $.KH.refreshPage(currentUrl); //refresh pageContent to current page
                        else
                            $.KH.refreshPage('/user/user'); // if we are on an auth-page redirect to user/user
                    }

                    // if user has not set publish right yet, show settings dialog and then continue
                    if (data.notSetFacebookPublish) {
                        $.KH.FacebookSettingsDialog(redirectHandler);
                    } else {
                        redirectHandler();
                    }
                } else {
                    if (data.error === 'connect') {
                        var $dialogConnect = $('#dialogFbConnect');

                        $dialogConnect.dialog({
                            resizable: false,
                            draggable: false,
                            bgiframe: true,
                            width: 400,
                            height: 200,
                            modal: true,
                            title: 'Facebook Connect',
                            open: function(){
                                $dialogConnect.find('a').click(function(e) {
                                    if ($(this).hasClass('login')) {
                                        e.preventDefault();
                                        $("input[name='fbconnect']").val("true");
                                        $.KH.refreshPage('/auth/pleaselogin/');
                                        $dialogConnect.dialog('destroy');
                                        return false;
                                    } else {
                                        $dialogConnect.dialog('destroy');
                                    }
                                });
                            },
                            close: function() { //always destroy on close
                                $dialogConnect.dialog('destroy');
                            }
                        });
                    } else if (data.error === 'login') {
                        // not logged into facebook
                        $.KH.error(data.info);
                    } else if (data.error === 'loggedIn') {
                        $.KH.reloadLogin({
                            onSuccess: function() {
                                $.KH.refreshPage(data.redirect);
                            }
                        });
                    } else {
                        $.KH.error(data.info);
                        //shake head
                        var posx = $('#login').offset().left;
                        var dist = 10;
                        var time = 50;
                        $('#login')
                            .animate({left: posx+dist}, time)
                            .animate({left: posx-dist}, time)
                            .animate({left: posx+dist}, time)
                            .animate({left: posx-dist}, time)
                            .animate({left: posx+dist}, time)
                            .animate({left: posx-dist}, time)
                            .animate({left: posx}, time)
                        ;
                    }
                }
            },
            dataType: 'json'
        });

        return false;
    },

    FacebookDisconnect : function() {
        $.KH.ajax({
            url: '/auth/fbdisconnect/',
            type: 'post',
            async: false, // see success()-NOTE
            success: function(data){
                if(data.success) {
                    $.KH.info(data.success);
                    // NOTE: don't know why, but without queuing it fails
                    setTimeout(function(){$.KH.refreshPage('/user/settings/');},0);
                } else {
                    $.KH.error(data.error);
                }
            },
            dataType: 'json'
        });

        return false;
    },

    FacebookConnect: function(options) {
        if (!options) {
            options = {};
        }

        options.successUrl = options.successUrl || null;

        $.KH.ajax({
            url: '/auth/fbconnect/',
            type: 'post',
            success: function(data){
                if(data.success) {
                    $.KH.info(data.success);

                    if (options.successUrl && options.successUrl !== '') {
                        $.KH.refreshPage(options.successUrl);
                        return;
                    }

                    var currentUrlArr = location.href.split('#');
                    var currentUrl = (currentUrlArr.length>1) ? currentUrlArr[1] : currentUrlArr[0];
                    if (currentUrl.length == 0 || _webPath+'/' == currentUrl) {
                        currentUrl = '/index/index';
                    }
                    $.KH.refreshPage(currentUrl); //refresh pageContent to current page
                } else {
                    $.KH.error(data.error);
                }
            },
            dataType: 'json'
        });
        return false;
    },

    FacebookSettingsDialog: function(callback) {
        var $dialogSettings = $('#dialogFbSettings');

        function closeDialog(settingsSaved) {
            $dialogSettings.dialog('destroy');
            callback(settingsSaved);
        }

        $dialogSettings.dialog({
            resizable: false,
            draggable: false,
            bgiframe: true,
            width: 400,
            height: 200,
            modal: true,
            title: 'Facebook Settings',
            buttons: {
                'Ja': function() {
                    $.KH.facebook.getPermissions('publish_stream',
                        function() {
                            $.KH.error('Um Beiträge automatisch auf Facebook posten zu können, musst Du den benötigten Zugriff auf dein Facebook-Profil durch kronehit.at erlauben.');
                        },
                        function() {
                            $.KH.ajax({
                                url: '/user/fbsettings/',
                                data: 'publish=1',
                                type: 'post',
                                success: function(data){
                                    if(data.success) {
                                        closeDialog(true);
                                    } else {
                                        $.KH.error(data.error);
                                        closeDialog(false);
                                    }
                                },
                                dataType: 'json'
                            });
                        }
                    );
                },
                'Nein': function() {
                    $.KH.ajax({
                        url: '/user/fbsettings/',
                        data: 'publish=0',
                        type: 'post',
                        success: function(data){
                            if(data.success) {
                                closeDialog(true);
                            } else {
                                $.KH.error(data.error);
                                closeDialog(false);
                            }
                        },
                        dataType: 'json'
                    });
                }
            },
            close: function() { //always destroy on close
                closeDialog(false);
            }
        });
    },

    FacebookShareDialog: function(yesCallback, noCallback) {
        var $dialogSettings = $('#dialogFbShare');

        $dialogSettings.dialog({
            resizable: false,
            draggable: false,
            bgiframe: true,
            width: 250,
            height: 100,
            modal: true,
            title: 'Facebook',
            buttons: {
                'Ja, senden': function() {
                    yesCallback();
                    $dialogSettings.dialog('destroy');
                },
                'Lieber nicht': function() {
                    noCallback();
                    $dialogSettings.dialog('destroy');
                }
            },
            close: function() { //always destroy on close
                noCallback();
                $dialogSettings.dialog('destroy');
            }
        });
    }

};

