/**
 * Create a facebook like button or like box.
 *
 * The Widget inserts a Facebook like button or like box into the target element on which the widget
 * is executed on.
 *
 *
 * ### Examples
 *
 * The Widget is executed on a pageelement and is called with passing optional parameters. In this
 * example the facebook like button is implemented and references to the web page of ePages, perfoms
 * the like action and provides the optional send button.
 *
 * JavaScript:
 *
 *     jQuery.ready({
 *         plugin: [ 'de_epages.externalcontent.ui.facebook' ],
 *         DOM: true
 *     }, function ($) {
 *         var widget = de_epages('<div>').externalcontentUiFacebook({
 *             action: "like",
 *             layout: "standard",
 *             send: true
 *         });
 *     });
 *
 * The Widget is executed on a pageelement and is called with passing optional parameters. In this
 * example the facebook like box is implemented and references to a web page of facebook. A facebook
 * url is required. The backgorund color is set to dark. The box shows faces of facebook members,
 * who like the web page and a stream of posts at the page.
 *
 * JavaScript:
 *
 *     jQuery.ready({
 *          plugin: [ 'de_epages.externalcontent.ui.facebook' ],
 *          DOM: true
 *     }, function ($) {
 *         var widget = de_epages('<div>').externalcontentUiFacebook({
 *             boxMode : true,
 *             url : "http://www.facebook.com/platform",
 *             color : "dark",
 *             showFaces : true,
 *             showStream : true
 *         });
 *     });
 *
 *
 * @class jQuery.ui.externalcontentUiFacebook
 * @extends jQuery.widget
 *
 * @uses de_epages
 * @uses jQuery.ui.widget
 * @uses jQuery.tmpl
 * @uses jQuery.i18n
 * @uses de_epages.externalcontent.ui.facebook
 * @since 6.15.0
 */

/**
 * @cfg {Boolean} [boxMode] An option to choose between the Like button (false) and the Like box
 * (true).
 */

/**
 * @cfg {String} [url] A reference to the target page to receive the Like.
 */

/**
 * @cfg {String} [action] Defines whether to show the Like button or the Recommend button. Values:
 * 'like', 'recommend'
 */

/**
 * @cfg {String} [layout] Defines how to display the total number of likes. Values: 'standard',
 * 'button_count', 'box_count'
 */

/**
 * @cfg {Boolean} [send] Specifies whether to include a Send button with the Like button.
 */

/**
 * @cfg {Integer} [width] Defines the width of the plugin in pixels.
 */

/**
 * @cfg {String} [color] Defines the color scheme for the plugin. Values: 'light', 'dark'
 */

/**
 * @cfg {Boolean} [showHeader] Specifies whether to display the Facebook header at the top of the
 * plugin.
 */

/**
 * @cfg {Boolean} [showStream] Specifies whether to display a stream of the latest posts from the
 * Page's wall.
 */

/**
 * See `jQuery.ui.externalcontentUiFacebook` for details.
 *
 * @param {Object}  [options]    A map of additional options to pass to the method.
 * @param {Boolean} [boxMode]    An option to choose between the Like button (false) and the Like
 *                               box (true).
 * @param {String}  [url]        A reference to the target page to receive the Like.
 * @param {String}  [action]     Defines whether to show the Like button or the Recommend button.
 *                               Values: 'like', 'recommend'
 * @param {String}  [layout]     Defines how to display the total number of likes. Values:
 *                               'standard', 'button_count', 'box_count'
 * @param {Boolean} [send]       Specifies whether to include a Send button with the Like button.
 * @param {Integer} [width]      Defines the width of the plugin in pixels.
 * @param {String}  [color]      Defines the color scheme for the plugin. Values: 'light', 'dark'
 * @param {Boolean} [showHeader] Specifies whether to display the Facebook header at the top of the
 *                               plugin.
 * @param {Boolean} [showStream] Specifies whether to display a stream of the latest posts from the
 *                               Page's wall.
 *
 * @method externalcontentUiFacebook
 * @member jQuery
 *
 * @since 6.15.0
 */

/*
 * @copyright   © Copyright 2006-2012, epages GmbH, All Rights Reserved.
 *
 * @module      de_epages.externalcontent.ui.facebook
 *
 * @revision    $$
 */
/*jslint nomen: true*/
/*global define, window*/
define('de_epages/externalcontent/ui/facebook', [
    'jquery/ui/widget',
    'ep',
    'de_epages',
    '$tmpl!./facebook',

    'jquery/i18n'
], function ($, ep, de_epages, template) {
    'use strict';
    // Constants.
    var gClassNames = 'SocialWeb',
        // we need this because facebook doesn't support all language codes which can be selected in
        // our storefront
        languageMap = {
            de_CH : 'de_DE',
            de_AT : 'de_DE',
            de_LU : 'de_DE',
            fr_BE : 'fr_FR',
            fr_CH : 'fr_FR',
            fr_LU : 'fr_FR',
            es_AR : 'es_ES',
            es_BO : 'es_ES',
            es_CO : 'es_ES',
            es_US : 'es_ES',
            it_CH : 'it_IT',
            nl_BE : 'nl_NL',
            ru_UA : 'ru_RU'
        };

    $.widget('ui.externalcontentUiFacebook', {

        options: {
            boxMode: false,
            // Boolean. If true, show like box. If false, show like button.
            url: ep.config.webUrlSsl || ep.config.baseUrl,
            // String. Specifying a site the like button or like box should reference.
            action: 'like',
            // String. Possible values: 'like', 'recommend'.
            layout: 'standard',
            // String. Possible values: 'standard', 'button_count', 'box_count'.
            send: false,
            // Boolean. If true, show "send button".
            width: 450,
            // Integer. Width.
            showFaces: false,
            // Boolean. If true, show profile images of people, who like the site.
            color: 'light',
            // String. Possible values 'light', 'dark'.
            showHeader: false,
            // Boolean. If true, show facebook title in box mode.
            showStream: false,
            // Boolean. If true, show comments and posts of the site as stream in box mode.
            type: 'button'
            // String. Possible values: 'button', 'box'.
        },

        _create: function () {
            var self = this,
                o = self.options,
                region = $.i18n.settings.region.replace(/-/, '_'),
                callback = function (opt) {
                    if (opt && opt.iframe){
                        self.iframeLoaded = true;
                    }

                    if (self.iframeLoaded) {
                        var iframe = self.placeholder.find('iframe'),
                            parent = self.placeholder.parents()
                                .filter(function () {
                                    return $(this).css('overflow') === 'hidden';
                                })
                                .first(),
                            parentBottom = parent.length ? parent.height() + parent.offset().top : 0,
                            placeholderTop = self.placeholder.offset().top,
                            fbIframeHeight = 329;

                        // Check if not enough space is below the element
                        if (parent.length && placeholderTop + fbIframeHeight > parentBottom) {
                            // Initialize a 'puller' because needed information is in iframe
                            window.setInterval(function () {
                                self.placeholder.css('padding-bottom', iframe.is('.fb_iframe_widget_lift') ? iframe.css('height') : 0);
                            }, 300);
                        }
                    }
                };

            // This event listener is useful if the iframe finished loading before the window.
            // Then the space calculation might be wrong and should be repeated.
            $(window).load(function () {
                callback()
            });

            if (languageMap[region]) {
                region = languageMap[region];
            }

            if (o.type === 'box') {
                o.boxMode = true;
            }

            // Prepend div with id "fb-root" for Facebook API.
            if (!$('#fb-root').length) {
                $('body').prepend('<div id="fb-root"></div>');

                // AsyncInit, otherwise it is error message flame war in chrome.
                window.fbAsyncInit = function () {
                    window.FB.init();
                };
            }

            // Load Facebook API.
            $.ajax({
                dataType: 'script',
                url: 'https://connect.facebook.net/' + region + '/all.js',
                cache: true
            }).done(function () {
                // Render placeholder.
                self.placeholder = template(o).appendTo(self.element.addClass(gClassNames));
                // Parse placeholder.
                window.FB.XFBML.parse(self.element[0]);

                self.placeholder
                    .find('iframe')
                    .on('load', function () {
                        callback({iframe: true});
                    });
            });
        },

        /**
         * This method removes the container on which the Facebook button has been appended to.
         *
         * @method destroy
         * @member jQuery.ui.externalcontentUiFacebook
         *
         * @since 6.15.0
         */
        destroy: function () {
            this.element.removeClass(gClassNames);
            if (this.placeholder) {
                this.placeholder.remove();
            }
            return this._superApply(arguments);
        }

    });

    return de_epages;

});