/* -*- Mode:c -*- */

var msecs_start = 0;
function get_msecs () {
	var now = new Date().getTime();
	if (msecs_start == 0)
		msecs_start = now;
	return (now - msecs_start);
}

var enable_show_info = 0;

function get_vote_id (elt) {
	return (elt.id.split ("_")[1]);
}

var heights = new Object ();

var last_dbg_msecs = 0;
function dbg (str) {
	if (0) {
		var msecs = get_msecs ();
		var delta = msecs - last_dbg_msecs;
		last_dbg_msecs = msecs;
		
		dump (delta + "\t" + str + "\n");
	}
}

var over_vote_id = 0;
var over_blurb_id = 0;

var over_elt = null;
var over_x = 0;
var over_y = 0;
var over_height = 0;

function over_state () {
	dbg ("over\t" + over_vote_id + "\t" + over_blurb_id);
}

function vote_click (elt) {
	var vote_id = get_vote_id (elt);
	document.location = "/vote.php?vote_id=" + vote_id;
}

function vote_over (elt) {
	var x, y;

	vote_id = get_vote_id (elt);

	blurb_id = "blurb_" + vote_id;
	if ((blurb = document.getElementById(blurb_id)) == null)
		return;

	btext_id = "btext_" + vote_id;
	btext = document.getElementById(btext_id);
	

	/*
	 * set the left side of the blurb to be the same as the left
	 * side of the <tr>
	 *
	 * brower chooses right side.
	 *
	 * with left and right pinned down, we can get the height.
	 * remember it in heights[] to avoid recomputing it all the
	 * time
	 */
	x = 0;
	y = 0;
	if (elt.offsetParent) {
		for (e = elt; e; e = e.offsetParent) {
			x += e.offsetLeft;
			y += e.offsetTop;
		}
	} else if (elt.x) {
		x += elt.x;
		y += elt.y;
	}

	if (enable_show_info) {
		var hist = blurb_id
			+ " me=" + elt.offsetTop
			+ " parent=" + elt.offsetParent.offsetTop
			+ "<br />\n";
		for (e = elt; e; e = e.offsetParent) {
			hist = hist
				+ " id="
				+ e + "::"
				+ e.parent + "::"
				+ e.className + "/"
				+ e.nodeName + "/"
				+ "style=" + e.style.margin + "+"
				+ e.offsetLeft
				+ "<br />\n"
				;
		}
		show_info (hist);
	}

	if (heights[blurb_id] == null) {
		dbg ("get height");

		btext.style.display = "block";

		blurb.style.position = 'absolute';
		blurb.style.visibility = 'hidden';
		blurb.style.display = 'block';
		blurb.style.left = x + 'px';

		blurb.style.top = 0 + 'px';
		blurb.style.width = elt.clientWidth + 'px';

		heights[blurb_id] = blurb.clientHeight;
	}
	
	over_vote_id = vote_id;
	over_elt = blurb;
	over_x = x;
	over_y = y + elt.clientHeight;

	over_height = heights[blurb_id];
	over_state ();
}

function vote_out (elt) {
	over_vote_id = 0;
	over_state ();
}

function blurb_over (elt) {
	over_blurb_id = get_vote_id (elt);
	over_state ();
}

function blurb_out (elt) {
	over_blurb_id = 0;
	over_state ();
}

var cur_id = 0;
var cur_elt = null;
var cur_ref_x = 0;
var cur_ref_y = 0;
var cur_height = 0;

var last_time = 0;

var vel = 0;
var pos = 0;

var stiffness = 80;
var damping = 12;

var pos_last = 0;
var dir_last = 0;

var unfurl_start_msecs = 0;

function anim_step () {
	var now = get_msecs ();
	var delta_t;

	if (last_time == 0)
		last_time = now;
	delta_t = (now - last_time) / 1000.0;
	last_time = now;

	if (delta_t > .1)
		delta_t = .1;

	var hiding = 0;

	if (over_vote_id != cur_id && over_blurb_id != cur_id) {
		hiding = 1;
		if (Math.abs (pos) < 2) {
			if (cur_elt)
				cur_elt.style.display = 'none';
			cur_elt = null;
		}
	}

	if (cur_elt == null) {
		if (over_vote_id == 0)
			return;
		cur_id = over_vote_id;
		cur_elt = over_elt;
		cur_ref_x = over_x;
		cur_ref_y = over_y;
		cur_height = over_height;

		pos = 0;
		vel = 0;
		pos_last = 0;
		unfurl_start_msecs = get_msecs ();

		dbg ("unfurl " + cur_id);
	}

	var delta_msecs = get_msecs () - unfurl_start_msecs;
	var fract = 5 * delta_msecs / 1000.0;

	if (fract > 1)
		fract = 1;

	var target = cur_height * fract;
	if (hiding)
		target = 0;
	dist = target - pos;

	force = stiffness * dist - damping * vel;

	if (0) {
		dbg ("pos " + Math.floor (pos)
		     + "; vel " + Math.floor (vel)
		     + "; target " + Math.floor (target)
		     + "; dist " + Math.floor (dist)
		     + "; force " + Math.floor (force)
			);
	}

	var limit = 5000;
	if (force < -limit)
		force = -limit;
	if (force > limit)
		force = limit;
	vel += force * delta_t;
	pos += vel * delta_t;

	var pos_desired = Math.floor (pos);

	if (pos_desired >= pos_last)
		dir_this = 1;
	else
		dir_this = -1;

	dist = Math.abs (pos_desired - pos_last);

	if (dir_this == dir_last || dist >= 2) {
		if (pos_desired < 2) {
			cur_elt.style.display = 'none';
		} else { 
			cur_elt.style.position = 'absolute';
			cur_elt.style.visibility = 'visible';
			cur_elt.style.display = 'block';
		
			cur_elt.style.overflow = 'hidden';
			cur_elt.style.height = pos + 'px';
		
			cur_elt.style.left = cur_ref_x + 'px';
		
			y = cur_ref_y - pos_desired;
			cur_elt.style.top = y + 'px';
		}

		pos_last = pos_desired;
		dir_last = dir_this;
	}
}

window.setInterval ('anim_step()', 30);
