window.OpinionPoll = function (id, opts)
{
	this.init();

	if (opts)
		this.set_options(opts);
	if (id)
		this.show(id);

	return this;
}

window.OpinionPoll.prototype = {
	DATA_PATH: "http://opinionpolls.welive.tv/opinionpolls/embed/",
	DATA_URI: "data.php",

	pid: null,
	element: null,
	options: {},

	templates: {
		loading: 'Loading...',
		question: '\
			<form action="javascript://">\
				<span class="poll_title"></span>\
				\
				<ul class="poll_choices"></ul>\
				\
				<input type="submit" value="Vote" class="poll_vote" />\
				<a href="" class="poll_show_results">View Results</a>\
			</form>',
		results: '\
			<span class="poll_title"></span>\
			\
			<ul class="poll_choices"></ul>',

		part_question_choice: '\
			<li class="poll_choice">\
				<label>\
					<input type="radio" name="choice" class="poll_choice_radio" />\
					<span class="poll_choice_text"></span>\
				</label>\
			</li>',
		part_question_answer: '\
			<li class="poll_answer">\
				<span class="poll_answer_text"></span>\
				<div class="poll_answer_percent">\
					<div class="poll_answer_bar"></div>\
					<div class="poll_answer_number"></div>\
				</div>\
			</li>'
	},

	init: function ()
	{
		this.templates = {};
		for (var k in OpinionPoll.prototype.templates)
			this.templates[k] = OpinionPoll.prototype.templates[k];
	},

	response_poll_question: function (pid, title, choices)
	{
		this.pid = pid;

		this.use_template("question");
		this.get_part("poll_title").innerHTML = title;

		var list = this.get_part("poll_choices");
		for (var i = 0; i < choices.length; i++)
		{
			var frag = this.make_part("question_choice");
			this.get_part("poll_choice_radio", frag).id = choices[i].id;
			this.get_part("poll_choice_text", frag).innerHTML = choices[i].title;

			list.appendChild(frag);
		}

		this.get_part("poll_vote").poll = this;
		this.get_part("poll_vote").onclick = function ()
		{
			var choices = this.poll.get_parts("poll_choice_radio");
			var choice = -1;

			for (var i = 0; i < choices.length; i++)
			{
				if (choices[i].checked)
					choice = choices[i].id;
			}

			if (choice == -1)
				alert("Please select an option.");
			else
				this.poll.communicate("vote", {pid: pid, choice: choice});
			return false;
		}

		this.get_part("poll_show_results").poll = this;
		this.get_part("poll_show_results").onclick = function ()
		{
			this.poll.communicate("load_results", {pid: pid});
			return false;
		}
	},

	response_poll_results: function (pid, title, choices, total)
	{
		this.pid = pid;

		this.use_template("results");
		this.get_part("poll_title").innerHTML = title;

		var list = this.get_part("poll_choices");
		for (var i = 0; i < choices.length; i++)
		{
			var frag = this.make_part("question_answer");
			var percent = total == 0 ? 0 : Math.floor(100 * choices[i].votes / total);

			this.get_part("poll_answer_text", frag).innerHTML = choices[i].title;
			this.get_part("poll_answer_bar", frag).style.width = percent + "%";
			this.get_part("poll_answer_number", frag).innerHTML = percent + "%";
			this.get_part("poll_answer_votes", frag).innerHTML = choices[i].votes;

			list.appendChild(frag);
		}
	},

	set_options: function (opts)
	{
		var supported = ["uid", "pid", "fallback"];

		for (var i = 0; i < supported.length; i++)
		{
			if (supported[i] in opts)
				this.options[supported[i]] = opts[supported[i]];
		}
	},

	set_template: function (name, value)
	{
		if (name in this.templates)
			this.templates[name] = value;
		return name in this.templates;
	},

	show: function (id)
	{
		this.element = document.getElementById(id);
		this.element.className += " opinionpoll";

		this.load_css("basic.css");

		this.use_template("loading");
		this.communicate("load_poll");
	},

	get_parts: function (name, ref)
	{
		if (!ref)
			ref = this.element;

		if ("getElementsByClassName" in ref)
			return ref.getElementsByClassName(name);

		var parents = [ref];
		var reg = new RegExp("(^| |\t)" + name.replace(/\-/g, "\\-") + "($| |\t)");

		var parts = [];
		while (parents.length > 0)
		{
			var parent = parents.pop();

			for (var i = 0; i < parent.childNodes.length; i++)
			{
				var node = parent.childNodes[i];
				if (reg.test(node.className))
					parts.push(node);

				if ("childNodes" in node)
					parents.push(node);
			}
		}

		return parts;
	},

	get_part: function (name, ref)
	{
		if (!ref)
			ref = this.element;

		if ("getElementsByClassName" in ref)
			return ref.getElementsByClassName(name)[0];

		var parents = [ref];
		var reg = new RegExp("(^| |\t)" + name.replace(/\-/g, "\\-") + "($| |\t)");

		while (parents.length > 0)
		{
			var parent = parents.pop();

			for (var i = 0; i < parent.childNodes.length; i++)
			{
				var node = parent.childNodes[i];
				if (reg.test(node.className))
					return node;

				if ("childNodes" in node)
					parents.push(node);
			}
		}

		return false;
	},

	make_part: function (name)
	{
		var frag = document.createDocumentFragment();
		var fake = document.createElement("div");
		fake.innerHTML = this.get_part_template(name);

		while (fake.childNodes.length > 0)
			frag.appendChild(fake.childNodes[0]);

		return frag;
	},

	get_part_template: function (name)
	{
		return this.templates["part_" + name];
	},

	use_template: function (name, ref)
	{
		if (!ref)
			ref = this.element;

		ref.innerHTML = this.templates[name];
	},

	load_css: function (file)
	{
		var head = document.getElementsByTagName("head");
		if (head.length != 0)
			head = head[0];
		else
			head = document.body;

		var link = document.createElement("link");
		link.type = 'text/css';
		link.rel = 'stylesheet';
		link.href = this.DATA_PATH + file;
		link.media = 'screen';

		head.appendChild(link);
	},

	communicate: function (act, vals, finish)
	{
		var cbo = "OpinionPoll_last" + new Date().getTime();
		var flat = ["action=" + encodeURIComponent(act), "t=" + new Date().getTime(), "cbo=" + encodeURIComponent(cbo)];

		vals = vals || {};
		for (var k in vals)
			flat.push(encodeURIComponent(k) + "=" + encodeURIComponent(vals[k]));
		for (var k in this.options)
			flat.push(encodeURIComponent("options[" + k + "]") + "=" + encodeURIComponent(this.options[k]));

		var url = this.DATA_PATH + this.DATA_URI + "?" + flat.join("&");

		window[cbo] = this;

		this.communicate_inner(url, finish);
	},

	communicate_inner: function (url, finish)
	{
		var script = document.createElement("script");
		var head = document.getElementsByTagName("head");
		if (head.length != 0)
			head = head[0];
		else
			head = document.body;

		function cleanup()
		{
			function cleanup_finish()
			{
				head.removeChild(script);
			}
			setTimeout(cleanup_finish, 0);
			if (finish)
				setTimeout(finish, 0);
		}

		script.onload = cleanup;
		script.onreadystatechange = function ()
		{
			if (this.readyState == "complete")
				cleanup();
		}

		script.type = "text/javascript";
		script.src = url;
		head.appendChild(script);
	},

	fire_event: function (type, params, obj)
	{
		var ev = {};
		var ontype;

		type = "OpinionPoll" + type;
		ontype = "on" + type;
		if (!obj)
			obj = window;

		if (document.createEvent)
			ev = document.createEvent("Event");

		if (params)
		{
			for (var k in params)
				ev[k] = params[k];
		}

		if (document.createEvent)
		{
			ev.initEvent(type, true, false);
			obj.dispatchEvent(ev);
		}

		if (ontype in obj)
			obj[ontype](ev);
	},

	fire_load: function ()
	{
		OpinionPoll.prototype.fire_event("Load");
	}
}

setTimeout(OpinionPoll.prototype.fire_load);

