/*jshint asi: false, bitwise: true, boss: true, curly: true, debug: false, eqeqeq: true, eqnull: false, evil: false, forin: false, immed: true, laxbreak: false, maxerr: 50, newcap: true, noarg: true, noempty: true, nonew: true, nomen: false, onevar: true, passfail: false, plusplus: false, regexp: false, undef: true, sub: false, strict: true, white: true, jquery: true, browser: true */
/*globals FB: true, _gaq: true, ajaxurl: true */
(function ($) {
	"use strict";
	
	var fb_init     = false,
	    fb_script   = false,
	    multicaster = false,
        props       = {
            queue: [],
            init: false
        };

	function showMulticaster(api, href) {
		function messageConfirmation(response) {
            if (response && response.id) {
                $('#message').remove();
                $('.wrap h2').after('<div id="message" class="updated below-h2">Facebook post was published</div>');
            } else {
                $('#message').remove();
                $('.wrap h2').after('<div id="message" class="updated below-h2">Facebook post was not published</div>');
            }
        }

        function postFBFeed(formatted) {
            var url = formatted.url,
                description = formatted.content,
                token = formatted.token,
                target = formatted.target;

            if (target === 'me') {
                FB.api('/me/feed', 'post', {
                        message: $('#title').val(),
                        name: $('#site-title').html(),
                        caption: $('#title').val(),
                        description: description,
                        type: 'link',
                        link: url,			
                        actions: [{ name: 'Direct Link', link: url }]
                    },
                    function (response) {
                        messageConfirmation(response);
                    }
                );
            }
            else {   
                FB.api('/' + target + '/feed', 'post', { 
                        message: $('#title').val(),
                        access_token: token,
                        name: $('#site-title').html(),
                        caption: $('#title').val(),
                        description: description,
                        type: "link",
                        link: url,		  
                        actions: [{ name: 'Direct Link', link: url }]
                    },
                    function (response) {
                        messageConfirmation(response);
                    }
                );
            } 
        }

        function doPagePublish(target, token) {
            var data = {	
                action: 'multicast_facebook',
                href: href,
                content: $('#content').val(),
                target: target,
                fb_token: token
            };

            // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
            jQuery.post(ajaxurl, data, postFBFeed, 'json');
        }

        // handle a session response from any of the auth related calls
        function handleSessionResponse(response) {
            // if we dont have a session, just hide the user info  
            if (!response.authResponse) {
                $('#facebookMultiCaster .inside').html('<a href="javascript://" id="fb-login"><img src="http://static.ak.fbcdn.net/rsrc.php/zB6N8/hash/4li2k73z.gif" alt="Login to Facebook" /></a>');
                $('#fb-login').click(function () {
                    FB.login(handleSessionResponse, {scope: 'publish_stream,manage_pages'});
                });

                return;
            }													   

            // if we have a session, query for the user's name
            FB.api({
                    method: 'fql.query',
                    query: 'SELECT name FROM profile WHERE id=' + response.authResponse.userID
                },
                function (response) {
                    var user = response[0];
                    $('#facebookMultiCaster .inside').html("<h4>You are logged in as " + user.name + " and may post to the following streams:</h4><ul></ul><br /><a href='javascript://' id='fb-logout'><img src='http://static.ak.fbcdn.net/rsrc.php/z2Y31/hash/cxrz4k7j.gif' /></a>");
                    $('#facebookMultiCaster .inside ul').append('<li><a class="fb-page" href="me" token="me" title="Post to ' + user.name + '">' + user.name + '</a></li>');
                    $('#fb-logout').click(function () {
                        FB.logout(handleSessionResponse);
                    });
                }
            );

            // Return list of accounts   
            FB.api('/me/accounts', function (response) {
                $.each(response.data, function (index, value) {
                    $('#facebookMultiCaster .inside ul').append('<li><a title="Post to ' + value.name + '" class="fb-page" href="' + value.id + '" token="' + value.access_token + '">' + value.name + '</a></li>');
                });
                $('.fb-page').click(function () {
                    doPagePublish($(this).attr('href'), $(this).attr('token'));
                    return false;	 
                });
            });	 
        }

        // fetch the status on load
        if (api) {
            FB.getLoginStatus(handleSessionResponse);
        }
    }

    /**
     * Initialise facebook; loads requires scripts and attaches event handlers.
     */
    function facebookInit(api, href) {
        var options, channelUrl, script, that = this;
        
        // Only run this once
        if (props.init) {
            return true;
        }
        props.init = true;

        // Set default; use the API in settings if not passed to the function
        api  = (typeof api === 'undefined') ? $.rwo.settings.api : api;
        href = (typeof href === 'undefined') ? $.rwo.settings.url : href; 
	  
        // This function is called automatically once the Facebook API libraries are loaded
        window.fbAsyncInit = function () {
            var i = props.queue.length;
            options = { xfbml: false, cookie: true, oauth: true, appId: api };
      
			channelUrl = $('meta[name=fb-channelUrl]').attr('content');
			
			if (channelUrl) {
                options.channelUrl = channelUrl;
            } 
			      
            FB.init(options);

            // Analytics
            FB.Event.subscribe('edge.create', function (targetUrl) {
                _gaq.push(['_trackSocial', 'Facebook', 'like', targetUrl]);
            });
            FB.Event.subscribe('edge.remove', function (targetUrl) {
                _gaq.push(['_trackSocial', 'Facebook', 'unlike', targetUrl]);
            });
            FB.Event.subscribe('message.send', function (targetUrl) {
                _gaq.push(['_trackSocial', 'Facebook', 'send', targetUrl]);
            }); 
			
            // Clear any items queued for parsing
            while (i--) {
                if (typeof props.queue[i] === 'function') {
                    // It's a function, so call it
                    props.queue[i].apply(that);
                } else {
                    // It's not, so parse it as XFBML
                    parse.apply(props.queue[i]);
                }
            }
            props.queue = [];
        };
    
        // Add FB script element; avoid $.getScript() as it doesn't cache the script.
        $('body').prepend('<div id="fb-root"></div>');
        script = document.createElement('script');
        script.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
        script.async = true;
        document.getElementById('fb-root').appendChild(script);
    }

    /**
     * Enable the multicaster; if facebook is not loaded, this will be queued
     * until the library loads, otherwise it will be loaded immediately.
     */
	function facebookMultiCast(api, href) {
        
        if (typeof FB === 'undefined') {
            // Queue a function to execute
            props.queue.push(function () {
                showMulticaster(api, href);
            });

            // ensure it is initialised and run the multicaster from this function
            facebookInit(api, href);		
        } else {
            // Facebook is already initialised, enable the multicaster directly
            showMulticaster(api, href);
        }
	}

    /**
     * Parse an element.  If the facebook libraries have not yet been loaded, 
     * this will queue the element for parsing once it is loaded, otherwise it
     * will be parsed immediately.
     *
     * Note that this must be called from the context of the elment to add.
     */
    function parse() {
        if (typeof FB === 'undefined') {
            // Initialise facebook
            facebookInit();

            props.queue.push(this);
        } else {
            FB.XFBML.parse(this.parentNode);
        }
    }
	
	$.rwo.libs.register('facebook', { 
		facebookMultiCast: facebookMultiCast,
		facebookInit: facebookInit,
        parse: parse
	});
}(jQuery));

