/*

 * 程序名：traffic.js
 * 用  途：流量统计系统 JS 程序
 * 作  者：邓威
 * 日  期：2006-04-18 

 * 修　改：2006-04-27 邓威，针对不同浏览器采用不同方法提交数据
 * 修　改：2006-04-29 邓威，增加对 URL 为空时的处理
 * 修　改：2006-04-30 邓威，声明 urls 为全局变量，解决离开时 url 为空的问题
 * 修　改：2006-05-05 邓威，修改变量名及函数名，防止重名
 * 修　改：2006-05-23 邓威，增加 Traffic_checker() 功能来防止和其它页面的事件冲突；要求流量统计 JS 必须在其它 JS 的下边，否则 Traffic_checker() 不起作用
 * 修　改：2006-05-30 邓威，修改在 Document 对象未创建时发送 Traffic_EventStart() 失败的错误
 * 修　改：2006-08-03 邓威，加入 IO/OUT 对应标识；加入 MAC 地址识别
 * 修　改：2006-08-07 邓威，对新加入的 MD5 算法进行排版；分散对上级页及顶级页处理的语句；加入对 domain 处理使 JS 可以跨域调用
 * 修　改：2006-08-08 邓威，移除设置 domain 功能
 * 修　改：2006-08-31 邓威，增加 Traffic_type 功能，获取不同平台的流量统计信息，默认为网站的统计
 * 修　改：2006-09-18 邓威，增加对 IE 版本的控制，在 IE5 环境下用 escape 替代 encodeURIComponent
 * 修　改：2006-09-25 邓威，所有浏览器都采用 onunload 捕获离开事件
 * 修　改：2006-10-11 邓威，增加对 TVBOX 的支持
 * 修　改：2006-10-13 邓威，增加对傲游(Maxthon)浏览器的判断
 * 修　改：2006-10-16 邓威，增加对 CMS 发布系统的三个 ID 的支持
 * 修　改：2006-12-04 邓威，增加统计部门要求的类别ID、内容ID、内容类型、上线时间

 */

var Traffic_matrix                      = "http://traffic.uusee.com/traffic/traffic.php?";

var Traffic_Counter                     = {};
var Traffic_Sstring                     = (navigator.appName+" "+navigator.appVersion).toLowerCase();
var Traffic_isIE                        = (Traffic_Sstring.indexOf('msie')>-1)?true:false;
var Traffic_isOP                        = (Traffic_Sstring.indexOf('opera')>-1)?true:false;
var Traffic_isIE5                       = (Traffic_Sstring.indexOf('msie 5')>-1)?true:false;
var Traffic_isMaxthon                   = (Traffic_Sstring.indexOf('maxthon')>-1)?true:false;
var Traffic_urls                        = "";
var Traffic_oScript;
var Traffic_iStartTime                  = new Date();
var Traffic_MAC				= null;

var Traffic_function_onload;
var Traffic_function_onunload;
var Traffic_function_onbeforeunload;

/**
  如果是 IE5 刚彩 encodeURI 否则用 encodeURIComponent 处理 URL
  */

var Traffic_encode                      = (Traffic_isIE5?escape:encodeURIComponent);

/* to convert strings to a list of ascii values */
var sAscii = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ";
sAscii = sAscii + "[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
/* convert integer to hex string */
var sHex = "0123456789ABCDEF";

// 流量统计对象容器
document.write('<div id="traffic_Div" style="width:0px;height:0px;"></div>');
// 当前页面状态检查
Traffic_checker();

function Traffic_GetPara(strname)
{
	var hrefstr,pos,parastr,para,tempstr;
	hrefstr = window.location.href;
	pos = hrefstr.indexOf("?");
	parastr = hrefstr.substring(pos+1);
	para = parastr.split("&");
	tempstr = "";
	for(i=0;i<para.length;i++)
	{
		tempstr = para[i];
		pos = tempstr.indexOf("=");
		if( tempstr.substring(0,pos) == strname )
		{
			return tempstr.substring(pos+1);
		}
	}
	return null;
}
// 设置 cookie
function Traffic_SetCookie(name, value, expires, path, domain, secure)
{  
	if( expires !== null)
	{
		expires = new Date((new Date()).getTime() + expires * 3600000);
		expires = expires.toGMTString();
	}
	
	document.cookie = name + "=" + escape (value) +
		((expires) ? "; expires=" + expires : "") +
		((path) ? "; path=" + path : "") +
		((domain) ? "; domain=" + domain : "") +
		((secure) ? "; secure" : "");  
  
}
// 获取 cookie
function Traffic_GetCookie(name)
{
	var cookieValue = "";
	var search = name + "=";
	
	if(document.cookie.length > 0)
	{
		offset = document.cookie.indexOf(search);
		if (offset != -1)
		{
			offset += search.length;
			end = document.cookie.indexOf(";", offset);
			if (end == -1)
			{
				end = document.cookie.length;
			}
			cookieValue = unescape(document.cookie.substring(offset, end))
		}
	}
	return cookieValue;
}
// 得到屏幕颜色深度
function Traffic_GetCoolor(Collector)
{
	if ( navigator.appName == "Netscape")
	{
		return screen.pixelDepth;
	}
	else 
	{
		return screen.colorDepth;
	}
}
// 在流量统计对象容器内添加请求对象
function Traffic_Addins(sPlugins)
{
	// 创建 src 脚本对象
	// var oScript = document.createElement(sPlugins);
	// 在当前文档对象中插入脚本对象	
	// document.body.appendChild(oScript);	
	if( !sPlugins )
	{
		return false;
	}

	if( !Traffic_findobj("traffic_Div") )
	{
		var oScript = document.createElement('<div id="traffic_Div" style="width:0px;height:0px;"></div>');
		document.body.appendChild(oScript);
	}	

	if( !Traffic_findobj("traffic_Div") )
	{
		return "";
	}
	
	Traffic_findobj("traffic_Div").innerHTML = sPlugins;	
	return true;
}
// 发送请求
function Traffic_SendRequest(sUrl)
{
	var code;
	
	if( !Traffic_isOP )
	{
		code = '<img src="' + sUrl + '" style="display: none;" width="0px" height="0px" \/>';
	}
	else
	{
		code = '<iframe width="0" height="0" marginwidth="0" marginheight="0" frameborder="0" scrolling="no" src="' + sUrl + '"><\/iframe>';
	}
	Traffic_Addins(code);
	return;	
}
// 查找对象
function Traffic_findobj(s)
{
	return document.getElementById(s);
}
// 开始事件
function Traffic_EventStart()
{
	Traffic_urls = "";
	// Add by 邓威 2006-08-03 IO/OUT 对应标识
	Traffic_Counter.IOUT = calcMD5( Traffic_Counter.url + Traffic_iStartTime.toString() );

	// 获取由 ActiveX 控件传递的 MAC 地址
	try
	{
		if( updateC2 )
		{
			Traffic_Counter.MAC = updateC2.getMAC();
		}
	}
	catch(e)
	{
		Traffic_Counter.MAC = null;
	}

	for(var subObj in Traffic_Counter )
	{
		if( Traffic_Counter[subObj] ) 
		{
			try
			{
				Traffic_urls += subObj + "=" + Traffic_encode(Traffic_Counter[subObj].toString()) + "&" ;
			}
			catch(e)
			{
			}
		}
	}

	Traffic_SendRequest(Traffic_matrix + Traffic_urls + "action=IN");
}
// 离开事件
function Traffic_EventEnd()
{
	var delay = 1400000;    
	Traffic_iStayTime = new Date();
	Traffic_iStayTime = (Traffic_iStayTime - Traffic_iStartTime)/1000;
	Traffic_urls = "";

	for(var subObj in Traffic_Counter )
	{
		if( Traffic_Counter[subObj] )
		{
			try
			{
				Traffic_urls += subObj + "=" + Traffic_encode(Traffic_Counter[subObj].toString()) + "&" ;
			}
			catch(e)
			{
			}
		}
	}
	Traffic_urls += "staytime=" + Traffic_iStayTime + "&";
	Traffic_SendRequest(Traffic_matrix + Traffic_urls + "action=OUT");
	while(delay--){};
}
// 页面状态检查
function Traffic_checker()
{
	if( !Traffic_findobj("traffic_Div") )
	{
		setTimeout(Traffic_checker, 100);				
		return;
	}

	Traffic_Counter.referrer                = null;
	Traffic_Counter.url                     = null;
	Traffic_Counter.current_date            = new Date();
	Traffic_Counter.color                   = 0;
	Traffic_Counter.size                    = screen.width + ',' + screen.height;
	Traffic_Counter.color                   = Traffic_GetCoolor(Traffic_Counter);
	Traffic_Counter.timezone                = new Date().getTimezoneOffset()/-60;
	Traffic_Counter.parent_referrer         = "";
	Traffic_Counter.top_referrer            = "";
	Traffic_Counter.parent_url              = "";
	Traffic_Counter.top_url                 = "";
	Traffic_Counter.IOUT                    = "";	// IO/OUT 对应标识
	Traffic_Counter.MAC                     = null;	// MAC 地址
	Traffic_Counter.type                    = null;	
	Traffic_Counter.category_id		= null;
	Traffic_Counter.content_id		= null;
	Traffic_Counter.content_type		= null;
	Traffic_Counter.release_time		= null;
	
	try { Traffic_Counter.type = Traffic_type; } catch(e) { Traffic_Counter.type = null;}
	try { Traffic_Counter.referrer = document.referrer; } catch(e) {}
	try { Traffic_Counter.url = window.location;	} catch(e) {}
	try { Traffic_Counter.parent_referrer = window.parent.document.referrer; } catch(e) { Traffic_Counter.parent_referrer = null; }
	try { Traffic_Counter.top_referrer = top.document.referrer; } catch(e) { Traffic_Counter.top_referrer = null; }
	try { Traffic_Counter.parent_url = window.parent.location; } catch(e) { Traffic_Counter.parent_url = null; }
	try { Traffic_Counter.top_url = top.window.location;	} catch(e) { Traffic_Counter.top_url = null; }

	if( !Traffic_Counter.url )
	{ 
		Traffic_Counter.url = document.URL.toString(); 
	}
	
	if( "search" == Traffic_Counter.type )
	{
		// 搜索专用统计信息
		try 
		{
			Traffic_Counter.keyword = document.getElementById("queryString").value;
			Traffic_Counter.pageno = Traffic_GetPara("p");
		}
		catch(e) 
		{
			Traffic_Counter.keyword = null;
			Traffic_Counter.pageno = null;
		}
	}
	else if( "uuplayer" == Traffic_Counter.type ) 
	{
		// 客户端专用统计信息
		try 
		{
			Traffic_Counter.platform = UUPLAYER_platform;
			Traffic_Counter.channel_number = UUPLAYER_channel_number;
		}
		catch(e) 
		{
			Traffic_Counter.platform = null;
			Traffic_Counter.channel_number = null;
		}
	}
	else if( "tvbox" == Traffic_Counter.type ) 
	{
		// TV-BOX 专用统计信息
		try 
		{
			Traffic_Counter.tvbox_url = TVBOX_URL;
			Traffic_Counter.tvbox_status = TVBOX_STATUS;
		}
		catch(e) 
		{
			Traffic_Counter.tvbox_url = null;
			Traffic_Counter.tvbox_status = null;		
		}
	}

	Traffic_EventStart();
	// Last modified by 邓威 2006-09-25
	// 包括 IE 和 FF 全都采用 onunload 	
	if( Traffic_isOP || Traffic_isMaxthon )
	{
		if( window.onunload !== null )
		{
			Traffic_Fixed_onunload();
			window.onunload =  Traffic_function_onunload;
		}
		else
		{
			window.onunload = Traffic_EventEnd;
		}
	}
	else
	{
		if( window.onbeforeunload !== null )
		{
			Traffic_Fixed_onbeforeunload();
			window.onbeforeunload = Traffic_function_onbeforeunload;
		}
		else
		{
			window.onbeforeunload = Traffic_EventEnd;
		}
	}
}
// onload 修正
function Traffic_Fixed_onload()
{
	var tmp_onload = false;
	if ( window.onload )
	{
		tmp_onload = window.onload;
	}
	Traffic_function_onload = function(){ tmp_onload();Traffic_EventStart(); };
}
// onunload 修正
function Traffic_Fixed_onunload()
{
	var tmp_onunload = false;
	if ( window.onunload )
	{
		tmp_onunload = window.onunload;
	}
	Traffic_function_onunload = function(){ tmp_onunload();Traffic_EventEnd(); };
}
// onbeforeunload 修正
function Traffic_Fixed_onbeforeunload()
{
	var tmp_onbeforeunload = false;
	if ( window.onbeforeunload )
	{
		tmp_onbeforeunload = window.onbeforeunload;
	}
	Traffic_function_onbeforeunload = function(){ tmp_onbeforeunload();Traffic_EventEnd(); };
}
// MD5 函数
function hex(i)
{
	h = "";
	for(j = 0; j <= 3; j++)
	{
		h += sHex.charAt((i >> (j * 8 + 4)) & 0x0F) +
		sHex.charAt((i >> (j * 8)) & 0x0F);
	}
	return h;
}

/* add, handling overflows correctly */
function add(x, y)
{
	return ((x&0x7FFFFFFF) + (y&0x7FFFFFFF)) ^ (x&0x80000000) ^ (y&0x80000000);
}

/* MD5 rounds functions */
function R1(A, B, C, D, X, S, T)
{
	q = add(add(A, (B & C) | (~B & D)), add(X, T));
	return add((q << S) | ((q >> (32 - S)) & (Math.pow(2, S) - 1)), B);
}

function R2(A, B, C, D, X, S, T)
{
	q = add(add(A, (B & D) | (C & ~D)), add(X, T));
	return add((q << S) | ((q >> (32 - S)) & (Math.pow(2, S) - 1)), B);
}

function R3(A, B, C, D, X, S, T)
{
	q = add(add(A, B ^ C ^ D), add(X, T));
	return add((q << S) | ((q >> (32 - S)) & (Math.pow(2, S) - 1)), B);
}

function R4(A, B, C, D, X, S, T)
{
	q = add(add(A, C ^ (B | ~D)), add(X, T));
	return add((q << S) | ((q >> (32 - S)) & (Math.pow(2, S) - 1)), B);
}

/* main entry point */
function calcMD5(sInp)
{
	/* Calculate length in machine words, including padding */
	wLen = (((sInp.length + 8) >> 6) + 1) << 4;
	var X = new Array(wLen);

	/* Convert string to array of words */
	j = 4;
	for (i = 0; (i * 4) < sInp.length; i++)
	{
		X[i] = 0;
		for (j = 0; (j < 4) && ((j + i * 4) < sInp.length); j++)
		{
			X[i] += (sAscii.indexOf(sInp.charAt((i * 4) + j)) + 32) << (j * 8);
		}
	}

	/* Append padding bits and length */
	if (j == 4)
	{
		X[i++] = 0x80;
	}
	else
	{
		X[i - 1] += 0x80 << (j * 8);
	}
	for(; i < wLen; i++) { X[i] = 0; }
	X[wLen - 2] = sInp.length * 8;

	/* hard-coded initial values */
	var a = 0x67452301;
	var b = 0xefcdab89;
	var c = 0x98badcfe;
	var d = 0x10325476;

	/* Process each 16-word block in turn */
	for (i = 0; i < wLen; i += 16) {
		aO = a;
		bO = b;
		cO = c;
		dO = d;

		a = R1(a, b, c, d, X[i+ 0], 7 , 0xd76aa478);
		d = R1(d, a, b, c, X[i+ 1], 12, 0xe8c7b756);
		c = R1(c, d, a, b, X[i+ 2], 17, 0x242070db);
		b = R1(b, c, d, a, X[i+ 3], 22, 0xc1bdceee);
		a = R1(a, b, c, d, X[i+ 4], 7 , 0xf57c0faf);
		d = R1(d, a, b, c, X[i+ 5], 12, 0x4787c62a);
		c = R1(c, d, a, b, X[i+ 6], 17, 0xa8304613);
		b = R1(b, c, d, a, X[i+ 7], 22, 0xfd469501);
		a = R1(a, b, c, d, X[i+ 8], 7 , 0x698098d8);
		d = R1(d, a, b, c, X[i+ 9], 12, 0x8b44f7af);
		c = R1(c, d, a, b, X[i+10], 17, 0xffff5bb1);
		b = R1(b, c, d, a, X[i+11], 22, 0x895cd7be);
		a = R1(a, b, c, d, X[i+12], 7 , 0x6b901122);
		d = R1(d, a, b, c, X[i+13], 12, 0xfd987193);
		c = R1(c, d, a, b, X[i+14], 17, 0xa679438e);
		b = R1(b, c, d, a, X[i+15], 22, 0x49b40821);
	
		a = R2(a, b, c, d, X[i+ 1], 5 , 0xf61e2562);
		d = R2(d, a, b, c, X[i+ 6], 9 , 0xc040b340);
		c = R2(c, d, a, b, X[i+11], 14, 0x265e5a51);
		b = R2(b, c, d, a, X[i+ 0], 20, 0xe9b6c7aa);
		a = R2(a, b, c, d, X[i+ 5], 5 , 0xd62f105d);
		d = R2(d, a, b, c, X[i+10], 9 , 0x2441453);
		c = R2(c, d, a, b, X[i+15], 14, 0xd8a1e681);
		b = R2(b, c, d, a, X[i+ 4], 20, 0xe7d3fbc8);
		a = R2(a, b, c, d, X[i+ 9], 5 , 0x21e1cde6);
		d = R2(d, a, b, c, X[i+14], 9 , 0xc33707d6);
		c = R2(c, d, a, b, X[i+ 3], 14, 0xf4d50d87);
		b = R2(b, c, d, a, X[i+ 8], 20, 0x455a14ed);
		a = R2(a, b, c, d, X[i+13], 5 , 0xa9e3e905);
		d = R2(d, a, b, c, X[i+ 2], 9 , 0xfcefa3f8);
		c = R2(c, d, a, b, X[i+ 7], 14, 0x676f02d9);
		b = R2(b, c, d, a, X[i+12], 20, 0x8d2a4c8a);
	
		a = R3(a, b, c, d, X[i+ 5], 4 , 0xfffa3942);
		d = R3(d, a, b, c, X[i+ 8], 11, 0x8771f681);
		c = R3(c, d, a, b, X[i+11], 16, 0x6d9d6122);
		b = R3(b, c, d, a, X[i+14], 23, 0xfde5380c);
		a = R3(a, b, c, d, X[i+ 1], 4 , 0xa4beea44);
		d = R3(d, a, b, c, X[i+ 4], 11, 0x4bdecfa9);
		c = R3(c, d, a, b, X[i+ 7], 16, 0xf6bb4b60);
		b = R3(b, c, d, a, X[i+10], 23, 0xbebfbc70);
		a = R3(a, b, c, d, X[i+13], 4 , 0x289b7ec6);
		d = R3(d, a, b, c, X[i+ 0], 11, 0xeaa127fa);
		c = R3(c, d, a, b, X[i+ 3], 16, 0xd4ef3085);
		b = R3(b, c, d, a, X[i+ 6], 23, 0x4881d05);
		a = R3(a, b, c, d, X[i+ 9], 4 , 0xd9d4d039);
		d = R3(d, a, b, c, X[i+12], 11, 0xe6db99e5);
		c = R3(c, d, a, b, X[i+15], 16, 0x1fa27cf8);
		b = R3(b, c, d, a, X[i+ 2], 23, 0xc4ac5665);
		
		a = R4(a, b, c, d, X[i+ 0], 6 , 0xf4292244);
		d = R4(d, a, b, c, X[i+ 7], 10, 0x432aff97);
		c = R4(c, d, a, b, X[i+14], 15, 0xab9423a7);
		b = R4(b, c, d, a, X[i+ 5], 21, 0xfc93a039);
		a = R4(a, b, c, d, X[i+12], 6 , 0x655b59c3);
		d = R4(d, a, b, c, X[i+ 3], 10, 0x8f0ccc92);
		c = R4(c, d, a, b, X[i+10], 15, 0xffeff47d);
		b = R4(b, c, d, a, X[i+ 1], 21, 0x85845dd1);
		a = R4(a, b, c, d, X[i+ 8], 6 , 0x6fa87e4f);
		d = R4(d, a, b, c, X[i+15], 10, 0xfe2ce6e0);
		c = R4(c, d, a, b, X[i+ 6], 15, 0xa3014314);
		b = R4(b, c, d, a, X[i+13], 21, 0x4e0811a1);
		a = R4(a, b, c, d, X[i+ 4], 6 , 0xf7537e82);
		d = R4(d, a, b, c, X[i+11], 10, 0xbd3af235);
		c = R4(c, d, a, b, X[i+ 2], 15, 0x2ad7d2bb);
		b = R4(b, c, d, a, X[i+ 9], 21, 0xeb86d391);

		a = add(a, aO);
		b = add(b, bO);
		c = add(c, cO);
		d = add(d, dO);
	}
	return hex(a) + hex(b) + hex(c) + hex(d);
}
