// custom ui controls
// copyright (c) Mathieu Gosset (mathieu at devandco dot net)

// slideshow ---------------------------------------------------------------

function slideshow(target_id, slides, transition_time, display_time,
	randomize)
{
	if (randomize)
		slides.sort(function rand_order(){return (Math.round(Math.
			random()) - 0.5);});

	this.target_el = dom.element(target_id);
	this.slides = slides;
	this.image_list = new Array();
	this.display_time = display_time;
	this.transition_time = transition_time;
	this.current_img = -1;
	this.paused = true;
	this.load_next_img();
}

slideshow.prototype.load_next_img = function()
{
	var index = this.image_list.length;
	if (index < this.slides.length) {
		var wrap = function(slideshow, index) { return function() {
			if (slideshow.paused && slideshow.current_img + 1 == index) {
				slideshow.current_img = index;
				slideshow.show_next();
			}}
		}
		var new_img = new Image();
		this.image_list.push(new_img);
		dom.add_listener(new_img, "load", wrap(this, index));
		new_img.src = this.slides[index];
	}
}

slideshow.prototype.show_next = function()
{
	dom.set_opacity(this.target_el, 0);
	this.target_el.src = this.image_list[this.current_img].src;
	this.start_time = (new Date()).getTime();
	this.paused = false;
	this.timer = window.setInterval(dom.bind(this, "_blending_function"),
		50);
	this.load_next_img();
}

slideshow.prototype._blending_function = function ()
{
	var elapsed = (new Date()).getTime() - this.start_time;
	dom.set_opacity(this.target_el, Math.min(100 * elapsed / this.
		transition_time, 100));
	if (elapsed > (this.transition_time + this.display_time)) {
		window.clearInterval(this.timer);
		if (++this.current_img >= this.slides.length)
			this.current_img = 0;
		if (this.current_img <= this.image_list.length)
			this.show_next();
		else
			paused = true;
	}
}

// scrolling slideshow -------------------------------------------------------

function scrolling_slideshow(target_id, slides, transition_time, display_time,
	randomize)
{
	if (randomize)
		slides.sort(function rand_order(){return (Math.round
			(Math.random()) - 0.5);});

	this.target_el = dom.element(target_id);
	this.img_holders = new Array();
	this.slides = slides;
	this.image_list = new Array();
	this.display_time = display_time;
	this.transition_time = transition_time;
	this.active_holder = 1;
	this.current_img = -1;
	this.paused = true;
	this.create_img_holder(0);
	this.create_img_holder(1);
	this.load_next_img();
}

scrolling_slideshow.prototype.create_img_holder = function(index)
{
	var h = document.createElement('img');
	h.style.display = "none";
	this.target_el.appendChild(h);
	h.style.position = "absolute";
	h.style.left = "500px";
	h.style.display = "block";
	this.img_holders[index] = h;
}

scrolling_slideshow.prototype.load_next_img = function()
{
	var index = this.image_list.length;
	if (index < this.slides.length) {
		var wrap = function(slideshow, index) { return function() {
			if (slideshow.paused && slideshow.current_img + 1 == index) {
				slideshow.current_img = index;
				slideshow.show_next();
			}}
		}
		var new_img = new Image();
		this.image_list.push(new_img);
		dom.add_listener(new_img, "load", wrap(this, index));
		new_img.src = this.slides[index].img;
	}
}

scrolling_slideshow.prototype.show_next = function()
{
	var next = this.active_holder ? 0 : 1;
	this.img_holders[next].src = this.image_list[this.current_img].src;
	var link = this.slides[this.current_img].link;
	if (link != null) {
		this.img_holders[next].style.cursor = "pointer";
		this.img_holders[next].onclick = function() {dom.redirect(link);};
	}
	this.start_time = (new Date()).getTime();
	this.paused = false;
	this.timer = window.setInterval(dom.bind(this, "_scrolling_function"), 20);
	this.load_next_img();
}

scrolling_slideshow.prototype._scrolling_function = function ()
{
	var elapsed = (new Date()).getTime() - this.start_time;
	var target_pos = dom.position(this.target_el);
	var next = this.active_holder ? 0 : 1;
	if (this.img_holders[this.active_holder].style)
		this.img_holders[this.active_holder].style.left = 0 - 
			Math.min((target_pos.w * elapsed) / this.transition_time,
			target_pos.w) + "px";
	this.img_holders[next].style.left = target_pos.w - 
		Math.min((target_pos.w * elapsed) / this.transition_time, 
		target_pos.w) + "px";

	if (elapsed > (this.transition_time + this.display_time)) {
		this.active_holder = next;
		window.clearInterval(this.timer);
		if (++this.current_img >= this.slides.length)
			this.current_img = 0;
		if (this.image_list.length > 1 && this.current_img <= this.image_list.length)
			this.show_next();
	}
}

function listbox(target_id, prefix)
{
	this.target_id = target_id;
	this.prefix = prefix;
	this.frame = dom.element(target_id);
}

listbox.prototype.refresh = function()
{
	this.populate(this.list, this.click_handler);
}

listbox.prototype.populate = function(list, click_handler, empty_handler)
{
	this.list = list;
	this.visible = false;
	this.click_handler = click_handler;
	this.empty_handler = empty_handler;
	this.selected_index = undefined;
	var html_code = '<table cellpadding="1" cellspacing="0"/>';
	for (var i = 0; i < list.length; ++i)
		html_code += '<tr id="' + this.prefix + i + '" class="' + (i & 1 ? 
			'odd' : 'even') + '"/><td>' + list[i].name + '</td></tr>';
	var target = dom.element(this.target_id);
	target.innerHTML = html_code + '</table>';
	var self = this;
	var wrap = function(index, handler) {
		return function() {
			self.select_item(index, false);
			handler(self.list[index]);
			return false;
		}
	}
	for (var i = 0; i < list.length; ++i) {
		var el = dom.element(this.prefix + i);
		el.style.cursor = "hand";
		el.onclick = wrap(i, click_handler);
	}
	if (!list.length)
		empty_handler();
}

listbox.prototype.remove_item = function(index)
{
	this.list.splice(index, 1);
	var el = dom.element(this.prefix + index)
	el.parentNode.removeChild(el);
	if (this.selected_index >= index) {
		index = this.selected_index - 1;
		this.selected_index = undefined;
		this.select_item(index, true);
	}
	if (!this.list.length)
		this.empty_handler();
}

listbox.prototype.select_by_value = function(key, value, call_handler)
{
	for (var i = 0; i < this.list.length; ++i)
		if (this.list[i][key] == value) {
			this.select_item(i, call_handler);
			return;
		}
}

listbox.prototype.select_item = function(index, call_handler)
{
	if (index >= this.list.length || index < 0)
		return;
	if (this.selected_index != undefined)
		dom.set_classname(dom.element(this.prefix + this.
			selected_index), this.selected_index & 1 ? "odd" : "even");
	var el = dom.element(this.prefix + index);
	dom.set_classname(el, "selected");
	this.selected_index = index;
	if (call_handler == true)
		el.onclick();
}

function combobox(target_id, change_handler)
{
	document.write('<div id="popup_' + target_id + '" class="combobox_popup"/></div>');
	this.target_id = target_id;
	this.selected_index = undefined;
	this.frame_el = dom.element(target_id);
	this.popup_el = dom.element('popup_' + target_id);
	this.change_handler = change_handler;

	dom.add_listener(this.frame_el, "mousedown", dom.bind(this, "dropdown"));
	dom.add_listener(this.popup_el, "mouseover", dom.bind(this, "mouse_over"));
	dom.add_listener(this.popup_el, "mouseup", dom.bind(this, "mouse_up"));
}

combobox.prototype.show_popup = function(show)
{
	if (show) {
		var parent_pos = dom.position(this.frame_el);
		var elements = this.popup_el.getElementsByTagName("td");
		var popup_height = 18 * this.list.length;
		if (popup_height > 200)
			popup_height = 200;
		this.popup_el.style.left = parent_pos.x + "px";
		this.popup_el.style.top = (parent_pos.y + parent_pos.h) + "px";
		this.popup_el.style.width = parent_pos.w + "px";
		this.popup_el.style.height = popup_height + "px";
	}
	this.popup_el.style.display = show ? "block" : "none";
	if (this.visible) {
		dom.remove_event(document, "mousedown", dom.bind(this, "doc_mouse_down"));
		dom.remove_event(document, "selectstart", dom.bind(this, "doc_select_start"));
	} else {
		dom.add_listener(document, "selectstart", dom.bind(this, "doc_select_start"));
		dom.add_listener(document, "mousedown", dom.bind(this, "doc_mouse_down"));
	}
	this.visible = show;
}

combobox.prototype.dropdown = function(ev)
{
	if (!this.list.length)
		return;
	this.show_popup(!this.visible)
	ev.cancelBubble = true;
	return false;
}

combobox.prototype.doc_select_start = function(ev) 
{
	return false;
}

combobox.prototype.doc_mouse_down = function(ev) 
{
	if (this.visible) {
		var target = dom.ev_target(ev);
		if (target != this.popup_el && !dom.is_child(this.popup_el, target))
			this.show_popup(false);

		/*var el = dom.element("debug");
		el.innerHTML += 'mouse down <br/>';*/
	}
	return false;
}

combobox.prototype.mouse_over = function(ev)
{
	var target = dom.ev_target(ev);
	if (target.tagName == 'TD') {
		if (this.selected_el)
			dom.set_classname(this.selected_el, "normal");
		this.selected_el = target;
		dom.set_classname(this.selected_el, "highlighted");
	}
}

combobox.prototype.select = function(index)
{
	var elements = this.popup_el.getElementsByTagName("td");
	if (this.selected_index != undefined)
		dom.set_classname(elements[this.selected_index], "normal");
	this.selected_index = index;
	this.frame_el.innerHTML = this.list[index].label;
	dom.set_classname(elements[this.selected_index], "highlighted");
	dom.set_classname(this.frame_el, index > 0 ? "combobox_active" : "combobox");
}

combobox.prototype.mouse_up = function(ev)
{
	var target = dom.ev_target(ev);
	if (target == this.popup_el)
		return;
	var elements = this.popup_el.getElementsByTagName("td");
	var changed = false;
	for(var i = 0; i < elements.length; ++i)
		if (elements[i] == this.selected_el) {
			this.selected_index = i;
			this.frame_el.innerHTML = unescape(this.list[i].label);
			changed = true;
			break;
		}
	this.show_popup(false);
	if (changed) 
		this.change_handler();
}

combobox.prototype.populate = function(list)
{
	this.list = list;
	var html_code = '<table cellpadding="1" cellspacing="0"/>';
	for (var i = 0; i < list.length; ++i) {
		html_code += '<tr><td class="normal"';
		if (!parseInt(list[i].count))
			html_code += ' style="color: #909090;"';
		html_code += '"/> ' + unescape(list[i].label) + '</td></tr>';
	}
	this.popup_el.innerHTML = html_code + '</table>';
	if (this.selected_index == undefined)
		this.select(0);
}

combobox.prototype.selected = function()
{
	if (this.selected_index != undefined)
		return this.list[this.selected_index];
	else
		return undefined;
}

/*dropdown_list control*/

function dropdown_list(pos, dropdown_css_class, on_selected_cb, on_close_cb)
{
	this.selected_index = -1;
	this.on_selected_cb = on_selected_cb;
	this.on_close_cb = on_close_cb;

	this.popup_el = document.createElement('div');
	document.body.appendChild(this.popup_el);
	dom.move(this.popup_el, pos.x, pos.y + pos.h, pos.w, "auto");
	dom.set_classname(this.popup_el, dropdown_css_class);

	dom.add_listener(this.popup_el, "mouseover", dom.bind(this, 
		"on_mouse_over"));
	dom.add_listener(this.popup_el, "mouseup", dom.bind(this, 
		"on_mouse_up"));
	this.sel_listener = dom.add_listener(document, "selectstart", 
		dom.bind(this, "on_select_start"));
	this.click_listener = dom.add_listener(document, "mousedown", 
		dom.bind(this, "on_mouse_down"));
}

dropdown_list.prototype.select = function(index)
{
	if (index == this.selected_index || index < 0 || index >= this.list.length)
		return;
	var elements = this.popup_el.getElementsByTagName("LI");
	if (this.selected_el)
		dom.css_remove_selector(this.selected_el, "item_selected");
	this.selected_index = index;
	this.selected_el = elements[index];
	dom.css_add_selector(this.selected_el, "item_selected");
}

dropdown_list.prototype.destroy = function()
{
	document.body.removeChild(this.popup_el);
	this.on_selected_cb = this.on_close_cb = null;
	dom.remove_event(document, "mousedown", this.click_listener);
	dom.remove_event(document, "selectstart", this.sel_listener);
}

dropdown_list.prototype.on_select_start = function(ev) 
{
	return false;
}

dropdown_list.prototype.on_mouse_down = function(ev) 
{
	var target = dom.ev_target(ev);
	if (target != this.popup_el && !dom.is_child(this.popup_el, target)) {
		this.on_close_cb();
	}

	return false;
}

dropdown_list.prototype.on_mouse_up = function(ev)
{
	if (dom.ev_target(ev) != this.popup_el)
		this.click_handler(this.list[this.selected_index]);
}

dropdown_list.prototype.on_mouse_over = function(ev)
{
	var target = dom.ev_target(ev);
	if (target.tagName == 'LI')
		this.select(dom.index_of_node(this.popup_el.getElementsByTagName("LI"),
			target));
}

dropdown_list.prototype.on_keydown = function(ev)
{
	var key_code = dom.ev_keycode(ev);
	if (key_code == 13)
		this.click_handler(this.list[this.selected_index]);
	else if (key_code == 38)
		this.select(this.selected_index - 1);
	else if (key_code == 40)
		this.select(this.selected_index + 1);
}

dropdown_list.prototype.populate = function(list, item_formatter, click_handler)
{
	this.list = list;
	this.click_handler = click_handler;
	var html_code = "<ul>";
	for (var i = 0; i < list.length; ++i)
		html_code += item_formatter(list[i]);
	this.popup_el.innerHTML = html_code + "</ul>";
}


function search_box(input_id, dropdown_css_class, on_changed_cb, on_return_cb)
{
	this.input_el = dom.element(input_id);
	this.on_changed_cb = on_changed_cb;
	this.on_return_cb = on_return_cb;
	this.dropdown_css_class = dropdown_css_class;

	dom.add_listener(this.input_el, "keydown", dom.bind(this, "on_key_down"));
}

search_box.prototype.get_text = function()
{
	return this.input_el.value;
}

search_box.prototype.show_hints = function(show)
{
	if (show) {
		if (this.dropdown_el == null) {
			this.dropdown_el = new dropdown_list(dom.position(this.input_el), 
				this.dropdown_css_class, dom.bind(this, "on_hint_selected"), 
				dom.bind(this, "on_dropdown_closed"));
		}
	} else if (this.dropdown_el) {
		this.dropdown_el.destroy();
		this.dropdown_el = null;
	}
}

search_box.prototype.populate = function(list, formatter, click_handler)
{
	this.dropdown_el.populate(list, formatter, click_handler);
}

search_box.prototype.on_key_down = function(ev)
{
	var self = this;
	var key_code = dom.ev_keycode(ev);
	if (key_code == 13) {
		if (this.dropdown_el && this.dropdown_el.selected_index >= 0)
			this.dropdown_el.on_keydown(ev);
		else
			window.setTimeout(function() {self.on_return_cb(self);}, 1);
	} else {
		if (key_code == 38 || key_code == 40)
			this.dropdown_el.on_keydown(ev)
		else
			window.setTimeout(function() {self.on_changed_cb(self);}, 1);
	}
}

search_box.prototype.on_dropdown_closed = function()
{
	this.show_hints(false);
}

