/************************************************************************************************************************************
*	fb.wall				Facebook Wall jQuery Plguin
*
*	@author:			Daniel Benkenstein / neosmart GmbH
*	@version:			1.2.7
*	@Last Update:		06.06.2011
*	@licence:			MIT (http://www.opensource.org/licenses/mit-license.php)
*						GPL	(http://www.gnu.org/licenses/gpl.html)
*	@documentation:		http://www.neosmart.de/social-media/facebook-wall
*	@feedback:			http://www.neosmart.de/blog/jquery-plugin-facebook-wall
*	
************************************************************************************************************************************/

(function ($) {

    $.fn.fbWall = function (options) {

        var opts = $.extend({}, $.fn.fbWall.defaults, options);
        var meta = this;

        return meta.each(function () {
            $this = $(this);
            var o = $.meta ? $.extend({}, opts, $this.data()) : opts;
            var output = '';
            var avatarBaseURL;
            var baseData;
            var graphURL = "https://graph.facebook.com/";

            /******************************************************************************************************
            * Load base data
            ******************************************************************************************************/

            meta.addClass('fb-wall').addClass('loading').html('');
            $.ajax({
                url: graphURL + o.id + '?access_token=' + o.accessToken,
                dataType: "jsonp",
                success: function (data, textStatus, XMLHttpRequest) {
                    initBase(data);
                }
            });

            /******************************************************************************************************
            * Load feed data
            ******************************************************************************************************/

            var initBase = function (data) {
                baseData = data;

                if (data == false) {
                    meta.removeClass('loading').html('The alias you requested do not exist: ' + o.id);
                    return false;
                };

                if (data.error) {
                    meta.removeClass('loading').html(data.error.message);
                    return false;
                };

                var type = (o.showGuestEntries == 'true' || o.showGuestEntries == true) ? 'feed' : 'posts';
                $.ajax({
                    url: graphURL + o.id + "/" + type + "?limit=" + o.max + '&access_token=' + o.accessToken,
                    dataType: "jsonp",
                    success: function (data, textStatus, XMLHttpRequest) {
                        meta.removeClass('loading');
                        initWall(data);
                    }
                });
            }

            /******************************************************************************************************
            * Parse feed data / wall
            ******************************************************************************************************/

            var initWall = function (data) {

                data = data.data;

                var max = data.length;
                var thisAvatar, isBase, hasBaseLink, thisDesc;

                for (var k = 0; k < max; k++) {

                    // Shortcut ------------------------------------------------------------------------------------------------------------------------------
                    isBase = (data[k].from.id == baseData.id);
                    hasBaseLink = isBase && (exists(baseData.link));
                    if (!o.showGuestEntries && !isBase) continue;

                    // Box -----------------------------------------------------------------------------------------------------------------------------------
                    output += (k == 0) ? '<div class="fb-wall-box fb-wall-box-first">' : '<div class="fb-wall-box">';
                    output += '<a href="http://www.facebook.com/profile.php?id=' + data[k].from.id + '" target="_blank">';
                    output += '<img class="fb-wall-avatar" src="' + getAvatarURL(data[k].from.id) + '" />';
                    output += '</a>';
                    output += '<div class="fb-wall-data">';

                    output += '<span class="fb-wall-message">';
                    output += '<a href="http://www.facebook.com/profile.php?id=' + data[k].from.id + '" class="fb-wall-message-from" target="_blank">' + data[k].from.name + '</a> ';
                    if (exists(data[k].message)) output += modText(data[k].message);
                    output += '</span>';

                    // Media -----------------------------------------------------------------------------------------------------------------------------------
                    if (exists(data[k].picture) || exists(data[k].link) || exists(data[k].caption) || exists(data[k].description)) {
                        output += exists(data[k].picture) ? '<div class="fb-wall-media">' : '<div class="fb-wall-media fb-wall-border-left">';
                        if (exists(data[k].picture)) {
                            if (exists(data[k].link)) output += '<a href="' + data[k].link + '" target="_blank" class="fb-wall-media-link">';
                            output += '<img class="fb-wall-picture" src="' + data[k].picture + '" />';
                            if (exists(data[k].link)) output += '</a>';
                        }
                        output += '<div class="fb-wall-media-container">';
                        if (exists(data[k].name)) output += '<a class="fb-wall-name" href="' + data[k].link + '" target="_blank">' + data[k].name + '</a>';
                        if (exists(data[k].caption)) output += '<a class="fb-wall-caption" href="http://' + data[k].caption + '" target="_blank">' + data[k].caption + '</a>';
                        if (exists(data[k].properties)) {
                            for (var p = 0; p < data[k].properties.length; p++) output += (p == 0) ? '<div>' + formatDate(data[k].properties[p].text) + '</div>' : '<div>' + data[k].properties[p].text + '</div>';
                        }
                        if (exists(data[k].description)) {
                            thisDesc = modText(data[k].description);
                            if (thisDesc.length > 299) thisDesc = thisDesc.substr(0, thisDesc.lastIndexOf(' ')) + ' ...';
                            output += '<span class="fb-wall-description">' + thisDesc + '</span>';
                        }
                        output += '</div>';
                        output += '</div>';
                    }
                    output += '<span class="fb-wall-date">';
                    if (exists(data[k].icon)) output += '<img class="fb-wall-icon" src="' + data[k].icon + '" title="' + data[k].type + '" alt="" />';
                    output += formatDate(data[k].created_time) + '</span>';

                    // Likes -------------------------------------------------------------------------------------------------------------------------------
                    if (exists(data[k].likes)) {
                        if (parseInt(data[k].likes.count) == 1) {
                            output += '<div class="fb-wall-likes"><div><span>' + data[k].likes.data[0].name + '</span> ' + o.translateLikesThis + '</div> </div>';
                        } else {
                            output += '<div class="fb-wall-likes"><div><span>' + data[k].likes.count + ' ' + o.translatePeople + '</span> ' + o.translateLikeThis + '</div> </div>';
                        }
                    }

                    // Comments -------------------------------------------------------------------------------------------------------------------------------
                    if (exists(data[k].comments) && exists(data[k].comments.data) && (o.showComments == true || o.showComments == 'true')) {

                        output += '<div class="fb-wall-comments">';
                        for (var c = 0; c < data[k].comments.data.length; c++) {
                            output += '<span class="fb-wall-comment">';
                            output += '<a href="http://www.facebook.com/profile.php?id=' + data[k].comments.data[c].from.id + '" class="fb-wall-comment-avatar" target="_blank">';
                            output += '<img src="' + getAvatarURL(data[k].comments.data[c].from.id) + '" />';
                            output += '</a>';
                            output += '<span class="fb-wall-comment-message">';
                            output += '<a class="fb-wall-comment-from-name" href="http://www.facebook.com/profile.php?id=' + data[k].comments.data[c].from.id + '" target="_blank">' + data[k].comments.data[c].from.name + '</a> ';
                            output += modText(data[k].comments.data[c].message);
                            output += '<span class="fb-wall-comment-from-date">' + formatDate(data[k].comments.data[c].created_time) + '</span>';
                            output += '</span>';
                            output += '</span>';
                        }
                        output += '</div>';
                    }

                    output += '</div>';
                    output += '<div class="fb-wall-clean"></div>';
                    output += '</div>';
                }

                // No data found --------------------------------------------------------------------------------------------
                if (max == 0) {
                    output += '<div class="fb-wall-box-first">';
                    output += '<img class="fb-wall-avatar" src="' + getAvatarURL(baseData.id) + '" />';
                    output += '<div class="fb-wall-data">';
                    output += '<span class="fb-wall-message"><span class="fb-wall-message-from">' + baseData.name + '</span> ' + o.translateErrorNoData + '</span>';
                    output += '</div>';
                    output += '</div>';
                }
                meta.hide().html(output).fadeIn(700);
            }

            /******************************************************************************************************
            * Get Avatar URLs
            ******************************************************************************************************/

            function getAvatarURL(id) {
                var avatarURL;
                if (id == baseData.id) { avatarURL = (o.useAvatarAlternative) ? o.avatarAlternative : graphURL + id + '/picture?type=square'; }
                else { avatarURL = (o.useAvatarExternal) ? o.avatarExternal : graphURL + id + '/picture?type=square'; }
                return avatarURL;
            }

            /******************************************************************************************************
            * Parse dateStr as formatted date
            * @return: if dateStr can't be parsed as Date, return dateStr
            ******************************************************************************************************/

            function formatDate(dateStr) {
                var year, month, day, hour, minute, dateUTC, date, ampm, d, time;
                var iso = (dateStr.indexOf(' ') == -1 && dateStr.substr(4, 1) == '-' && dateStr.substr(7, 1) == '-' && dateStr.substr(10, 1) == 'T') ? true : false;

                if (iso) {
                    year = dateStr.substr(0, 4);
                    month = parseInt((dateStr.substr(5, 1) == '0') ? dateStr.substr(6, 1) : dateStr.substr(5, 2)) - 1;
                    day = dateStr.substr(8, 2);
                    hour = dateStr.substr(11, 2);
                    minute = dateStr.substr(14, 2);
                    dateUTC = Date.UTC(year, month, day, hour, minute);
                    date = new Date(dateUTC);
                } else {
                    d = dateStr.split(' ');
                    if (d.length != 6 || d[4] != 'at')
                        return dateStr;
                    time = d[5].split(':');
                    ampm = time[1].substr(2);
                    minute = time[1].substr(0, 2);
                    hour = parseInt(time[0]);
                    if (ampm == 'pm') hour += 12;
                    date = new Date(d[1] + ' ' + d[2] + ' ' + d[3] + ' ' + hour + ':' + minute);
                    date.setTime(date.getTime() - (1000 * 60 * 60 * 7));
                }
                day = (date.getDate() < 10) ? '0' + date.getDate() : date.getDate();
                month = date.getMonth() + 1;
                month = (month < 10) ? '0' + month : month;
                hour = date.getHours();
                minute = (date.getMinutes() < 10) ? '0' + date.getMinutes() : date.getMinutes();
                if (o.timeConversion == 12) {
                    ampm = (hour < 12) ? 'am' : 'pm';
                    if (hour == 0) hour == 12;
                    else if (hour > 12) hour = hour - 12;
                    if (hour < 10) hour = '0' + hour;
                    return day + '.' + month + '.' + date.getFullYear() + ' at ' + hour + ':' + minute + ' ' + ampm;
                }
                return day + '.' + month + '.' + date.getFullYear() + ' ' + o.translateAt + ' ' + hour + ':' + minute;
            }

            /******************************************************************************************************
            * Helper Function
            ******************************************************************************************************/

            function exists(data) {
                if (!data || data == null || data == 'undefined' || typeof (data) == 'undefined') return false;
                else return true;
            }

            function modText(text) {
                return nl2br(autoLink(escapeTags(text)));
            }

            function escapeTags(str) {
                return str.replace(/</g, '&lt;').replace(/>/g, '&gt;');
            }

            function nl2br(str) {
                return str.replace(/(\r\n)|(\n\r)|\r|\n/g, "<br>");
            }

            function autoLink(str) {
                return str.replace(/((http|https|ftp):\/\/[\w?=&.\/-;#~%-]+(?![\w\s?&.\/;#~%"=-]*>))/g, '<a href="$1" target="_blank">$1</a>');
            }

        });
    };

    /******************************************************************************************************
    * Defaults 
    ******************************************************************************************************/

    $.fn.fbWall.defaults = {
        avatarAlternative: 'avatar-alternative.jpg',
        avatarExternal: 'avatar-external.jpg',
        id: 'neosmart.gmbh',
        max: 5,
        showComments: true,
        showGuestEntries: true,
        translateAt: 'at',
        translateLikeThis: 'like this',
        translateLikesThis: 'likes this',
        translateErrorNoData: 'has not shared any information.',
        translatePeople: 'people',
        timeConversion: 24,
        useAvatarAlternative: false,
        useAvatarExternal: false,
        accessToken: ''
    };

})(jQuery);
