
Function.prototype.bind = function(){
    // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Functions:arguments
    var _$A = function(a){return Array.prototype.slice.call(a);}
    if(arguments.length < 2 && (typeof arguments[0] == "undefined")) return this;
    var __method = this, args = _$A(arguments), object = args.shift();
    return function() {
      return __method.apply(object, args.concat(_$A(arguments)));
    }
};

String.prototype.getByteLength = function() {
	var size = 0;
	
	for(var i = 0; i < this.length; i++) {
		var charCode = this.charCodeAt(i);
		
		if(charCode <= 0x00007F) size += 1;
		else if(charCode <= 0x0007FF) size += 2;
		else if(charCode <= 0x00FFFF) size += 3;
		else size += 4;
	}
	
	return size;
};

Date.prototype.setDateString = function(s) {
	if(s.length == 19) {
		this.setYear(Number(s.substring(0, 4)));
		this.setMonth(Number(s.substring(5, 7)) - 1);
		this.setDate(Number(s.substring(8, 10)));
		this.setHours(Number(s.substring(11, 13)));
		this.setMinutes(Number(s.substring(14, 16)));
		this.setSeconds(Number(s.substring(17, 19)));
	} else if(s.length == 14) {
		this.setYear(Number(s.substring(0, 4)) - 1900);
		this.setMonth(Number(s.substring(4, 6)) - 1);
		this.setDate(Number(s.substring(6, 8)));
		this.setHours(Number(s.substring(8, 10)));
		this.setMinutes(Number(s.substring(10, 12)));
		this.setSeconds(Number(s.substring(12, 14)));
	} else if(s.length == 10) {
		this.setYear(Number(s.substring(0, 4)) - 1900);
		this.setMonth(Number(s.substring(5, 7)) - 1);
		this.setDate(Number(s.substring(8, 10)));
	} else if(s.length == 8) {
		this.setYear(Number(s.substring(0, 4)) - 1900);
		this.setMonth(Number(s.substring(4, 6)) - 1);
		this.setDate(Number(s.substring(6, 8)));
	}
}
Date.prototype.yyyyMMddhhmmss = function(dateStr, timeStr) {
	var gapStr = "";
	if(typeof(dateStr) == "undefined" && typeof(timeStr) == "undefined") gapStr = "";
	else gapStr = " ";
	if(typeof(dateStr) == "undefined") dateStr = "";
	if(typeof(timeStr) == "undefined") timeStr = dateStr;
	
	return (this.getYear() + 1900) + dateStr + this.__zerofill2(this.getMonth()+1) + dateStr + this.__zerofill2(this.getDate()) + gapStr + 
		this.__zerofill2(this.getHours()) + timeStr + this.__zerofill2(this.getMinutes()) + timeStr+ this.__zerofill2(this.getSeconds());

}
Date.prototype.yyyyMMddhhmmss2 = function() {
	return this.yyyyMMddhhmmss("-", ":");
}
Date.prototype.yyyyMMdd = function(dateStr) {
	if(typeof(dateStr) == "undefined") dateStr = "";
	return (this.getYear() + 1900) + dateStr + this.__zerofill2(this.getMonth()+1) + dateStr + this.__zerofill2(this.getDate());
}
Date.prototype.yyyyMMdd2 = function() {
	return this.yyyyMMdd("-");
}
Date.prototype.hhmmss = function(timeStr) {
	if(typeof(timeStr) == "undefined") timeStr = "";
	return this.__zerofill2(this.getHours()) + timeStr + this.__zerofill2(this.getMinutes()) + timeStr+ this.__zerofill2(this.getSeconds());
}
Date.prototype.hhmmss2 = function() {
	return this.hhmmss(":");
}
Date.prototype.isToday = function() {
	var d = new Date();
	if(this.getYear() != d.getYear()) return false;
	if(this.getMonth() != d.getMonth()) return false;
	if(this.getDate() != d.getDate()) return false;
	return true;
}
Date.prototype.summary = function() {
	if(this.isToday()) return this.hhmmss2();
	else return this.yyyyMMdd2();
}
Date.prototype.summary2 = function() {
	if(this.isToday()) return this.__zerofill2(this.getHours()) + ":" + this.__zerofill2(this.getMinutes());
	else return this.__zerofill2(this.getMonth()+1) + "." + this.__zerofill2(this.getDate());
}
Date.prototype.__zerofill2 = function(digit) {
	if(digit < 10) return "0" + digit;
	else return digit;
}

Date.prototype.format = function(format) {
	var token = /Y|m|d|H|i|s/g;
	var pad = function(val, len) {
		val = String(val);
		len = len || 2;
		while(val.length < len) val = "0" + val;
		
		return val;
	};
	
	var flags = {
		Y : this.getFullYear(),
		m : pad(this.getMonth() + 1),
		d : pad(this.getDate()),
		H : pad(this.getHours()),
		i : pad(this.getMinutes()),
		s : pad(this.getSeconds())
	};
	
	return format.replace(token, function($0) {
		return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
	});
}

TopProfile = function(boxId, opt) {
	this.init(boxId, opt);
}

TopProfile.prototype = {
	init : function(boxId, opt) {
		this.boxId = boxId;
		this.box = $("#"+boxId);
		this.itemsBox = $('#topProfileBox');
		this.itemsDesc = $('#profileDesc');
		this.option = opt;
		if(!this.option) this.option = {};
		
		this.items = this.box.find("div ul li");
		this.itemsLength = this.items.length; 
		this.itemWidth = this.items.width();
		this.prevBtn = this.box.find(".prevBtn");
		this.nextBtn = this.box.find(".nextBtn");
		
		this.initItemLeft =  this.box.find("ul").position().left;
		this.itemsBox.find("ul").css("position", "absolute");
		
		this.over = $("<div></div>").hide().addClass("over").appendTo(this.itemsBox);
		this.selected = $("<div></div>").hide().addClass("selected").appendTo(this.itemsBox);
		
		this.prevBtn.click(this.clickPrevBtn.bind(this));
		this.nextBtn.click(this.clickNextBtn.bind(this));
		
		var __btnOver = function() {
			this.selected.hide();
		}.bind(this);
		this.prevBtn.mouseover(__btnOver);
		this.nextBtn.mouseover(__btnOver);

		this.items.mouseover(this.itemMouseover.bind(this));
		//this.over.mouseout(this.itemMouseout.bind(this));
		this.over.click(this.itemMouseclick.bind(this));
					
	},
	getFirstParent : function(ele, selector) {
		var max = 0;
		var _ret = false;
		while(ele.length > 0 && _ret == false && max < 1000) {
			_ret = ele.is(selector);
			if(!_ret) 
				ele = ele.parent();
			else 
				return ele;
			max++;
		}
		return null;
	},
	itemMouseover : function(e) {
		var item = this.getFirstParent($(e.target),"li");
		if(item == null) return;
		this.over.attr("href",item.find("a").attr("href"));		
		
		this.over.hide();
		this.selected.hide();
		this._itemMouseoverAct(item);
		
	},
	_itemMouseoverAct : function (item)
	{
		this.over.css(
			{top : item.position().top, left : (item.position().left + this.box.find("ul").position().left)} 
		);
		this.over.show();
		
		var nextItem = this.itemsDesc.find("li");
		while (nextItem.length > 0)
		{
			nextItem.hide();
			nextItem = nextItem.next();
		}		
		$("#topProf_"+item.find("input").val()+"_desc").show();		
	},
	itemMouseout : function(e) {
		this.over.hide();
	},
	itemMouseclick : function(e) {
		var item = this.getFirstParent($(e.target),"div");
		if(item == null) return;		
		window.open(this.over.attr("href"));	
		
		this.selected.css(
			{top : item.position().top, left : item.position().left} 
		);
		this.selected.show();
		this.over.hide();		
	},
	clickPrevBtn : function() {
		var ul = this.box.find("ul");
		if(ul.position().left > this.initItemLeft - 1 || ul.position().left % (63*7) != 0) return;
		var _left = ul.position().left + 63*7;
		ul.animate({left:_left});
	}, 
	clickNextBtn : function() {		
		var ul = this.box.find("ul");
		if(ul.position().left + this.itemsLength*63 <= 63*7) return;
		var _left = ul.position().left - 63*7;
		ul.animate({left:_left});
	},
	_temp : function() {}
}

$n = {
	create : function() {
		return function() { this.initialize.apply(this, arguments); } 
	},
	overed : function(destination, source) {
		for (var property in source) {destination[property] = source[property];}
		return destination;
	},
	extend : function(ext, sup) {
		var ext_prototype = ext.prototype; var sup_prototype = sup.prototype;
		for (var property in sup_prototype) { if(!ext_prototype[property]) ext_prototype[property] = sup_prototype[property]; }
	},
	log : {
		LEVEL : 2,
		levels: {
			DEBUG:0,
			INFO:1,
			ERROR:2
		},
		setLogLevel : function(lv) {
			if(lv == "DEBUG") $n.log.LEVEL = $n.log.levels.DEBUG; 
			else if(lv == "INFO") $n.log.LEVEL = $n.log.levels.DEBUG;
			else if(lv == "ERROR") $n.log.LEVEL = $n.log.levels.DEBUG;
		},
		log : function(s) {
			try {
				if(typeof(console) != "undefined") console.log(s);
				else alert($n.object.toString(s));
			} catch(e) {}
		},
		debug : function(s) {
			if($n.log.LEVEL <= $n.log.levels.DEBUG) $n.log.log(s);;
		},
		info : function(s) {
			if($n.log.LEVEL <= $n.log.levels.INFO) $n.log.log(s);;
		},
		error : function(s) {
			if($n.log.LEVEL <= $n.log.levels.ERROR) $n.log.log(s);;
		}
	},
	date : {
		yyyyMMdd : function(d) {
			if(!d) d = new Date();
			return d.yyyyMMdd();
		}
	},
	math : {
		abs : function(x) {
			return Math.abs(x);
		},
		random : function(n) {
			if(typeof(n) == "undefined") return Math.random();
			else return $n.math.floor(Math.random() * n, 0);
			
		},
		round : function(n, index) {
			return $n.math._get("round", n, index);
		},
		ceil : function(n, index) {
			return $n.math._get("ceil", n, index);
		},
		floor : function(n, index) {
			return $n.math._get("floor", n, index);
		},
		_get : function(type, n, index) {
			if(typeof(index) == "undefined" || index == null) {
				index = 0;
			}
			if(index==0) return eval("Math."+type+"(n)");
			else {
				var p = Math.pow(10, index);
				return eval("Math."+type+"(n * p) / p");
			}
		}
	},
	cookie : {
		set : function(name, value) {
			var argc = arguments.length;
			var argv = arguments;
			var expires = ( argc > 2) ? argv[2]:null;
			var path = ( argc > 3) ? argv[3]:null;
			var domain = ( argc > 4) ? argv[4]:null;
			var secure = ( argc > 5) ? argv[5]:false;
	
			document.cookie = name + "=" + escape(value) +
				((expires == null) ? "" : ("; expires =" + expires.toGMTString())) +
				((path == null) ? "" : ("; path =" + path)) +
				((domain == null) ? "" : ("; domain =" + domain)) +
				((domain == true) ? "; secure" : "");
		},
		get : function(name) {
			var dcookie = document.cookie;
			var cname = name + "=";
			var clen = dcookie.length;
			var cbegin = 0;
			while (cbegin < clen) {
				var vbegin = cbegin + cname.length;
					if (dcookie.substring(cbegin, vbegin) == cname) {
						var vend = dcookie.indexOf (";", vbegin);
						if (vend == -1) vend = clen;
					return unescape(dcookie.substring(vbegin, vend));
				}
				cbegin = dcookie.indexOf(" ", cbegin) + 1;
				if (cbegin == 0) break;
			}
			return "";
		}
	},
	visible : function(e) {
		var _is_display = false;
		if(e) e.each(function() {if(this.style.display != "none") _is_display = true; });
		return _is_display;
	},
	focusNblur : function(selector, focusClass, blurClass) {
		if(typeof focusClass == "undefined") focusClass = "focus";
		if(typeof blurClass == "undefined") blurClass = "default";
		$(selector).focus(function(e) {
			var ee = $(e.target);
			ee.removeClass(blurClass);
			ee.addClass(focusClass);
		}).blur(function(e) {
			var ee = $(e.target);
			ee.removeClass(focusClass);
			ee.addClass(blurClass);
		});
	},
	object : {
		toString : function(obj) {
			var str = "";
			if(typeof obj == "string") return obj;
			else {
				for (var property in obj) {
					str += property + ":" + "{" + $n.object.toString(obj[property])+ "}";
				}
				return str;
			}
		},
		empty : function(obj) {
			if(typeof obj == "undefine" || obj == null) return true;
			if(typeof obj == "string") return $n.valid.empty(obj);
			if(typeof obj == "object") {
				var _ret = true;
				for (var property in obj) {
					_ret = false; break;
				}
				return _ret;
			}
		}
	},
	utils : {
		stripTag : function(s) {
			s = s.replace(/&(lt|gt);/g, function (strMatch, p1){	return (p1 == "lt")? "<" : ">"; });
			return s.replace(/<\/?[^>]+(>|$)/g, "");
		},
		toTag : function(s) {
			s = s.replace(/&(lt|gt);/g, function (strMatch, p1){	return (p1 == "lt")? "<" : ">"; });
			return s;
		},
		cutstring : function(s, length, postfix) {
			if(!s) return "";
			if(!postfix) postfix = "";
			if(s.length <= length) return s;
//			if($n.utils.byteSize(s) <= length) return s;
			else return s.substring(0, length) + postfix;
		},
		cutstring1 : function(s, length) {
			return $n.utils.cutstring(s, length, "...");
		},
		
		trim : function(str) {
			return str.replace(/(^\s*)|(\s*$)/g, "");
		}, 
		byteSize : function(str, twoByteWeight) {
			if(typeof twoByteWeight == "undefined") twoByteWeight = 2;
			if(!str ||  typeof str != 'string') return 0;
			var cnt = 0;
			for (var i = 0; i < str.length; i++) {
				if (str.charCodeAt(i) > 127)
					cnt += twoByteWeight;
				else
					cnt++;
			}
			return $n.math.ceil(cnt);
		},
		strlengthByByte : function(str, size, twoByteWeight) {
			if(typeof twoByteWeight == "undefined") twoByteWeight = 2;
			if(!str ||  typeof str != 'string') return 0;
			var cnt = 0, len = 0;
			
			for (var i = 0; i < str.length; i++) {
				if (str.charCodeAt(i) > 127)
					cnt += twoByteWeight;
				else
					cnt++;
				if(cnt > size) return len;
				len++;

			}
			return len;
		},
		cutbytestring : function(s, size, postfix, twoByteWeight) {
			if(!s) return "";
			if(!postfix) postfix = "";
			if($n.utils.byteSize(s) <= size) return s;
			else return s.substring(0, $n.utils.strlengthByByte(s, size, twoByteWeight)) + postfix;
		},
		cutbytestring1 : function(s, size, twoByteWeight) {
			return $n.utils.cutbytestring(s, size, "...", twoByteWeight);
		},
		cut : function(str, size, postfix) {
			if(typeof(postfix) == 'undefined') postfix = '...';

			var bytes = $n.utils.byteSize(str);
			if(bytes < size) return str;
			
			var cnt = 0, len = 0, t = -1;

			for(var i = 0; i < str.length; i++) {
				cnt += (str.charCodeAt(i) > 127) ? 2 : 1;
				
				if(t < 0 && (cnt + postfix.length > size)) t = len;
				
				if(cnt > size) break;
				len++;
			}
			
			if(cnt <= size) return str.substring(0, len);
			else return str.substring(0, t) + postfix;
		},
		cutline : function(str, size, line, postfix) {
			if(typeof(postfix) == 'undefined') postfix = '...';
			
			var cnt = 0, ln = 0, start = 0, end = 0;
			var result = '';
			
			for(var i = 0; i < str.length; i++) {
				cnt += (str.charCodeAt(i) > 127) ? 2 : 1;
				if(cnt > size) {
					var tmp = str.substring(start, end);
					ln++;
					
					if(ln < line) result += tmp + "\n";
					else {
						if(i <= str.length - 1) tmp = $n.utils.cut(tmp + postfix, size, postfix);
						
						result += tmp;
						break;
					}
					
					start = end++;
					cnt = (str.charCodeAt(i) > 127) ? 2 : 1;
				}
				else end++;
			}
			
			if(ln < line && end > start) result += str.substring(start, end);
			
			return result;
		}
	},	
	valid : {
		empty : function(str) {
			if(typeof str == "string" && $n.utils.trim(str).length > 0) 
				return false;
			return true;
		},
		email : function(str) {
			return (/\w+([-+.]\w+)*@\w+([-.]\w+)*\.[a-zA-Z]{2,4}$/).test(str);
		},
		kor : function(str) {
			str = $n.utils.trim(str);
			return (/^[가-힣]+$/).test(str);
		},
		numeng : function(str) {
			str = $n.utils.trim(str);
			return (/^[0-9a-zA-Z]+$/).test(str);
		},
		numengkor : function(str) {
			str = $n.utils.trim(str);
			return (/^[가-힣0-9a-zA-Z]+$/).test(str);
		},
		notkor : function(str) {
			str = $n.utils.trim(str);
			return (/[가-힣]+/).test(str);
		},
		numdash : function(str) {
			str = $n.utils.trim(str);
			return (/^[0-9]{1}[0-9\-]+$/).test(str);
		},
		url : function(str) {
			str = $n.utils.trim(str);
			return (/^http:\/\/([\w\-]+\.)+/).test(str);
		},
		num : function(str) {
			str = $n.utils.trim(str);
			return (/^[0-9]+$/).test(str);
		},
		phone : function(str) {
			str = $n.utils.trim(str);
			return (/^[0-9]{1,3}-[0-9]{3,4}-[0-9]{4}$/).test(str);
		},
		include2byte : function(str) {
			if(!str ||  typeof str != 'string') return false;
			for (var i = 0; i < str.length; i++) {
				if (str.charCodeAt(i) > 127)
					return true;
			}
			return false;
		}
	},
	mainurl : function() {
		var url = document.location.href;
		//return url;
		if(url.indexOf("me.sayclub.com") > 0) {
			return "http://me.sayclub.com";
		} else return _staticUrl;
	} 
}

$n.template = $n.create();
$n.template.prototype = {
	initialize : function(tmpl, json) {
		this.setTemplate(tmpl);
		this.setData(json);
	}, 
	setFile : function(src) {
		// TODO
	},
	setTemplate : function(tmpl) { if(tmpl) this._template = tmpl;},
	
	setData : function(data) {
		if(data && data != "") {
			this._data = $n.overed(this._data||{}, data||{});
		} else {
			this._data = {};
		}
	},
	html : function() {
		var js = this._template.replace(/[\r\t\n]/g, " ")
			.replace(/'(?=[^%]*%>)/g, "\t")
			.split("'").join("\\'")
			.split("\t").join("'")
			.replace(/<%=(.+?)%>/g, "',$1,'")
			.split("<%").join("');")
			.split("%>").join("write.push('");
		var f = new Function('obj', "var write=[];with (obj){write.push('"+js+"');}return write.join('');");
		if (!this._data) return f;
		var r = f(this._data);
		return r;
	}
	
}



$n.object.select = $n.create();
$n.object.select.prototype = {
	initialize : function(id, name, value, option) {
		this.id = id;
		this.name = name;
		if(arguments.length == 3 && typeof(value) != "string") {
			option = value;
			value = $("#"+this.id).attr("_value");
		}
		this.value = value;
		this.option = $n.overed({
			onchange : function() {},
			onclick : function() {},
			notitle : "&nbsp;",
			overflow : false
		}, option || {});
		this.select = $("#"+this.id).addClass("selectForm");
		this.selectList = this.select.find(" > div:last").hide();
		this.selected = this.select.find(" > div:first").addClass("selectTitle")
			.bind("click", this.selectList, this.clickSelected);

		if(this.option.overflow == false) { 
			this.selectList.addClass("selectLayer");
		} else {
			this.selectList.addClass("selectLayerWrap");
			this.selectList.find("ul").addClass("selectLayer");
		}
		
		if(this.option.width) {
			this.selected.css("width", this.option.width);
			this.selectList.css("width", this.option.width);
		}
		

		this.selectOptions = this.initOption(this.select.find(" > div:last li"));
		var __inp = this.select.find(" > input[name="+this.name+"]:hidden");
		if(__inp.length > 0) {
			this.select.find(" > input:hidden").attr("value", this.value);
			this.hiddenObject = __inp;
		} else {
			this.hiddenObject = $("<input type=\"hidden\"/>").attr("name", this.name).attr("value", this.value).appendTo(this.select);
		}
		this.setValue(this.value);
	},
	initOption : function(_opt) {
		if(_opt) 
			_opt.hover(function(e) { $(this).addClass("over");}, function(e) { $(this).removeClass("over");})
				.bind("click", this, this.clickOption);
		return _opt;
	},
	clickOption : function(e) {
		var _new = $(this).attr("_value");
		var _old = e.data.getValue();
		if(_new != _old) {
			e.data.setValue(_new);
			e.data.option.onchange(_old, _new);
		}
		e.data.selectList.hide();
		e.data.option.onclick(_old, _new);
	},
	clickSelected :	function(e) {
		if(e.data.parent().hasClass("selectFormOff")) return;
		
		if($n.visible(e.data)) e.data.hide();
		else {
			e.data.show();
			e.data.children().show();
		}
	},
	getValue : function() {
		return this.hiddenObject.attr("value");
	},
 	setValue : function(value) {
		if(typeof(value) == "undefined") {
			this.selected.find("> a").html(this.option.notitle);
		}
		this.value = value;
		var selectedOption = this.selectOptions.removeClass("selected")
					.filter("[_value="+value+"]");
		if(selectedOption.length == 0) {
			this.selected.find("> a").html(this.option.notitle);
		} else {
			this.selected.find("> a").html(selectedOption.addClass("selected").text());
		}
		this.hiddenObject.attr("value", value);
	},
	getText : function(key) {
		if(typeof key == "undefined") key = this.getValue();
		return this.select.find(" > div:last li[_value="+key + "] a").text();
	},
	appendOption : function(value, text) {
		this.selectOptions = this.initOption(
				$("<li></li>").attr("_value", value).html(text).appendTo(this.selectOptions.parent())
			).parent().find("li");
	},
	prependOption : function(value, text) {
		this.selectOptions = this.initOption(
				$("<li></li>").attr("_value", value).html(text).prependTo(this.selectOptions.parent())
			).parent().find("li");
	},
	removeOption : function(index) {
		this.selectList.find("li:eq(" + index + ")").remove();
		this.selectOptions = this.selectList.find("li");
	},
	hideOption : function(value) {
		this.selectOptions.filter("li[_value=" + value + "]").hide();
	},
	showOption : function(value) {
		this.selectOptions.filter("li[_value=" + value + "]").show();
	},
	onchange : function(f) {
		var old = this.option.onchange; 
		this.option.onchange = function(o, n) { old(o, n); f(o, n); }.bind(this);
	},
	onclick : function(f) {
		var old = this.option.onclick;
		this.option.onclick = function(o, n) { old(o, n); f(o, n); }.bind(this);
	},
	hide : function(speed) {
		if(speed) this.select.hide(speed);
		else this.select.hide();
	},
	show : function(speed) {
		if(speed) this.select.show(speed);
		else this.select.show();
	},
	setEnabled : function(enabled) {
		if(enabled) this.select.removeClass("selectFormOff").addClass("selectForm");
		else {
			this.select.removeClass("selectForm").addClass("selectFormOff");
			this.selectList.hide();
		}
	}

}
