
var FF = window.FF || {};

FF.namespace = function(){
	var a=arguments, o=null, i, j, d;
	for (i=0; i<a.length; ++i){
		d=a[i].split('.');
		o=FF;

		for (j=(d[0] == 'FF') ? 1 : 0; j<d.length; ++j){
			o[d[j]]=o[d[j]] || {};
			o=o[d[j]];
		}
	}
	return o;
};

FF.namespace('util', 'app', 'widget');

(function(){

var $C = YAHOO.util.Connect;
var $D = YAHOO.util.Dom;
var $E = YAHOO.util.Event;
var $KL = YAHOO.util.KeyListener;
var isIE =  YAHOO.env.ua.ie;
var isIE6 = (isIE == 6);
var isGecko = YAHOO.env.ua.gecko;
var isWebkit = YAHOO.env.ua.webkit;
var isOpera = YAHOO.env.ua.opera;
var isStr = YAHOO.lang.isString;

function trim(str) {
	str = str.replace(/^\s\s*/, '');
	var ws = /\s/,
		i = str.length;
	while (ws.test(str.charAt(--i)));
	return str.slice(0, i + 1);
}

FF.CONST = {
	TEXT_LIMIT: {
		message: 140,
		privatemessage: 140,
		help: 140,
		pro_bas_detail: 200,
		pro_int_misc: 200,
		pro_int_music: 200,
		pro_int_movie: 200,
		pro_int_books: 200,
		pro_int_sports: 200,
		pro_int_persons: 200
	},
	DOMAIN:'fanfou.com'
}; 

FF.util = {
	/**
	 * 跨浏览器使用连续字符的换行
	 * Cross Browser Word Breaker
	 * @link http://www.hedgerwow.com/360/dhtml/css-word-break.html
	 * @param {string|HTMLElement} el 需要处理连续字符的区块
	 * @return {bool} 成功返回true 失败返回false
	 */
	breakWord:function(el) {
		el = $D.get(el);
		if(!el || el.nodeType !== 1) return false;
		if(el.currentStyle && typeof el.currentStyle.wordBreak === 'string'){// for ie
			el.runtimeStyle.wordBreak = 'break-all';
			return true;
		} else if (document.createTreeWalker){ //for firefox opera and safari
			var walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null, false);
			var node,s,c = String.fromCharCode('8203');
			while (walker.nextNode()) {
				node = walker.currentNode;
				s = trim( node.nodeValue ).split('').join(c);
				node.nodeValue = s;
			}
			return true;
		} else {
			return false;
		}
	},
	/**
	 * focus 后光标位置不正确(最前面)的修复方案
	 * @param {string | HTMLElement} elTextarea textarea 元素的 id 或引用
	 */
	fixTextareaCursorPosition: function(elTextarea){
		if (isStr(elTextarea)) elTextarea = $D.get(elTextarea);
		if (isIE || isOpera){
			var rng = elTextarea.createTextRange();
			rng.text = elTextarea.value;
			rng.collapse(false);
		} else if (isWebkit) {
			elTextarea.select();
			window.getSelection().collapseToEnd();
		}
	},
	/**
	 * 对textarea自动聚焦并修正光标，
	 * 注：IE下disable的textarea聚焦会产生错误，所以需要放在try中
	 * @param {string | HTMLElement} elTextarea textarea 元素的 id 或引用
	 */
	focusTextarea:function(elTextarea){
		try {
			elTextarea.focus();
			this.fixTextareaCursorPosition(elTextarea);
		} catch(e) {
		}
	},
	/**
	 * 判断大写键是否打开
	 * @link http://dancewithnet.com/2007/04/16/detect-caps-lock/
	 * @link http://blog.dougalmatthews.com/2008/07/javascript-detecting-caps-lock/
	 * @param {object} event
	 */
	checkCapsLock: function(e){
	   e = (e) ? e : window.event;
	   var charCode = false;
	   if (e.which) {
		   charCode = e.which;
	   } else if (e.keyCode) {
		   charCode = e.keyCode;
	   }
	   var shifton = false;
	   if (e.shiftKey) {
		   shifton = e.shiftKey;
	   } else if (e.modifiers) {
		   shifton = !!(e.modifiers & 4);
	   }
	   if (charCode >= 97 && charCode <= 122 && shifton) {
		   return true;
	   }
	   if (charCode >= 65 && charCode <= 90 && !shifton) {
		   return true;
	   }
	   return false;
	},
	/**
	 * 获取res
	 * @param {object} o YAHOO.util.Connect.asyncRequest 的返回
	 * @param {string} sCustomMsg 自定义错误字段的信息
	 */
	getEvalRes: function(o, sCustomMsg){
		try {
			return eval('('+ o.responseText +')');
		} catch (ex){
			return {'status':0, 'msg': sCustomMsg || '网络有问题，请稍后重试。'};
		}
	},
	/**
 	 * 通过ctrl enter来操作
	 * @param {string | HTMLElement} el 需要操作的元素id或者引用
	 * @param {function} fSubcribe ctrlEnter后需要执行的函数
	 */
	ctrlEnter: function(el, fSubcribe){
		var ctrlEnter = new YAHOO.util.KeyListener(el, {ctrl:true, keys:[13, 100]}, function(){
			fSubcribe();
			ctrlEnter.disable();
			window.setTimeout(function(){
				ctrlEnter.enable();
			}, 2000);
		});
		ctrlEnter.enable();
	},
	/**
	 * 删除并黄色褪变
	 * @param {string | HTMLElement} elLink 发生的元素
	 * @param {string} sParentTag 父级tag
	 */
	yFadeRemove: function(elLink, sParentTag){
		var p = $D.getAncestorByTagName(elLink, sParentTag);
		if (!p) return;
		FF.util.Effect.yellowFadeOut(p, function(el){
			el.parentNode.removeChild(el);
			if (isIE){// fixed ie reflow
				FF.util.reFlow();
			}
		});
	},
	/**
 	 * reflow, 使页面能够更新布局（IE专用）
 	 */
	reFlow: function(){
		if (isIE){
			document.body.style.zoom = 1.1;
			document.body.style.zoom = '';
		}
	},
	/**
	 * 字符串长度 中文算两字符
	 * @param {string} str 字符串
	 * @return {int} 
	 */
	getLength:function(str){
		if(!str) return 0;
		for (var i = 0, count = 0, len = str.length ; i < len; i++) { 
			count = str.charCodeAt(i) > 255 ? count + 2 : count + 1;
		}
		return count; 
	},
	/**
	 * 字符半角转全角
	 * 全角空格为12288，半角空格为32 
	 * 其他字符全角(65281-65374)减去半角(33-126)等于65248 
	 * @param {string} str 字符串
	 * @return {int} 
	 */
	toFull:function(str){
		var ret = '';
		for(var i = 0, len = str.length; i < len; i++) {  
			var charCode = str.charCodeAt(i);
			if(charCode == 32) { 
				ret += String.fromCharCode(12288);
			} else if(charCode < 127) {
				ret += String.fromCharCode(charCode + 65248);
			} else {
				ret += str[i];
			}
		}
		return ret;     
	},
	/**
	 * 字符全角转半角
	 * 全角空格为12288，半角空格为32 
	 * 其他字符全角(65281-65374)减去半角(33-126)等于65248 
	 * @param {string} str 字符串
	 * @return {int} 
	 */
	toHalf:function(str){
		var ret = '';   
		for(var i = 0, len = str.length; i < len; i++) {  
			var charCode = str.charCodeAt(i);
			if(charCode == 12288){
				ret += String.fromCharCode(32);
			} else if(charCode > 65280 && charCode < 65375)   {   
				ret += String.fromCharCode(charCode - 65248);   
			} else { 
				ret += String.fromCharCode(charCode);   
			}
		}
		return ret;  
	},
	/**
	 * 转换postData
	 * @param {object} o 要转换的对象 如{token:'abcdef', action:'msg.del'}
	 */
	toPostData:function(o){
		var arr = [];
		for(var i in o){
			arr.push(i + '=' + o[i]);	
		}
		return arr.join('&');
	},
	/**
	 * 预加载图片
	 * @param {string} src 图片地址
	 */ 
	loadImage:function(src){
		var img = new Image();
		img.src = src;
	},
	/**
	 * 填补数字的空白
	 * @param {number} num 需要填补空白的数字
	 * @param {number} count 需要凑齐的位数
	 * @param {string} letter 填补的字母
	 */
	pad:function(num, count, letter) {
		if(!letter) letter = '0';
		var len = num.toString().length;
		while(len < count) {
			num = letter + num;
			len++;
		}
		return num;
	},

	/**
	 * 解析服务器返回的UTC时间
	 * @param {string} strTime 格式如Wed Jun 13 10:11:18 +0000 2007
	 */
	parseDate: function(strTime){
		var tmp = strTime.split(' ');
		var stdFormat = tmp[1] + " " + tmp[2] + ", " + tmp[5] + " " + tmp[3];
		return Date.parse(stdFormat) - (new Date()).getTimezoneOffset() * 60 * 1000;
	},
	/**
	 * 获取服务器相对时间
	 * @param {string|Date} strTime 格式如Wed Jun 13 10:11:18 +0000 2007 或者Date对象
	 */
	getRelativeTime: function(strTime) {
		var time = isStr(strTime) ? this.parseDate(strTime).valueOf() : strTime;
		var now = new Date();
		var seconds = parseInt((now.getTime() - time) / 1000, 10);
		if (seconds < 1) {
			return '1 秒前';
		} else if (seconds < 60) {
			return seconds + ' 秒前';
		} else if (seconds < 60 * 60) {
			return parseInt(seconds / 60, 10) + ' 分钟前';
		} else if (seconds < 60 * 60 * 24) {
			return '约 ' + parseInt(seconds / 3600, 10) + ' 小时前';
		} else {
			return this.getFullTime(strTime);
		}
	},
	/**
	 * 获取服务器完整时间
	 * @param {string|Date} strTime 格式如Wed Jun 13 10:11:18 +0000 2007 或者Date对象
	 * @return {string} 如2008-11-03
	 */
	getFullTime: function(strTime){
		var d = new Date(isStr(strTime) ? this.parseDate(strTime):strTime);
		var year = d.getFullYear();
		var month = this.pad(d.getMonth() + 1, 2);
		var date = this.pad(d.getDate(), 2);
		var hour = this.pad(d.getHours(), 2);
		var minute = this.pad(d.getMinutes(), 2);
		return year + '-' + month + '-' + date + ' ' + hour + ':' + minute;
	},
	/**
	 * 获取节点的文本 webkit核心如chrome和safari需要使用trim
	 * @param {string|HTMLElement} el dom节点
	 */ 
	getText:function(el){
		if(isStr(el)) el = $D.get(el);
		var text = el.innerText || el.textContent;
		return trim(text); 
	},
	/**
 	 * @namespace 一些效果封装
 	 */
	Effect: {
		/**
		 * yellow fade helper function
		 * @private
		 */
		_yfade: function(el, sType, arrColorConfig, fCallback){
			var a = arguments,
				f = '#fff478',
				t = '#ffffff';
			if (YAHOO.lang.isArray(a[2])){
				f = a[2][0] ? a[2][0] : f;
				t = a[2][1] ? a[2][1] : t;
			} else if (YAHOO.lang.isFunction(a[2])){
				var cb = a[2];
			}
			if (YAHOO.lang.isFunction(a[3])){
				var cb = a[3];
			}
			var opa = sType == 'out' ? {from:1, to:0} : {from:0, to:1};
			var anim = new YAHOO.util.ColorAnim(el,{backgroundColor:{from: f, to: t}, opacity:opa}, 1, YAHOO.util.Easing.easeNone);
			if ('undefined' != typeof cb){
				anim.onComplete.subscribe(function(){
					cb(el);
				});
			}
			anim.animate();
			return anim;
		},
		/**
		 * 所谓的黄色褪变技术（消失）
		 * @param {string, HTMLElement} el 对象的id或者引用
		 * @param {array} [arrColorConfig] 在褪变完成后的回调 arrColorConfig[0]为起始颜色，arrColorConfig[1]为最终颜色
		 * @param {function} [fCallback] 在褪变完成后的回调
		 */
		yellowFadeOut: function(el, arrColorConfig, fCallback) {
			return FF.util.Effect._yfade(el, 'out', arrColorConfig, fCallback);
		},
		/**
		 * 所谓的黄色褪变技术（显示）
		 * @param {string, HTMLElement} el 对象的id或者引用
		 * @param {array} [arrColorConfig] 在褪变完成后的回调 arrColorConfig[0]为起始颜色，arrColorConfig[1]为最终颜色
		 * @param {function} [fCallback] 在褪变完成后的回调
		 */
		yellowFadeIn: function(el, arrColorConfig, fCallback) {
			return FF.util.Effect._yfade(el, 'in', arrColorConfig, fCallback);
		}
	}
}; // FF.util ends here


FF.widget = {
	/**
	 * 使用 flash 复制文本
	 * @param {string | HTMLElement} elInput 需要拷贝的 input 框
	 */
	selectAndCopy: function(elInput, elButton, sMsg){
		if (isStr(elInput)) elInput = $D.get(elInput);
		var cpel = 'flashcopier',
			embedId = 'flashembed';

		/* http://www.jeffothy.com/weblog/clipboard-copy/ */
		function copy(inElement) {
			if(!$D.get(cpel)) {
				var divholder = document.createElement('div');
				divholder.id = cpel;
				document.body.appendChild(divholder);
			}
			var cper = $D.get(cpel);
			cper.innerHTML = '<embed src="http://static.fanfou.com/swf/cp.swf" FlashVars="clipboard='+encodeURIComponent(inElement.value)+'" width="0" height="0" type="application/x-shockwave-flash" id="'+embedId+'"></embed>';
				// 检测是否安装了 Flash
			var flashObj = window[embedId] || document[embedId] || {};
			if (!flashObj.SetVariable){// 没有 flash
				try {
					return window.clipboardData.setData("Text", inElement.value);
				}
				catch(exx){
					return false;
				}
			}
			return true;
		}

		$E.on(elInput, 'click', doCopy);
		$E.on(elButton, 'click', doCopy);
		function doCopy(){
			// 这个方法在flash10中已经失效，另外有种方法是加一个flash覆盖层，但是太复杂。
			// 所以在firefox中将不再提示
			// @link http://stackoverflow.com/questions/127040/put-text-on-the-clipboard-with-firefox-safari-and-chrome
			if (copy(elInput) && isIE){
				alert(sMsg || '复制成功，你可以粘帖到MSN或QQ中发给好友。');
			}
			setTimeout(function(){
				elInput.select();
			}, 0);
		}
	},
	/**
	 * 计算表单中的剩余允许字数
	 * @param {string | HTMLElement} elForm 需要计算的表单
	 */
	fieldLimit:function(elForm){
		if (isStr(elForm)) elForm = $D.get(elForm);
		var count = FF.CONST.TEXT_LIMIT[elForm.getAttribute('id')];
		var elCount = $D.getElementsByClassName('tip', 'p', elForm)[0];
		var elTextarea = elForm.content;
		var last = '';
		if(!count) count = 140;

		window.setInterval(compute, 50);
		$E.onDOMReady(compute);

		function compute() {
			if($D.hasClass(elTextarea, 'hint')){ //有提示文字则不计算
				return;
			} else if(elTextarea.value == last) { // 如果没改动则跳过，频繁赋值ie会闪烁
				return;
			} else {
				last = elTextarea.value;
			}
			var elSubmit = $D.getElementsByClassName('formbutton', 'input', elForm)[0];
			var length = elTextarea.value.length;
			if (length === 0) {
				//elSubmit.disabled = true;
				//$D.addClass(elSubmit, 'forbidden');
			} else {
				//elSubmit.disabled = false;
				//$D.removeClass(elSubmit, 'forbidden');
			}
			if (length <= count) {
				elCount.innerHTML = '可以输入 <span class="counter">' + (count - length) + '</span> 字';
				$D.removeClass(elCount, 'caution');
			} else {
				elCount.innerHTML = '已经超出 <span class="counter">' + (length - count) + '</span> 字';
				$D.addClass(elCount, 'caution');
			}
		}
	},
	/**
	 * 计算表单中的剩余允许字数
	 * 如/settings中自述
	 * @param {string | HTMLElement} el 需要计算的表单域
	 */
	textLimit:function(el){
		var count = FF.CONST.TEXT_LIMIT[el.id];
		$E.on(el, 'keyup', function(e){
			if(el.value.length > count) {
				el.value = el.value.slice(0, count);
				$D.getElementsByClassName('hint', 'span', $D.getAncestorBy(el), function(o){
					$D.removeClass(o, 'hidden');
				});
			}
		});
	}
};

// 快速回复
FF.app.QuickReply = function(focus){
	var elForm = $D.get('message');
	var elTextarea = elForm['content'];
	var elReplyId = elForm['in_reply_to_status_id'];
	var elRepostId = elForm['repost_status_id'];
	var elStream = $D.get('stream');

	if(focus){
		FF.util.focusTextarea(elTextarea);
	}

	$E.on(elStream, 'click', function(e){
		var target = $E.getTarget(e);
		var nodeName = target.nodeName.toLowerCase();
		if (nodeName == 'a' && $D.hasClass(target, 'reply')){
			$E.stopEvent(e);
			var name = target.getAttribute('ffname');
			var id = target.getAttribute('ffid');
			elTextarea.value = combine('@'+name, trim(elTextarea.value));
			elReplyId.value = id;
			if(elRepostId){
				elRepostId.value = '';
			}
			window.scrollTo(0, 0);
			window.setTimeout(function(){ 
				FF.util.focusTextarea(elTextarea); 
			}, 10);
		}
	});
	// 合并用户名 新的插到最前面 
	function combine(name, nameString){
		var seperator = ' ';
		var names = nameString.split(seperator);
		if(nameString.length === 0)
			return name + seperator;
		for(var i = 0, len = names.length; i < len; i++){
			if(names[i] == name){
				names.splice(i, 1);
				break;
			}
		}
		names.unshift(name);
		return names.join(seperator) + seperator;
	}
};

// 首页好友通知
FF.app.loadFeed = function(){
	$C.asyncRequest('GET', '/notifications', {
		success: function(o){
			var res = YAHOO.lang.trim(o.responseText);
			if (res !== ''){
				$D.get('newsfeed-list').innerHTML = res;
			}
		},
		failure: function(o){}
	});
};

FF.app.Stream = {
	/**
	 * 绑定单条消息的事件
	 * @param {HTMLElement} el 单条消息所在的li
	 */
	attach:function(el){
		//$D.addClass(el, 'unlight');
		$E.on(el, 'mouseover', function(e){
			$D.replaceClass(this, 'unlight', 'light');
			showReply(this);
		});
		$E.on(el, 'mouseout', function(e){
			$D.replaceClass(this, 'light', 'unlight');
			showReply(this);
		});
		function showReply(el){
			var elReplys = $D.getElementsByClassName('reply', 'span', el);
			if(!elReplys.length) return;
			var elReply = elReplys[0];
			var ela = elReply.getElementsByTagName('a')[0];
			var html = ela.innerHTML;
			var reg = /(\(查看\))$/g;
			if(reg.test(html)){
				ela.innerHTML = html.replace(reg, '');
			} else {
				ela.innerHTML = html + '(查看)';
			}
		}
	},
	/**
	 * 防止ie内存泄露，事先清除事件绑定再销毁节点
	 * @param {HTMLElement} el 单条消息所在的li
	 */ 
	clean:function(el){
		el.onmouseover = null;
		el.onmouseout = null;
	},
	/**
	 * 消息流的初始化
	 */
	init:function(){
		$D.getElementsBy(function(){return true;}, 'li', 'stream', this.attach);
	},
	/**
	 * @param {HTMLElement} 页面删除
	 * @param {array} data hidden字段变量数组
	 * @param {string} sConfirm 需要确认的提示语
	 * @notice delete是关键词，这里不能用作函数名
	 */
	remove:function(el, data, sConfirm){
		el.blur();
		if (sConfirm && !confirm(sConfirm)) return;
		//ajax请求需要设置ajax为yes
		data['ajax'] = 'yes';
		//单条消息和单张照片的删除页面需要跳转
		var redirect = el.getAttribute('redirect');
		var postData = FF.util.toPostData(data);
		var async = $C.asyncRequest('POST', window.location.href, {
			success:function(o){
				var res = FF.util.getEvalRes(o);	
				if(res.status){
					if(redirect){
						window.location.href = redirect;
					} else {
						FF.util.yFadeRemove(el, 'li');
						if (/^\/home/.test(window.location.pathname)){ //如果首页则清除最后消息
							var href = el.getAttribute('href'),
								m = href.match(/^\/msg.del\/(\w+)/);
							if (m && m.length && m.length > 1){
								var id = m[1], last = $D.get('lastmsg-'+ id);
								if(last) last.innerHTML = '';
							}
						}
					}
				} else {
					alert(res.msg);
				}
			},
			failure:function(o){}
		}, postData);
	}
};

FF.app.Post = (function(){
	return {
		isSubmited: false,
		
		helper: function(elTextarea, elForm, fnSubmit){
			$E.on(elTextarea, 'keyup', function(e){
				ctrlEnter(e);
			});
			$E.on(elForm, 'submit', function(e){
				submit(e);
			});
			// so ugly 改天消灭它
			function isKeyTrigger(e,keyCode){
				var argv = isKeyTrigger.arguments;
				var argc = isKeyTrigger.arguments.length;
				var bCtrl = false;
				if (argc > 2) bCtrl = argv[2];
				var bAlt = false;
				if (argc > 3) bAlt = argv[3];
				var nav4 = window.Event ? true : false;
				if (typeof e == 'undefined') e = event;
				if (bCtrl && !((typeof e.ctrlKey != 'undefined') ? e.ctrlKey : e.modifiers & Event.CONTROL_MASK > 0)) return false;
				if (bAlt && !((typeof e.altKey != 'undefined') ? e.altKey : e.modifiers & Event.ALT_MASK > 0)) return false;
				var whichCode = 0;
				if (nav4) whichCode = e.which;
				else if (e.type == 'keypress' || e.type == 'keydown') whichCode = e.keyCode;
				else whichCode = e.button;
				return (whichCode == keyCode);
			}
			function ctrlEnter(e) {
				if (isIE) {
					if (window.event.ctrlKey && window.event.keyCode == 13){
						submit();
					}
				} else {
					if (isKeyTrigger(e, 13, true)) {
						submit();
					}
				}
			}
			function submit(e){
				if(e) $E.stopEvent(e);
				if(elTextarea.value === ''){
					alert('消息不能为空');
					return;
				} 
				if(FF.app.Post.isSubmited) return;
				FF.app.Post.isSubmited = true;
				$D.getElementsByClassName('loading', 'img', elForm, function(el){
					el.style.visibility = 'visible';
				});
				$D.getElementsByClassName('formbutton', 'input', elForm, function(el){
					el.disabled = true;
				});
				// 如果表单含有统计的code 则延迟提交
				var trackCode = elForm.getAttribute('track');	
				if(trackCode){
					FF.ga.trackClick(trackCode);
					window.setTimeout(function(){ fnSubmit(elForm); }, 50);
				} else {
					fnSubmit(elForm);
					//elForm.submit();
				}
			}
		},
		
		init: function(elTextarea, elForm){
			FF.app.Post.helper(elTextarea, elForm, function(el){
				el.submit();
			});
		},

		quickPost: function(elForm){
			if (isStr(elForm)) elForm = $D.get(elForm);
			var elTextarea = elForm.getElementsByTagName('textarea')[0];
			var elLoading = $D.getElementsByClassName('loading', 'img', elForm)[0];
			var ajax = elForm['ajax'];
			if (!ajax){
				var input = document.createElement('input');
				input.name = 'ajax';
				input.value = 'yes';
				input.type = 'hidden';
				elForm.appendChild(input);
			}
			FF.app.Post.helper(elTextarea, elForm, function(el){
				$C.setForm(el);
				var async = $C.asyncRequest('POST', '/home', {
					success: function(o){
						var res = FF.util.getEvalRes(o);
						elLoading.style.visibility = 'hidden';
						$D.getElementsByClassName('formbutton', 'input', el, function(input){
							input.disabled = false;
						});
						FF.app.Post.isSubmited = false;
						if(res.status){
							var elContainer = $D.get('container'),
								elColumn = $D.get('columns'),
								div = $D.get('sysmsg-success');
							if(!div) {
								div = document.createElement('DIV');
								div.id = 'sysmsg-success';
								div.className = 'sysmsg';
								div.innerHTML = ' 发送成功！ ';
								elContainer.insertBefore(div, elColumn);
							}
							FF.util.Effect.yellowFadeIn(div, ['#ffffff', '#fffcaa']);
							elTextarea.value = '';
						} else {
							alert(res.msg);
						}
					},
					failure: function(o){
						elLoading.style.visibility = 'hidden';
						$D.getElementsByClassName('formbutton', 'input', el, function(input){
							input.disabled = false;
						});
						FF.app.Post.isSubmited = false;
					}
				});
				
				if ($C.isCallInProgress(async)){
					elLoading.style.visibility = 'visible';
				}
			});
		}
	};// return ends here
})();

FF.app.LeaveMsg = function(el){
	if(isStr(el)) el = $D.get(el);
	var elMsg = $D.get('overlay');
	var elClose = $D.get('closeicon');
	var elForm = $D.get('message');
	var elTextarea = elForm['content'];
	// 默认文本
	var defaultText = elTextarea.value; 
	// 提交按钮
	var elSubmit = $D.getElementsByClassName('formbutton', 'input', elForm)[0]; 
	// loading图标
	var elLoading = $D.getElementsByClassName('loading', 'img', elForm)[0];
	var isSubmited = false;
	var data = {};
	$E.on(el, 'click', function(e){
		var position = $D.getXY(el), x, y;
		$E.stopEvent(e);
		elMsg.style.display = 'block';
		x = position[0] - 40;
		y = position[1] + 25;
		$D.setXY(elMsg, [x, y]);
		FF.util.focusTextarea(elTextarea);
	});
	$E.on(elClose, 'click', function(e){
		elMsg.style.display = 'none';
	});
	$E.on(document, 'click', function(e){
		var target = $E.getTarget(e),
			nodeName = target.nodeName.toLowerCase();
		if(target != elMsg && !$D.isAncestor(elMsg, target)){
			elMsg.style.display = 'none';
		}
	});
	$E.on(elForm, 'submit', doSubmit);
	FF.util.ctrlEnter(elTextarea, doSubmit);
	function doSubmit(e){
		if(e) $E.stopEvent(e);
		if(isSubmited) return;
		var msg = elTextarea.value;
		var realname = elForm.realname.value;
		var minLength = realname.length + 2;

		if(msg === '' || msg == defaultText){
			return alert('留言不能为空');
		}
		if(msg.length < minLength || msg.substr(0, minLength) != '@' + realname + ' '){
			return alert('留言必须以 @' + realname + '+空格 开头，这样你的关注者才能收到你发的消息。');
		}
		isSubmited = true;
		elLoading.style.visibility = 'visible';
		elSubmit.disabled = true;

		FF.ga.trackClick('/leavemsg');

		$C.setForm(elForm);
		$C.asyncRequest('POST', '/home',{
			success:handleResponse,
			failure:function(o){}
		});
		function handleResponse(o){
			var res = FF.util.getEvalRes(o);	
			if(res.status){
				isSubmited = false;
				elLoading.style.visibility = 'hidden';
				elSubmit.disabled = false;
				elTextarea.value = defaultText;
				elMsg.style.display = 'none';
				var elContainer = $D.get('container'),
					elColumn = $D.get('columns'),
					div = $D.get('sysmsg-success');
				if(!div) {
					div = document.createElement('DIV');
					div.id = 'sysmsg-success';
					div.className = 'sysmsg';
					div.innerHTML = ' 留言发送成功！ ';
					elContainer.insertBefore(div, elColumn);
				}
				FF.util.Effect.yellowFadeIn(div, ['#ffffff', '#fffcaa']);
			} else {
				alert(res.msg);
			}
		}
	}
};


FF.app.Sidebar = {
	toggle:function(el){
		if(isStr(el)) el = $D.get(el);
		if(!el || !el.id) return;
		var elb = el.getElementsByTagName('b')[0];
		var elTitle = el.getElementsByTagName('h2')[0];
		var elList = el.getElementsByTagName('ul')[0];
		var Cookie = YAHOO.util.Cookie;
		var cookieName = 'sidebar_collapse_' + el.id;
		var cookieConfig = { expires:new Date(2018, 1, 1), path:'/', domain:FF.CONST.DOMAIN };
		var isCollapse = Cookie.get(cookieName);

		if(isCollapse == 'true'){
			$D.addClass(elb, 'collapse');
			elList.style.display = 'none';
		} else {
			elList.style.display = 'block';
		}

		$E.on([elTitle, elb], 'click', trigger);
		function trigger(){
			if($D.hasClass(elb, 'collapse')){
				$D.removeClass(elb, 'collapse');
				elList.style.display = 'block';
				Cookie.set(cookieName, false, cookieConfig);
			} else {
				$D.addClass(elb, 'collapse');
				elList.style.display = 'none';
				Cookie.set(cookieName, true, cookieConfig);
			}
		}
	},
	init:function(){
		$D.getElementsByClassName('colltab', 'div', 'sidebar', this.toggle);
	}
};


})(); // core ends here
