//////////////////////////////////////////////////////
// globals
//////////////////////////////////////////////////////
var $WM = {
	hostYID 	: '',
	defaultYID 	: '',
	currentYID 	: '',
	isLoggedin	: false,
	msgCount	: 0,
	blonCount	: 0,
	constmsg	: ["%d", "%d", "我在线", "我隐身"]
};
var hostOnline = {e:"0", o:"0"};
// get sth by id
function $$(name) {
	return document.getElementById(name);
}

// get the movie reference
function $m(movieName) {
    if (navigator.appName.indexOf("Microsoft") != -1) {
        return window[movieName];
    } else {
        return document[movieName];
    }
}

// get/create a div
function $d(name) {
	var d = $$(name);
	if (!d) {
		d = document.createElement("div");
		d.id = name;
		document.getElementsByTagName("body")[0].appendChild(d);
	}
	return d;
}

function getCookie() {
	var c=document.cookie;
	var auth= "";
	var ar= c.split("; ");
	for(var i=0; i<ar.length; i++){
        if((ar[i].charAt(0)=="Y" || ar[i].charAt(0)=="T") && ar[i].charAt(1)=="="){
            auth+=ar[i]+"; ";
        }
	}
	auth=auth.substr(0, auth.length-2);
	return auth;
}

function getUserName(cookie) {
	if (!cookie) {
		cookie = getCookie();
	}
	var ar = cookie.split("; ");
	var y = "";
	for (var i = 0; i<ar.length; i++) {
		if (ar[i].indexOf("Y=") == 0) {
			y = ar[i];
		}
	}
	var lIndex = Math.max(y.indexOf("&l="), y.indexOf("=l="));
	var lEndIndex = y.indexOf("&", lIndex+3);
	if (lEndIndex == -1) {
		lEndIndex = y.length;
	}
	if (lIndex == -1) {
		return null;
	}
	var a = y.substring(lIndex+3, lEndIndex-2);
	var b = "";
	for (var i = 0; i<a.length; i++) {
		var c = a.charCodeAt(i);
		if (c<48) {
		} else if (c<58) {
			c += 49;	// 0-9 => a-j
		} else if (c<96) {
		} else if (c<113) {
			c += 10;
		} else {
			c -= 65;
		}
		b += String.fromCharCode(c);
	}
	return b;
}

function set_cookie(cn, cv, d, dm) {
	var now = new Date();
	var expire = new Date();
	if(d==null || d==0)
		d=1;
	expire.setTime(now.getTime() + 3600000 * 24 * d);
	document.cookie = cn + "=" + escape(cv) + ";expires=" + expire.toGMTString() + ";path=/" + ";domain=" + dm;
}

function delete_cookie(cn,dm) {
	if(get_cookie(cn)) {
		document.cookie = cn + "=" + ";path=/" + ((dm)?"; domain=" + dm:"") + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
	}
}
	
function get_cookie(cn) {
	var dc = document.cookie;
	var prefix = cn + "=";
	var begin = dc.indexOf("; " + prefix);
	if(begin == -1) {
		begin = dc.indexOf(prefix);
		if(begin!=0)
			return null;
	}
	else {
		begin += 2;
	}
	var end = document.cookie.indexOf(";",begin);
	if(end == -1) {
		end = dc.length;
	}
	return unescape(dc.substring(begin + prefix.length, end));
}
/**
 *   Gets the flash player version
 *
 *   @returns the flash version
 */
function getFPV()
{
    var ver,fi, n = navigator;
    if(n.plugins && n.plugins.length)
    {
        fi = n.plugins["Shockwave Flash"];
        if(fi && fi.description)
        {
            fi = fi.description;
            ver = fi.charAt(fi.indexOf(".")-1);
        }
    }
    else if(n.mimeTypes && n.mimeTypes.length)
    {
        fi = n.mimeTypes["application/x-shockwave-flash"];
        if(fi && fi.enabledPlugin && fi.enabledPlugin.description)
        {
            fi = fi.enabledPlugin.description;
            ver = fi.charAt(fi.indexOf(".")-1);
        }
    }
    else
    {
        for(var a = 0; a < 12; ++a)
        {
            try
            {
                var b = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+a);
                ver = a;
            }
            catch (e){}
        }
    }
    return ver;
}

//Convert JSON to XML
//The biggest catch currently is that arrays can only contain other objects
function j2x(o, tag) {
	// obj, arr arrays in case there are attribs mixed in
	var objs = [];
	var arrs = [];
	
	if (!tag)
		tag = 'payload';
	
	var x = ['<'+tag+' '];
	for (var key in o) {
		if (typeOf(o[key]) === 'object')
			objs.push(key);
		else if (typeOf(o[key]) === 'array')
			arrs.push(key);
		else
		{
			x.push(key);
			x.push('="');
			var strn = o[key];
			if(typeOf(strn) === 'number') {
				strn = String(strn);
			}
			x.push(strn);
			x.push('" ');
		}
	}
	x.push('>');

	var n;
	for (n=0; n<objs.length; n++)
		x.push(j2x(o[objs[n]], objs[n]));

	for (n=0; n<arrs.length; n++)
	{
		var arr = o[arrs[n]];
		for (var i=0; i<arr.length; i++)
		{
			if (typeOf(arr[i]) === 'object')
				x.push(j2x(arr[i], arrs[n]));
		}
	}

	x.push('</'+tag+'>');    
	return x.join("");
}

function typeOf(val)
{
	var s = typeof val;
	if (s === 'object') {
		if (val) {
			if (val instanceof Array) {
				s = 'array';
			}
		} else {
			s = 'null';
		}
	}
	return s; 
}

//////////////////////////////////////////////////////
// sdk
//////////////////////////////////////////////////////
// WEBSDK namespace: required by websdk2_js.swf
var cb;
var YEvent = null;
var YCONST = null;

var websdk = function() {
	var _sdk = null;
	var _loaded = false;
	var _const = {};
	var _callbacks;
	var _self = this;
	var _api = {
		"load": load,
		"onLoaded": onLoaded,
		"onEvent": onEvent,
		"log": log,
		"send": send,
		"login": login,
		"logoff": logoff,
		"eov": ""		// end of API lists
	};

    // Init callback table
	function initcb() {
		// a reverse lookup table from const value to string
		var n;
		_callbacks = {};
		for (var s in YCONST) {
            var a = s.split("_");
			if (a[0] == "YES" && a[1] != "STATUS") {
				n = YCONST[s];
				_const[n] = s;
				// function named as "handle_prelogin_data"
				_callbacks[n] = "handle_"+s.split("_").slice(1).join("_").toLowerCase();
			}
		}
		cb = _callbacks;
	}
	
	function load() {
        if (getFPV() < 9) {
			alert("Flash player 9 or latest version is required!");
            return;
        }
        
		var buf = [
				'<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"',
				'id="WEBSDK2" width="1" height="1"',
				'codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">',
				'<param name="movie" value="http://cn.webmessenger.yahoo.com/websdk2_js.swf" />',
				'<param name="quality" value="high" />',
				'<param name="bgcolor" value="#869ca7" />',
				'<param name="allowScriptAccess" value="always" />',
				'<embed src="http://cn.webmessenger.yahoo.com/websdk2_js.swf"',
				'	quality="high" bgcolor="#869ca7"',
				'	width="1" height="1" name="WEBSDK2" align="middle"',
				'	play="true"',
				'	loop="false"',
				'	quality="high"',
				'	allowScriptAccess="always"',
				'	type="application/x-shockwave-flash"',
				'	pluginspage="http://www.macromedia.com/go/getflashplayer">',
				'</embed>',
				'</object>'
				].join(" ");
		$d("id_sdk").innerHTML = buf;
	}
		
	function onLoaded(params) {
		// TODO: why double loading?
		if (!_loaded) {
			_loaded = true;
			YEvent = params.YEvent;
			YCONST = params.YCONST;
			initcb();
			log("onLoaded");
			_sdk = $m("WEBSDK2");
			setTimeout("websdk.login()", 1000);
		}
	}
	
	function login() {
		_sdk.login(app.getConfig());
	}
	
	function logoff() {
		_sdk.logoff();
	}
	
	function send(type, payload) {
		_sdk.send(type, payload);
	}

	function log(s) {
		gLog(s);
	}
	
	function onEvent(event, params) {
		log("onEvent: " + event);
		var fn = _callbacks[event];
        gLog("sdk:onEvent(), " + fn);
		if (fn && app[fn]) {
			app[fn](params);
		} else {
			YLog.log_e("sdk.onEvent()- undefined event handler: "+event);
		}
	}
	//
	return _api;
}();

//////////////////////////////////////////////////////
// app
//////////////////////////////////////////////////////
var app = function()
{
	var self;
	var $c = websdk;		//YAHOO.Msgr.ClientLib;
	var _loggedIn = false;

	var _memberInfos = {};
	var _blockInfos = {};

	/**
	*	Initializes the client
	*/
    var _server, _port;
	function init(s, p)
	{
        _server = s;
        _port = p
		self = this;
		gLog("app::init() >>>>> start_time: " + (new Date()).getTime());
		$c.load();
	}
	//lwmcs1.msg.dcn.yahoo.com
	//wm.cn.scs.msg.yahoo.com
	//httpcs1.msg.dcn.yahoo.com
	//httpcs1.msg.vip.cnb.yahoo.com
	function getConfig() {
		var o = {	servers: [
										{host: "wm.cn.scs.msg.yahoo.com", port: 5050},
										{host: "webcs1.msg.cnb.yahoo.com", port: 5050},
										{host: "webcs2.msg.cnb.yahoo.com", port: 5050},
										], 
					cookie: getCookie(),
					userId: null,
					vendorId: 403,
					weight: 6,
					visible: true
				};
		// use specified server/port combination
		if (_server && _port) {
			o.servers = [{host: _server, port: _port}];
		}
		return o;
	}

	function onStatus(data)
	{
		if(_memberInfos && _memberInfos[data.name]) {
			if(data.away_status) {
				_memberInfos[data.name].statusInfo.awayStatus = parseInt(data.away_status);
				if(!!data.custom_dnd_status && '1' == data.custom_dnd_status) {
					_memberInfos[data.name].statusInfo.customDNDStatus = 1;
				}
				else {
					_memberInfos[data.name].statusInfo.customDNDStatus = 0;
				}
				if(data.away_status != YCONST.YMSG_Offline) {
					_memberInfos[data.name].isOnline = true;
				}
				else {
					_memberInfos[data.name].isOnline = false;
				}
			}
			if(data.away_msg) {
				_memberInfos[data.name].statusInfo.customMessage = data.away_msg;
			}
		}
	}

	/* 
	 * Event handlers 
	 */	
	function handle_logged_in(params) {
		gLog("app::handle_logged_in()");
		// for webmessenger
		if(!_loggedIn) {
			_loggedIn = true;
			$WM.isLoggedin = true;
			var bldcookie_t = window.setInterval(function() {
				if($WM.isLoggedin) {
					var nn = 0;
					for(var mm in _memberInfos) {
						if(_memberInfos[mm].isOnline == true) {
							nn++;
						}
					}
					set_cookie("cn_wm_blonn", String(nn), 360, ".yahoo.com");
				}
			}, 1000);
			var visible_t = window.setTimeout(function() {
				if(!!visible_t) {
					window.clearTimeout(visible_t);
					var vv = get_cookie("cn_wm_visible") || "1";
			        var c = parseInt(vv);
			        if(isNaN(c)) {
			            c = 1;
			        }
					if(c) {
						setOldVisibility(true);
					}
					else {
						setOldVisibility(false);
					}
				}
			}, 10);
		}
	}

	function handle_connection_failed(params) {
		gLog("app::handle_connection_failed()");
		$WM.isLoggedin = false;
		_memberInfos = [];
	}

	function handle_user_logoff_err(params) {
		gLog("app::handle_user_logoff_err()");
		$WM.isLoggedin = false;
		_memberInfos = [];
	}

    function handle_prelogin_data(params) {
        gLog("app::handle_prelogin_data()");
        self.opts.profile = params.user_id;
        self.opts.profiles = params.identity_list.split(",");
    }
	
    function handle_buddy_list(params) {
		gLog("app::handle_buddy_list()");
		// forward list only
		try {
			var glist = params.group_record_list.records;
		} catch (e) {
			gLog("[Error][app::handle_prelogin_data] Failed to get buddy list.")
			return;
		}
		var len = glist.length;
		for(var n=0; n<len; n++) {
			var g = glist[n];
			try {
				var rs = g.buddy_record_list.records;
			} catch (e) {
                gLog("[Error][app::handle_prelogin_data] Failed to get buddy list for a group.")
            }
            var rlen = rs.length;
			for (var m=0; m<rlen; m++) {
				var b = rs[m];
				_memberInfos[b.name] = {
					username: b.name, 
					groupname: g.name, 
					isOnline: (!!b.away_status&&b.away_status!=YCONST.YMSG_Offline)?true:false, 
					isUnauth: true, 
					statusInfo: {
						customDNDStatus: !!b.custom_dnd_status?parseInt(b.custom_dnd_status):0, 
						awayStatus: !!b.away_status?parseInt(b.away_status):YCONST.YMSG_Offline, 
						customMessage: !!b.away_msg?b.away_msg:""}};
			}
		}
		try
		{
			var ignorlist = params.ignored_buddy_record_list.records;
		}
		catch (e)
		{
			gLog("[Error][app::handle_prelogin_data] Failed to get buddy ignor list.");
			return;
		}
		var rlen = ignorlist.length;
		for (var m=0; m<rlen; m++) {
			var b = ignorlist[m];
			_blockInfos[b.name] = {username: b.name};
		}
    }

    function handle_buddy_info(params) {
        gLog("app::handle_buddy_info()");
		var rs;
		try {
			rs = params.buddy_info_list.records;
		} catch (e) {}
		var rl = rs.length;
		for (var n=0; n<rl; n++) {
			onStatus(rs[n]);
		}
		gLog("<<<<< stop_time: " + (new Date()).getTime());
    }

	 function handle_buddy_info_ok(params) {
        gLog("app::handle_buddy_info_ok()");
		handle_buddy_info(params);
	}

	function handle_refresh_bc(params) {
		gLog("app::handle_refresh_bc()");
		handle_buddy_list(params);
	}

    function handle_buddy_info_notify(params) {
		gLog("app::handle_buddy_info_notify()");
        handle_buddy_info(params);
    }

    function handle_set_away_status(params) {
		gLog("app::handle_set_away_status()");
        onStatus(params);
    }
    
    function handle_user_logoff_notify(params) {
		gLog("app::handle_user_logoff_notify()");
        params.away_status = null;
		params.away_status = YCONST.YMSG_Offline;
        onStatus(params);
    }

    function handle_user_login_notify(params) {
		gLog("app::handle_user_login_notify()");
		onStatus(params);
    }

	function handle_buddy_authorize_new_buddyof(params) {
		gLog("app::handle_buddy_authorize_new_buddyof()");
		var buddy = params.sender;

		var c = get_cookie("cn_wm_msgn") || "0";
        var count = parseInt(c);
        if(isNaN(count)) {
            count = 0;
        }
		set_cookie("cn_wm_msgn", String(count + 1), 360, ".yahoo.com");
		set_cookie("cn_wm_cb", buddy, 360, ".yahoo.com");
	}

	function handle_user_has_saved_msg(params) {
		gLog("app::handle_user_has_saved_msg()");
		var tout = window.setTimeout(function() {
			if(tout) {
				window.clearTimeout(tout);
				handle_user_has_msg(params, false);
			}
		}, 500);
	}

    function handle_user_has_msg(params, self) {
		gLog("app::handle_user_has_msg()");
        var me, buddy, cloud;   
        if (self) {
            me = params.current_id;
            buddy = params.target_user;
        } else {
            me = params.target_user;
            buddy = params.sender;
        }

		var c = get_cookie("cn_wm_msgn") || "0";
        var count = parseInt(c);
        if(isNaN(count)) {
            count = 0;
        }
		set_cookie("cn_wm_msgn", String(count + 1), 360, ".yahoo.com");
		set_cookie("cn_wm_cb", buddy, 360, ".yahoo.com");
		saveMsg(buddy, params.msg);
    }

	// utility
	function setVisibility(bVisible) {
		gLog("app::setVisibility()");
		var j = {flag: bVisible? "1":"2"};
		var x = j2x(j);
        $c.send("setVisibility", x);
	}

	function logoff() {
		$c.logoff();
	}
	
	function saveMsg(yid, msg) {
		var jse = $$('websdk2_jse');
		if(jse) {
			//jse.parentNode.removeChild(jse);
		}
		jse = document.createElement('script');
		document.body.appendChild(jse);
		jse.id = "websdk2_jse";
		jse.src = "http://cn.webmessenger.yahoo.com/savemsg.php?rdm=" + Math.random() + "&yid=" + yid + "&msg=" + encodeURIComponent(msg);
	}

	return {
        // commands
		"init": init,
		"logoff": logoff,
        // callbacks
		"handle_user_logoff_err": handle_user_logoff_err,
		"handle_user_logoff_notify": handle_user_logoff_notify,
		"handle_user_login_notify": handle_user_login_notify,
		"handle_buddy_list": handle_buddy_list,
		"handle_buddy_info": handle_buddy_info,
		"handle_buddy_info_ok": handle_buddy_info_ok,
		"handle_buddy_info_notify": handle_buddy_info_notify,
		"handle_set_away_status": handle_set_away_status,
        "handle_refresh_bc": handle_refresh_bc,
        "handle_prelogin_data": handle_prelogin_data,
		"handle_logged_in": handle_logged_in,
		"handle_buddy_authorize_new_buddyof": handle_buddy_authorize_new_buddyof,
		"handle_user_has_msg": handle_user_has_msg,
		"handle_user_has_saved_msg": handle_user_has_saved_msg,
		// utils
        "getConfig": getConfig,
		"setVisibility": setVisibility
		};
}();

///////////////////////////////////////////
// Interface
///////////////////////////////////////////
function enableLog() {
		var myConfigs = {
		      width: "380px", // Width of console
		      height: "340px", // Height of container
		      right: "10px", // Position from left edge of viewport
		      top: "10px", // Position from top edge of viewport
		      footerEnabled: true, // Don't show filters/pause/resume/clear UI
		      fontSize: "12px" // Increase default font size
		   };
		var myContainer = null; // LogReader will create markup from scratch
		myLogReader = new YAHOO.widget.LogReader(myContainer, myConfigs);
		myLogReader.newestOnTop = false;
		YAHOO.widget.Logger.disableFirebug();

		gLog = function(msg) {
			if (-1 != msg.indexOf("Warning")) {
				YAHOO.log(msg, "warn");
			} 
			else if (-1 != msg.indexOf("ERROR")) {
				YAHOO.log(msg, "error");
			} 
			else if (-1 != msg.indexOf("DEBUG")) {
				YAHOO.log(msg, "debug");
			} 
			else {
				YAHOO.log(msg, "info");
			}
		}
}

function gLog(msg) {
}

var g_logging = false;
function f9login(b) {
	g_logging = b;
	if (b) {
		enableLog();
	}
	app.init();
}

function cookieLogin() {
	var cookie = getCookie();
	$WM.hostYID = getUserName(cookie);
	if ( $WM.defaultYID.length == 0 ) {
		$WM.defaultYID = 'xiaoi001';
	}
	if (!cookie) {
		return;
	} else {
		f9login(false);
	}
}

function getURLParam(sParamName){
	var sReturn = "";
	var sHref = window.location.href;
	if ( sHref.indexOf("?") > -1 ) {
		var sQueryString = sHref.substr(sHref.indexOf("?")).toLowerCase();
		var aQueryString = sQueryString.split("&");
		for ( var iParam = 0; iParam < aQueryString.length; iParam++ ){
			if (aQueryString[iParam].indexOf(sParamName + "=") > -1 ){
				var aParam = aQueryString[iParam].split("=");
		        	sReturn = aParam[1];
        			break;
			}
		}
	}
	return sReturn;
}

function setOldVisibility(_bVisible) {
	setVisibility(_bVisible);
}

function setVisibility(_bVisible) {
	if(_bVisible) {
		set_cookie("cn_wm_visible", '1', 360, ".yahoo.com");
		$$('ymsgr_webim_status').innerHTML = $WM.constmsg[2];
	}
	else {
		set_cookie("cn_wm_visible", '0', 360, ".yahoo.com");
		$$('ymsgr_webim_status').innerHTML = $WM.constmsg[3];
	}
	$$('messenger_tip').style.display = "none";
	app.setVisibility(_bVisible);
}

function logoff() {
	app.logoff();
}

function onClickMsgCountAndBuddy() {
	window.open("http://cn.webmessenger.yahoo.com/blog.php?src=messenger_blog_tab&to=" + $WM.currentYID, "_blank");
}

function startUpdateMsgCountAndBuddy() {
	var websdk2_tt = window.setInterval(function() {
		var c = get_cookie("cn_wm_msgn") || "0";
		var count = parseInt(c);
		if(isNaN(count)) {
			count = 0;
		}
		$WM.msgCount = count;
		$$('ymsgr_webim_nmsg').innerHTML = $WM.constmsg[0].replace(/%d/g, $WM.msgCount);

		c = get_cookie("cn_wm_blonn") || "0";
		count = parseInt(c);
		if(isNaN(count)) {
			count = 0;
		}
		$WM.blonCount = count;
		$$('ymsgr_webim_nbdl').innerHTML = $WM.constmsg[1].replace(/%d/g, $WM.blonCount);
		if(!$WM.isLoggedin) {
			$$('messenger_tip').style.display = "none";
		}
		$WM.currentYID = get_cookie("cn_wm_cb") || "xiaoi001";
	}, 1000);
}

var msgstd = null;
/* i.cn spec */
var messenger = new Messenger();
msgstd = messenger;
/* other
if(typeof messenger == 'undefined' || !messenger) {
	msgstd = new Messenger();
}
else {
	msgstd = messenger;
}
*/
function msgrDetect() {
	var obj = {installed: false};
    try {
        obj = msgstd.detect();
    }
    catch(e) {}
    if(obj.installed)
    {
		$$('ymsgr_std').style.display = "";
		$$('ymsgr_std_std').onclick = function () {
			if(navigator.userAgent.toLowerCase().indexOf('msie') != -1) {
				window.location.href="ymsgr:addfriend?请在此处输入您想添加好友的YID";
			}
			else {
				window.location.href="ymsgr:addfriend?%C7%EB%D4%DA%B4%CB%B4%A6%CA%E4%C8%EB%C4%FA%CF%EB%CC%ED%BC%D3%BA%C3%D3%D1%B5%C4YID";
			}
			return false;
		};
    }
    else
    {
		var websdk2_tt = window.setInterval(function() {
			if(websdk2_tt) {
				clearInterval(websdk2_tt);
			}
			$$('ymsgr_webim').style.display = "";
			$$('ymsgr_webim_nmsg').innerHTML = $WM.constmsg[0].replace(/%d/g, 0);
			$$('ymsgr_webim_nbdl').onclick = onClickMsgCountAndBuddy;
			$$('ymsgr_webim_nmsg').onclick = onClickMsgCountAndBuddy;
			
			$WM.blonCount = 0;
			set_cookie("cn_wm_blonn", String($WM.blonCount), 360, ".yahoo.com");
			
			startUpdateMsgCountAndBuddy();
			if(!!hostOnline && hostOnline.e == '0' && hostOnline.o == '0') {
				cookieLogin();
			}
		}, 1000);
    }
}

function loadMsg() {
	msgrDetect();
}

function unloadMsg() {
	if($WM.isLoggedin) {
		app.logoff();
	}
}

function showStatusCon() {
	if(!$WM.isLoggedin) {
		$$('messenger_tip').style.display = "none";
	}
	else {
		$$('messenger_tip').style.display = "";
	}
}