/* Main search javascript file */


function beforeCall() {
    message('');
    searchBarBeforeCall();
    contentUrlHide();
    $('#refresh_data').css("display", "none");
    if (typeof graphBeforeCall != 'undefined')
        graphBeforeCall();
    userTableBeforeCall();
    exportResultsBeforeCall();
    if (typeof vennBeforeCall != 'undefined')
        vennBeforeCall();
    if (isPageKeywordsMode() && !$('.keywordsMode input:checked').val())
        inputs.val('');
    $("#common_count").text("");
    $("#detailed_count").text("");
    $("#twtr-profile-widget").css("display", "none");
    $("#movie").css("display", "none");
    $("#introMovie").css("display", "block");
    $("#user_message").html('');
    $('#user_message').removeClass('underMiniBar');
    $("#user_notification").css("display", "none");
    $('#new_users_header').remove();
    searchResults = {};
}


function afterCall() {
    message('');
    searchBarAfterCall();
    if (typeof graphAfterCall != 'undefined' && $('#displayType').val() == 'map')
        graphAfterCall();
    if (userData) {
        $('#refresh_data').css("display", "block");
    }
    updateSocialIconLinks();
}


function isWatchedUsers(watched_users, users) {
    var watched = false;
    for (var i=0; i<watched_users.length; i++) {
        if (watched_users[i].toString() == users.toString()) {
            watched = true;
            break;
        }
    }
    return watched;
}


var searchSortFunction = function (a, b) {
    return a.toLowerCase() > b.toLowerCase() ? 1 : (a.toLowerCase() < b.toLowerCase() ? -1 : 0);
}


function showNewUsersHeader() {
    var newUsersText = searchTextGetNewUsersHeader();
    var newUsersHeader = $('#new_users_header');
    if (newUsersHeader) {
        newUsersHeader.remove();
    }
    if (newUsersText) {
        var html = '<div id="new_users_header">' + newUsersText + '</div>';
        $("#userTable").before(html);
    }
}


function showResults(data) {
    userTableBeforeShow();
    if (isResultVennMode() && $('#displayType').val() == 'table' && typeof vennBeforeShow != 'undefined')
        vennBeforeShow();
    var followedByText = '';
    var userList = [];
    for (var i=0; i<data.friends.length; i++) {
        userList.push(data.friends[i].screen_name);
        if (!data.my_friends && data.friends[i].id in searchBarFollows) {
            continue;
        }
        var sortedUsers = data.friends[i].users.sort(searchSortFunction);
        if (isResultTwiangulation() && sortedUsers.toString() != followedByText) {
            followedByText = sortedUsers.toString();
            html = searchTextGetSectionHeader(sortedUsers, i);
            $('#userTable').append(html);
        }
        if (i % 10 == 0 && i != 0) {
            userTableAddLinkToTop();
        }
        userTableAddRow(data.friends[i], i+1);
    }
    userTableAfterShow(isResultKeywordsMode() && Math.floor(searchResults.total_keywords_result_number / 100 + 1) > 1);
    if (isResultVennMode() && $('#displayType').val() == 'table' && typeof vennAfterShow != 'undefined')
        vennAfterShow();
    showNewUsersHeader();
    contentUrlShow();
    exportResultsShow(userList);
}


function sortAndShow(field, order) {
    userTableSort(field, order);
    showResults(searchResults);
}


function showManyFollowersWarning() {
    var users = searchResults.search_user_data;
    for (var i=0; i<users.length; i++) {
        if (users[i].friends_count > 10000) {
            var searchCriteria = searchBarGetCriteria().toLowerCase();
            if (searchCriteria != searchBarOldCriteria) {
                searchBarOldCriteria = searchCriteria;
                var msg = "Warning: " + users[i].screen_name + " follows more than 10k people. ";
                msg += "Nobody we've met can read 100k tweets a day, so ";
                msg += (users[i].screen_name + "'s follows are probably not meaningful.");
                alert(msg);
            }
        }
    }
}


function showSearchResults(data, textStatus) {
    afterCall();
    if (data.error_message) {
        message(data.error_message, 'error_message');
    } else {
        searchResults = data;
        searchBarResultData = data.friends;
        if (!isResultTwitterListMode()) {
            searchBarSearchUserData = searchBarSearchUserData.concat(data.search_user_data);
        }
        searchBarSetUserData();
        searchBarSetInputs();
        var msg = data.only_from_cache ? "Sorry, we're out of Twitter API calls, we can show only partial results." : '';
        if (data.friends_number == 0) {
            msg += (isResultTwiangulation() ? '<br/>No common Tweeters were found.' : "No Tweeters were found.");
            message(msg, 'info_message');
        } else {
            if (!isResultTwiangulation()) {
                msg += "To highlight meaningful Tweeters, we've ignored all tweeps following more than 11k people or with a follower/friend ratio less than 1.5.";
            }
            if (data.user_message) {
                msg += ('<br/>' + data.user_message);
                message(msg, 'info_message');
            }
            if (msg) {
                message(msg, 'info_message');
            }
            if (data.friends.length) {
                var sortOrder = isResultFollowerMode() ? 'desc' : 'asc';
                if (isResultVennMode()) {
                    sortAndShow('followers_count', sortOrder);
                } else {
                    var users = searchBarGetUsers();
                    if (isResultKeywordsMode()) {
                        message('');
                        var actPage = searchResults.act_page || 1;
                        var actNumber = (actPage - 1) * 100;
                        if (searchBarResultData.length >= 100) {
                            var msg = 'For more useful results, add an additional search term';
                            msg += users.length > 0 ? '.' : " or search within one person's friends.";
                            message(msg, 'info_message')
                        }
                        sortOrder = $('#keywordsSort').val() == 'smallest' ? 'asc' : 'desc';
                        setPager(actPage);
                    }

                    var html = searchTextGetResultHeader(users, data.friends);
                    $('#common_count').html(html);
                    sortAndShow('followers_count', sortOrder);
                }
            }
        }
    }
}


function setPager(pageNumber) {
    userTableSetPager(pageNumber, Math.floor(searchResults.total_keywords_result_number / 100 + 1), pagerCallback);
}


function pagerCallback(pageNumber) {
    setPager(pageNumber);
    $('#pageCount').text(pageNumber);
    getSearchResults(null);
}


function showSearchResultGraph(data, textStatus) {
    afterCall();
    if (data.error_message && data.error_message > 0) {
        graphBeforeCall();
        message(data.graph.error_message, 'error_message');
        return;
    }
    if (!data.friends.length && !data.lone_friends.length) {
        graphBeforeCall();
        message('No Tweeters were found.', 'info_message');
        return;
    }
    searchResults = data;
    searchBarResultData = data.friends.concat(data.lone_friends);
    if (!isResultTwitterListMode()) {
        searchBarSearchUserData = searchBarSearchUserData.concat(data.search_user_data);
        searchBarSetUserData();
    }
    searchBarSetInputs();
    searchBarSwitchToMini();
    searchGraphDisplay(data.graph_data, data.friends.concat(data.search_user_data), data.lone_friends);
    contentUrlShow();
}


function scrollToSection(sectionId) {
    $.scrollTo('#' + sectionId, {offset: -230});
}


function showErrors(XMLHttpRequest, textStatus, errorThrown) {
    afterCall();
    if (typeof graphBeforeCall != 'undefined') graphBeforeCall();
    var error_msg = "Something went wrong. Maybe Twitter, maybe us. We'll check. Meanwhile, please try it again.";
    message(error_msg, 'error_message');
}


function verify_form() {
    var error_message = '';
    var users = searchBarGetUsers();
    // verify input parameter numbers
    if (isPageTwitterListMode() && users.length <= 1) {
        error_message = 'Please specify at least two different twitter lists.';
    } else if (isPageTwiangulation() && users.length <= 1) {
        error_message = 'Please specify at least two different search users.';
    } else if (!isPageKeywordsMode() && users.length == 0) {
        error_message = 'Please specify a search user.';
        inputs[0].focus();
    } else if (isPageKeywordsMode() && $('.keywordsInput').val() == '') {
        error_message = 'Please specify a keyword.';
        $('.keywordsInput')[0].focus();
    }
    if (!error_message) {
        // verify input parameter format
        if (isPageTwitterListMode()) {
            for (var i = 0; u = users[i]; i++) {
                if (u.indexOf('/') == -1 || u.split('/').length != 2) {
                    error_message = 'Twitter lists should be specified as &quot;&lt;user name&gt;/&lt;list name&gt;&quot;.';
                    inputs[i].focus();
                }
                if (!u.match(/^[a-z0-9_/-]*$/i)) {
                    error_message = 'Please use only letters, numbers, \'<acronym title="dash">-</acronym>\', \'<acronym title="dash">/</acronym>\' and \'<acronym title="underscore">_</acronym>\'.';
                    inputs[i].focus();
                }
            }
        } else if (!users.join('').match(/^[a-z0-9_]*$/i)) {
            error_message = 'Please use only letters, numbers and \'<acronym title="underscore">_</acronym>\'.';
            for (var i = 0; u = users[i]; i++) {
                if (!u.match(/^[a-z0-9_]*$/i)) {
                    inputs[i].focus();
                }
            }
        }
    }
    return error_message;
}


function getSearchResults(event, referer, refresh) {
    beforeCall();
    var error_message = verify_form();
    if (error_message) {
        message('<span class="message">' + error_message + '</span>', 'error_message');
        searchBarAfterCall(true);
    } else {
        if (bookmark_present) {
            getWatches(referer);
            message('<img class="ajax_loader" src="/site_media/img/ajax-loader.gif" /><span class="message">' + searchTextGetSearchText() + '</span>', 'info_message');
            var successFunction = ($('#displayType').val() == 'map') ? showSearchResultGraph : showSearchResults;
            var target = document.location.href + 'xhr-1/';
            $.ajax({
                type: 'GET',
                dataType: "json",
                url: target,
                timeout: 300000,
                error: showErrors,
                success: successFunction
            });
            follows = 0;
        } else if (refresh) {
            message('<img class="ajax_loader" src="/site_media/img/ajax-loader.gif" /><span class="message">Refreshing search results without using cached data...</span>', 'info_message');
            var successFunction = ($('#displayType').val() == 'map') ? showSearchResultGraph : showSearchResults;
            var target = document.location.href + 'xhr-1/refresh_cache/';
            $.ajax({
                type: 'GET',
                dataType: "json",
                url: target,
                timeout: 300000,
                error: showErrors,
                success: successFunction
            });
        } else {
            document.location = searchBarGetUrl(siteUrls.home);
        }
    }
}


function refreshResults(event) {
    getSearchResults(null, null, true);
}


function getTweetTableMessage(data) {
    var search_url = document.location.href;
    var searchUsers = searchBarGetUsers();
    var prefix = '<tr><td><form><textarea>';
    var postfix = '</textarea><div><h2>140</h2><button type="submit"></button></div></form></td></tr>';
    var msg = '';
    if (data.tweet_follow_users.length == 3) {
        var users = data.tweet_follow_users;
        var title = 'Please help Twiangulate grow by tweeting about us or leaving a review at <a target="_new" href="http://oneforty.com/item/twiangulate">oneforty.com</a>.';
        var choice1 = prefix + "I've just found 5 cool new tweeps using " + search_url + " @Twiangulate" + postfix;
        var choice2 = prefix + "I found @" + users[0] + ", @" + users[1] + ", and @" + users[2] + " using @Twiangulate. You should try it too. " + search_url + postfix;
        var choice3 = prefix + "I twiangulated @" + searchUsers.join(" + @") + " and found @" + data.follow_user_screen_name + ". @Twiangulate" + postfix;
        var choice4 = prefix + "I've found " + data.follow_number + " interesting tweeps using @Twiangulate. Check out the video intro: http://bit.ly/93eryW" + postfix;
        var choice5 = '<br/><a href="javascript:closeTweet();">Not now, thanks.</a>';
        msg = title + '<table id="tweet_table">' + choice1 + choice2 + choice3 + choice4 + '</table>' + choice5;
    } else if (follows == 5 || follows == 20) {
        var choice1 = prefix + 'I followed ' + follows + ' new people twiangulating who @' + searchUsers.join(' + @') + ' follow in common: ' + search_url + postfix;
        var choice2 = '<br/><a href="javascript:closeTweet()";>No thank you.</a>';
        msg = '<table id="tweet_table">' + choice1 + '</table>' + choice2;
    }
    return msg;
}


function onSearchBarSetUserData() {
    if ('friends' in searchResults) {
        showResults(searchResults);
    }
}


function showFollowResult(data, textStatus) {
    if (data.error_message) {
        message(data.error_message, 'error_message');
    } else {
        $('#followCount').text((parseInt($('#followCount').text()) + 1).toString());
        searchBarAddToFollowers(data.follow_user_screen_name);
        showResults(searchResults);
        if (isResultTwiangulation()) {
            var msg = getTweetTableMessage(data);
            if (msg.length) {
                message(msg, 'info_message');
                $.scrollTo(0);
                $("#tweet_table textarea").keyup(remainingCharactersTable);
                $("#tweet_table form").submit(submitTweet);
                remainingCharactersTable()
            }
        }
    }
}


function follow(event) {
    if (userData) {
        var data = {'follow_user': this.value, 'csrfmiddlewaretoken': $('#csrfmiddlewaretoken').val()};
        $(this).attr("disabled", "disabled");
        $("#user_message").html('');
        var successFunction = showFollowResult;
        if ($('#displayType').val() == 'map') {
            $('#user_message').hide();
            graphAreaSizeSetup();
            successFunction = showFollowResultInTooltip;
        }
        $.ajax({
            type: "POST",
            dataType: "json",
            url: siteUrls.actions,
            data: data,
            timeout: 30000,
            error: showErrors,
            success: successFunction
        });
        follows += 1;
    } else {
        signInWithTwitter();
    }
}


function showAddWatchResult(data, textStatus) {
    if (data.error_message) {
        message(data.error_message, 'error_message');
    } else {
        $('#watchCount').text((parseInt($('#watchCount').text()) + 1).toString());
        if ('watched_users' in watched_data) {
            watched_data.watched_users.push(data.users);
        } else {
            watched_data.watched_users = data.users;
        }
        showResults(searchResults);
    }
}


function addToWatchList(pos) {
    var users = searchResults.friends[pos].users.slice(0); // make a copy
    var data = {'watch_list': searchBarGetCriteria(users), 'mode': searchResults['mode'], 'csrfmiddlewaretoken': $('#csrfmiddlewaretoken').val()};
    $("#user_message").html('');
    $.ajax({
        type: "POST",
        dataType: "json",
        url: siteUrls.actions,
        data: data,
        timeout: 30000,
        error: showErrors,
        success: showAddWatchResult
    });
}


function showWatchesResult(data, textStatus) {
    if (!data.error_message) {
        watched_data = data;
        if ('friends' in searchResults) {
            showResults(searchResults);
            var newUsersText = searchTextGetNewUsersHeader();
        }
    }
}


function getWatches(referer) {
    var mode = $('#searchMode').val();
    if (userData && (mode == 'common_followers' || mode == 'common_friends' || isPageTwitterListMode())) {
        var target = siteUrls.watches + userData.username +  '/' + searchBarGetCriteria() + '/';
        target += (mode + '/');
        if (referer) {
            target += 'referer-' + referer + '/';
        }
        if ('versions' in userData && 'watches' in userData.versions) {
            target += '?' + userData.versions.watches;
        }
        $.ajax({
            type: "GET",
            dataType: "json",
            url: target,
            timeout: 30000,
            error: showErrors,
            success: showWatchesResult
        });
    }
}


function includeClick(event) {
    if (userData) {
        getSearchResults(event);
    } else {
        signInWithTwitter();
    }
}


function closeIntro() {
    var data = {'close_intro': '1', 'csrfmiddlewaretoken': $('#csrfmiddlewaretoken').val()};
    $.ajax({
        type: "POST",
        dataType: "json",
        url: siteUrls.actions,
        data: data,
        timeout: 30000
    });
    $("#introContainer").css("display", "none");
    return false;
}


function onKeypress(event) {
    if (event.which == 13) {
        getSearchResults(event);
    }
}


function startTwitterWidget() {
    twiangulateWidget.start();
}


function getResultNumbers(data, exclude) {
    var keysSortFunction = function(a, b) {
        if (a.split(',').length < b.split(',').length) {
            return 1;
        } else if (a.split(',').length > b.split(',').length) {
            return -1;
        } else {
            if (a > b) {
                return 1;
            } else if (a < b) {
                return -1;
            }
        }
        return 0;
    }
    var groupedData = new Object();
    var followersSumData = new Object();
    var followNumbers = new Array();
    var keys = new Array();
    for (var i=0; i<data.friends.length; i++) {
        if (exclude && !data.my_friends && data.friends[i].id in searchBarFollows) {
            excluded_own_friends_count += 1;
            continue;
        }
        var sortedUsers = data.friends[i].users.sort(searchSortFunction);
        var key = sortedUsers.toString();
        if (groupedData[key]) {
            groupedData[key] += 1;
            followersSumData[key] += data.friends[i].followers_count;
        } else {
            groupedData[key] = 1;
            followersSumData[key] = data.friends[i].followers_count;
            keys.push(key);
        }
    }
    keys.sort(keysSortFunction)
    for (var i=0; i<keys.length; i++) {
        followNumbers.push({'users': keys[i].split(','), 'number': groupedData[keys[i]], 'followersSum': followersSumData[keys[i]]});
    }
    return followNumbers;
}


function initializeWithUser() {
    searchBarInitialize();
    updateSocialIconLinks();
    if (bookmark_present) {
        var referer = $('#referer');
        if (!userData && referer.text() == 'auto_wl') {
            var directMessageSignInDialog = $("#directMessageSignInDialog").overlay({
                expose: '#000',
                closeOnClick: false,
                api: true
            });
            directMessageSignInDialog.load();
            $('#directMessageSignInDialog form').submit(function(e) {
                directMessageSignInDialog.close();
                var next = escape(window.location.href)
                window.location = siteUrls.login + '?next=' + next;
                return e.preventDefault();
            });
            $('#directMessageSignInDialog form .close').click(function(e) {
                getSearchResults(null, referer.text());
                bookmark_present = false;
                referer.text('');
            });
        } else {
            getSearchResults(null, referer.text());
            bookmark_present = false;
            referer.text('');
        }
    } else if (document.location.hash) {
        var mode_selector = '#mode_' + document.location.hash.replace('#', '');
        var item = $(mode_selector);
        if (item) {
            item.click();
        }
    }
    if (typeof searchGraphInitialize != 'undefined') {
        searchGraphInitialize();
    }
}


function initialize() {
    Shadowbox.init({players: ['iframe']});
    $.scrollTo(0);
    $('.submitSearch button').click(getSearchResults);
    $('#refresh_data button').click(refreshResults);
    $("#introCloseButton").click(closeIntro);
    $(".includeFriendsSelector *:checkbox").click(includeClick);
    $('.searchBar form').keypress(onKeypress);
    searchResults = {};
    follows = 0;
    excluded_own_friends_count = 0;
    watched_data = {};
    getUserData(initializeWithUser);
}


$(initialize);
