String.prototype.stripAndExtractScripts = function () {
	var html = '', scripts = [];
	var m, pStart = /<script[^>]*(\/)?>/img, pEnd = "</script>", right = 0;
	while ((m = pStart.exec(this)) != null) {
		var start = pStart.lastIndex - m[0].length, last = pStart.lastIndex;
		html += this.substring(right, start);
		right = last;
		if (m[1]) continue;  // <script />

		var index = this.indexOf(pEnd, right);
		if (index == -1) throw "No </script> tag";

		var script = this.substring(right, index);
		right = index + pEnd.length;
		script = script.replace(/^\s*<!--\s*/m, '')
		               .replace(/\s*(?:\/\/\s*)?-->\s*$/m, '');
		if (!script) continue;

		scripts.push(script);
	}
	html += this.substring(right);
	return { "html": html, "scripts": scripts };
};

var Category = {

	COOKIE_TMPL: new Template('nicocategory=#{category}; expires=#{expires}; path=/'),
	COOKIE_EXPIRE: 30 * 24 * 60 * 60 * 1000,

	updateCallbacks: [],

	get: function (tag) {
		var param = '';

		if (tag !== undefined) {
			param = 'g=' + encodeURIComponent(tag);
			if (tag === '') {
				tag = 'allcategory';
			}
		}

		Category.sendRequest(param, tag);
	},

	sendRequest: function (parameters) {
		var tag = arguments[1];
		return new Ajax.Request('./category_recent.php', {
			parameters: parameters,
			onSuccess: function (req) {
				if (req && req.responseText) {
					var html = req.responseText;
					var data = html.stripAndExtractScripts();

					var fullPage;
					try { fullPage = req.getResponseHeader('X-Full-Page'); } catch (e) { }
					if (fullPage) {
						data.fullPage = true;
					}

					data.category = tag;
					Category.update(data, false);
				}
			}
		});
	},

	update: function (data, updateCookie) {
		if (data.fullPage) {
			$('PAGEBODY').update(data.html);
		} else {
			$('category_recent').update(data.html);
		}

		Category.updateCallbacks.each(function (callback) {
			try { callback(data); } catch (e) { }
		});
		data.scripts.each(function(script) {
			try { eval(script); } catch (e) { }
		});

		if (updateCookie && data.category) {
			var expire = (new Date());
			expire.setTime(expire.getTime() + Category.COOKIE_EXPIRE);

			document.cookie = Category.COOKIE_TMPL.evaluate({
				category: data.category,
				expires:  expire.toGMTString()
			});
		}
	},

	onUpdate: function (callback) {
		Category.updateCallbacks.push(callback);
	}

};

function switchCategoryTag(tag) {
	Category.get(tag);
}

function submitAdult(form) {
	var param = Form.serialize(form);
	Form.disable(form);
	Category.sendRequest(param);
}

function updateColumnMode(tag, col) {
	Cookie.set('col', col, 1000*60*60*24*365, '.nicovideo.jp', '/');
	switchCategoryTag(tag);
}
