// ==UserScript==
// @name           Twitter: Support tweeting
// @author         noriaki
// @namespace      noriaki
// @license        The MIT License
// @version        0.1.5
// @released       2009-10-25 12:00:00
// @updated        2010-04-18 09:37:00
// @compatible     Greasemonkey
// @include        http://twitter.com/
// @include        http://twitter.com/#*
// @include        http://twitter.com/?status=*
// @require        http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js
// @require        http://blog.fulltext-search.biz/files/gm/gm-config-helper.js
// @require        http://blog.fulltext-search.biz/files/gm/gm-update-checker.js
// @require        http://blog.fulltext-search.biz/javascripts/gm/jquery.autocomplete.tw-suprt-twing.js
// @resource       img-indicator http://blog.fulltext-search.biz/images/gm/indicator.gif
// ==/UserScript==

jQuery(function($) {
    if($('#me_name').size() === 0) return;

    var u = unsafeWindow;
    var conf = new ConfigHelper();
    var following_list = conf.val('following_list') || [];
    var retweet_format = conf.val('retweet_format') || ' RT @#{screen_name}: #{entry_content}';

/*
    var hash_tags_regexp = new RegExp(' ?(#[a-z0-9_]+)', 'i');
    $('#status')
    .keyup(function(e) {
        log($(this).val().match(hash_tags_regexp));
    });
*/

    apply_retweet_link();

    if(followingListTooOld()) {
        addIndicatorIcon();
        following_list = [];
        getFollowingList(-1, addKeyUpEvent, 3);
    } else {
        addKeyUpEvent(following_list);
    }


    function followingListTooOld() {
        var following_list_updated = conf.val('following_list_updated');
        var updated_time = new Date(following_list_updated);
        updated_time.setDate(updated_time.getDate() + 7);

        return(following_list_updated === undefined || updated_time.getTime() < (new Date()).getTime());
    }

    function addKeyUpEvent(following_list) {
        $('#status')
        .autocompleteArray(following_list, {
            autoFill: true,
            delay: 40,
            maxItemsToShow: 10,
            formatItem: function(item) {
                var matchText = new RegExp('^(' + $('#status').val() + ')(.*)$', 'i');
                return item[0].replace(matchText, '<strong>$1</strong>$2');
            }
        });
    }

    function saveFollowingList(following_list, callback) {
        following_list = following_list.sort();
        conf.val('following_list', following_list);
        conf.val('following_list_updated', (new Date()).getTime());
        removeIndicatorIcon();

        callback(following_list);
    }

    function getFollowingList(cursor, callback, retry) {
        var friends_resource_uri = "/statuses/friends/" + $('#me_name').text() + '.json';

        $.ajax({
            data: { cursor: cursor },
            dataType: "json",
            url: friends_resource_uri,
            username: $('#me_name').text(),
            success: function(data) {
                $.each(data.users, function(i,user) {
                    var name = user.screen_name;
                    following_list.push('@' + name + ' ');
                    following_list.push('D ' + name + ' ');
                });
                if(data.next_cursor !== 0) {
                    setTimeout(function() { getFollowingList(data.next_cursor, callback, retry); }, 3000);
                } else {
                    saveFollowingList(following_list, callback);
                }
            },
            error: function(xhr, stat, e) {
                // retry
                if(retry > 0) {
                    setTimeout(function() { getFollowingList(cursor, callback, retry - 1); }, 2000);
                } else {
                    errorGetFollowingList(stat);
                }
            }
        });
    }

    function errorGetFollowingList(e) {
        $('#notifications')
        .css({
            'background-color': '#fff',
            color: '#f00',
            'font-weight': 'bold'
        })
        .html([
            'Greasemonkey [Support tweeting] ERROR - ', e,
            ' : ', '<a href="javascript:location.reload();">Please reload this page</a>', '.'
        ].join(''));
    }

    function addIndicatorIcon() {
        $('#heading')
        .append(
            $('<span>')
            .attr('id', 'gm_support_tweeting_update_following_list')
            .css('background', 'transparent url(' + GM_getResourceURL('img-indicator') + ') no-repeat scroll 0 50%')
            .text('Updating following list...')
        );
    }
    function removeIndicatorIcon() {
        $('#gm_support_tweeting_update_following_list')
        .css({
            background: 'none',
            'padding-left': 0,
            'background-color': '#ffa'
        })
        .text('Following list was updated. Please try enter "@" or "D" in the Status.');
    }

    function apply_retweet_link() {
        $.each($.grep($('.actions-hover'), function(n) {
            return($("span.retweet, span.del", n).size() > 0);
        }, true), function(i) {
            var $status_body = $(this).parents('span.status-body:first'),
                screen_name = $status_body.find('a.screen-name:first').text(),
                entry_content = $status_body.find('span.entry-content:first').text(),
                status_id = $(this).parents('li.hentry.status:first').attr('id').replace('status_', '');

            $(this)
            .append(
                $('<li>')
                .append(
                    $('<span>')
                    .addClass('retweet')
                    .append(
                        $('<span>')
                        .addClass('retweet-icon')
                        .addClass('icon')
                    )
                    .append(
                        $('<a>')
                        .attr({
                            title: 'retweet to ' + screen_name,
                            href: [
                                '/?status=',
                                encodeURIComponent(build_retweet_text(screen_name, entry_content)),
                                '&in_retweet_to_status_id=', status_id,
                                '&in_retweet_to=', screen_name
                            ].join('')
                        })
                        .text('ReTweet')
                        .hover(function() {
                            $(this)
                            .siblings('span.retweet-icon')
                            .css('background-position', '-192px 0px')
                        }, function() {
                            $(this)
                            .siblings('span.retweet-icon')
                            .css('background-position', '-176px 0px')
                        })
                        .click(function() {
                            var status = $('#status').val(build_retweet_text(screen_name, entry_content)).get(0);
                            status.focus();
                            status.setSelectionRange(0,0);
                            window.scroll(0,0);

                            return false;
                        })
                    )
                )
            );
        });
    }

    function after_pagenation() {
        apply_retweet_link();
    }

    var i=4;
    function addFilter() {
        if(window.AutoPagerize && window.AutoPagerize.addFilter) {
            window.AutoPagerize.addFilter(after_pagenation);
        } else if(i-- > 0) {
            setTimeout(arguments.callee, 500);
        }
    }
    addFilter();
    if(u.$('#timeline') !== undefined && $.isFunction(u.$('#timeline').bind)) {
        u.$('#timeline').bind('ajaxStop', after_pagenation);
    }

    function build_retweet_text(screen_name, entry_content) {
        var hash = {
            'screen_name': screen_name,
            'entry_content': entry_content
        };
        return retweet_format.replace(/#{([^}]+)}/gi, function(str, p1, p2) {
            return hash[p1.toLowerCase()];
        });
    }

    GM_addStyle(<><![CDATA[
        .ac_results {
            padding: 0px;
            border: 1px solid WindowFrame;
            background-color: Window;
            overflow: hidden;
        }

        .ac_results ul {
            width: 100%;
            list-style-position: outside;
            list-style: none;
            padding: 0;
            margin: 0;
        }

        .ac_results li {
            margin: 0px;
            padding: 2px 5px;
            color: #666666;
            cursor: pointer;
            display: block;
            width: 100%;
            font: menu;
            font-size: 12px;
            overflow: hidden;
            text-align: left;
        }

        .ac_results li.ac_over {
            background-color: #ffa;
            color: #222222;
        }

        #gm_support_tweeting_update_following_list {
            padding-left: 16px;
            margin-left: 20px;
            font-size: 80%;
            color: #666666;
        }

    ]]></>);

    function log() {
        if(u.console) u.console.log(arguments);
    }

});

new UpdateChecker({
    script_name: 'Twitter: Support tweeting'
    ,script_url: 'http://blog.fulltext-search.biz/files/twitter_support_tweeting.user.js'
    ,current_version: '0.1.5'
    ,more_info_url: 'http://blog.fulltext-search.biz/archives/2009/10/greasemonkey-support-tweeting-on-twitter.html'
});
