(function($)
{
    /*
     *   fb_geturl // this value is used for getting comments on the current clip
     *   fb_posturl // this valie is used for for posting comments to Disqus
     *   fb_user // the logged in users Facebook user-ID
     *   fb_gotcomments // needed so that Facebook doesn't perform double gets (bad for performance) :(
     *   fb_postedcomment // needed so that Facebook doesn't perform double posts (bad for moral) :(
     *   fb_loggedin // value holding if the users is currently logged in or not
     *   accordionLoaded // accordion only needs to be set once
     *   currentTimestamp // holds the timestamps value for when the current page was rendered
     *   currentComment // the clip ID / external content ID for the current clip, used to get comments from Facebook when filtering on friends tab
     *   postScopePrivate // this value represents if the post that is made is privat or not (perhaps for future use when filtering on friends tab
     *   pageSelfUrl // the current page's URL, used for login and log out
     *
     */
    $.extend($.fn, {
        exists: function(fn) {
            var l = this.length;
            if ($.isFunction(fn)) {
                if (l > 0) fn.apply(this);
                return this;
            } else {
                return (l > 0) ? true : false;
            }
        }
    });
    $.fbc =
    {
        constants:
        {
            fb_geturl: null,
            fb_posturl: null,
            fb_user: false,
            fb_gotcomments: false,
            fb_postedcomment: false,
            fb_loggedin: false,
            accordionLoaded: false,
            currentTimestamp: null,
            currentComment: null,
            postScopePrivate: false,
            pageSelfUrl: null,
            allURLS: false,
            commentsCurrentHeight: null,
            changedTab: false
        },
        functions:
        {
            followURL: function(followurl)
            {
                // this function is used for login and logout page reload
                window.location = followurl;
                return false;
            },
            getCommentTime: function(timestamp)
            {
                //Function to render "human readable" nice Facebook-ish timestamps for the comments
                var diff = $.fbc.constants.currentTimestamp - timestamp;

                var allMinutes = parseInt(diff / 60);
                var allHours = parseInt(allMinutes / 60);
                var allDays = parseInt(allHours / 24);

                var minutes = parseInt(allMinutes % 60);
                var hours = parseInt(allHours % 24);
                var days = parseInt(allDays % 365);
                var years = parseInt(allDays / 365);

                var formatedTime;

                if (years > 0) {
                    formatedTime = "f&ouml;r" + years + " &aring;r";
                    if (days > 0) {
                        formatedTime += " och " + days + (days > 1 ? " dagar sedan" : " dag sedan");
                    } else {
                        formatedTime += " sedan";
                    }
                } else if (days > 0) {
                    formatedTime = "f&ouml;r " + days + (days > 1 ? " dagar" : " dag");
                    if (hours > 0) {
                        formatedTime += " och " + hours + (hours > 1 ? " timmar sedan" : " timme sedan");
                    } else {
                        formatedTime += " sedan";
                    }
                } else if (hours > 0) {
                    formatedTime = "f&ouml;r " + hours + (hours > 1 ? " timmar" : " timme");
                    if (minutes > 0) {
                        formatedTime += " och " + minutes + (minutes > 1 ? " minuter sedan" : " minut sedan")
                    } else {
                        formatedTime += " sedan";
                    }
                } else if (minutes > 0) {
                    formatedTime = "f&ouml;r " + minutes + " minuter sedan";
                } else {
                    formatedTime = "f&ouml;r sekunder sedan";
                }
                return formatedTime;
            },
            getScope: function()
            {
                // Function that tells us which scope we're in/which accordion tab is active
                return $("#fbconnect div.accordion-tab.selected").attr("id");
            },
            showIntro: function()
            {
                // Display the "Please login"-introduction box
                $("#fbconnect div.accordion-tab.selected div.introduction").show();
                $("#fbconnect div.accordion-tab.selected div.introduction img.title").show();
            },
            updateIntro: function()
            {
                // Change the title-image inside the introduction box if no comments exists
                $("#fbconnect div.accordion-tab.selected div.introduction img.title").attr("src", IMAGE_PATH + '/text/header-first.gif');
                $("#fbconnect div.accordion-tab.selected div.introduction").show();
                $("#fbconnect div.accordion-tab.selected div.introduction img.title").show();
            },
            checkURLS: function()
            {
                if (!$.fbc.constants.currentComment || !$.fbc.constants.pageSelfUrl || !$.fbc.constants.fb_geturl || !$.fbc.constants.fb_geturlcategory || !$.fbc.constants.fb_geturlsite || !$.fbc.constants.fb_posturl)
                {
                    $.fbc.functions.allURLS = false;
                }
                else
                {
                    $.fbc.functions.allURLS = true;
                }
            },
            updateTimeStamp: function() {
                $.get($.fbc.constants.nowActionUrl, "", function(result) {
                    $.fbc.constants.currentTimestamp = result.timestamp;
                }, "json");
            },
            resetScrollview: function()
            {
                // this function resets the jScrollPane so that it has the proper height
                var $toHeight = $('#fb-content')[0].commentHeight;
                var $introHeight = $("#fb-content .accordion-tab.selected div.introduction").outerHeight(true);
                var $tabHeight = $("#fb-content .accordion-tab.selected ul.fb-tabs").outerHeight(true);
                if (!$.fbc.constants.fb_loggedin)
                {
                    $toHeight -= ($introHeight + 5);
                } else {
                    $toHeight -= $tabHeight;
                }

                $('#fb-content .accordion-tab.selected div.comments').height($toHeight);
                $('#fb-content .accordion-tab.selected div.comments').jScrollPane({
                    scrollbarMargin: 5,
                    maintainPosition: true,
                    reinitialiseOnImageLoad: true
                });
            },
            updateCommentsHeight: function()
            {
                var $commentHeight = $('#fb-content .accordion-tab.selected div.comments').height();
                setTimeout('$.fbc.functions.updateCommentsHeight()', 3000);
                if ($.fbc.constants.changedTab) {
                    $.fbc.constants.commentsCurrentHeight = $commentHeight;
                    $.fbc.functions.resetScrollview();
                }
                if ($commentHeight != $.fbc.constants.commentsCurrentHeight)
                {
                    $.fbc.constants.commentsCurrentHeight = $commentHeight;
                    $.fbc.functions.resetScrollview();
                }
                $.fbc.constants.changedTab = false;
            }
        }
    };

    // jQuery document ready
    $(function()
    {
        // get the value from the hidden input, used to login and logout the user. reload the page with this value
        // $.fbc.constants.pageSelfUrl = $("#pageSelfUrl").val();
        $.fbc.constants.pageSelfUrl = document.location;

        // get the value from the hidden input, used for rendering "human readable" timestamps on comments fetched from Facebook
        $.fbc.constants.currentTimestamp = $("#rendertimestamp").val();

        // get the value from the hidden input, used for getting updated value when rendering "human readable" timestamps on comments fetched from Facebook
        $.fbc.constants.nowActionUrl = $("#nowUrl").val();

        // get the value from the hidden input, the main get URL used for getting comments from Disqus
        $.fbc.constants.fb_geturl = $("#getUrl").val();

        // get the value from the hidden input, the get URL for the current category, used when loading that accordion tab
        $.fbc.constants.fb_geturlcategory = $("#categoryListUrl").val();

        // get the value from the hidden input, the get URL for the main site, used when loading that accordion tab
        $.fbc.constants.fb_geturlsite = $("#siteListUrl").val();

        // get the value from the hidden input, the main post URL for the current clip, used when posting to Disqus
        $.fbc.constants.fb_posturl = $("#postUrl").val();

        // get the value from the hidden input, get the external id (ie the current clips id), used for fetching comments from Facebook on this clip id (used only for the friend filter)
        $.fbc.constants.currentComment = $("#identifier").val();

        // bind the login action to the login button. requireSession is called as a callback when the user has logged in
        $("#fbconnect .fbloginbutton").click(function()
        {
            FB.Connect.requireSession(function()
            {
                $("#fbintro").hide();
                // reload the page
                setTimeout('$.fbc.functions.followURL($.fbc.constants.pageSelfUrl)', 2000);
                return false;
            });
            return false;
        });

        // re-render comments when clicking "from all"/"from friends"-tabs
        $('ul.fb-tabs li a').click(function()
        {
            $parent = $(this).parent();
            if ($parent.is(".selected"))
            {
                return false;
            }
            $(this).parents('ul.fb-tabs').find('li').removeClass('selected');
            $parent.addClass('selected');
            $.fbc.constants.fb_gotcomments = false;
            if ($(this).parent().is(".tab-friends"))
            {
                $("#privateComment").val("1");
                $.fbc.constants.postScopePrivate = true;
                $.fbc.constants.changedTab = true;
                getFBComments();
            } else
            {
                $("#privateComment").val("0");
                $.fbc.constants.postScopePrivate = false;
                $.fbc.constants.changedTab = true;
                getDBComments();
            }
            $(this).blur();
            return false;
        });

        // bind hover function to loginbutton
        $("#fbconnect .fbloginbutton").hover(function()
        {
            $(this).addClass("login-hover");
        },
                function()
                {
                    $(this).removeClass("login-hover");
                });

        // this function resets the height of the contents inside the accordion tab being loaded
        $("#fbconnect div.accordion-tab h3:not('.selected')").click(function()
        {
            var $parent = $(this).parent();
            var $scope = $parent.attr("id");
            $toheight = $('#fb-content')[0].commentHeight;
            if ($scope != "act-1")
            {
                // add 30 since tabs are missing on all tabs but the first/clips
                $toheight += 30;
            }
            $("#" + $scope + " div.content").height($toheight);
        });
    });
})(jQuery);

// Functions within easy reach outside of jQuery (could be re-written later)
// Function that runs when the user is not logged in
function setNotLoggedIn()
{
    if ($.fbc.constants.fb_loggedin)
    {
        // this state occurs when the user has logged out via the comments module, we then reload the page for the logout to be properly executed and the module reset
        $.fbc.constants.fb_gotcomments = false;
        $("#fbmodule, #fb-tabs-clip").hide();
        setTimeout('$.fbc.functions.followURL($.fbc.constants.pageSelfUrl)', 2000);
        return false;
    }
    $.fbc.constants.fb_loggedin = false;
    $.fbc.functions.showIntro();
    setStandardEvents();
    $.fbc.functions.updateCommentsHeight();
    getDBComments($.fbc.functions.getScope());
}
// Function that runs when the user has logged in
function setLoggedIn()
{
    $.fbc.constants.fb_loggedin = true;
    $.fbc.constants.fb_user = FB.Facebook.apiClient.get_session().uid;
    setStandardEvents();
    setPostEvent();
    $("#fbmodule, #fb-tabs-clip").show();
    if ($.browser.msie && $.browser.version == "6.0")
    {
        $("#iesucks").show();
    }
    $.fbc.functions.updateCommentsHeight();
    getDBComments($.fbc.functions.getScope());
}
function setStandardEvents()
{
    setAccordion();
    $.fbc.functions.checkURLS();
}
function setPostEvent()
{
    // Set this function to run when a comment is posted via the Facebook FB:comments module
    FB.CommentClient.add_onComment(function(result)
    {
        if (!$.fbc.constants.fb_postedcomment)
        {
            $.fbc.constants.fb_postedcomment = true;
            postCustomComment(result);
        }
    });
}
// Sets the accordion plugin to the module and sets height to the tabs and its contents
function setAccordion()
{
    if (!$.fbc.constants.accordionLoaded)
    {
        $.fbc.constants.accordionLoaded = true;
        $('#fb-content').tv4accordion({
            init: function()
            {
                var $toHeight = $('#fb-content')[0].commentHeight;
                $('#fb-content .accordion-tab').css("visibility", "visible");
                var $introHeight = $("#fb-content .accordion-tab.selected div.introduction").outerHeight(true);
                var $tabHeight = $("#fb-content .accordion-tab.selected ul.fb-tabs").outerHeight(true);
                if (!$.fbc.constants.fb_loggedin)
                {
                    $toHeight -= ($introHeight + 5);
                } else {
                    $toHeight -= $tabHeight;
                }
                $('#fb-content .accordion-tab.selected div.comments').height($toHeight);
                $('#fb-content .accordion-tab.selected div.comments').jScrollPane({
                    scrollbarMargin: 5,
                    maintainPosition: true,
                    reinitialiseOnImageLoad: true
                });
            },
            complete: function()
            {
                getTabComments();
            },
            easing: 'easeOutQuint',
            duration: 700
        });
    }
}
// This function renders markup for the comments fetched from Facebook
function getUserComment(val)
{
    if ($.fbc.constants.fb_loggedin) {
        return '<li><div class="photo"><fb:profile-pic size="square" uid="' + val.fromid + '" facebook-logo="true"></fb:profile-pic></div><p class="comment"><span class="username"><fb:name useyou="false" uid="' + val.fromid + '"></fb:name></span><span class="comment-body">' + val.text + '</span><span class="timestamp">' + $.fbc.functions.getCommentTime(val.time) + '</span></p></li>';
    } else {
        return '<li><div class="photo"><fb:profile-pic linked="false" size="square" uid="' + val.fromid + '" facebook-logo="true"></fb:profile-pic></div><p class="comment"><span class="username"><fb:name useyou="false" firstnameonly="true" linked="false" uid="' + val.fromid + '"></fb:name></span><span class="comment-body">' + val.text + '</span><span class="timestamp">' + $.fbc.functions.getCommentTime(val.time) + '</span></p></li>';
    }
}
// Get comments for the current accordion tab being displayed. Called from the accordion plugin callback
function getTabComments()
{
    if (!$.fbc.constants.allURLS)
    {
        $.fbc.constants.fb_gotcomments = false;
        var $tab = $("#fb-content div.accordion-tab.selected");
        var $scope = $tab.attr("id");
        if (!$.fbc.constants.fb_loggedin) {
            $tab.find("div.introduction").show();
            $tab.find("div.introduction img.title").show();
        }
        $.fbc.constants.changedTab = true;
        getDBComments($scope);
    }
}
// Get comments for scope from Database
function getDBComments(scope) {
    if (!$.fbc.constants.fb_gotcomments) {
        $.fbc.constants.fb_gotcomments = true;
        if ($.fbc.constants.fb_loggedin) {
            $getoptions = { linked: "1" }
        } else {
            $getoptions = { linked: "0" }
        }
        // which comment-set are we asking for
        if (scope == "act-3") {
            $geturl = 'http://www.tv4.se' + $.fbc.constants.fb_geturlsite;

            $getoptions = { linked: "0" };

            var forum_id = $("#forumId").val()
            var getSiteUrl = $("#getSiteCommentsUrl").val()

            $.get(getSiteUrl + "?forum_id=" + forum_id, $getoptions, function(resultdata) {
                if (resultdata.length == 0) {
                    if (!$.fbc.constants.fb_loggedin) {
                        $.fbc.functions.updateIntro();
                    } else {
                        if (!$("#" + scope + " .commentlist p.first-post").exists()) {
                            $("#" + scope + " .commentlist").empty();
                            var o = $('<p class="first-post">Det finns inga kommentarer än. Bli först med att kommentera!</p>');
                            $("#" + scope + " .commentlist").append(o);
                        }
                    }

                } else {

                    $("#" + scope + " .commentlist").empty();
                    $resultlist = $("<ul></ul>");

                    $resultlist.html(resultdata);
                    $("#" + scope + " .commentlist").append($resultlist);

                    $.fbc.constants.fb_postedcomment = false;
                    // Parse the DOM again, enabling Facebook to render its XFBML components
                    FB.XFBML.Host.parseDomTree();
                    // Reset the jScrollPane
                    $.fbc.functions.resetScrollview();
                }

            });
            return false;
        } else {
            scope = "act-1";
            $geturl = 'http://www.tv4.se' + $.fbc.constants.fb_geturl;
        }
        var thread_identifier = $("#identifier").val()
        var thread_title = $("#title").val()
        var getUrl = $("#getUrl").val()
        var videoUrl = $("#videoRef").val()

        $getoptions = { linked: "0" };
        $.get(getUrl + "?title=" + thread_title + "&identifier=" + thread_identifier + "&url=" + videoUrl, $getoptions, function(resultdata) {
            if (resultdata.length == 0) {
                if (!$.fbc.constants.fb_loggedin) {
                    $.fbc.functions.updateIntro();
                } else {
                    if (!$("#" + scope + " .commentlist p.first-post").exists()) {
                        $("#" + scope + " .commentlist").empty();
                        var o = $('<p class="first-post">Det finns inga kommentarer än. Bli först med att kommentera!</p>');
                        $("#" + scope + " .commentlist").append(o);
                    }
                }


            } else {

                $("#" + scope + " .commentlist").empty();
                $resultlist = $("<ul></ul>");

                $resultlist.html(resultdata);
                $("#" + scope + " .commentlist").append($resultlist);

                $.fbc.constants.fb_postedcomment = false;
                // Parse the DOM again, enabling Facebook to render its XFBML components
                FB.XFBML.Host.parseDomTree();
                // Reset the jScrollPane
                $.fbc.functions.resetScrollview();
            }

        });
    }
}

// Get comments from Facebook on the current clip. Can also get comments for "show all"-tab but this is not used currently
function getFBComments() {

    if (!$.fbc.constants.fb_gotcomments)
    {
        $.fbc.constants.fb_gotcomments = true;
        $.fbc.functions.updateTimeStamp();
        if ($.fbc.constants.postScopePrivate)
        {
            // friends only

            var commentsquery = "SELECT xid, fromid, time, text, id, reply_xid FROM comment WHERE xid='" + $.fbc.constants.currentComment + "' AND (fromid IN (SELECT uid2 FROM friend WHERE uid1 = " + $.fbc.constants.fb_user + ") OR fromid=" + $.fbc.constants.fb_user + ") LIMIT 8";
        } else
        {
            // all comments
            var commentsquery = "SELECT xid, fromid, time, text, id, reply_xid FROM comment WHERE xid='" + $.fbc.constants.currentComment + "' LIMIT 8";
        }
        FB.Facebook.apiClient.fql_query(commentsquery,
                function(result, exception)
                {
                    if (result) {
                        $("#commentlist-clip").empty();
                        $resultlist = $("<ul></ul>");
                        $.each(result, function(key, val) {
                            $resultlist.append(getUserComment(val));
                        });
                        $("#commentlist-clip").append($resultlist);
                        $.fbc.constants.fb_postedcomment = false;
                        // Re-render the DOM
                        FB.XFBML.Host.parseDomTree();
                        // Refresh jScrollPane
                        $.fbc.functions.resetScrollview();
                    }
                });
    }
}
// Post a comment to the database, this function is called from the Facebook "add_onComment"-callback. The result-object is the result from Facebook
function postCustomComment(result) {
    var thread_identifier = $("#identifier").val()
    var thread_title = $("#title").val()
    var show_name = $("#tv4CategoryName").val()
    var postUrl = $("#postUrl").val()
    var getUrl = $("#getUrl").val()
    var videoUrl = $("#videoRef").val()

    $("#act-1 .commentlist").empty();
    $resultlist = $("<ul></ul>");
    $parameters = {title:thread_title, identifier:thread_identifier, message:result.post, authorName:show_name, authorEmail:result.user, url:videoUrl}

    $.post(postUrl, $parameters, function(data) {
        $.ajax({
            url: getUrl + "?title=" + thread_title + "&identifier=" + thread_identifier + "&url=" + videoUrl,
            success: function(data) {
                $.fbc.constants.fb_gotcomments = false;
                if ($.fbc.constants.postScopePrivate) {
                    // we're on the "friends" tab
                    getFBComments();
                } else {
                    $resultlist.html(data);
                    $("#act-1 .commentlist").append($resultlist);
                    $.fbc.constants.fb_postedcomment = false;
                    // Parse the DOM again, enabling Facebook to render its XFBML components
                    FB.XFBML.Host.parseDomTree();
                    // Reset the jScrollPane
                    $.fbc.functions.resetScrollview();
                }
            }
        });
    });
}
// This function is called after posting a comment, this is to render the latest comments returned from the post-page
function displayResult(result)
{
    $("#act-1 .commentlist").empty();
    $resultlist = $("<ul></ul>");
    $resultlist.append(result);
    $("#act-1 .commentlist").append($resultlist);
    $.fbc.constants.fb_postedcomment = false;
    // Parse the DOM again, enabling Facebook to render its XFBML components
    FB.XFBML.Host.parseDomTree();
    // Reset the jScrollPane
    $.fbc.functions.resetScrollview();
}