//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(){
    //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("Ajax Request fehlgeschlagen.");
        }
    });

    //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('/')), '');
        }
        $.KH.ajax({
            url: href,
            element: $("#"+$(this).attr('target')),
            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(e.path != '/') {
            if(_historyLive) targetUrl = e.path;
        } else targetUrl = location.href;
        //load #pageContent contents
        if(targetUrl) {
            $.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
    });

    //init webplayer
    var flashvars = {
        channelId: "0", //play this channel on startup. optional. default: 0
        xmlChannels: "/player/channel", //required. default: "data/channels.xml"
        xmlPodcasts: "/player/podcasts", //required. default: "data/podcasts.xml"
        scriptRating: "$.KH.rating", //DISABLE: set to empty string (disables click handler for stars in player)
        scriptAddToPlaylist: "$.KH.addToPlaylist", //DISABLE: set to empty string (hides 'add' icon)
        scriptRecommend: "/player/recommendsong", //default: "recommend.php". DISABLE: set to empty string (hides 'weiterempfehlen')
        stringRecommend: "höre gerade '[SONG]' von '[ARTIST]' auf '[CHANNEL]', einem der KRONEHIT Webchannels auf kronehit.at." //default: "[SONG] - [ARTIST] - [CHANNEL]"
    };
    swfobject.embedSWF("/swf/webplayer.swf", "player", "310", "378", "9.0.0", null, flashvars, {wmode:'opaque'}, null,
        function(e){
            if(!e.success) {
                $('#artistcarousel').hide();
                $('#modbox').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.mira4.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'});
            //load moderator box
            var flashvars = {
                xmlModbox: "/content/modbox",
                slideDelay: 7
            };
            swfobject.embedSWF("/swf/modbox.swf", "modbox", "500", "178", "9.0.0", null, flashvars, {wmode:'opaque'});
            //news category dropdown
            $('.boxKronehitNews .categories').change(function(){
                $.KH.ajax({
                    url: '/index/news/category/'+$(this).val()+'/smallcount/'+$(this).attr('rel'),
                    element: $('.boxKronehitNews .items'),
                    success: function(data){
                        $('.boxKronehitNews .items').html(data);
                    }
                });
            });
            $('#KH-activityStream').KH_activityStream();
        },

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

            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);
                            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);
                            //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() {
            var element = this;
            $(".textButton", this).click(function (){
                $.KH.ajax({
                    url: "/auth/logout",
                    success: function(data){
                        element.html(data); //render logged out state
                        $.KH.refreshPage(); //refresh to index page
                    },
                    element: element
                });
                return false;
            });
            element.data('logged-in', true);
        },

        KH_register: function() {
            var element = this;
            var form = $("#form_register",element);
            $("#button_register",element).click(function(){
                $.KH.ajax({
                    url: "/auth/register",
                    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() {
            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('/user/user');
                            $.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(response); //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 + '/' + response); //set uploadify-path and server filename (response) to hidden field to submit later on
                    $("#avatar_preview").empty().html('<img src="' + $.KH.uploadifyOptions.folder + '/' + response + '" 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(response); //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 + '/' + response); //set uploadify-path and server filename (response) to hidden field to submit later on
                    $("#modimage_preview").empty().html('<img src="' + $.KH.uploadifyOptions.folder + '/' + response + '" width="64" />'); //show temp image
                }
            }));
        },

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

            $("#button_settings",element).click(function(){
                $.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;
            });
        },

        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
                                $.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_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(response); //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 + '/' + response + '" 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(response); //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 + '/' + response + '" 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
                    $.KH.error("Bitte einen Musicbrainz Artist auswählen!");
                    return false;
                }

                $.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 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
            });

            //autocomplte on artistnames for related artists
            $("input[name=title_ra]", element).autocomplete('/artist/findmusicbrainzartist', {
                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() {
            //first step, answer questions
            $('.boxLotteryQuestion', this).each(function(i){
                var $box = $(this);
                if(i==0) $box.show();
                $('.textButton', $box).click(function(){
                    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();
                        }
                    } 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());
                $.KH.ajax({
                    url: $form.attr('action'),
                    data: $form.KH_serialize(),
                    type: 'POST',
                    element: $('#lottery'),
                    success: function(data){
                        if(data.success) {
                            $.KH.info(data.msg);
                            $('#lottery').html('<p class="message">'+data.msg+'</p>');
                        } else {
                            $('#lottery').html(data.html);
                        }
                    },
                    dataType: 'json'
                });
                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();
            }
            //helpers
            function loadUserdataForm() {
                $.KH.ajax({
                    url: '/content/lotterysubmit',
                    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;
            });
        },

        //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){
                        $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", 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;
            });
        },

        //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(response);
                    $("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(){
                    $.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);
                                $msg.blur();
                                $url.blur();
                            }
                            else {
                                $.KH.info(data.msg, 3);
                                $msg.val('').formclear();
                                $url.val('').formclear();
                                $updateTab.click(); //reload tab where message should appear
                                if ($updateTab.attr('id') == 'KH-storiesTab') {
                                    var $amount = $('#KH-storiesTab .slice.main span');
                                    var newAmount = parseInt($amount.text().replace(/(\(|\))/g, ''))+1;
                                    $amount.html('('+newAmount+')');
                                }
                            }
                        }
                    });
                    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;
                }
            });
            //'more' link
            /* a paging should be used instead in the future
            if($stream.children().length > 15) {
                $stream.children(':gt(14)').hide();
                $('<a href="#">mehr...</a>').click(function(){
                    var limitedHeight = $stream.height();
                    $stream.children().show(); //show all to get the total height
                    var totalHeight = $stream.height();
                    $stream.css({'height':limitedHeight, 'overflow':'hidden'});
                    $stream.animate({height:totalHeight}, {duration:1000, complete:function(){
                        $stream.css('height','auto'); //remove fixed height so expanding items (eg flickr images) in stream won't cut the whole stream
                    }});
                    $(this).remove();
                    return false;
                }).insertAfter($stream);
            }
            */
            //prepare comments
            $('.comments', $stream).each(function(){
                var $comments = $(this);
                var $activity = $comments.closest('li');
                $comments.KH_comments({$outerAddBtn: $('.comment', $activity)});
            });
        },

        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')) {
                            $.KH.ajax({
                                url: '/user/addcomment',
                                data: $('form', $addBox).serialize(),
                                type: 'post',
                                success: 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();
                                    }
                                },
                                dataType: 'json',
                                element: $addBox
                            });
                        }
                        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 still work
                if(!$target.closest('.KH-link').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(bShowWarning) {
            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' && bShowWarning) {
                    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 $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;
            });
        }
    });


    //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 {
            $.KH.ajax({
                url: $button.attr('href'),
                type: 'post',
                dataType: 'json',
                success: function(data){
                    $button.addClass('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+')');
                    }
                }
            });
        }
    }

    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);

$.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) {
        //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', {
            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();
                }
            },
            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);
    },

    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!
        moderatorTargets: Array('artistcarousel'),
        currentPlaylistXmlUrl: '',
        currentModeratorXmlUrl: '',
        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;
        },
        broadcastModerator: function(xmlUrl) { //called by modbox to trigger loading of a new moderator in artistcarousel
            for(index in this.moderatorTargets) {
                try { $('#'+this.moderatorTargets[index]).get(0).loadModerator(xmlUrl); }
                catch(e) {} //swf will call swfReady, so don't worry here
            }
            this.currentModeratorXmlUrl = 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);
            }
            //moderator: check wheter this is a valid target and there is already a xml to load (sent from modbox)
            var moderatorTargetIndex = $.inArray(targetString, this.moderatorTargets);
            if(moderatorTargetIndex != -1 && this.currentModeratorXmlUrl != '') {
                $('#'+targetString).get(0).loadModerator(this.currentModeratorXmlUrl);
            }
        },
        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;
        }
    },

    //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();
                    }
                }
            });
        }
    },

    //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.ajax({
                        url: '/auth/index' + strParam,
                        element: $login,
                        success: function(data){
                            $login.html(data);
                        }
                    });
                }
            });
        } 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(_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(_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');

        $.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
    }

};
