/* Graph main javascript file */

function graphBeforeCall() {
    $('#graph_content').hide();
    $('#graph_content').children().remove();
}


function graphAfterCall() {
    $('#graph_content').html(
        '<div id="graph_anchor"></div>' +
        '<div id="graph_tooltip"></div>' +
        '<div id="graph_info"></div>' +
        '<div id="graph_orphans"></div>'
    );
    $('#graph_content').show();
}

var update_position;
function constellationRoamer_onMouseOver(nodeID) {
    if (tooltip_stay != nodeID)
        tooltip_stay = false;
    if ($('#graph_tooltip').attr('value') == nodeID && !$('#graph_tooltip').is(':hidden'))
        return;

    $('#graph_tooltip').hide();
    clearInterval(update_position);
    searchGraphTooltipCreate(nodeID);
    searchGraphTooltipUpdatePosition();
    update_position = setInterval('searchGraphTooltipUpdatePosition();', 150);
}


function constellationRoamer_onMouseOut(nodeID) {
    if (!tooltip_stay)
        searchGraphTooltipClose();
}

var tooltip_stay = false;
function constellationRoamer_onClick(nodeID) {
    tooltip_stay = nodeID;
    searchGraphTooltipCreate(nodeID);
}


function searchGraphTooltipCreate(nodeID) {
    var addFollowButton = nodeID in searchBarFollows ? false : true;
    var node_percentage = 0;
    for (var i = 0; node = node_data[i]; i++) if (node.id == nodeID) {
        node_percentage = node.percentage;
        break;
    }

    for (var i = 0; user = user_data[i]; i++) if (user.id == nodeID) {
        $('#graph_tooltip').html(
            (user.icon_url != 'user_icon' ? '<div class="icon"><img src="' + user.icon_url + '" alt="user icon" title="' +  user.screen_name + '" /></div>' : '') +
            '<img class="close_button" src="/site_media/img/close.png" />' +
            '<h3 class="user_name">' +
                '<a href="http://twitter.com/' + user.screen_name + '/" target="_blank">@' + user.screen_name + '</a>' +
                '<em> (linked to ' + node_percentage + '% of mapped tweeps) </em>' +
            '</h3>' +
            (user.friends_count > 0 ? '<div class="right"><em>Friends:</em> ' + user.friends_count + '</div>': '') +
            (user.followers_count > 0 ? '<div class="right"><em>Followers:</em> ' + user.followers_count + '</div>': '') +
            (user.full_name.length > 0 ? '<em>Name:</em> ' + user.full_name + '<br />' : '') +
            (user.location.length > 0 ? '<em>Location:</em> ' + user.location + '<br />' : '') +
            (user.url.length > 0 ? '<span class="web"><em>Web:</em> <a href="' + user.url + '"> ' + user.url.substring(user.url.indexOf('//') + 2) + ' </a></span><br />' : '') +
            (addFollowButton ? '<button class="follow_button" value="' + user.screen_name + '"> Follow </button>' : '') +
            (user.description.length > 0 ? '<div>' + user.description + '</div>' : '') +
            '<h3 class="tweets"> Recent tweets: </h3>' +
            '<ul id="user_' + user.screen_name + '"></ul>'
        );
        break;
    }

    $('#graph_tooltip button.follow_button').click(follow);
    $('#graph_tooltip').attr('value', nodeID);
    $('#graph_tooltip .close_button').click(searchGraphTooltipClose);
    $('#user_message').hide();
    $('#graph_tooltip').show();
    searchGraphOrphanSizeSetup();
    searchGraphLoadTweets($('#user_' + user.screen_name)[0]);
}


function searchGraphTooltipClose() {
    $('#graph_tooltip').hide();
    clearInterval(update_position);
    searchGraphOrphanSizeSetup();
}


function searchGraphTooltipUpdatePosition() {

    var nodeID = $('#graph_tooltip').attr('value');
    var roamer = swfobject.getObjectById(graph_attributes.id);
    if (typeof roamer == 'undefined') return;
    var position = roamer.getNodePositionByID(nodeID);

    var container = {
        width: $('#graph_content').width(),
        height: $('#graph_content').height(),
        margin: {
            right: 35,
            bottom: 35,
            left: 10,
            top: 10
        }
    }
    var tooltip = {
        left: position.x + 20,
        top: position.y + 15,
        width: $('#graph_tooltip').width(),
        height: $('#graph_tooltip').height()
    }
    var over = {
        right: tooltip.left + tooltip.width - (container.width - container.margin.right),
        bottom: tooltip.top + tooltip.height - (container.height - container.margin.bottom),
        left: container.margin.left - tooltip.left,
        top: container.margin.top - tooltip.top
    }

    if (over.right > 0)
        tooltip.left -= over.right;
    if (over.bottom > 0)
        tooltip.top -= over.bottom;
    if (over.left > 0)
        tooltip.left = container.margin.left;
    if (over.top > 0)
        tooltip.top = container.margin.top;

    $('#graph_tooltip').css({
        'left': parseInt(tooltip.left) + 'px',
        'top': parseInt(tooltip.top) + 'px'
    });
}


function searchGraphOrphanSizeSetup() {
    var height = $('#graph_content').height() - $('#graph_tooltip').height() - 135;
    if ($('#graph_content').height() - $('#graph_tooltip').height() < $('#graph_orphans').height() + 20) {
        $('#graph_orphans div').css({
            'height': height + 'px',
            'margin-right': '-10px',
            'overflow-y': 'scroll',
            'overflow-x': 'hidden'
        });
    } else if ($('#graph_orphans div').css('margin-right') == '-10px') {
        $('#graph_orphans div').css(
            'height', height
        );
    }
}


function searchGraphToggleOrphans() {
    if ($('#graph_orphans').hasClass('closed')) {
        $('#graph_orphans').removeClass('closed').unbind('click');
        $('#graph_orphans .close_button').click(searchGraphToggleOrphans);
        searchGraphOrphanSizeSetup();
    } else {
        $('#graph_orphans').addClass('closed');
        $('#graph_orphans').click(searchGraphToggleOrphans);
        return false; //stop bubbling this event to #graph_orphans
    }
}


function searchGraphToggleInfo() {
    $('#graph_info').toggle();
}


function searchGraphHideInfo() {
    $('#graph_info').hide();
}


function searchGraphBeforeTweetCall(username) {
    $('#user_' + username + ', .user_' + username).addClass('loading');
}


function searchGraphAfterTweetCall() {
    var line = $('tr.loading');
    $('ul.loading, tr.loading').removeClass('loading');
    return line;
}


function searchGraphParseUrlsInText(text) {
    text = text.replace(/\n/g, ' ');

    var url_regexp = new RegExp('(https?:\/\/[^ \<\>@]+)', 'g');
    var match = url_regexp.exec(text);
    if (match)
        text = text.replace(match[1],
            '<a href="' + match[1] + '" target="_blank">' +
                match[1].replace(/\//g, '/&#8203;') + // word braking for IE
            '</a>'
        );

    text = text.replace(/@(\w+)/g, '<a href="http://twitter.com/$1/" target="_blank">@$1</a>');

    return text;
}


function searchGraphDisplayTweets(data, message) {
    var line = searchGraphAfterTweetCall();

    if (data.length > 0) {
        var tweet_list = $('#user_' + data[0].username);
        tweet_list.children().remove();
        data = data.slice(0, 8);
        $(data).each(function() {
            tweet_list.append(
                '<li>' +
                    '<em title="' + this.created_at + '">' + this.timestamp + '</em>' + searchGraphParseUrlsInText(this.text) +
                '</li>'
            );
        });
        tweet_list.show().find('*').show();
        line = $('.user_' + data[0].username);
    } else {
        $('#graph_tooltip ul').replaceWith('None yet.');
        if (line.length > 0) {
            line.find('ul').replaceWith('<p class="noTweets"> None yet. </p>');
            line.find('p').show();
        }
    }
    line.find('.toggle a').html('hide tweets');
}


function searchGraphLoadTweets(tweet_list) {
    var list_id = (typeof tweet_list.id == 'undefined')
        ? $(this).parent()[0].id
        : tweet_list.id;
    var username = list_id.substring(list_id.indexOf('_') + 1)
    searchGraphBeforeTweetCall(username);
    $.ajax({
        dataType: 'json',
        url: siteUrls.tweets + username + '/',
        error: searchGraphAfterTweetCall,
        success: searchGraphDisplayTweets
    });
}


var node_data = new Array();
function searchGraphDisplay(config, user_results, lone_nodes) {
    graphAreaSizeSetup();

    graph_flashvars.selected_node_id = config.center_id;
    graph_flashvars.config_url = '/graph_data/' + config.dir_name + '/' + config.config_file_name + '/';

    node_data = config.nodes;
    user_data = user_results.concat(lone_nodes);

    swfobject.embedSWF(
        '/site_media/flash/constellation_roamer.swf',
        'graph_anchor', '100%', '100%',
        '9', '/site_media/flash/expressInstall.swf',
        graph_flashvars, graph_parameters, graph_attributes
    );

    $('#graph_info').html(
        '<p> Map displays tweeps who: </p>' +
        '<ul>' +
        '<li>Follow each other</li>' +
        '<li>Follow fewer than 11,000 tweeps</li>' +
        '<li>Are followed by at least 10% of other tweeps on map</li>' +
        '</ul>' +
        '<p>Click on tweeps to learn more about them and follow them.</p>' +
        '<p>Each tweep’s percentage = <span># friends of tweep</span> <span>&divide;</span> <span># mapped tweeps &times; 100</span></p>' +
        '<img class="close_button" src="/site_media/img/close.png" />'
    );
    $('#graph_info .close_button').click(searchGraphHideInfo);

    if (lone_nodes && lone_nodes.length > 0) {
        var lone_users = [];
        var lone_usernames = [];
        for (var i = 0; node = lone_nodes[i]; i++) {
            label = 'names';
            if (typeof query_params != 'undefined' && (reg = /label=([^&]*)/i.exec(query_params)))
                label = reg[1];
            else if ($('#graphNodes').val() != '')
                label = $('#graphNodes').val();
            lone_users[lone_users.length] = '<span id="node_' + node.id + '">' + (
                    label == 'nicknames'
                        ? node.screen_name
                        : label == 'names'
                            ? node.full_name
                            : ('<img src="' + node.icon_url + '" alt="user icon" title="' +  node.screen_name + '" />')
                ) + '</span>';
            lone_usernames[lone_usernames.length] = node.screen_name
        }

        $('#graph_orphans').html(
            '<p> Tweeps undisplayed because they fall outside current default search parameters: </p>' +
            '<div>' + lone_users.join(', ') + '</div>' +
            '<img class="close_button" src="/site_media/img/close.png" />' +
            '<span id="toggle_orphans" title="' + getUserList(lone_usernames) + '"> ' + lone_nodes.length + ' omitted tweep' + (lone_nodes.length > 1 ? 's' : '') +' </span>'
        ).addClass('closed').click(searchGraphToggleOrphans).show();
        $('#graph_orphans div span').click(function() {
            constellationRoamer_onClick(this.id.substring(this.id.indexOf('_') + 1));
        });
    }
}


var graph_flashvars = {
    instance_id: '1',
    passthru: '',
    debug: 'false'
};


var graph_parameters = {
    bgcolor: '#ffffff',
    allowScriptAccess: 'sameDomain',
    quality: 'high',
    scale: 'noscale',
    wmode: 'transparent'
};


var graph_attributes = {
    id: "constellation_roamer",
    name: "constellation_roamer",
    width: 800,
    height: 650
};


function graphAreaSizeSetup() {
    var width = $('#graph_content').width();
    var space = $(window).width() - width - 25;
    var height = $(window).height() - $('.searchBar').height() - 20;
    if ($('#user_message').css('display') == 'block') height = height - $('#user_message').height() - 55;
    var left = parseInt($('#graph_content').css('left'));
    $('#graph_content').css('left', left - (space / 2));
    $('#graph_content').css({
        'height': height,
        'width': width + space
    });

    searchGraphOrphanSizeSetup();
}


function searchGraphInitialize() {
    graphAreaSizeSetup();

    $(window).resize(graphAreaSizeSetup);
}
