//Dropdown types
//typ = 0 right
//typ = 1 down
//typ = 2 left
//typ = 3 top
var speed = 10;
var interval_ms = 10;
var close_intervals = 2;
var close_interval_count = {};
var intervals = {};
var status = {};
var other_thread_running = {};
var next_handling_thread = {};
var parameters = {};
var thread_id = 1;

function dropdown(opener_id, container_id ,typ, offset_x, offset_y, on_open_function, on_close_function)
{
	//preset variables
	other_thread_running[container_id] = 0;
	close_interval_count[container_id] = 0;
	status[container_id] = 'hidden';
	parameters[container_id] = {};
	parameters[container_id]['on_open_function'] = (on_open_function)?on_open_function:"";
	parameters[container_id]['on_close_function'] = (on_close_function)?on_close_function:"";
	parameters[container_id]['opener_id'] = opener_id;
	parameters[container_id]['typ'] = typ;
	parameters[container_id]['start_x'] = 0;
	parameters[container_id]['end_x'] = 0;
	parameters[container_id]['start_y'] = 0;
	parameters[container_id]['end_y'] = 0;
	parameters[container_id]['offset_x'] = offset_x;
	parameters[container_id]['offset_y'] = offset_y;
	
	calculate_position(container_id);
	
	//Register event listener
	document.getElementById(opener_id).onmouseout = function (event) {
		intervals[thread_id] = window.setInterval("hide('" + container_id + "', " + thread_id + ")", interval_ms);
		thread_id++;
	}
	document.getElementById(container_id).onmouseout = function (event) {
		intervals[thread_id] = window.setInterval("hide('" + container_id + "', " + thread_id + ")", interval_ms);
		thread_id++;
	}
	document.getElementById(container_id).onmouseover = function(event){
		intervals[thread_id] = window.setInterval("show('" + container_id + "', " + thread_id + ")", interval_ms);
		thread_id++;
	}
	
	//start thread
	intervals[thread_id] = window.setInterval("show('" + container_id + "', " + thread_id + ")", interval_ms);
	
	//increment thread id
	thread_id++;
}
function calculate_position(container_id)
{
	opener_id = parameters[container_id]['opener_id'];
	typ = parameters[container_id]['typ'];
	offset_x = parameters[container_id]['offset_x'];
	offset_y = parameters[container_id]['offset_y'];
	
	var x = getX(opener_id);
	var y = getY(opener_id);
	var x_clip = document.getElementById(container_id).offsetHeight;
	var y_clip = document.getElementById(container_id).offsetWidth; 
	if(typ == 0)
	{
		y += document.getElementById(opener_id).offsetWidth;
		y_clip = 0;
	}
	else if(typ == 1)
	{
		x += document.getElementById(opener_id).offsetHeight;
		x_clip = 0;
	}
	else if(typ == 2)
	{
		y -= document.getElementById(container_id).offsetWidth;
	}
	else if(typ == 3)
	{
		x -= document.getElementById(container_id).offsetHeight;
	}
	if(offset_x) x += offset_x;
	if(offset_y) y += offset_y;
	var start_x = x;
	var start_y = y;
	if(typ == 0)
	{
		start_y -= document.getElementById(container_id).offsetWidth;
	}
	else if(typ == 1)
	{
		start_x -= document.getElementById(container_id).offsetHeight;
	}
	else if(typ == 2){
		start_y += document.getElementById(container_id).offsetWidth;
	}
	else if(typ == 3)
	{
		start_x += document.getElementById(container_id).offsetHeight;
	}
	parameters[container_id]['start_x'] = start_x;
	parameters[container_id]['end_x'] = x;
	parameters[container_id]['start_y'] = start_y;
	parameters[container_id]['end_y'] = y;
	parameters[container_id]['x_clip'] = x_clip;
	parameters[container_id]['y_clip'] = y_clip;
	
	//Set start position
	document.getElementById(container_id).style.top = start_x; 
	document.getElementById(container_id).style.left = start_y;
	set_clip(container_id, x_clip, y_clip);
}
function set_clip(container_id)
{
	
	var typ = parameters[container_id]['typ'];
	
	max_x = document.getElementById(container_id).offsetHeight;
	max_y = document.getElementById(container_id).offsetWidth;
	end_x = parameters[container_id]['end_x'];
	end_y = parameters[container_id]['end_y'];
	start_x = parameters[container_id]['start_x'];
	start_y = parameters[container_id]['start_y'];
	
	var p1_x = 0;
	var p1_y = max_y;
	var p2_x = max_x;
	var p2_y = 0;
	
	if(typ == 0)
	{
		p1_x = 0;
		p1_y = max_y;
		p2_x = max_x;
		p2_y = end_y - parseInt(get_value(document.getElementById(container_id).style.left));
	}
	else if(typ == 1)
	{
		p1_x = end_x - parseInt(get_value(document.getElementById(container_id).style.top));
		p1_y = max_y;
		p2_x = max_x;
		p2_y = 0;
	}
	else if(typ == 2)
	{
		p1_x = 0;
		p1_y = (start_y - parseInt(get_value(document.getElementById(container_id).style.left)));
		p2_x = max_x;
		p2_y = 0;
	}
	else if(typ == 3)
	{
		p1_x = 0;
		p1_y = max_y;
		p2_x = (start_x - parseInt(get_value(document.getElementById(container_id).style.top)));
		p2_y = 0;
	}
	document.getElementById(container_id).style.clip = 'rect(' + p1_x + 'px, ' + p1_y + 'px, ' + p2_x + 'px, ' + p2_y + 'px)';
}
function show(container_id, thread_id)
{
	end_x = parameters[container_id]['end_x'];
	end_y = parameters[container_id]['end_y'];
	if((status[container_id] == 'waiting'))
	{
		status[container_id] = 'stop_closing';
		window.clearInterval(intervals[thread_id]);
	}
	else if((status[container_id] == 'hidden' || status[container_id] == 'showing') && (other_thread_running[container_id] == 0 || other_thread_running[container_id] == thread_id ))
	{
		var typ = parameters[container_id]['typ'];
		if(status[container_id] == 'hidden'){eval_function(parameters[container_id]['on_open_function'], container_id);calculate_position(container_id);}
		status[container_id] = 'showing';
		other_thread_running[container_id] = thread_id;	
		next_handling_thread[container_id] = 0;	
		var container = document.getElementById(container_id);
		var x = parseInt(get_value(container.style.top));
		var y = parseInt(get_value(container.style.left));
		if(typ == 0)
		{
			if(y + speed >= end_y)
				{document.getElementById(container_id).style.left = end_y;}
			else
				{document.getElementById(container_id).style.left = speed + y;}
		}
		else if(typ == 1)
		{
			if(x + speed >= end_x)
				{document.getElementById(container_id).style.top = end_x;}
			else
				{document.getElementById(container_id).style.top = speed + x;}
		}
		else if(typ == 2)
		{
			if(y - speed <= end_y)
				{document.getElementById(container_id).style.left = end_y;}
			else
				{document.getElementById(container_id).style.left = y - speed;}
		}
		else if(typ == 3)
		{
			if(x - speed <= end_x)
				{document.getElementById(container_id).style.top = end_x;}
			else
				{document.getElementById(container_id).style.top = x - speed;}
		}
		if(get_value(document.getElementById(container_id).style.top) == end_x + "" && get_value(document.getElementById(container_id).style.left) == end_y + "")
		{	
			document.getElementById(container_id).visibility = 'visible';
			window.clearInterval(intervals[thread_id]);
			status[container_id] = 'shown';
			other_thread_running[container_id] = 0;		
		}
		set_clip(container_id);
	}
	else if(status[container_id] == 'hiding' && next_handling_thread[container_id] == 0)
	{
		next_handling_thread[container_id] = thread_id;
	}
	else if(next_handling_thread[container_id] == thread_id)
	{
		//Wait for other thread to terminate
	}
	else
	{
		window.clearInterval(intervals[thread_id]);
	}
}
function hide(container_id, thread_id)
{	

	start_x = parameters[container_id]['start_x'];
	start_y = parameters[container_id]['start_y'];
	if((status[container_id] == 'stop_closing') && (other_thread_running[container_id] == thread_id))
	{
		status[container_id] = 'shown';
		next_handling_thread[container_id] = 0;		
		other_thread_running[container_id] = 0;
		close_interval_count[container_id] = 0;
		window.clearInterval(intervals[thread_id]);
	}
	else if((status[container_id] == 'shown' || status[container_id] == 'waiting') && (next_handling_thread[container_id] == 0 || next_handling_thread[container_id] == thread_id ) && (other_thread_running[container_id] == 0 || other_thread_running[container_id] == thread_id) && (close_interval_count[container_id] <= close_intervals && close_interval_count[container_id] >= 0))
	{
		status[container_id] = 'waiting';
		other_thread_running[container_id] = thread_id;
		next_handling_thread[container_id] = 0;	
		close_interval_count[container_id]++;
	}
	else if((status[container_id] == 'hiding' || status[container_id] == 'waiting') && (other_thread_running[container_id] == thread_id ))
	{
		var typ = parameters[container_id]['typ'];
		if(status[container_id] == 'waiting'){eval_function(parameters[container_id]['on_close_function'], container_id);}
		status[container_id] = 'hiding';
		close_interval_count[container_id] = 0;
		var container = document.getElementById(container_id);
		var x = parseInt(get_value(container.style.top));
		var y = parseInt(get_value(container.style.left));
		if(typ == 0)
		{
			if(y - speed <= start_y)
				{document.getElementById(container_id).style.left = start_y; }
			else
				{document.getElementById(container_id).style.left = y - speed;}
		}
		else if(typ == 1)
		{
			if(x - speed <= start_x)
				{document.getElementById(container_id).style.top = start_x; }
			else
				{document.getElementById(container_id).style.top = x - speed;}
		}
		else if(typ == 2)
		{
			if(y + speed >= start_y)
				{document.getElementById(container_id).style.left = start_y; }
			else
				{document.getElementById(container_id).style.left = y + speed;}
		}
		else if(typ == 3)
		{
			if(x + speed >= start_x)
				{document.getElementById(container_id).style.top = start_x; }
			else
				{document.getElementById(container_id).style.top = x + speed;}
		}
		if(get_value(document.getElementById(container_id).style.top) == start_x + "" && get_value(document.getElementById(container_id).style.left) == start_y + "")

		{
			document.getElementById(container_id).visibility = 'hidden';
			status[container_id] = 'hidden';
			other_thread_running[container_id] = 0;	
			window.clearInterval(intervals[thread_id]);	
		}
		set_clip(container_id);
	}
	else if(status[container_id] == 'showing' && next_handling_thread[container_id] == 0)
	{
		next_handling_thread[container_id] = thread_id;
	}
	else if(next_handling_thread[container_id] == thread_id)
	{
		//Wait for other thread to terminate
	}
	else
	{
		window.clearInterval(intervals[thread_id]);
	}
}
function get_value(val)
{
	return val.replace('px', '').replace('pt', '');
}
function eval_function(command, container_id)
{	
	eval(command.replace('this', 'document.getElementById(\''+ parameters[container_id]['opener_id'] + '\')'));
}
function getX(elem)
{
	var x=0;
	var element = document.getElementById(elem);
	while(element != document.body)
	{
		x=x+element.offsetTop;
		if (typeof(element)=="object" && typeof(element.offsetParent)=="object")
		{
			element=element.offsetParent;
		}
	}
	return x
}
function getY(elem)
{
	var y=0;
	var element = document.getElementById(elem);
	while(element != document.body)
	{
		y=y+element.offsetLeft;
		if (typeof(element)=="object" && typeof(element.offsetParent)=="object")
		{
			element=element.offsetParent;
		}
	}
	return y;
}
