function $i(id){
	return $("#"+id).get(0);
}
var boxys=new Object();	//保存所有已使用boxy对象

// 扩展内置对象 ===== begin =====
String.prototype.sInclude=function(s){
	var re=new RegExp("(^|,)"+s+"(,|$)","ig");
	return re.test(this, s);
};
String.prototype.sRemove=function(s){
	if(this.sInclude(s)){
		var lc=RegExp.leftContext;
		var rc=RegExp.rightContext;
		if(lc.length>0 && rc.length>0){
			return lc+","+rc;
		}else if(lc.length>0){
			return lc;
		}else if(rc.length>0){
			return rc;
		}else{
			return "";
		}
	}else{
		return this;
	}
};
String.prototype.isRelate=function(){
	var r=/^\w+\:\/\//g;
	return !r.test(this);
};
String.prototype.gbLen=function(){
	var len = this.length;
	for (var i=0; i<this.length; i++) {
		if (this.charCodeAt(i)>255) {
			len++;
		}
	}
	return len;
};
String.prototype.gbIndexOf=function(str){
	var idx=this.indexOf(str);
	return this.substr(0,idx).gbLen()+1;
};
String.prototype.gbLeft=function(len, s){
	var str = '';
	var sp  = s || '';
	var len2 = 0;
	var over=false;
	var ll=0;
	if (len<1){
		return str;
	}
	if (this.length*2<=len || sp.length>this.length){
		return this.toString();
	}
	for (var i=0; i<this.length; i++) {
		var l = (this.charCodeAt(i)>255) ? 2 : 1;
		if (len2+l>len){
			over=true;
			break;
		}else{
			len2+=l;
			ll++;
		}
	}
	if (over && sp.length>0){
		len2+=s.gbLen();
		while(len2>len){
			ll--;
			len2 -= (this.charCodeAt(ll)>255) ? 2 : 1;
		}
		str = this.substr(0,ll)+ s;
	}else{
		str = this.substr(0,ll);
	}
	return str;
};
String.prototype.trimEnd=function(){
	var str, n;
	n=this.length;
	while(n>=0){
		var c=this.charCodeAt(n-1);
		if(c!=32 && c!=12288){
			break;
		}else{
			n--;
		}
	}
	if(n==0){
		return "";
	}else{
		return this.substr(0,n);
	}
};
String.prototype.trim=function(){
	var s=0,e=this.length-1;
	while(s<this.length){
		var c=this.charCodeAt(s);
		if(c!=32 && c!=12288){
			break;
		}else{
			s++;
		}
	}
	while(e>s){
		var c=this.charCodeAt(e);
		if(c!=32 && c!=12288){
			break;
		}else{
			e--;
		}
	}
	
	if (s>e){
		return "";
	}else{
		return this.substring(s,e+1);
	}
};
// 字符串是否全部为空白字符,IE中\s不包含中文空格
String.prototype.isSpace=function(){
	var re = /^(\s|　)*$/g;
	return re.test(this);
};
Array.prototype.include=function(v){
	for(var i=0;i<this.length;i++){
		if(this[i]==v){
			return true;
		}
	}
	return false;
};
// 数字转为两为字符串，时间使用
Number.prototype.twoDigit=function(n){
	return this<10?"0"+this:this.toString();
};
Date.prototype.toFriendString=function(){
	var n=new Date();
	var d1=new Date(n.getFullYear(),n.getMonth(),n.getDate());
	var d2=(new Date(d1)).setDate(d1.getDate()-1);
	var d3=(new Date(d1)).setDate(d1.getDate()-2);;
	var ft=this.getHours().twoDigit()+":"+this.getMinutes().twoDigit();
	var sd=(this.getMonth()+1).twoDigit()+"-"+this.getDate().twoDigit()+" "+ft;
//	var fd=d.getFullYear()+"-"+sd;
	var s;
	n=Math.floor((n-this)/1000);
	if(n<3600){
		s=Math.ceil(n/60)+"分钟前";
	}else if(n<36000){
		s=Math.floor(n/3600)+"小时"+Math.floor(n%3600/60)+"分前";
	}else if (this>d1){
		s="今天 "+ft;
	}else if(this>d2){
		s="昨天 "+ft;
	}else if(this>d3){
		s="前天 "+ft;
	}else{
		s=sd;
	}
	return s;
};
// 扩展内置对象 ===== end =====

var iwms=new Object();

iwms.urlPrefix="";
iwms.payEnable=0;

// 设置时间差，用服务器时间，用于讨论区和消息
iwms.setTimeDiff=function(sTime){
	iwms.timeDiff=new Date()-new Date(sTime);
};
// 通过时间差服务器时间转为客户端时间
iwms.getClientDate=function(sTime){
	return new Date(Date.parse(new Date(sTime))+iwms.timeDiff);
};

// 消息位置 =====  begin =====
iwms.msgPos=function(ele,msg){
	var pos={x:0,y:0};
	var vis=[msg.style.display.toString(),msg.style.visibility.toString()];
	with(document.documentElement){
		var cw=clientWidth;
		var sl=scrollLeft;
		var st=scrollTop;
	}
	msg.style.display="block";
	msg.style.visibility="hidden";
	// 在ele下显示
	if (ele){
		var p=iwms.elePos(ele);
		pos.x=p.x;
		pos.y=p.y + p.h;
		// 超出页面宽度
		if (pos.x+msg.offsetWidth>cw+sl){
			pos.x=cw+sl-msg.offsetWidth;
			if(pos.x<0){
				pos.x=0;
			}
		}
		// 超出内容设定宽度
		var $w=$(".twidth:eq(0)");
		if($w.length==1){
			var woffset=$w.offset();
			if(pos.x+msg.offsetWidth>$w.width()+woffset.left){
				pos.x=$w.width()+woffset.left-msg.offsetWidth;
			}
		}
	}else{
		//pos.x=cw+sl-msg.offsetWidth-3;
		pos.x=Math.floor((cw-msg.offsetWidth)/2);
		pos.y=st;
	}
	msg.style.display=vis[0];
	msg.style.visibility=vis[1];
	return pos;
};

iwms.elePos=function(ele){
	var p={'x':0,'y':0,'w':0,'h':0};
	p.h = ele.offsetHeight;
	p.w = ele.offsetWidth;
	do{
		p.x += ele.offsetLeft || 0;
		p.y += ele.offsetTop  || 0;
		ele=ele.offsetParent;
	}while(ele);

	return p;
};
// 消息位置 ===== end =====

// 显示消息 ===== begin =====
iwms.popDivs=new Array();
iwms.popMsg=function(kind,ele,cld,cls)
{
	var div;
	iwms.clearPopTimer(kind);
	// 取div
	for(var i=0;i<iwms.popDivs.length;i++){
		if(iwms.popDivs[i].id=="pop_"+kind){
			div=iwms.popDivs[i];
		}
	}
	if(div==null){
		div=document.createElement("DIV");
		div.id="pop_"+kind;
		iwms.popDivs.push(div);
		div.onmouseout=function(){iwms.hideMsg(kind,800)};
		div.onmouseover=function(){iwms.clearPopTimer(kind);};
		document.body.appendChild(div);
	}else{
		div.removeChild(div.childNodes[0]);
	}
	div.className=cls?cls:(ele?"aj_msg":"aj_msg aj_msgTop");
	if(typeof(cld)=="string"){
		div.innerHTML=cld;
	}else{
		div.appendChild(cld);
	}
	
	var pos=iwms.msgPos(ele,div);
	with(div.style){
		top=pos.y+"px";
		left=pos.x+"px";
		display="block";
		zIndex=100;
	}
	if(ele){
		iwms.dropShadow(kind,div);
		ele.onmouseout=function(){iwms.hideMsg(kind,800);};
	}
};


iwms.popTimers=new Array();
iwms.hideMsg=function(kind,time){
//	alert('hide');
	iwms.clearPopTimer(kind);
	if (time && time>0){
		iwms.popTimers.push([kind,window.setTimeout("iwms.hideMsg('"+kind+"')",time)]);
	}else{
		var div;
		for(var i=0;i<iwms.popDivs.length;i++){
			if(iwms.popDivs[i].id=="pop_"+kind){
				div=iwms.popDivs[i];
				break;
			}
		}
		if (div){
			div.style.display="none";
			iwms.clearShadow(kind);
		}
	}
};

iwms.clearPopTimer=function(kind){
//	alert('clear');
	var n=-1;
	for(var i=0;i<iwms.popTimers.length;i++){
		if(iwms.popTimers[i][0]==kind){
			n=i;
			break;
		}
	}
//	alert("timers:"+iwms.popTimers.length+","+n);
	if(n>=0){
		var tm=iwms.popTimers.splice(n,1)[0][1];
//		alert("timer"+tm);
		if(tm){
			window.clearTimeout(tm);
		}
	}
};

// 显示阴影
iwms.shadows=new Array();
iwms.dropShadow = function(kind,ele)
{
	//ie的iframe中渲染有问题
	if(self!=top && $.browser.msie && self.frameElement.tagName=="IFRAME"){
		return;
	}
	var num=1;
	var arr=null;
	for(var i=0;i<iwms.shadows.length;i++){
		if(iwms.shadows[i][0]==kind){
			arr=iwms.shadows[i][1];
			break;
		}
	}
	if(arr==null){
		arr=[kind,new Array()];
		for(var i=0;i<num;i++){
			var o=document.createElement("DIV");
			o.className="shadow";
			with(o.style){
				position="absolute";
				zIndex=ele.style.zIndex-1;
				var op=Math.floor(100*(num-i)/num);
				if (typeof(opacity)=="string"){
					opacity=(op/100).toString();
				}else{
					filter="alpha(opacity="+ op +")";
				}
			}
			arr[1].push(o);
			document.body.appendChild(o);
		}
		iwms.shadows.push(arr);
		arr=arr[1];
	}
	var p=iwms.elePos(ele);
	for(var i=0;i<arr.length;i++){
		with(arr[i].style){
			top=p.y+(i+1)*1+"px";
			left=p.x+(i+1)*1+"px";
			width=p.w+"px";
			height=p.h+"px";
		}
	}
};

// 隐藏阴影
iwms.clearShadow=function(kind)
{
	var o, n=-1, arr;
	for(var i=0;i<iwms.shadows.length;i++){
		if(iwms.shadows[i][0]==kind){
			n=i;
			break;
		}
	}
	if(n==-1){
		return;
	}
	arr=iwms.shadows.splice(n,1);
	arr=arr[0][1];
	while(o=arr.pop()){
		document.body.removeChild(o);
	}
};
// 显示消息 ===== end =====

// cookie函数 ===== begin =====
iwms.cookie=function(name,value,expires){
	// 取cookie
	if(value==undefined){
		var search = name + "=";
		var c=document.cookie;
		if(c.length > 0){
			offset = c.indexOf(search);
			if(offset != -1)	{
				offset += search.length;
				end = c.indexOf(";", offset);
				if(end == -1){
					end = c.length;
				}
				return decodeURI(c.substring(offset, end));
			}
		}
		return "";
	}
	
	if(expires!=undefined && expires!=null){
		var LargeExpDate = new Date ();
		LargeExpDate.setTime(LargeExpDate.getTime() + (expires*1000*3600*24));
	}
	document.cookie = name + "=" + encodeURI(value) + "; path=/;" +((expires==undefined || expires==null) ? "" : (" expires=" +LargeExpDate.toGMTString()));
};
// cookie函数 ===== end =====


// 图片自适应 ===== begin =====
iwms.imgResize=function(){
	if(iwms.imgCont){
		iwms.imgCont.style.overflowX="hidden";
		iwms.imgCont.style.wordBreak="break-all";
		var imgs = iwms.imgCont.getElementsByTagName("img");
	}else{
		return;
	}
	for(var i=0;i<imgs.length;i++){
		var o=imgs[i];
		if(o.complete){
			iwms.imgLoaded(o);
		}else{
			o.onload=function(){iwms.imgLoaded(this);};
		}
		// 点图片下一页
		if (iwms.imgPage && typeof(pager)=="object" && imgs.length==1 && o.width>200){
			o.style.cursor="pointer";
			if (o.resized=="1"){
				o.setAttribute("title","ctrl+鼠标左键原大小");
				o.onclick=function(eventTag){var evt=eventTag||window.event;evt.ctrlKey ? iwms.imgFullsize(this) : pager.Next()};
			}else{
				o.onclick=function(){pager.Next()};
			}
		}
	}
};

iwms.imgLoaded=function(o){
	var mw=parseInt(iwms.imgCont.clientWidth)-50;
	if (o.width>mw){
		if (o.style.width){
			o.style.width="";
		}
		o.width=mw;
		o.removeAttribute("height");
		o.style.cursor="pointer";
		o.style.display="block";
		o.vspace=5;
		o.resized=1;
		if (typeof(o.onclick)!="function"){
			o.onclick=function(){iwms.imgFullsize(this);};
		}
	}
};

iwms.imgFullsize=function(oImg){
	if (oImg.parentElement){
		if (oImg.parentElement.tagName=="A"){
			return;
		}
	}
	var b = new Boxy("<p><img src='"+ oImg.src +"'/></p>", {title: "查看图片", fixed: false, modal: true, unloadOnHide: true, afterShow: function(){
			var a=this.getPosition();if(a[1]<0)this.moveTo(a[0],0);
		}, behaviours: function(r){
			$(r).click(function(){b.hide()});
		}
		}
	);
};

// 图片自适应 ===== end =====

// 显示登陆框 ===== begin =====
iwms.obj2json=function(o){
	var s="{";
	for(var p in o){
		if(s.length>1) s+= ",";
		var v=o[p];
		s+=p+":";
		if(typeof(v)=='string'){
			s+="'"+v.replace(/'/g,"\\'")+"'";
		}else{
			s+=v;
		}
	}
	return s+"}";
};

// 保存用户cookie
iwms.logSave=function(u){
	var d=new Date();
	var m=new Date(2000,0,1);
	u.lastSet=Math.floor((d-m)/60000);
	var s=iwms.obj2json(u);
	if (u.keep){
		iwms.cookie("iwmsUser",s,30);
	}else{
		iwms.cookie("iwmsUser",s);
	}
};

// 退出登陆
iwms.logOut=function(){
	iwms.cookie("iwmsUser","",-30);
	iwms.logReload();
};

// 重加载页面
iwms.logReload=function(){
	var url=top.location.href;
	if(url.charAt(url.length-1)=='#'){
		url = url.substr(0,url.length-1);
	}
	// 会员功能页全部转到首页
	if(url.substr(url.lastIndexOf("/")+1).indexOf("member")==0){
		url = url.substr(0,url.lastIndexOf("/"));
	}
	top.location=url;
};

iwms.logedUser=function(){
	var s=iwms.cookie("iwmsUser").trim();
	if (s.length==0 || s.charAt(0)!='{' || s.charAt(s.length-1)!='}'){
		s={ver:1,id:0,name:'',pass:'',admin:0,admPs:0,signin:0,msg:0,keep:0,lastSet:0};
	}else{
		eval("s="+s);
	}
	return s;
};

iwms.user=iwms.logedUser();

iwms.logDisp=function(){
	$u=$("#topUser");
	if($u.length==0 || iwms.user.id<1){
		return;
	}
	var getInterval=5;	// 3分钟更新一次会员信息
	var d=new Date();
	var m=new Date(2000,0,1);
	var nd=Math.floor((d-m)/60000);
	if(nd-iwms.user.lastSet>getInterval){
		// 重取会员资料
		iwms.logReset();
		return;
	}
	var str=["你好，",iwms.user.name,
		"<a href='#' onmouseover='iwms.popMine(this)'>我的</a>",
		(iwms.user.msg?"<a href='#' onclick='msg.disp()' class='remind'>新消息</a>":"<a href='#' onclick='msg.disp()'>消息</a>"),
		(iwms.user.signin>0?"<a href='"+iwms.urlPrefix+"memberSignIns.aspx' class='remind'>待签收</a>":""),
		"<a href='",iwms.urlPrefix,"memberNewsAdd.aspx'>发布</a>",
		(iwms.payEnable?"<a href='"+iwms.urlPrefix+"memberCharge.aspx'>充值</a>":""),
		(iwms.user.admin?"<a href='"+iwms.urlPrefix+"admin_login.aspx' target='_blank'>管理</a>":""),
		"<a href='",iwms.urlPrefix,"memberList.aspx'>会员</a>",
		"<a href='",iwms.urlPrefix,"search.aspx'>搜索</a>",
		"<a href='#' onclick='iwms.logOut()'>退出</a>"].join("");
	$u.html(str);
};

// 重新从服务器取cookie
iwms.logReset=function(){
	iwms.ajSrc=null;
	$.post(iwms.urlPrefix+'ajax.aspx',{cmd:'userJson'},function(r){
		iwms.logSave(r);
		iwms.user=r;
		iwms.logDisp();
	},'json');
};

$(function(){
	iwms.logDisp();
});

iwms.logPop=function(){
	var b=boxys.login;
	if(b){
		b.toggle();
	}else{
		b=new Boxy("<iframe src='"+iwms.urlPrefix+"login.aspx' height='100%' width='100%' frameborder='0'></iframe>",{title:"会员登录"});
		b.resize(380,180);
		boxys.login=b;
	}
};

iwms.popMine=function(ele){
	var $d=$("<div class='popMine'></div>").appendTo(document.body)
		.append("<a href='"+iwms.urlPrefix+"memberProfile.aspx?id="+iwms.user.id+"' target='_blank'>会员信息</a>")
		.append("<a href='"+iwms.urlPrefix+"search.aspx?where=memberid&keyword="+iwms.user.id+"' target='_blank'>发布内容</a>")
		.append("<a href='"+iwms.urlPrefix+"memberModify.aspx?id="+iwms.user.id+"' taget='_blank'>控制中心</a>");
	iwms.popMsg("my",ele,$d.get(0));
};

iwms.addFriend=function(ele,friendId){
	if(iwms.user.id<=0){
		iwms.popMsg("addFriend",ele,"登陆会员才可以添加好友");
		iwms.hideMsg("addFriend",2000);
		return;
	}
	var o={};
	o.cmd="friendAdd";
	o.friendId=friendId;
	$.post(iwms.urlPrefix+"ajax.aspx",o,function(r){
		var msg;
		if(r.success){
			msg="添加好友成功";
		}else{
			msg="添加好友失败，已添加或达到好友数上限";
		}
		iwms.popMsg("addFriend",ele,msg);
		iwms.hideMsg("addFriend",3000);
	},'json');
};

iwms.removeFriend=function(ele,friendId){
	if(iwms.user.id<=0){
		return;
	}
	var o={};
	o.cmd="friendRemove";
	o.friendId=friendId;
	$.post(iwms.urlPrefix+"ajax.aspx",o,function(r){
		var msg;
		if(r.success){
			$(ele).parent().remove();
		}else{
			msg="删除好友失败";
			iwms.popMsg("removeFriend",ele,msg);
			iwms.hideMsg("removeFriend",3000);
		}
	},'json');
	
};
// 显示登陆框 ===== end =====

// 显示会员消息界面 ===== begin =====
var msg=new Object();
msg.friendLoaded=false;
msg.gotUnread=false;	// 最近联系人是否有未读，全部读取后重设会员cookie

msg.dispContact=function(ele){
	$src=$(ele);
	if($src.next().css("display")!="none"){
		return;
	}
	$("#msFriend,#msRecent").hide();
	if($src.next().attr("id")=="msFriend" && !msg.friendLoaded){
		msg.getFriends();
	}else{
		$src.next().show();
	}
};

msg.appendMsg=function(o){
	var $con=$("<div/>");
	$con.addClass("msMsg");
	$("<div/>").addClass(o.sender==iwms.user.name?"msMe":"msSender").text(o.sender+"　"+ iwms.getClientDate(o.time).toFriendString()).appendTo($con);
	$("<div/>").addClass(o.unread?"msBody msUnread":"msBody").html(o.body.replace(/\n/g,'<br/>')).appendTo($con);
	$("#msList").append($con).scrollTop(10000);
	
};

msg.init=function(u){
	$("#msCon").find("div.msHead").click(function(){
		msg.dispContact(this);
	});
	$("#msRecent a,#msFriend a").live("click",function(evt){
		$this=$(this);
		$("#msRecent a,#msFriend a").removeClass("msCur");
		$this.addClass("msCur").removeClass("msUnread");
		iwms.ajSrc=null;
		$.post(iwms.urlPrefix+"ajax.aspx",{cmd:"msgGet",receiverId:$this.data("id")},function(r){
			$list=$("#msList").empty();
			
			for(var i=0;i<r.length;i++){
				var o=r[i];
				msg.appendMsg(o);
			}
			
			$("#msForm form input[name='id']").val($this.data("id"));
			
			if(msg.gotUnread && $("#msRecent a.msUnread").length==0){
				msg.gotUnread=false;
				iwms.logReset();
			}
		},'json');
		msg.enable();
		evt.preventDefault();
	});
	
	msg.getRecent(u);
	
	$("#msForm form").submit(function(){
//		$("body").append("提交表单<br/>");
		var o=new Object();
		var $body=$("#msForm form textarea");
		o.receiverId=$("#msForm form input[name='id']").val();
		o.body=$body.val();
//	alert(o.receiver);
		if (!/^\d+$/.test(o.receiverId)){
			alert("请选择联系人");
			return false;
		}
		if (o.body.trim().length<2){
			alert("请填写消息内容");
			return false;
		}
		o.cmd="msgPost";
		o.body=iwms.ajEncode(o.body);
		$.post(iwms.urlPrefix+"ajax.aspx",o,function(r){
			if(r.success){
				msg.appendMsg({sender:iwms.user.name,time:new Date(Date.parse(new Date())-iwms.timeDiff),body:r.body});
				$body.val("");
			}
		},'json');
		return false;
	});
	
	msg.handle=function(evt){
		if (evt.ctrlKey && evt.keyCode==13){
			$("#msForm form").submit();
			return false;
		}else{
			return true;
		}
	};
	
	msg.disable();
};

msg.disable=function(){
	$("#msForm button").attr("disabled","disabled");
	$("#msForm textarea").val("").attr("disabled","disabled");
};

msg.enable=function(){
	$("#msForm button, #msForm textarea").removeAttr("disabled");
};

msg.getRecent=function(u){
	iwms.ajSrc=null;
	$.post(iwms.urlPrefix+"ajax.aspx",{cmd:"msgRecent"},function(r){
		iwms.setTimeDiff(r.serverTime);
		$recent=$("#msRecent");
		for(var i=0;i<r.contact.length;i++){
			var o=r.contact[i];
			var $a=$("<a/>").text(o.name).attr("href","#").data("id",o.id).appendTo($recent);
			if(o.unread){
				$a.addClass("msUnread");
				msg.gotUnread=true;
			}
		}
		if(u){
			msg.addRecent(u);
		}
	},'json');
};


msg.addRecent=function(u){
	var $a=null;
	$("#msRecent a").each(function(){
		if($(this).data("id")==u.id){
			$a=$(this);
		}
	});
	if($a==null){
		$a=$("<a/>").text(u.name).attr("href","#").data("id",u.id).prependTo($recent);
	}
	$a.click();
};

msg.getFriends=function(){
		iwms.ajSrc=null;
		$.post(iwms.urlPrefix+"ajax.aspx",{cmd:"msgFriends"},function(r){
//						alert(r.friend.length);
			$friend=$("#msFriend");
			for(var i=0;i<r.contact.length;i++){
				var o=r.contact[i];
				$("<a/>").text(o.name).attr("href","#").data("id",o.id).appendTo($friend);
			}
			msg.friendLoaded=true;
			$friend.show();
		},'json');
};

msg.disp=function(u){
	var b=boxys.msg;
	if(b){
		b.toggle();
		if(u){
			msg.addRecent(u);
		}
	}else{
		iwms.ajSrc=null;
		$.get(iwms.urlPrefix+"msg.xml",function(r){
				var html=$(r).find("html:eq(0)").text();
				boxys.msg=new Boxy(html,{title:"查看消息"});
				msg.init(u);
		},'xml');
	}
};
// 显示会员消息界面 ===== end =====

// 文章digg ===== begin =====
iwms.diggIt = function(ele,id){
	var digged=iwms.cookie("iwmsDigged");
	digged = digged.length==0 ? [] : digged.split(',');
	if(digged.include(id)){
		ele.innerHTML="已投票!";
		ele.onclick=function(){return false;};
		ele.style.color="#999";
		return
	}
	
	iwms.ajSrc=ele;
	$.post(iwms.urlPrefix+'ajax.aspx',{cmd:'digg',aid:id},function(data){
		if (data.success){
			var o=ele.parentNode.parentNode.getElementsByTagName("LI")[0];
			o.innerHTML=parseInt(o.innerHTML)+1;
			ele.innerHTML="已投票!";
			ele.onclick=function(){location.href=iwms.urlPrefix+'hot.aspx'};
			ele.style.color="#999";
			if(digged.length>9){
				digged=digged.slice(digged.length-9);
			}
			digged.push(id);
			iwms.cookie("iwmsDigged",digged.toString(),30);
		}else{
			iwms.popMsg('digg',ele,'digg操作失败');
			iwms.hideMsg('digg',2000);
		}
		
	},"json");
};
// 文章digg ===== end =====

// 申请友情链接 ===== begin =====
iwms.addLink=function(){
	var b = boxys.addLink;
	if(b){
		b.toggle();
	}else{
		b = new Boxy("<iframe src='"+iwms.urlPrefix+"admin_popLinkAdd.aspx' height='100%' width='100%' frameborder='0'></iframe>",{title:"申请友情链接"});
		b.resize(500,340);
		boxys.addLink = b;
	}
};
// 申请友情链接 ===== end =====

// 菜单脚本 ===== begin =====
var menu=new Object();

menu.container=null;	// 外容器
menu.ele=null;	// 显示菜单链接
menu.items=null;
menu.done=false;

menu.bind=function(){
	$("#navbar a[title]").each(function(){
		$this=$(this);
		$this.mouseover(function(){
			menu.show(this,$(this).data("id"),1,0);
		}).data("id",$this.attr("title")).removeAttr("title");
	});
};

$(function(){
	menu.bind();
});

menu.show=function(e,idx,p,paging){
	//p为当前页数,paging为当前是不是翻页
	if(menu.items==null){
		iwms.ajSrc=null;
		$.get(iwms.urlPrefix+'json.aspx',{cmd:'menu'},function(r){
			menu.items=r;
			menu.show(e,idx,p,paging);
		});
		return;
	}
	if(menu.items[idx]==null){
		return;
	}
	if (!document.all&&!document.getElementById&&!document.layers){
		return false;
	}

	menu.ele=e;
	var cur=menu.items[idx];
	var pSize=10;	//每页连接数
	var pTotal=Math.floor((cur.length-1)/pSize)+1;		//页数
	
	// 无下级不显示
	if(cur.length==0){
		return;
	}
	
	if (menu.container==null){
		var o=document.createElement("DIV");
		menu.container=o;
	}
	
	//设置菜单内容
	if (pTotal==1){
		menu.addItem(cur);
	}else{
		cur=cur.slice( (p-1)*pSize, p*pSize );
		menu.addItem(cur);
		menu.container.appendChild(menu.pageDiv(idx,p,pTotal));
	}
	
	iwms.popMsg("menu",e,menu.container,"menuskin");
	return false;
};

// 分页的DIV
menu.pageDiv=function(idx,p,pTotal){
	var $div=$("<div/>").addClass("menuitems").css({'text-align':'right','padding-right':'10px','white-space':'nowrap'});
	var $prev=$("<font/>").attr('face','arial').html('&#9668;');
	if(p==1){
		$prev.attr('color','#cccccc');
	}else{
		$prev.css('cursor','pointer').data('idx',idx).data('page',p-1).click(menu.pageClick);
	}
	$div.append($prev);
	var $next=$("<font/>").attr('face','arial').html('&#9658;');
	if(p==pTotal){
		$next.attr('color','#cccccc');
	}else{
		$next.css('cursor','pointer').data('idx',idx).data('page',p+1).click(menu.pageClick);
	}
	$div.append($next);
	return $div.get(0);
};

menu.pageClick=function(){
	menu.show(menu.ele,$(this).data('idx'),$(this).data('page'),true);
	iwms.hideMsg('menu',1500);
};

menu.addItem=function(arr)
{
	for(var i=menu.container.childNodes.length;i--;i>=0){
		menu.container.removeChild(menu.container.childNodes[i]);
	}
	for(var i=0; i<arr.length; i++){
		var a = arr[i];
		var o_d=document.createElement("DIV");
		o_d.className="menuitems";
		o_d.onmouseover=new Function("menu.highlight(this,'on');");
		o_d.onmouseout=new Function("menu.highlight(this,'off');");
		var o_a=document.createElement("A");
		if (iwms.urlPrefix.length>0 && a[1].isRelate()){
			o_a.href=iwms.urlPrefix+a[1];
		}else{
			o_a.href=a[1];
		}
		if (a[2]){
			o_a.target="_blank";
		}
		o_a.innerHTML=a[0];
		o_d.appendChild(o_a);
		menu.container.appendChild(o_d);
	}
};

menu.highlight=function(ele,state){
	ele.id=(state=="on") ? "mouseoverstyle" : "";
};
// 菜单脚本 ===== end =====

// 显示flash ===== begin =====
function Flash(file, w, h)
{
	document.write(['<div style="padding:5px"><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" width="',
		w,
		'" height="',h,'"><param name="movie" value="',iwms.urlPrefix,file,
		'"> <param name="quality" value="high"><param name="wmode" value="opaque"><embed src="',file,
		'" loop="false" menu="false" quality="high" width="',w,
		'" height="',h,
		'" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed></object></div>'].join(''));
}
// 显示flash ===== end =====


// 调查功能 ===== begin =====
function pollCheck(o,checkMax){
	var checkNum = 0;
	var f = o.form;
	for(var i=0; i<f.elements.length; i++){
		var c = f.elements[i];
		if (c.name==o.name && c.checked){
			checkNum++;
		}
	}
	if (checkNum>checkMax){
		alert("最多选择"+ checkMax +"项!");
		o.checked = false;
	}
}

function ViewPoll(id) {
	window.open(iwms.urlPrefix+"pollView.aspx?act=result&id="+id, "iwmsPoll","width=500,height=400,left=0,top=0,scrollbars=1,status=1,resizable=1");
}
// 调查功能 ===== end =====

// 友情链接滚动 ===== begin =====
function StartRollV() {
	var rollspeed=3000;
	var $d=$("#oRollV");
	if ($d.length==0){
		return;
	}
	if($d.children().length==0){
		$d.hide();
		return;
	}
	$lastChild = $d.children().last();
	// 实际内容高度小于样式高度
	if ( ($lastChild.offset().top - $d.offset().top + $lastChild.height()) < $d.height() ){
		$d.css("height","auto");
		return;
	}
	myInter=setInterval(MarqueeV,rollspeed);
	$d.mouseover(function() {clearInterval(myInter)});
	$d.mouseout(function() {myInter=setInterval("MarqueeV()",rollspeed)});
}

// 重新制作友情链接滚动
function MarqueeV(){
	var $div = $("#oRollV");
	var $a = $("a:eq(0)",$div);
	$a.slideUp('slow', function(){
		$div.append(this);
		$(this).show();
	});
}

// 友情链接高度
function linkSize()
{
	var $nav,o2;
	$nav = $("#siteNav");
	$roll = $("#oRollV");
	if ($nav.length>0 && $roll.length>0 && $nav.parents("table:last").find("#oRollV").length==1){
		if ($roll.parent().last().height()<$nav.offsetParent().height()){
			$roll.height($roll.height() + $nav.parent().outerHeight() - $roll.parent().outerHeight());
			// ie7 bug fix
			if($.browser.msie && $.browser.version=="7.0"){
				$roll.parents("table:last").css("table-layout","fixed");
			}
		}
	}
}
// 友情链接滚动 ===== end =====

// 公告翻转 ===== begin =====
var bRoll=new Object();
bRoll.delay=3000;
bRoll.timer=0;
bRoll.height=0;
bRoll.count=0;
bRoll.roll=function(){
	var b=$i("bulletinBody");
	if(bRoll.count==bRoll.height){
		if(b.scrollHeight-bRoll.height<=b.scrollTop){
			b.scrollTop=b.scrollHeight/2-bRoll.height;
		}
		bRoll.count=0;
		bRoll.timer=setTimeout('bRoll.roll()',bRoll.delay);
	}else{
		b.scrollTop++;
		bRoll.count++;
		bRoll.timer=setTimeout('bRoll.roll()',10);
	}
};
bRoll.clear=function(){
	if(bRoll.count==0){
		clearTimeout(bRoll.timer);
		bRoll.timer=0;
	}
};
bRoll.init=function(arr){
	document.write('<div id="bulletin" class="bulletin"></div>');
	var o,oD,oU,oL;
	o=$i("bulletin");
	bRoll.height=o.scrollHeight;
	oD=document.createElement("DIV");
	oU=document.createElement("UL");
	o.onmouseover=bRoll.clear;
	o.onmouseout=function(){if(!bRoll.timer){bRoll.timer=setTimeout('bRoll.roll()',bRoll.delay);}};
	for(var i=0;i<arr.length;i++){
		var a=arr[i];
		if(iwms.urlPrefix.length>0 && a[1].isRelate()){
			a[1]=iwms.urlPrefix+a[1];
		}
		oL=document.createElement("LI");
		oL.innerHTML='<a href="'+a[1]+'" target="_blank">'+a[0]+'</a><em>('+a[2]+')</em></a></li>';
		oU.appendChild(oL);
	};
	oD.appendChild(oU);
	oD.id="bulletinBody";
	oD.innerHTML+='<br style="clear:both"/>'+oD.innerHTML;
	o.appendChild(oD);
	bRoll.timer=setTimeout('bRoll.roll()',bRoll.delay);
};
// 公告翻转 ===== end =====


// 头条图片幻灯 ===== begin =====
var imgSlide=new Object();
imgSlide.idx=0;
imgSlide.timer;
imgSlide.imgs;

imgSlide.show=function (idx){
	imgSlide.idx=idx;
	imgSlide.setNum(idx);
	imgSlide.setImg(idx);
	imgSlide.setTitle(idx);
};
imgSlide.setNum=function (v){
	for(var i=0;i<imgSlide.imgs.length;i++){
		$("#slNum a").eq(i).attr("class",v==i?"slOn":"slOff");
	}
};
imgSlide.setImg=function (v){
	var o=$i("slImg");

	$(o).find("a:eq(0)").attr("href",imgSlide.imgs[v][1]).end()
	.find("img:eq(0)").attr("src",imgSlide.imgs[v][2]);
		
};

imgSlide.setTitle=function (v){
	//ie有兼容问题，只能用innerHTML
	$("#slLink a:eq(0)").attr({href:imgSlide.imgs[v][1]}).get(0).innerHTML=imgSlide.imgs[v][0];
};

imgSlide.clear=function (){
	clearInterval(imgSlide.timer);
};

imgSlide.start=function (){
	imgSlide.timer=setInterval("imgSlide.next()", 3000);
};

imgSlide.next=function (){
	imgSlide.idx++;
	if(imgSlide.idx>imgSlide.imgs.length-1){imgSlide.idx=0;}
	imgSlide.show(imgSlide.idx);
};

imgSlide.init=function(w,h,arr,len){
	var l,a,v1;
	var d=document;
	d.write('<div id="slImg" style="width:'+w+'px;height:'+h+'px"></div><div id="slTitle" style="width:'+w+'px"><div id="slNum"></div><div id="slLink"></div></div>');
	if(arr.length==0){
		v1=["请先添加头条图片新闻","###","style/iwms/no_picture.gif"];
	}else{
		v1=arr[0];
	}
	
	for(var i=0;i<arr.length;i++){
		// 标题截取
		arr[i][0]=arr[i][0].gbLeft(len,"...");
		// 加相对链接
		if(iwms.urlPrefix.length>0){
			if(arr[i][1].isRelate()){
				arr[i][1]=iwms.urlPrefix+arr[i][1];
			}
			if(arr[i][2].isRelate()){
				arr[i][2]=iwms.urlPrefix+arr[i][2];
			}
		}
	}
	imgSlide.imgs=arr;
	
	$imgs=$("<ul/>");
	for(var i=0;i<imgSlide.imgs.length;i++){
		var $a=$("<a/>").attr('href','###').html(i+1).addClass(i==0?'slOn':'slOff').mouseover(imgSlide.clear).mouseout(imgSlide.start).click(new Function("imgSlide.show("+i+")"));
		$imgs.append($("<li/>").append($a)).appendTo("#slNum");
	}

	var $imgA=$("<a/>").attr({'href':v1[1],'target':'_blank'});
	var $img=$("<img/>").attr({'src':v1[2],'width':w,'height':h});
	if(arr.length>1){
		$img.mouseover(imgSlide.clear).mouseout(imgSlide.start);
	}
	$imgA.append($img).appendTo("#slImg");

	var $link=$("<a/>").text(v1[0]).attr({'href':v1[1],'target':'_blank'});
	var $slLink=$("#slLink").append($link);
	if(arr.length>1){
		$slLink.mouseover(imgSlide.clear).mouseout(imgSlide.start);
	}
	
	if(arr.length>1){
		imgSlide.start();
	}
};
// 头条图片幻灯 ===== end =====

/* 输出ajax错误信息
function writeobj(o){
	for(var a in o){
		$("body").append("<br/>"+a+":"+o[a]+",");
	}
}
*/

// 定义$.ajax事件
iwms.ajSrc=null;
$(function(){
	$("body").ajaxStart(function(){
//		$("body").append("<li>开始发送数据</li>");
		iwms.popMsg("ajax",iwms.ajSrc,"开始发送数据");
	}).ajaxSuccess(function(request,settings){
//		$("body").append("<li>成功接收数据</li>");
		iwms.popMsg("ajax",iwms.ajSrc,"成功接收数据");
	}).ajaxComplete(function(request,settings){
//		$("body").append("<li>成功完成</li>");
		iwms.hideMsg("ajax",1000);
	}).ajaxError(function(evt,request,settings){
//		$("body").append("<li>发送数据错误"+evt+"</li>");
//		writeobj(settings);
		iwms.popMsg("ajax",iwms.ajSrc,"发送数据错误");
	});
});

// 表单值放入对象
iwms.ajForm=function(fm) {
	var o=new Object();
	$("[name]:input",fm).each(function(){
		if(this.name.length==0 || this.tagName=="BUTTON" || this.type=="reset" || this.type=="submit" || this.name=="__VIEWSTATE" || this.name=="__EVENTVALIDATION"){
			return;
		}
		var val="";
		if(this.type=="SELECT" && this.multiple){
			for(var i=0;i<this.options.length;i++){
				var op=this.options[i];
				if(op.selected){
					if(val.length>0){
						val+=",";
					}
					val+=iwms.ajEncode(op.value);
				}
			}
		}else{
			val=this.value;
		}
		eval("o."+iwms.ajTrueName(this.name)+"='"+ iwms.ajEncode(val) +"';");
	});
	
	$("[name]:radio",fm).each(function(){
		if(this.name.length>0 && this.checked){
			eval("o."+iwms.ajTrueName(this.name)+"='"+ iwms.ajEncode(this.value) +"';");
		}
	});
	
	$("[name]:checkbox",fm).each(function(){
		if(this.name.length>0){
			eval("o."+iwms.ajTrueName(this.name)+"='"+ (this.checked?"1":"0") +"';");
		}
	});
	
	return o;
};

iwms.ajEncode=function(v){
	v=escape(v);
	v=v.replace(/\+/g,"%2B");
	return v;
};

// 控件在其它placeHolder中时id前会加holderId$id，处理掉
iwms.ajTrueName=function(fname){
		if(fname.indexOf("$")>=0){
			var	sname = fname.substr(fname.lastIndexOf("$")+1);
			return sname;
		}else{
			return fname;
		}
};


/**
 * Boxy 0.1.4 - Facebook-style dialog, with frills
 *
 * (c) 2008 Jason Frame
 * Licensed under the MIT License (LICENSE)
 */
 
/*
 * jQuery plugin
 *
 * Options:
 *   message: confirmation message for form submit hook (default: "Please confirm:")
 * 
 * Any other options - e.g. 'clone' - will be passed onto the boxy constructor (or
 * Boxy.load for AJAX operations)
 */
jQuery.fn.boxy = function(options) {
    options = options || {};
    return this.each(function() {      
        var node = this.nodeName.toLowerCase(), self = this;
        if (node == 'a') {
            jQuery(this).click(function() {
                var active = Boxy.linkedTo(this),
                    href = this.getAttribute('href'),
                    localOptions = jQuery.extend({actuator: this, title: this.title}, options);
                    
                if (active) {
                    active.show();
                } else if (href.indexOf('#') >= 0) {
                    var content = jQuery(href.substr(href.indexOf('#'))),
                        newContent = content.clone(true);
                    content.remove();
                    localOptions.unloadOnHide = false;
                    new Boxy(newContent, localOptions);
                } else { // fall back to AJAX; could do with a same-origin check
                    if (!localOptions.cache) localOptions.unloadOnHide = true;
                    Boxy.load(this.href, localOptions);
                }
                
                return false;
            });
        } else if (node == 'form') {
            jQuery(this).bind('submit.boxy', function() {
                Boxy.confirm(options.message || 'Please confirm:', function() {
                    jQuery(self).unbind('submit.boxy').submit();
                });
                return false;
            });
        }
    });
};

//
// Boxy Class

function Boxy(element, options) {
    
    this.boxy = jQuery(Boxy.WRAPPER);
    jQuery.data(this.boxy[0], 'boxy', this);
    
    this.visible = false;
    this.options = jQuery.extend({}, Boxy.DEFAULTS, options || {});
    
    if (this.options.modal) {
        this.options = jQuery.extend(this.options, {center: true, draggable: false});
    }
    
    // options.actuator == DOM element that opened this boxy
    // association will be automatically deleted when this boxy is remove()d
    if (this.options.actuator) {
        jQuery.data(this.options.actuator, 'active.boxy', this);
    }
    
    this.setContent(element || "<div></div>");
    this._setupTitleBar();
    
    this.boxy.css('display', 'none').appendTo(document.body);
    this.toTop();

    if (this.options.fixed) {
        if (jQuery.browser.msie && jQuery.browser.version < 7) {
            this.options.fixed = false; // IE6 doesn't support fixed positioning
        } else {
            this.boxy.addClass('fixed');
        }
    }
    
    if (this.options.center && Boxy._u(this.options.x, this.options.y)) {
        this.center();
    } else {
        this.moveTo(
            Boxy._u(this.options.x) ? this.options.x : Boxy.DEFAULT_X,
            Boxy._u(this.options.y) ? this.options.y : Boxy.DEFAULT_Y
        );
    }
    
    if (this.options.show) this.show();

};

Boxy.EF = function() {};

jQuery.extend(Boxy, {
    
    WRAPPER:    "<table cellspacing='0' cellpadding='0' border='0' class='boxy-wrapper'>" +
                "<tr><td class='top-left'></td><td class='top'></td><td class='top-right'></td></tr>" +
                "<tr><td class='left'></td><td class='boxy-inner'></td><td class='right'></td></tr>" +
                "<tr><td class='bottom-left'></td><td class='bottom'></td><td class='bottom-right'></td></tr>" +
                "</table>",
    
    DEFAULTS: {
        title:                  null,           // titlebar text. titlebar will not be visible if not set.
        closeable:              true,           // display close link in titlebar?
        draggable:              true,           // can this dialog be dragged?
        clone:                  false,          // clone content prior to insertion into dialog?
        actuator:               null,           // element which opened this dialog
        center:                 true,           // center dialog in viewport?
        show:                   true,           // show dialog immediately?
        modal:                  false,          // make dialog modal?
        fixed:                  true,           // use fixed positioning, if supported? absolute positioning used otherwise
        closeText:              '[close]',      // text to use for default close link
        unloadOnHide:           false,          // should this dialog be removed from the DOM after being hidden?
        clickToFront:           false,          // bring dialog to foreground on any click (not just titlebar)?
        behaviours:             Boxy.EF,        // function used to apply behaviours to all content embedded in dialog.
        afterDrop:              Boxy.EF,        // callback fired after dialog is dropped. executes in context of Boxy instance.
        afterShow:              Boxy.EF,        // callback fired after dialog becomes visible. executes in context of Boxy instance.
        afterHide:              Boxy.EF,        // callback fired after dialog is hidden. executed in context of Boxy instance.
        beforeUnload:           Boxy.EF         // callback fired after dialog is unloaded. executed in context of Boxy instance.
    },
    
    DEFAULT_X:          50,
    DEFAULT_Y:          50,
    zIndex:             1337,
    dragConfigured:     false, // only set up one drag handler for all boxys
    resizeConfigured:   false,
    dragging:           null,
    
    // load a URL and display in boxy
    // url - url to load
    // options keys (any not listed below are passed to boxy constructor)
    //   type: HTTP method, default: GET
    //   cache: cache retrieved content? default: false
    //   filter: jQuery selector used to filter remote content
    load: function(url, options) {
        
        options = options || {};
        
        var ajax = {
            url: url, type: 'GET', dataType: 'html', cache: false, success: function(html) {
                html = jQuery(html);
                if (options.filter) html = jQuery(options.filter, html);
                new Boxy(html, options);
            }
        };
        
        jQuery.each(['type', 'cache'], function() {
            if (this in options) {
                ajax[this] = options[this];
                delete options[this];
            }
        });
        
        jQuery.ajax(ajax);
        
    },
    
    // allows you to get a handle to the containing boxy instance of any element
    // e.g. <a href='#' onclick='alert(Boxy.get(this));'>inspect!</a>.
    // this returns the actual instance of the boxy 'class', not just a DOM element.
    // Boxy.get(this).hide() would be valid, for instance.
    get: function(ele) {
        var p = jQuery(ele).parents('.boxy-wrapper');
        return p.length ? jQuery.data(p[0], 'boxy') : null;
    },
    
    // returns the boxy instance which has been linked to a given element via the
    // 'actuator' constructor option.
    linkedTo: function(ele) {
        return jQuery.data(ele, 'active.boxy');
    },
    
    // displays an alert box with a given message, calling optional callback
    // after dismissal.
    alert: function(message, callback, options) {
        return Boxy.ask(message, ['OK'], callback, options);
    },
    
    // displays an alert box with a given message, calling after callback iff
    // user selects OK.
    confirm: function(message, after, options) {
        return Boxy.ask(message, ['OK', 'Cancel'], function(response) {
            if (response == 'OK') after();
        }, options);
    },
    
    // asks a question with multiple responses presented as buttons
    // selected item is returned to a callback method.
    // answers may be either an array or a hash. if it's an array, the
    // the callback will received the selected value. if it's a hash,
    // you'll get the corresponding key.
    ask: function(question, answers, callback, options) {
        
        options = jQuery.extend({modal: true, closeable: false},
                                options || {},
                                {show: true, unloadOnHide: true});
        
        var body = jQuery('<div></div>').append(jQuery('<div class="question"></div>').html(question));
        
        // ick
        var map = {}, answerStrings = [];
        if (answers instanceof Array) {
            for (var i = 0; i < answers.length; i++) {
                map[answers[i]] = answers[i];
                answerStrings.push(answers[i]);
            }
        } else {
            for (var k in answers) {
                map[answers[k]] = k;
                answerStrings.push(answers[k]);
            }
        }
        
        var buttons = jQuery('<form class="answers"></form>');
        buttons.html(jQuery.map(answerStrings, function(v) {
            return "<input type='button' value='" + v + "' />";
        }).join(' '));
        
        jQuery('input[type=button]', buttons).click(function() {
            var clicked = this;
            Boxy.get(this).hide(function() {
                if (callback) callback(map[clicked.value]);
            });
        });
        
        body.append(buttons);
        
        new Boxy(body, options);
        
    },
    
    // returns true if a modal boxy is visible, false otherwise
    isModalVisible: function() {
        return jQuery('.boxy-modal-blackout').length > 0;
    },
    
    _u: function() {
        for (var i = 0; i < arguments.length; i++)
            if (typeof arguments[i] != 'undefined') return false;
        return true;
    },
    
    _handleResize: function(evt) {
        var d = jQuery(document);
        jQuery('.boxy-modal-blackout').css('display', 'none').css({
            width: d.width(), height: d.height()
        }).css('display', 'block');
    },
    
    _handleDrag: function(evt) {
        var d;
        if (d = Boxy.dragging) {
            d[0].boxy.css({left: evt.pageX - d[1], top: evt.pageY - d[2]});
        }
    },
    
    _nextZ: function() {
        return Boxy.zIndex++;
    },
    
    _viewport: function() {
        var d = document.documentElement, b = document.body, w = window;
        return jQuery.extend(
            jQuery.browser.msie ?
                { left: b.scrollLeft || d.scrollLeft, top: b.scrollTop || d.scrollTop } :
                { left: w.pageXOffset, top: w.pageYOffset },
            !Boxy._u(w.innerWidth) ?
                { width: w.innerWidth, height: w.innerHeight } :
                (!Boxy._u(d) && !Boxy._u(d.clientWidth) && d.clientWidth != 0 ?
                    { width: d.clientWidth, height: d.clientHeight } :
                    { width: b.clientWidth, height: b.clientHeight }) );
    }

});

Boxy.prototype = {
    
    // Returns the size of this boxy instance without displaying it.
    // Do not use this method if boxy is already visible, use getSize() instead.
    estimateSize: function() {
        this.boxy.css({visibility: 'hidden', display: 'block'});
        var dims = this.getSize();
        this.boxy.css('display', 'none').css('visibility', 'visible');
        return dims;
    },
                
    // Returns the dimensions of the entire boxy dialog as [width,height]
    getSize: function() {
        return [this.boxy.width(), this.boxy.height()];
    },
    
    // Returns the dimensions of the content region as [width,height]
    getContentSize: function() {
        var c = this.getContent();
        return [c.width(), c.height()];
    },
    
    // Returns the position of this dialog as [x,y]
    getPosition: function() {
        var b = this.boxy[0];
        return [b.offsetLeft, b.offsetTop];
    },
    
    // Returns the center point of this dialog as [x,y]
    getCenter: function() {
        var p = this.getPosition();
        var s = this.getSize();
        return [Math.floor(p[0] + s[0] / 2), Math.floor(p[1] + s[1] / 2)];
    },
                
    // Returns a jQuery object wrapping the inner boxy region.
    // Not much reason to use this, you're probably more interested in getContent()
    getInner: function() {
        return jQuery('.boxy-inner', this.boxy);
    },
    
    // Returns a jQuery object wrapping the boxy content region.
    // This is the user-editable content area (i.e. excludes titlebar)
    getContent: function() {
        return jQuery('.boxy-content', this.boxy);
    },
    
    // Replace dialog content
    setContent: function(newContent) {
        newContent = jQuery(newContent).css({display: 'block'}).addClass('boxy-content');
        if (this.options.clone) newContent = newContent.clone(true);
        this.getContent().remove();
        this.getInner().append(newContent);
        this._setupDefaultBehaviours(newContent);
        this.options.behaviours.call(this, newContent);
        return this;
    },
    
    // Move this dialog to some position, funnily enough
    moveTo: function(x, y) {
        this.moveToX(x).moveToY(y);
        return this;
    },
    
    // Move this dialog (x-coord only)
    moveToX: function(x) {
        if (typeof x == 'number') this.boxy.css({left: x});
        else this.centerX();
        return this;
    },
    
    // Move this dialog (y-coord only)
    moveToY: function(y) {
        if (typeof y == 'number') this.boxy.css({top: y});
        else this.centerY();
        return this;
    },
    
    // Move this dialog so that it is centered at (x,y)
    centerAt: function(x, y) {
        var s = this[this.visible ? 'getSize' : 'estimateSize']();
        if (typeof x == 'number') this.moveToX(x - s[0] / 2);
        if (typeof y == 'number') this.moveToY(y - s[1] / 2);
        return this;
    },
    
    centerAtX: function(x) {
        return this.centerAt(x, null);
    },
    
    centerAtY: function(y) {
        return this.centerAt(null, y);
    },
    
    // Center this dialog in the viewport
    // axis is optional, can be 'x', 'y'.
    center: function(axis) {
        var v = Boxy._viewport();
        var o = this.options.fixed ? [0, 0] : [v.left, v.top];
        if (!axis || axis == 'x') this.centerAt(o[0] + v.width / 2, null);
        if (!axis || axis == 'y') this.centerAt(null, o[1] + v.height / 2);
        return this;
    },
    
    // Center this dialog in the viewport (x-coord only)
    centerX: function() {
        return this.center('x');
    },
    
    // Center this dialog in the viewport (y-coord only)
    centerY: function() {
        return this.center('y');
    },
    
    // Resize the content region to a specific size
    resize: function(width, height, after) {
        if (!this.visible) return;
        var bounds = this._getBoundsForResize(width, height);
        this.boxy.css({left: bounds[0], top: bounds[1]});
        this.getContent().css({width: bounds[2], height: bounds[3]});
        if (after) after(this);
        return this;
    },
    
    // Tween the content region to a specific size
    tween: function(width, height, after) {
        if (!this.visible) return;
        var bounds = this._getBoundsForResize(width, height);
        var self = this;
        this.boxy.stop().animate({left: bounds[0], top: bounds[1]});
        this.getContent().stop().animate({width: bounds[2], height: bounds[3]}, function() {
            if (after) after(self);
        });
        return this;
    },
    
    // Returns true if this dialog is visible, false otherwise
    isVisible: function() {
        return this.visible;    
    },
    
    // Make this boxy instance visible
    show: function() {
        if (this.visible) return;
        if (this.options.modal) {
            var self = this;
            if (!Boxy.resizeConfigured) {
                Boxy.resizeConfigured = true;
                jQuery(window).resize(function() { Boxy._handleResize(); });
            }
            this.modalBlackout = jQuery('<div class="boxy-modal-blackout"></div>')
                .css({zIndex: Boxy._nextZ(),
                      opacity: 0.7,
                      width: jQuery(document).width(),
                      height: jQuery(document).height()})
                .appendTo(document.body);
            this.toTop();
            if (this.options.closeable) {
                jQuery(document.body).bind('keypress.boxy', function(evt) {
                    var key = evt.which || evt.keyCode;
                    if (key == 27) {
                        self.hide();
                        jQuery(document.body).unbind('keypress.boxy');
                    }
                });
            }
        }
        this.boxy.stop().css({opacity: 1}).show();
        this.visible = true;
        this._fire('afterShow');
        return this;
    },
    
    // Hide this boxy instance
    hide: function(after) {
        if (!this.visible) return;
        var self = this;
        if (this.options.modal) {
            jQuery(document.body).unbind('keypress.boxy');
            this.modalBlackout.animate({opacity: 0}, function() {
                jQuery(this).remove();
            });
        }
        this.boxy.stop().animate({opacity: 0}, 300, function() {
            self.boxy.css({display: 'none'});
            self.visible = false;
            self._fire('afterHide');
            if (after) after(self);
            if (self.options.unloadOnHide) self.unload();
        });
        return this;
    },
    
    toggle: function() {
        this[this.visible ? 'hide' : 'show']();
        return this;
    },
    
    hideAndUnload: function(after) {
        this.options.unloadOnHide = true;
        this.hide(after);
        return this;
    },
    
    unload: function() {
        this._fire('beforeUnload');
        this.boxy.remove();
        if (this.options.actuator) {
            jQuery.data(this.options.actuator, 'active.boxy', false);
        }
    },
    
    // Move this dialog box above all other boxy instances
    toTop: function() {
        this.boxy.css({zIndex: Boxy._nextZ()});
        return this;
    },
    
    // Returns the title of this dialog
    getTitle: function() {
        return jQuery('> .title-bar h2', this.getInner()).html();
    },
    
    // Sets the title of this dialog
    setTitle: function(t) {
        jQuery('> .title-bar h2', this.getInner()).html(t);
        return this;
    },
    
    //
    // Don't touch these privates
    
    _getBoundsForResize: function(width, height) {
        var csize = this.getContentSize();
        var delta = [width - csize[0], height - csize[1]];
        var p = this.getPosition();
        return [Math.max(p[0] - delta[0] / 2, 0),
                Math.max(p[1] - delta[1] / 2, 0), width, height];
    },
    
    _setupTitleBar: function() {
        if (this.options.title) {
            var self = this;
            var tb = jQuery("<div class='title-bar'></div>").html("<h2>" + this.options.title + "</h2>");
            if (this.options.closeable) {
                tb.append(jQuery("<a href='#' class='close'></a>").html(this.options.closeText));
            }
            if (this.options.draggable) {
                tb[0].onselectstart = function() { return false; };
                tb[0].unselectable = 'on';
                tb[0].style.MozUserSelect = 'none';
                if (!Boxy.dragConfigured) {
                    jQuery(document).mousemove(Boxy._handleDrag);
                    Boxy.dragConfigured = true;
                }
                tb.mousedown(function(evt) {
                    self.toTop();
                    Boxy.dragging = [self, evt.pageX - self.boxy[0].offsetLeft, evt.pageY - self.boxy[0].offsetTop];
                    jQuery(this).addClass('dragging');
                }).mouseup(function() {
                    jQuery(this).removeClass('dragging');
                    Boxy.dragging = null;
                    self._fire('afterDrop');
                });
            }
            this.getInner().prepend(tb);
            this._setupDefaultBehaviours(tb);
        }
    },
    
    _setupDefaultBehaviours: function(root) {
        var self = this;
        if (this.options.clickToFront) {
            root.click(function() { self.toTop(); });
        }
        jQuery('.close', root).click(function() {
            self.hide();
            return false;
        }).mousedown(function(evt) { evt.stopPropagation(); });
    },
    
    _fire: function(event) {
        this.options[event].call(this);
    }
    
};
