﻿/*--
标题：频道控件
设计：王集鹄
博客：http://blog.csdn.net/zswang
日期：2009年4月8日
修改：2009年4月26日
--*/

// 2009年7月24日 完善 加强掉线保护
// 2009年8月9日 添加 频道列表实时显示

if (!Common.scripts["Channel"]) {
	loadCss("/Scripts/Channel.css?version=2009091001");
	Common.scripts["Channel"] = true;
}

function Channel(url, channel) {
	this.url = url;
	this.channel = channel;
	this.entering = false;
	this.interval = 3000;
	this.timer = 0;
	this.index = 0;
	this.directors = [];
	var self = this;

	addEventHandler(window, "beforeunload", function(e) {
		if (!self.entering || !self.unloadmessage) return;
		e = e || event;
		e ? e.returnValue = self.unloadmessage : null;
		self.action("check", "");
		return self.unloadmessage;
	});
}

Channel.prototype.enter = function() {
	if (!this.url || !this.channel) return;
	this.index = 0;
	this.action("enter", "");
	this.respireTime = new Date().getTime();

	var self = this;
	clearTimeout(self.respireTimer);
	clearTimeout(self.timer);
	this.respireTimer = setInterval(function() {
		if (self.black) {
			clearTimeout(self.respireTimer);
			clearTimeout(self.timer);
			return;
		}
		var tick = new Date().getTime() - self.respireTime;
		if (tick >= 15 * 1000) {
			self.interval = 3000;
			clearTimeout(self.timer);
			self.timer = setTimeout(function() {
				self.respire();
			}, self.interval);
			if (self.onerror) self.onerror("[color=#cc0000]可能掉线了，正在修复。[/color]");
		}
	}, 5000);
}

Channel.prototype.exit = function() {
	if (!this.url || !this.channel) return;
	this.action("exit", "");
}

Channel.prototype.respire = function() {
	if (!this.url || !this.channel) return;
	this.action("respire", "");
	this.respireTime = new Date().getTime();
}

Channel.prototype.action = function(action, param) {
	if (!this.url || !this.channel) return;
	if (this.black) return;
	var self = this;
	var data = {};
	var tick = new Date().getTime();
	data.channel = this.channel;
	data.action = action;
	data.param = param;
	data.index = this.index;
	requestHttp(this.url, 'POST', json2Text(data), function(xmlhttp) {
		try {
			if (typeof self.ondelay == "function") self.ondelay(new Date().getTime() - tick);
			if (!xmlhttp.responseText) return;
			var result = str2Object(xmlhttp.responseText);
			if (result.error) {
				if (self.onerror) self.onerror(result.error);
				clearTimeout(self.timer);
				if (result.black) {
					self.black = result.black;
					clearInterval(self.respireTime);
					return;
				}
				if (result.error.indexOf("请求的序号超出范围") >= 0) {
					clearInterval(self.respireTime);
					self.enter();
					return;
				}
				self.timer = setTimeout(function() {
					self.respire();
				}, self.interval);
				return;
			}
			switch (action) {
				case "enter":
				case "respire":
					self.interval = Math.min(7000, self.interval + 100);
					clearTimeout(self.timer);
					self.timer = setTimeout(function() {
						self.respire();
					}, self.interval);
					if (action == "enter") {
						self.entering = true;
						if (self.channels) self.channels.detect();
					}
					break;
				default:
					self.interval = 3000;
					break;
			}
			if (result.from == self.index) {
				self.index = result.to;
				for (var i = 0; i < self.directors.length; i++) {
					if (typeof self.directors[i].action == "function")
						self.directors[i].action(action, param, result);
				}
			}
			if (self.channels && result.channels) {
				self.channels.update(result.channels);
			}
			switch (action) {
				case "exit":
					self.entering = false;
					clearTimeout(self.timer);
					clearInterval(self.respireTimer);
					if (typeof self.onclose == "function") self.onclose();
					break;
			}
		} catch (e) {
			alert("Channel.prototype.action() : " + e.message);
		}
	}, function() {
		if (self.onerror) self.onerror("[color=#cc0000]网络出现异常。[/color]");
		clearTimeout(self.timer);
		self.timer = setTimeout(function() {
			self.respire();
		}, self.interval);
	});
}

Channel.prototype.addDirector = function(director) {
	if (!director) return;
	var self = this;
	director.channel = this;
	director.onaction = function(action, param) {
		self.action(action, param);
	};
	this.directors.push(director);
}

Channel.Ping = function(url, channel, loaded) {
	if (typeof loaded != "function") return;
	var data = {};
	data.channel = channel;
	data.action = "ping";
	data.index = 0;
	requestHttp(url, 'POST', json2Text(data), function(xmlhttp) {
		try {
			var result = str2Object(xmlhttp.responseText);
			if (result.error) return;
			loaded(result);
		} catch (e) {
			alert(e.message);
		}
	});
}

function Channels(parent, channel, plugin) {
	this.plugin = plugin;
	this.parent = parent || document.body;
	if (typeof channel == "string")
		this.url = channel;
	else this.channel = channel;

	this.div_channels = document.createElement("div");
	this.div_title = document.createElement("div");
	this.div_title.innerHTML = ubb2Html("[b]房间列表[/b]");

	this.span_title = document.createElement("span");
	this.span_title.innerHTML = ubb2Html("在线");
	this.div_title.appendChild(this.span_title);
	
	this.div_title.style.backgroundColor = "#cccccc";
	this.div_channels.appendChild(this.div_title);
	this.parent.appendChild(this.div_channels);
	if (this.channel) this.channel.channels = this;
	this.channels = {};
}

Channels.prototype.update = function(channels) {
	if (!this.detecting) return;
	var names = [];
	for (var i in channels) names.push(i);
	names.sort(function(a, b){
		a = parseInt("0" + /\d+$/.exec(a.replace(/big|extend/ig, "100")), 10);
		b = parseInt("0" + /\d+$/.exec(b.replace(/big|extend/ig, "100")), 10);
		var result = a - b;
		if (result == 0) return a > b ? 1 : (a < b ? -1 : 0);
		return result;
	});
	
	for (var k = 0; k < names.length; k++) {  
		var i = names[k];
		if (this.channels[i]) {
			this.channels[i].a_link.innerHTML = ubb2Html("[b]房间：[/b]" + channels[i].subject
				+ " [b]在线：[/b]" + channels[i].number + "人");
			var j = 0;
			var html = "";
			while (channels[i]["p" + j + ".caption"]) {
				html += "、" + ubb2Html(channels[i]["p" + j + ".caption"]);
				j++;
			}
			this.channels[i].span_players.innerHTML = html.replace(/^、/, "");
			this.channels[i].number = channels[i].number;
		} else {
			this.channels[i] = {};
			var channel = document.createElement("div");
			this.channels[i].div_channel = channel;
			this.channels[i].number = channels[i].number;
			channel.className = "div_channel";
			
			var link = document.createElement("a");
			this.channels[i].a_link = link;
			link.innerHTML = ubb2Html("[b]房间：[/b]" + channels[i].subject
				+ " [b]在线：[/b]" + channels[i].number + "人");
			link.href = channels[i].url;
			link.onclick = function() { publics.counter('click_channel', location); };
			channel.appendChild(link);
			
			var players = document.createElement("span");
			this.channels[i].span_players = players;
			var j = 0;
			var html = "";
			while (channels[i]["p" + j + ".caption"]) {
				html += "、" + ubb2Html(channels[i]["p" + j + ".caption"]);
				j++;
			}
			players.innerHTML = html.replace(/^、/, "");
			channel.appendChild(players);
			this.div_channels.appendChild(channel);
		}
	}
	var number = 0;
	for (var i in this.channels)
		number += parseInt(this.channels[i].number);
	this.div_title.innerHTML = ubb2Html("[b]房间列表 共在线：[/b]" + number + "人");
}

Channels.prototype.detect = function() {
	if (!this.plugin) return;
	this.detecting = false;
	var self = this;
	var data = {};
	data.action = "detect";
	data.plugin = this.plugin;
	requestHttp(this.channel ? this.channel.url : this.url, 'POST', 
		json2Text(data), function(xmlhttp) {
		try {
			var result = str2Object(xmlhttp.responseText);
			if (result.error) return;
			self.detecting = true;
			self.update(result.channels);
		} catch (e) {
			alert(e.message);
		}
	});
}