/**
 * @fileOverview HGM Social library
 * 
 * @requires hgm.js
 * @author david
 * @see http://code.google.com/apis/analytics/docs/tracking/gaTrackingSocial.html
 */

if (typeof hgm == 'undefined') {
    throw('hgm.social requires hgm core library');
}

/**
 * Creates the social namespace.
 *
 * @todo Add track()
 *
 * @namespace hgm.social
 */
hgm.social = hgm.social || {};

/**
 * Creates the Facebook library in its own namespace.
 *
 * @namespace hgm.social.fb
 */
(function(facebook) {
    //hgm.module('hgm.social.fb', isReady, bind, init);
    
    /**
     * Status of our Facebook library.
     * 
     * @private
     * @type {(boolean|string)} false, 'init', or 'ready'
     * @default false
     */
    var status = false;
    
    /**
     * Maps event types to arrays of callback functions.
     *
     * @private
     * @type {object.<string,function[]>}
     */
    var callbacks = {};
    
    /**
     * Returns true if this library has been initialized successfully.
     *
     * @public
     * @return {boolean}
     */
    facebook.isReady = function() {
        return status == 'ready';
    };
    
    /**
     * Registers a callback function to be called when the given event is triggered.
     *
     * @public
     * @param {string} event Type of event such as 'init' or 'like'
     * @param {function} callback Called each time event is triggered in the order bound
     */
    facebook.bind = function(event, callback) {
        (callbacks[event] = callbacks[event] || []).push(callback);
    };
    
    /**
     * Calls each callback registered for the given event, passing in args.
     *
     * @private
     * @param {string} event Type of event such as 'init' or 'like'
     * @param {object} [args] Optional named parameters describing the event
     */
    var trigger = function(event, args) {
        var calls = callbacks[event];
        if (calls) {
            console.log('Triggering ' + event + ' event');
            for (var i = 0, l = calls.length; i < l; i++) {
                calls[i](args);
            }
        }
    };
    
    /**
     * Loads the Facebook JS library, initializes it, registers our events,
     * executes hgmFbAsyncInit() if it exists, and parses XFBML.
     *
     * @public
     * @param {string} apiKey
     * @param {string} channel URL
     */
    facebook.init = function(apiKey, channel) {
        if (status === false) {
            status = 'init';
            $.getScript(document.location.protocol + '//connect.facebook.net/en_US/all.js', function() {
                status = 'ready';
                $('body').append('<div id="fb-root" style="top:0; left:0; position: fixed;"></div>');
                FB.init({
                    appId: apiKey,
                    status: true,
                    cookie: true,
                    channelUrl: channel,
                    xfbml: true
                });
                FB.Event.subscribe('edge.create', function(targetUrl) {
                    console.log('You liked ' + targetUrl);
                    _gaq.push(['_trackSocial', 'facebook', 'like', targetUrl]);
                    //trigger('like', { url: targetUrl });
                });
                FB.Event.subscribe('edge.remove', function(targetUrl) {
                    console.log('You unliked ' + targetUrl);
                    _gaq.push(['_trackSocial', 'facebook', 'unlike', targetUrl]);
                    //trigger('unlike', { url: targetUrl });
                });
                FB.Event.subscribe('message.send', function(targetUrl) {
                    console.log('You shared ' + targetUrl);
                    _gaq.push(['_trackSocial', 'facebook', 'send', targetUrl]);
                    //trigger('send', { url: targetUrl });
                });
                trigger('init', {
                    apiKey: apiKey,
                    channel: channel
                });
            });
        }
    };
    
})(hgm.social.fb = hgm.social.fb || {});

/**
 * Creates the Twitter library in its own namespace.
 *
 * @namespace hgm.social.twttr
 */
(function(twitter) {
    /**
     * Status of our Twitter library.
     * 
     * @private
     * @type {(boolean|string)} false, 'init', or 'ready'
     * @default false
     */
    var status = false;
    
    /**
     * Maps event types to arrays of callback functions.
     *
     * @private
     * @type {object.<string,function[]>}
     */
    var callbacks = {};
    
    /**
     * Returns true if this library has been initialized successfully.
     *
     * @public
     * @return {boolean}
     */
    twitter.isReady = function() {
        return status == 'ready';
    };
    
    /**
     * Registers a callback function to be called when the given event is triggered.
     *
     * @public
     * @param {string} event Type of event such as 'init' or 'tweet'
     * @param {function} callback Called each time event is triggered in the order bound
     */
    twitter.bind = function(event, callback) {
        (callbacks[event] = callbacks[event] || []).push(callback);
    };
    
    /**
     * Calls each callback registered for the given event, passing in args.
     *
     * @private
     * @param {string} event Type of event such as 'init' or 'like'
     * @param {object} [args] Optional named parameters describing the event
     */
    var trigger = function(event, args) {
        var calls = callbacks[event];
        if (calls) {
            console.log('Triggering ' + event + ' event');
            for (var i = 0, l = calls.length; i < l; i++) {
                calls[i](args);
            }
        }
    };
    
    /**
     * Loads the Twitter JS library and registers our events.
     *
     * @public
     * @param {string} user Screen name of the site's Twitter account
     */
    twitter.init = function(user) {
        if (status === false) {
            status = 'init';
            $.getScript(document.location.protocol + '//platform.twitter.com/widgets.js', function() {
                status = 'ready';
                twttr.events.bind('tweet', function(e) {
                    if (e) {
                        var targetUrl;
                        if (e.target && e.target.nodeName == 'IFRAME') {
                            targetUrl = hgm.extractParamFromUri(e.target.src, 'url');
                        }
                        _gaq.push(['_trackSocial', 'twitter', 'tweet', targetUrl]);
                        trigger('tweet', { url: targetUrl });
                    }
                });
                twttr.events.bind('follow', function(e) {
                    _gaq.push(['_trackSocial', 'twitter', 'follow', e.data.screen_name]);
                    trigger('follow', { user: e.data.screen_name });
                });
            });
            trigger('init', {
                user: user
            });
        }
    };
})(hgm.social.twttr = hgm.social.twttr || {});

/**
 * Parses the URI and returns the value of the named parameter.
 * 
 * @public
 * @param {string} uri
 * @param {string} name
 * @return {(string|undefined)} the parameter's value or undefined if missing
 */
hgm.extractParamFromUri = function(uri, name) {
    if (uri) {
        uri = uri.split('#')[0];  // Remove anchor.
        var parts = uri.split('?');  // Check for query params.
        if (parts.length > 1) {
            var query = decodeURI(parts[1]);

            // Find url param.
            name += '=';
            var params = query.split('&');
            for (var i = 0, param; param = params[i]; ++i) {
                if (param.indexOf(name) === 0) {
                    return unescape(param.split('=')[1]);
                }
            }
        }
    }
    return undefined;
};

