function input_suggest(e, suggests, title) {
    var div = $('<div class="suggestions" style="position: absolute; display: none;"></div>');
    var innerdiv = $('<div></div>').appendTo(div);
    if(title) innerdiv.append("<h3>" + title + "</h3>");
    var ul = $("<ul></ul>");
    $.each(suggests, function(i, o) {
        var li = $("<li>" + o + "</li>");
        li.click(function(event) {
            e.val(o);
        });
        ul.append(li);
    });
    innerdiv.append(ul);
    e[0].show_suggestions = function() {
        $(".suggestions:visible").fadeOut(200);
        div.css('margin-left', $(this).outerWidth() + 'px');
        div.fadeIn(200);
    };
    e.before(div);
    e.focus(function(event) { if(div.is(':hidden')) this.show_suggestions(); });
    e.blur(function(event) { div.fadeOut(200);});
}

function attach_suggestions(e, suggestions) {
    var div = $(suggestions).clone().insertBefore(e);
    div.css("position", "absolute");

    var width = $(e).outerWidth();

    $("li.option", div).each(function(i, o) {
        $(this).click(function(event) {
            $(e).val($(this).text());
        });
    });

    $(e).focus(function(event) {
        div.css('margin-left', width + 'px');
        div.fadeIn(200);
    });
    $(e).blur(function(event) {
        div.fadeOut(200);
    });
}

function phase_hidden(e, callback) {
    // Blink element e in and out of the hidden ether to calculate real proportions

    if(!e.hasClass('hidden')) callback.call(e);

    e.css({'visibility': 'hidden', 'position': 'absolute'});
    e.removeClass("hidden");

    callback.call(e);

    e.css({'visibility': 'visible', 'position': 'static'});
    e.addClass("hidden");
}

SHORT_URL_SAMPLE = "http://bit.ly/xxxxxx"
SHORT_URL_LEN = SHORT_URL_SAMPLE.length;
MIN_URL_LEN = SHORT_URL_LEN + 5;

re_find_url = /((http|https|ftp):\/\/[\w\?=&.,\/\-;#~%-=]+)/g

function shorten_urls(text) {
    // Simulate what the text might look like if we shortened the urls longer than MIN_URL_LEN
    m = text.match(re_find_url);
    if(!m) return text;
    for(var i=0, end=m.length; i<end; i++) {
        if(m[i].length > MIN_URL_LEN) text = text.replace(m[i], SHORT_URL_SAMPLE);
    }
    return text
}

function add_counter(e, max) {
    var width = 0;
    phase_hidden(e.parent(".hidden"), function() {
        width = e.outerWidth();
    });

    var counter = $('<div class="char-counter">' + max + '</div>').css('margin-left', width + 'px');
    var warned = false;
    $(e).before(counter);
    var check_change = function(event) {
        var text = e.val();
        mini_text = shorten_urls(text);
        var left = max - mini_text.length;
        if(mini_text == text) {
            counter.text(left);
        } else {
            counter.text(left + " with shortened links");
        }

        if(left<10) {
            counter.addClass('warning');
            warned = true;
        } else if(warned) {
            counter.removeClass('warning');
        }
    };
    check_change();
    $(e).keydown(check_change);
    $(e).keyup(check_change); // Do we really need both? Is there a better way?
}

var FnQueue = function() {
    this.queue = [];
}
FnQueue.prototype = {
    push: function(fn) {
        this.queue.push(fn);
    },
    flush: function() {
        for(var fn = this.queue.shift(); fn; fn=this.queue.shift()) { fn(); };
    },
    close: function() {
        this.push = function(fn) { fn(); }
        this.flush();
    }
}


function show_comments(e) {
    var c = $(e).parents(".challenge-entry").children(".comments").removeClass('hidden');
    $("textarea", c).focus();
}

function expand_comments(e) {
    $(e).parent().children(".comment").removeClass('hidden');
    $(e).remove();
}

function api_call(params, callback) {
    if(typeof params === "string") // Full url is provided in params arg
        return $.get(params, callback);
    return $.get('/api', params, callback);
}

function api_replace(params, target) {
    $(target).hide();
    api_call(params, function(r) {
        $(target).html(r);
        FB.XFBML.parse($(target)[0]);
        $(target).fadeIn();
    });
}
function api_append(params, target) {
    var new_target = $(target).parent();
    $(target).remove();
    api_call(params, function(r) {
        $(new_target).append(r);
        FB.XFBML.parse($(new_target)[0]);
    });
}

var active_tab = false;
function open_tab(e, params) {
    if(active_tab) $(active_tab).removeClass('selected');
    active_tab = e;
    $(e).addClass('selected');
    api_replace(params, $('#data-canvas'));
}

function open_invite(e, service) {
    window.opened_invite = e;
    window.open("/account/" + service +"/invite?popup=1&callback=window.opener.set_invite", "inviteFriend", "location=0,status=0,width=680,height=400");
}
function set_invite(data) {
    var e = window.opened_invite;
    var challenge_box = $(e).parents('.challenge-box')[0];
    challenge_box.add_participant(data['name'], data['remote_id'], data['service']);
}

function init_challenge_box(e) {
    var challenge_form = $("form[name='challenge']", e);
    var add_form = $("form[name='add-friend']", e);
    var from_action = $(".participant:first input.activity", challenge_form);

    var participants = {};

    var add_participant = e.add_participant = function(name, remote_id, remote_service, action) {
        if(participants[remote_id]) return;
        if(!action) action = from_action.val();

        var div = $('<li class="participant"><h3><strong>' + name + '</strong> will...</h3>' +
                    '<input class="activity" type="text" name="remote_action[]" value="'+ action +'" />' +
                    '<input type="hidden" name="remote_id[]" value="' + remote_id +'" />' +
                    '<input type="hidden" name="remote_name[]" value="' + name +'" />' +
                    '<input type="hidden" name="remote_service[]" value="' + remote_service + '" />' +
                    '</li>');
        participants[remote_id] = div;
        $('ul.participants', challenge_form).append(div);
        $('.action-box', e).removeClass('hidden');
        $('input:first', div).focus();
    }

    $(add_form).submit(function() {
        var name = $("input[name='username']", add_form).val();
        add_participant(name, name, 'username');
        $("input[name='username']", add_form).val('');
        return false;
    });
    $("input:first", challenge_form).focus();
}

function change_action(e) {
    var participant = $(e).parents('.participant');
    $(".meta", participant).addClass('hidden');
    $(".statement", participant).addClass('hidden');
    $(".change-action", participant).removeClass('hidden');
}

