/*
    $Rev: 85508 $
    XXX: REQUIREMENTS
        -- OOP.js
        -- facebook/graph/base.js
*/

var BaseBirthdayReminders = {
    /*
       XXX: Must extend CommonInterface

       This class represents all the logic needed to:
            -- connect to Facebook
            -- pull user's friends and birthdays
            -- display a set number of upcoming birthday
                -- link the profile pic to site's birthday ecard page

       For further definitions of some of the base calls, see CommonInterface.
    */

    userTemplate: '' +
        '<img id="agi-fbshare-mthumb" src="PICTURE" ' +
         'border="0" alt"NAME" and title="NAME">' +
            '<div id="agi-fbshare-welcome">'+
                'Hi <span id="agi-fbshare-user">NAME</span>,' +
                '<span id="agi-fbshare-mstatus">' +
                    'You are signed into your Facebook account.' +
                    '<br><a href="javascript:facebookHeadliner.logout(\'reload\')">not NAME</a>?' +
                '</span>'+
            '</div>',

    friendTemplate: '' +
        '<li ISCLICKABLE>\n' +
            '<a><img src="PICTURE" title="send an ecard to NAME!"/></a>\n' + 
            '<div class="agi-fb-frienddata">\n' +
                '<span class="agi-fb-friend">NAME</span>\n' +
                '<span class="agi-fb-bday" style="text-decoration:none">\n' + 
                    'BIRTHDAY_FRIENDLY_NO_YEAR\n' +
                '</span>\n' +
            '</div>\n' +
        '</li>\n',

    init: function(friendRenderer, pageAttrs, FBAttrs) {

        pageAttrs.userTemplate = pageAttrs.userTemplate || this.userTemplate;
        pageAttrs.friendTemplate = 
            this.attachOnclick(pageAttrs.birthdayPage,
                    pageAttrs.friendTemplate || this.friendTemplate);

        this.parent(friendRenderer, pageAttrs, FBAttrs);

        this.numFriendsToShow = pageAttrs.numFriendsToShow;
        this.numCols = pageAttrs.numCols;
        this.showNoFriendsMessage = true;
        this.upcomingBirthdays = {};
        this.completeFriendsList = {};
    },

    attachOnclick: function(birthdayPage, friendTemplate) {
        /* If ``birthdayPage`` holds a value, attach an onclick
           to friend's profile pic that will send the user to specified URL.
        */
        var isClickable = '';

        // only route to a diff page if birthdayPage is set
        if (birthdayPage) {
            isClickable = 'style="cursor:pointer"' + 
                'onmouseover="this.style.textDecoration=\'underline\'" ' +
                'onmouseout="this.style.textDecoration=\'none\'" ' +
                'title="send an ecard to NAME!" ' +
                'onclick="window.location=\'' + birthdayPage + '\'"';
        }

        return friendTemplate.replace('ISCLICKABLE', isClickable);
    },

    onLoggedOut: function () {
        this.parent();
        this.upcomingBirthdays = {};
        this.completeFriendsList = {};
    },

    onLoggedIn: function() {
        // container not found on page; return
        if (!(document.getElementById(this.friendListContainerId))) {
            return;
        }

        this.parent();
        this.showUpcomingBirthdays();
    },

    showUpcomingBirthdays: function() {
        /* Fire off an FQL request to retrieve user's friends
           (with birthdays attached) and display them.
        */
        var birthdayQuery = FB.Data.query(
                this.FQLQueries.friendsAndBirthdays, this.tokenObject.uid);

        birthdayQuery.wait(OOP.hitch(this._showBirthdaysCallback, this));
    },

    _showBirthdaysCallback: function(users) {
        /* Given a list of users (friends), derive upcoming birthdays 
           and call method to display them.

           Save off complete friend list, as well as upcoming birthday list.
        */
        this.completeFriendsList = users;
        this.upcomingBirthdays = this.deriveUpcomingBirthdays(users);

        this.renderFriends(this.upcomingBirthdays);
    },

    deriveUpcomingBirthdays: function(users) {
        /* Attempt to:
            -- find upcoming birthday's (based on today's date)
            -- tack those onto the front of the list
            -- return only the first N
        */

        if (!users.length) {
            return [];
        }

        var now = new Date();
        var nowMonth = now.getMonth() + 1;
        var nowDay = now.getDate();

        var index = -1;
        var resortedUsers = users;

        /* Loop through users. If birthday > current month, set pivot.
           Or, if birthday == curent month and >= today, set pivot.
        */
        for (var i=0; i<users.length; i++) {

            // current day and month
            var birthday = users[i].birthday_date.split('/');
            var birthdayMonth = Number(birthday[0]);
            var birthdayDay = Number(birthday[1]);

            if (birthdayMonth > nowMonth) {
                index = i;
                break;
            } else if (birthdayMonth == nowMonth && birthdayDay >= nowDay) {
                index = i;
                break;
            }
        }

        // shove upcoming birthdays to the front
        if (index >= 0) {
            resortedUsers = (users.slice(i)).concat(users.slice(0, i))
        }

        // return just the first N
        return resortedUsers.slice(0, this.numFriendsToShow);
    },

    renderFriends: function (users, numShow, supressDisplay) {
        /* Construct the HTML for upcoming birthdays and display them. 
           (unless told to *NOT* display them)
               -- if ``numShow`` not passed in, 
                  ``this.numFriendsToShow`` will be used
        */
        var friendRows = '';

        if (!users.length) {
            // only show message if told to do so
            if (this.showNoFriendsMessage) {
                var friendRows = '' + 
                    'No friends are available.<br><br>' +
                    '<a style="text-decoration:underline"target="_blank" ' +
                    'href="http://www.facebook.com">Add from Facebook</a>.';
            }
        }
        else {
            // call parent's renderFriends
            var friendRows = this.parent(
                    users, 
                    this.friendTemplate, 
                    numShow || this.numFriendsToShow, 
                    this.numCols);
        }

        // Display friends on the page?
        if (!supressDisplay) {
            document.getElementById(this.friendListContainerId).innerHTML = 
                '<ul>' + friendRows + '</ul>';
        }

        return friendRows;
    },

    createCarousel: function() {
        /* Attempt to create a (Dojo) carousel for scrolling
           through the user's friends.
        */
        if (typeof dojo != undefined) {
        	dojo.publish('agi/facebook/reminders/show');
        }
    }
};


var BMABirthdayReminders = {
    /*
       XXX: Must extend BaseBirthdayReminders

       Specialized version for BMA to override friendContainer.
           -- See docstring of BaseBirthdayReminders
    */

    friendTemplate: '' +
        '<li ISCLICKABLE>\n' +
            '<a><img src="PICTURE" /></a>\n' +
            '<div class="agi-fb-frienddata">\n' +
                '<span class="agi-fb-bday">BIRTHDAY_SLASHES_NO_YEAR</span>\n' +
                '<span class="agi-fb-friend">NAME</span>\n' +
            '</div>\n' +
        '</li>\n',

    init: function(friendRenderer, pageAttrs, FBAttrs) {
        pageAttrs.friendTemplate = this.friendTemplate;
        this.parent(friendRenderer, pageAttrs,FBAttrs);
    },

    renderFriends: function (users, numShow) {
        /* Call the parent and have the friends RETURNED (instead of
           having the innerHTML set).

           We need to tack on some special style information to the <ul>
           containing the friends.
        */
        var friendRows = this.parent(users, numShow, true);
        var container = document.getElementById(this.friendListContainerId);

        container.innerHTML = '' +
            '<ul class="agi-fb-birthday-container" ' +
                ' style="position:relative; width:2690px; left:0px;">' +
                friendRows + 
            '</ul>';

        this.createCarousel();
    }
};


var JLBirthdayReminders = {
    /*
       XXX: Must extend BaseBirthdayReminders

       Specialized version for BMA to override friendContainer.
           -- See docstring of BaseBirthdayReminders
    */

    friendTemplate: '' +
        '<li ISCLICKABLE>\n' +
            '<a><img src="PICTURE" title="Send a birthday card to NAME!"/></a>\n' + 
            '<div class="agi-fb-frienddata">\n' +
                '<span class="agi-fb-friend">NAME</span>\n' +
                '<span class="agi-fb-bday" style="text-decoration:none">\n' + 
                    'BIRTHDAY_FRIENDLY_NO_YEAR\n' +
                '</span>\n' +
            '</div>\n' +
        '</li>\n',

    init: function(friendRenderer, pageAttrs, FBAttrs) {
        pageAttrs.friendTemplate = this.friendTemplate;
        this.parent(friendRenderer, pageAttrs,FBAttrs);
    }

};

var BirthdayHeadlinerProduct = {
    /*
       XXX: Must extend BaseBirthdayReminders

           -- See docstring of BaseBirthdayReminders

           TODO: break this out to headliners.js
    */

    friendTemplate: '' +
        '<li onclick="facebookHeadliner.setFriend(\'UID\')">\n' +
            '<a>\n' +
            '<img src="PICTURE" />\n' + 
            '<span class="agi-fb-frienddata">\n' +
                '<span class="agi-fb-friend">NAME</span>\n' +
                '<span class="agi-fb-bday">BIRTHDAY_SLASHES_NO_YEAR</span>\n' +
                '<span class="agi-fb-link">Preview</span>\n' +
            '</span>\n' +
            '</a>\n' +
        '</li>\n',

    init: function(friendRenderer, pageAttrs, FBAttrs) {
        pageAttrs.friendTemplate = this.friendTemplate;
        this.parent(friendRenderer, pageAttrs, FBAttrs);

        this.postButtonId = pageAttrs.pageIds.postButton;
        this.showNoFriendsMessage = false;
        this.selectedFriendId = undefined;
    },

    onLoggedIn: function() {
        /* 
           -- init parent (CommonInterface)
           -- display user info
           -- wire up search box
        */
        this.parent();
        this._sendAccessTokenToFlash();
        this.renderUser();
        this._attachSearchEvents();
    },

    _attachSearchEvents: function() {
        /* Wire up user events to the search box. Will be used for
           searching against list of friends.
        */
        if (this.searchBoxId) {
            var box = document.getElementById(this.searchBoxId);
            box.onkeyup = OOP.hitch(this.searchUsers, this);
            //box.onblur = OOP.hitch(this.searchUsers, this);
        }
    },

    onLoggedOut: function() {
        /* Call when user logs out, or is determined to be logged out.
           Perform some cleanup + hide some divs.
        */
        this.parent();
        document.getElementById(this.userContainerId).innerHTML = '';
    },

    searchUsers: function() {
        /* Based upon user inputted text, search against full list of friends.
           Then display the users whose names contain search term.
        */
        var searchBox = document.getElementById(this.searchBoxId);
        var users = this.parent(this.completeFriendsList, searchBox.value);
        this.renderFriends(users, 'all');
    },

    renderFriends: function (users, numShow) {
        /* Given a list of refined users, render the HTML markup
           for those friends and display them.

                -- can overried # of friends to show by passing ``numShow``
                   to parent's ``renderFriends``
        */

        // extra string replacements for the friendTemplate
        this.friendRenderer.extraAttrs = { 
            'ACCESS_TOKEN': this.getAccessToken() };

        return this.parent(users, numShow);

        if (typeof dojo != undefined) {
        	dojo.publish('agi/facebook/reminders/show');
        }
    },

    viewAll: function() {
        /* Display full list of friends
        */
        this.resetSearchBox();
        this.renderFriends(this.completeFriendsList, 'all');
    },

    viewUpcoming: function() {
        /* Display N upcoming birthdays (as saved off by
           _showBirthdaysCallback()
        */
        this.resetSearchBox();
        this.renderFriends(this.upcomingBirthdays);
    },

    resetSearchBox: function() {
        try {
            document.getElementById(this.searchBoxId).
                value = 'Search My Friends';
        } catch (err) { OOP.log(err); }
    },

    /* 
       Helper methods for sending information to Flash.
       The headliner product needs info such as:
            * access_token
            * friend_id
            * user_id
    */

    setFriend: function(friendId) {
        /* Store off friend's FB ID (when clicked), and also
           send it into the Flash.
        */
        this.selectedFriendId = friendId;
        this.togglePostButton('visible');
        this._sendFriendIdToFlash(friendId);
    },

    togglePostButton: function(buttonMode) {
        document.getElementById(this.postButtonId).
            style.visibility = buttonMode
    },

    postProduct: function(friendId) {
        friendId = friendId || this.selectedFriendId || this.tokenObject.uid;
        this._savePers(friendId);
        this.parent(friendId);
    },

    _savePers: function(friendId) {
        /* TODO: This should all be pulled out somewhere else
                so it can be more generic/dynamic.
        */
        var pers = "{'Msg': '', 'NETA': '_params=" + 
            this.__makeNetaParams(friendId) + "'}";

        document.getElementById('pers').value = Base64.encode(pers);
    },

    __makeNetaParams: function(friendId) {
        var neta = '' +
            '{' +
                '"user_ID": "' + this.tokenObject.uid + '", ' +
                '"friend_ID": "' + friendId + '", ' +
                '"gender" :"' + this._getGenderFromFlash() + '"' +
            '}';

        return escape(neta);
    },

    _getGenderFromFlash: function() {
        try {
            return getFlashHandle().getGender();
        } catch(err) { OOP.log(err); return 'girl'; }

    },

    _sendAccessTokenToFlash: function() {
        try {
            getFlashHandle().setAccessToken(this.getAccessToken());
        } catch(err) { OOP.log(err); }
    },

    _sendUserIdToFlash: function() {
        try {
            getFlashHandle().sendUserIDToFlash(this.tokenObject.uid);
        } catch(err) { OOP.log(err); }
    },

    _sendFriendIdToFlash: function(friendId) {
        try {
            getFlashHandle().sendFriendIDToFlash(friendId);
        } catch(err) { OOP.log(err); }
    }
};
