// milliseconds
var EXTRA_HIDE_DELAY = 500;
var EXTRA_SHOW_DELAY = 100;

$(function () {
    init_ajax_rails_authenticity_token();
    init_follow_mode();
    init_q2();
    init_queueables();
    init_search_autocomplete();
    init_flash_to_gritter();
});

function init_ajax_rails_authenticity_token() {
    $(document).ajaxSend(append_rails_authenticity_token);
}

function append_rails_authenticity_token(event, request, settings) {
    // http://henrik.nyh.se/2008/05/rails-authenticity-token-with-jquery
    if (typeof(AUTH_TOKEN) == "undefined") 
        return;
    // Don't add anything to a get request let IE turn it into a POST.
    // http://www.justinball.com/2009/07/08/jquery-ajax-get-in-firefox-post-in-internet-explorer/
    if ("GET" == settings.type) 
	return; 
    // settings.data is a serialized string like "foo=bar&baz=boink" (or null)
    settings.data = settings.data || "";
    settings.data += (settings.data ? "&" : "") + 
        "authenticity_token=" + encodeURIComponent(AUTH_TOKEN);
}

function init_follow_mode() {
    var cb = $("li#follow input[type=checkbox]");

    $("li#follow").show();
    cb.click(function () {
	var options = {
	    "_method": "put"
	};

	$.post("/queue/follow", options);
    });
}

function init_q2() {
    var q2_menu = $(".jsddm li.q2");
    var q2_wrapper = $("#q2_wrapper");

    q2_menu.hover(q2_mouseenter, q2_mouseleave);
    // if the q2 is hidden, it can't bind properly
    q2_wrapper.css("visibility", "hidden").show();
    q2_menu.css("visibility", "hidden").show();
    $("table tbody", q2_wrapper).mildred_q2({
	activate: function (e, ui) {
	    q2_menu.unbind("mouseenter mouseleave");
	    q2_mouseenter_show();
	},
	deactivate: function (e, ui) {
	    q2_menu.hover(q2_mouseenter_show, q2_mouseleave_hide);
	    q2_mouseleave_hide();
	}
    });
    q2_menu.css("visibility", "visible");
    q2_wrapper.hide().css("visibility", "visible");
    if (0 < $("td.pos", q2_wrapper).length) {
	q2_mouseenter_show();
    }
}

function q2_mouseenter() {
    clear_timer(this);
    this.timer = setTimeout(function () {
	q2_mouseenter_show();
    }, EXTRA_SHOW_DELAY);
}

function q2_mouseenter_show() {
    if ($("#q2_wrapper").is(":hidden")) {
	$("#q2_wrapper").fadeIn("slow");
	q2_realign();
    }
}

function q2_mouseleave() {
    clear_timer(this);
    this.timer = setTimeout(function () {
	q2_mouseleave_hide(self);
    }, EXTRA_HIDE_DELAY);    
}

function q2_mouseleave_hide() {
    if (!$("#q2_wrapper").is(":hidden")) {
	$("#q2_wrapper").fadeOut("slow");
    }
}

function q2_realign() {
    var q2_wrapper = $("#q2_wrapper");
    var body = $("body");
    var left = body.width() / 2 - q2_wrapper.width() / 2;
    q2_wrapper.offset({left: left});
}

// TODO make me a jquery plugin
function init_queueables() {
    var options = {
	containment: "document",
	connectToSortable: ".sortable_receiver",
	helper: clone_for_dragging,
	opacity: 0.5,
	revert: "invalid",
	scroll: true,
        start: function (e, ui) {
	    // FIXME get rid of the helper class, use jquery ui theme classes
	    // instead
            ui.helper.addClass("helper"); 
        }
    };
    $(".queueable").draggable(options);
}

// FIXME I need cleanup badly
function clone_for_dragging(e, elem) {
    var image = $("<div/>");
    image.addClass("image");
    var img = find_image_for_helper(e.currentTarget);
    image.append(img);

    var text = $("<div/>").addClass("text");
    text.append($(".mildred_id", e.currentTarget).clone());
    text.append($(".mildred_type", e.currentTarget).clone());
    var title_and_artist = $("<a/>").addClass("title_and_artist");
    var title = find_title_for_helper(e.currentTarget);
    title_and_artist.append(title);
    var artist = find_artist_for_helper(e.currentTarget);
    if (0 < title.length) {
	title_and_artist.append("<br/>");
    }
    title_and_artist.append(artist);
    text.append(title_and_artist);

    var div = $("<div/>");
    div.append(image);
    div.append(text);
    div.addClass("song").addClass("queueable");
    var w = $("#playlist .song").width();
    div.attr("style", "height: 4.25em; width: " + w + "px"); // CSS somewhere overrides me otherwise
    return div;
}

function find_image_for_helper(elem) {
    var img;

    img = $(".image", elem);
    if (0 == img.length) {
	img = $("#content .img img").eq(0);
    }

    return img.clone();
}

function find_title_for_helper(elem) {
    return $("span.title", elem).clone();
}

function find_artist_for_helper(elem) {
    var artist;

    artist = $("span.artist", elem).clone();
    if (0 == artist.length) {
	artist = $("#content span.artist_name").clone();
	if (0 == artist.length) {
	    artist = $("<span/>").append($("#content div.artist_name a").text());
	}
	$("span", artist).remove();
	artist.addClass("artist");
    }
    return artist;
}

function init_search_autocomplete() {
    var options = {
	max: 150,
        width: "48ex",
	selectFirst: false,
	scrollHeight: "22em",
	formatResult: function (data, pos, total) {
	    return $(".text span.title", data[0]).text();
	},
	formatItem: function (data, pos, total, term) {
	    return $(data[0]).html();
	}
    };

    // TODO use jquery ui 1.8 autocomplete instead
    $("[name=q]").autocomplete("/search", options)
	.result(function (event, item) {
            var a = $("a[href]", item[0]);

            if (a && a.attr("href"))
		document.location = a.attr("href");
        }
    );
}

function init_flash_to_gritter() {
    gritter_from_flash();
}

function gritter_from_flash() {
    $(function () {
        $(".flash.notice").each(function () {
	    var flash = $(this);

    	    $.gritter.add({
		title: "Notice",
    		text: $(this).html(),
                after_open: function () {
		    flash.remove();
		}
    	    });
        });
        $(".flash.error").each(function () {
	    var flash = $(this);

    	    $.gritter.add({
		title: "Error",
    		text: $(this).html(),
		after_open: function () {
		    flash.remove();
		}
    	    });
	});
        $(".flash.warn").each(function () {
	    var flash = $(this);

    	    $.gritter.add({
		title: "Warning",
    		text: $(this).html(),
		after_open: function () {
		    flash.remove();
		}
    	    });
        });
    });
}





function init_art_picker() {
    // TODO use jquery ui theming highlight class instead
    $("ul.art li").click(function () {
	$("li", $(this).parent("ul")).removeClass("highlight");
	$(this).addClass("highlight");
    });

    $("ul.art li :checked").click();
}





function setup_playlist() {
    setup_playlist_song_hovers();
    setup_playlist_sortable();
    setup_star_rating();
}

// TODO move this stuff into the mildred.playlist plugin
function setup_playlist_song_hovers() {
    $("#playlist .song .extra").each(move_playlist_song_extra_info_into_place);
    $("#playlist .song").hover(playlist_song_mouseenter, 
			       playlist_song_mouseleave);
}

function move_playlist_song_extra_info_into_place() {
    var self = $(this);
    var song = self.parents(".text").eq(0);

    self.css("top", song.offset().top - parseInt(self.css("border-top-width")));
    self.css("left", song.offset().left - self.outerWidth());
}

function playlist_song_mouseenter() {
    var self = $(this);

    clear_timer(this);
    this.timer = setTimeout(function () {
	playlist_song_mouseenter_show(self);
    }, EXTRA_SHOW_DELAY);
}

function clear_timer(element) {
    if (element.timer) {
        clearTimeout(element.timer);
        element.timer = null;
    }
}

function playlist_song_mouseenter_show(element) {
    $("#playlist .hover").each(function (i, e) {
	playlist_song_mouseleave_hide(e);
    });
    $(element).addClass("hover");
    $(".extra", element).each(move_playlist_song_extra_info_into_place);
    $(".extra", element).show();
}

function playlist_song_mouseleave() {
    var self = $(this);

    clear_timer(this);
    this.timer = setTimeout(function () {
	playlist_song_mouseleave_hide(self);
    }, EXTRA_HIDE_DELAY);
}

function playlist_song_mouseleave_hide(element) {
    $(".extra", element).hide();
    $(element).removeClass("hover");
}

function setup_playlist_sortable() {
    $("#playlist").mildred_playlist();
    $(".queueable").draggable("option", "connectToSortable", 
			      ".sortable_receiver");
}

function setup_star_rating() {
    var rating = $.trim($("#playlist .song.current td.rating").text());

    if (isNaN(parseInt(rating))) {
	rating = "";
    }

    $(".star_rating").stars({
	cancelValue: "",
	disableValue: false,
	showTitles: true,
	callback: function (ui, type, value) {
	    var form = ui.element.parents("form");
	    var rating = value > 0 ? value : "Nil";
	    $("#playlist .song.current td.rating").text(rating);
	    $.post(form.attr("action"), form.serialize());
	}
    }).stars("select", rating);

    var max_width = $("#playlist").width();
    var stars_width = 11 * 16; // 11 images at 16 px each == 176 pixels
    $(".star_rating").css("margin-left", (max_width - stars_width)/2 + "px");
}



// TODO I doubt this works as of 2010-05-25
function check_follow_mode() {
    // called via rendered JS from rails
    var should_be = $("#playlist .current a").attr("href");
    var is = get_path(window.location);

    if (typeof(LAST_FOLLOWED) == "undefined")
	LAST_FOLLOWED = should_be.replace("&followed=true", "");

    // is != should_be indicates that we're not on the page for the currently
    // playing song, while should_be != LAST_FOLLOWED indicates that the
    // currently playing song has changed since the last time we "followed" a
    // song.
    if (is != should_be && should_be != LAST_FOLLOWED)
	window.location.href = should_be + "&followed=true";
}

function get_path(url) {
    var re = /https?:\/\/[^\/]+(\/.*)/;
    var res = re.exec(url);

    if (res.length > 1)
	return res[1];
    else
	return null;
}
