//
// ZEN MOTION 1.1
// Written by Blain Hosford
// Copyright 2009, ZenWebware
// www.zenwebware.com
//

var motion_nodes = [];
var motion_stage_width;
var motion_stage_height;
var motion_timer;
var motion_rate;
var motion_waiting = false;


function motion_set_stage(width, height) {
	motion_stage_width = width;
	motion_stage_height = height;
}


function motion_play(fps) {
	motion_rate = Math.round(1000 / fps);
	motion_timer = setTimeout("motion_update()", motion_rate);
}


function motion_stop() {
	clearInterval(motion_timer);
}


function motion_add_node(id) {
	//
	// Element
	//
	var element = document.getElementById(id);
	//
	// Node
	//
	var node = [];
	node['id'] = id;
	//
	// Position
	//
	node['left'] = parseInt(element.style.left);
	node['right'] = parseInt(element.style.right);
	node['top'] = parseInt(element.style.top);
	node['bottom'] = parseInt(element.style.bottom);
	node['width'] = parseInt(element.style.width);
	node['height'] = parseInt(element.style.height);
	node['target_x'] = null;
	node['target_y'] = null;
	node['position_timer'] = 0;
	//
	// Scale
	//
	node['original_width'] = parseInt(element.style.width);
	node['original_height'] = parseInt(element.style.height);
	node['scale_x'] = 1;
	node['scale_y'] = 1;
	node['target_scale_x'] = null;
	node['target_scale_y'] = null;
	node['scale_timer'] = 0;
	//
	// Opacity
	//
	node['opacity'] = parseInt(element.style.opacity);
	node['target_opacity'] = null;
	node['opacity_timer'] = 0;
	//
	// Velocity
	//
	node['velocity_x'] = 0;
	node['velocity_y'] = 0;
	node['boundary_behaviour'] = null;
	//
	// Shake
	//
	node['shake_x'] = 0;
	node['shake_y'] = 0;
	//
	// Tracking
	//
	node['target_id'] = null;
	
	//
	// Add node
	//
	motion_nodes[motion_nodes.length] = node;
	return (motion_nodes.length - 1);
}


function motion_update() {
	for(var i = 0; i < motion_nodes.length; i++) {
		var element = document.getElementById(motion_nodes[i]['id']);
		//
		// Update tracking target position.
		//
		//var target_index = motion_find_node(motion_nodes[i]['target_id']);
		//motion_nodes[i]['target_x'] = motion_nodes[target_index]['left'];
		//motion_nodes[i]['target_y'] = motion_nodes[target_index]['bottom'];
		//
		// Update velocity.
		//
		motion_nodes[i]['left'] = motion_nodes[i]['left'] + motion_nodes[i]['velocity_x'];
		if(motion_nodes[i]['boundary_behaviour'] == "wrap") {
			if(motion_nodes[i]['left'] >= motion_stage_width) {
				motion_nodes[i]['left'] = motion_nodes[i]['left'] - motion_stage_width - 500;
			}
		}
		//
		// Update shake.
		//
		var shake_x = Math.random() * motion_nodes[i]['shake_x'] * 2 - motion_nodes[i]['shake_x'];
		var shake_y = Math.random() * motion_nodes[i]['shake_y'] * 2 - motion_nodes[i]['shake_y'];
		//
		// Update position.
		//
		if(motion_nodes[i]['position_timer'] > 0) {
			motion_nodes[i]['position_timer'] = motion_nodes[i]['position_timer'] - motion_rate;
			if(motion_nodes[i]['position_timer'] < 0) motion_nodes[i]['position_timer'] = 0;
			if(motion_nodes[i]['left'] != null) {
				if(motion_nodes[i]['target_x'] != null && motion_nodes[i]['left'] != motion_nodes[i]['target_x']) {
					motion_nodes[i]['left'] = motion_interpolate(motion_nodes[i]['left'], motion_nodes[i]['target_x'], motion_nodes[i]['position_timer']);
				}
			} else {
				if(motion_nodes[i]['target_x'] != null && motion_nodes[i]['right'] != motion_nodes[i]['target_x']) {
					motion_nodes[i]['right'] = motion_interpolate(motion_nodes[i]['right'], motion_nodes[i]['target_x'], motion_nodes[i]['position_timer']);
				}
			}
			if(motion_nodes[i]['top'] != null) {
				if(motion_nodes[i]['target_y'] != null && motion_nodes[i]['top'] != motion_nodes[i]['target_y']) {
					motion_nodes[i]['top'] = motion_interpolate(motion_nodes[i]['top'], motion_nodes[i]['target_y'], motion_nodes[i]['position_timer']);
				}
			} else {
				if(motion_nodes[i]['target_y'] != null && motion_nodes[i]['bottom'] != motion_nodes[i]['target_y']) {
					motion_nodes[i]['bottom'] = motion_interpolate(motion_nodes[i]['bottom'], motion_nodes[i]['target_y'], motion_nodes[i]['position_timer']);
				}
			}
		}
		if(element.style.left) element.style.left = Math.round(motion_nodes[i]['left'] + shake_x) + "px";
		if(element.style.right) element.style.right = Math.round(motion_nodes[i]['right'] + shake_x) + "px";
		if(element.style.top) element.style.top = Math.round(motion_nodes[i]['top'] + shake_y) + "px";
		if(element.style.bottom) element.style.bottom = Math.round(motion_nodes[i]['bottom'] + shake_y) + "px";
		//
		// Update scale.
		//
		if(motion_nodes[i]['scale_timer'] > 0) {
			motion_nodes[i]['scale_timer'] = motion_nodes[i]['scale_timer'] - motion_rate;
			if(motion_nodes[i]['scale_timer'] < 0) motion_nodes[i]['scale_timer'] = 0;
			if(motion_nodes[i]['target_scale_x'] != null && motion_nodes[i]['scale_x'] != motion_nodes[i]['target_scale_x']) {
				motion_nodes[i]['scale_x'] = motion_interpolate(motion_nodes[i]['scale_x'], motion_nodes[i]['target_scale_x'], motion_nodes[i]['scale_timer']);
				element.style.width = Math.round(motion_nodes[i]['original_width'] * motion_nodes[i]['scale_x']) + "px";
			}
			if(motion_nodes[i]['target_scale_y'] != null && motion_nodes[i]['scale_y'] != motion_nodes[i]['target_scale_y']) {
				motion_nodes[i]['scale_y'] = motion_interpolate(motion_nodes[i]['scale_y'], motion_nodes[i]['target_scale_y'], motion_nodes[i]['scale_timer']);
				element.style.height = Math.round(motion_nodes[i]['original_height'] * motion_nodes[i]['scale_y']) + "px";
			}
		}
		//
		// Update opacity.
		//
		if(motion_nodes[i]['opacity_timer'] > 0) {
			motion_nodes[i]['opacity_timer'] = motion_nodes[i]['opacity_timer'] - motion_rate;
			if(motion_nodes[i]['opacity_timer'] < 0) motion_nodes[i]['opacity_timer'] = 0;
			motion_nodes[i]['opacity'] = motion_interpolate(motion_nodes[i]['opacity'], motion_nodes[i]['target_opacity'], motion_nodes[i]['opacity_timer']);
			element.style.opacity = motion_nodes[i]['opacity'];
			element.style.filter = "alpha(opacity=" + Math.round(motion_nodes[i]['opacity'] * 100) + ")";
			if(motion_nodes[i]['opacity'] == 0) element.style.display = "none";
		}
	}
	clearTimeout(motion_timer);
	motion_timer = setTimeout("motion_update()", motion_rate);
}


function motion_interpolate(value, target_value, timer) {
	var frame_count = timer / motion_rate;
	if(frame_count < 1) {
		return target_value;
	} else {
		return value + (target_value - value) / frame_count;
	}
}


function motion_animate_node_position(id, x, y, time) {
	var index = motion_find_node(id);
	motion_nodes[index]['target_x'] = x;
	motion_nodes[index]['target_y'] = y;
	motion_nodes[index]['position_timer'] = time;
}


function motion_animate_node_scale(id, scale_x, scale_y, time) {
	var index = motion_find_node(id);
	motion_nodes[index]['target_scale_x'] = scale_x;
	motion_nodes[index]['target_scale_y'] = scale_y;
	motion_nodes[index]['scale_timer'] = time;
}


function motion_animate_node_opacity(id, opacity, time) {
	var index = motion_find_node(id);
	motion_nodes[index]['target_opacity'] = opacity;
	motion_nodes[index]['opacity_timer'] = time;
}


function motion_set_node_position(id, x, y) {
	var index = motion_find_node(id);
	var element = document.getElementById(motion_nodes[index]['id']);
	if(element.style.right) {
		motion_nodes[index]['right'] = x;
		element.style.right = x + "px";
	} else {
		motion_nodes[index]['left'] = x;
		element.style.left = x + "px";
	}
	if(element.style.bottom) {
		motion_nodes[index]['bottom'] = y;
		element.style.bottom = y + "px";
	} else {
		motion_nodes[index]['top'] = y;
		element.style.top = y + "px";
	}
}


function motion_set_node_scale(id, scale_x, scale_y) {
	var index = motion_find_node(id);
	var element = document.getElementById(motion_nodes[index]['id']);
	motion_nodes[index]['scale_x'] = scale_x;
	motion_nodes[index]['scale_y'] = scale_y;
	element.style.width = Math.round(motion_nodes[index]['original_width'] * motion_nodes[index]['scale_x']) + "px";
	element.style.height = Math.round(motion_nodes[index]['original_height'] * motion_nodes[index]['scale_y']) + "px";
}


function motion_set_node_opacity(id, opacity) {
	var index = motion_find_node(id);
	var element = document.getElementById(motion_nodes[index]['id']);
	motion_nodes[index]['opacity_timer'] = 0;
	motion_nodes[index]['target_opacity'] = null;
	motion_nodes[index]['opacity'] = opacity;
	element.style.opacity = opacity;
	element.style.filter = "alpha(opacity=" + Math.round(opacity * 100) + ")";
}


function motion_set_node_velocity(id, velocity_x, velocity_y, boundary_behaviour) {
	var index = motion_find_node(id);
	motion_nodes[index]['velocity_x'] = velocity_x;
	motion_nodes[index]['velocity_y'] = velocity_y;
	motion_nodes[index]['boundary_behaviour'] = boundary_behaviour;
}


function motion_set_node_shake(id, shake_x, shake_y) {
	var index = motion_find_node(id);
	motion_nodes[index]['shake_x'] = shake_x;
	motion_nodes[index]['shake_y'] = shake_y;
}


function motion_set_node_depth(id, z) {
	var element = document.getElementById(id);
	element.style.zIndex = z;
}


function motion_set_node_tracking(id, target_id) {
	var index = motion_find_node(id);
	motion_nodes[index]['target_id'] = target_id;
}


function motion_show_node(id) {
	var element = document.getElementById(id);
	element.style.display = "block";
}


function motion_hide_node(id) {
	var element = document.getElementById(id);
	element.style.display = "none";
}


function motion_wait_for_node(id) {
	var index = motion_find_node(id);
	while(motion_nodes[index]['position_timer'] != 0 || motion_nodes[index]['scale_timer'] != 0 || motion_nodes[index]['opacity_timer'] != 0) {
		motion_update();
		clearTimeout(motion_timer);
		motion_timer = setTimeout("motion_wait_for_node('" + id + "')", motion_rate);
	}
	clearTimeout(motion_timer);
	motion_timer = setTimeout("motion_update()", motion_rate);
}


function motion_find_node(id) {
	for(var i = 0; i < motion_nodes.length; i++) {
		if(motion_nodes[i]['id'] == id) {
			return i;
		}
	}
}

//opacity:0.9; filter:alpha(opacity=90)

