/**
 * @fileoverview
 * cafen v21 의 각종 함수입니다.
 * 당 프로그램의 저작권은 http://cafen.net (outmind@cafen.net)에 있습니다
 * 당 프로그램의 수정 후 재 배포는 저작권자의 허락을 득한 후 재배포 할수 있습니다. 
 * 당 프로그램의 이용은 비 상업적인 목적의 경우 무료로 이용할 수 있습니다.
 * 당 프로그램의 이용은 상업적인 목적의 경우 저작권자의 허락을 득한 후 이용할 수 있습니다.
 * 당 프로그램의 설치후 관리자는 outmind@cafen.net 으로 설치하였다는 통보 메일을 발송하여야 합니다.
 * 당 프로그램안에 있는 모든 저작권 표시 영역은 수정할수 없습니다.
 *
 * ------------------------------------------------
 * 설치 방법은 함께 배포된 README 파일 참조 바랍니다.
 * ------------------------------------------------
 *
 * @author Kimjonggab(outmind@cafen.net)
 * @copyright Copyright (c) 2004 Cafen.net (http://cafen.net)
 */

var cafenGlobalBaseConf = {onloadQueue : [], httpproxy: 'http://service2.cafen.net/httpproxy.php', scripturl : 'http://service2.cafen.net/', hl : 'ko', licence : false, useImageEditor : false, useMediaPlayer : false, useTranlate : true, siteMsg : {confirmWithoutFilter:'You cannot submit this data for the private data. Remove private data',confirmFileFilterTitle:'Private Data was found in this file.',confirmFileFilter:'You cannot upload this file.',confirmFileExeFilter:'You cannot upload executable file.',forbiddenExt:''}};

if (typeof cafenGlobalConf == 'undefined') {
	var cafenGlobalConf = cafenGlobalBaseConf;
} else {
	for (var idx in cafenGlobalConf ) 
		cafenGlobalBaseConf[idx] = cafenGlobalConf[idx];
	idx = null;
	cafenGlobalConf = cafenGlobalBaseConf;
}
if (typeof siteMsg != 'undefined') {
	for (var idx in siteMsg ) 
		cafenGlobalConf['siteMsg'][idx] = siteMsg[idx];
}

if (_cafen_service_url == null)
	var _cafen_service_url = cafenGlobalConf.scripturl;
if (typeof cafenGlobalLang == 'undefined' || cafenGlobalLang.lang != cafenGlobalConf.hl ) {
	if (cafenGlobalConf.hl == 'cn')
		document.write('<scr'+'ipt TYPE="text/JavaScript" charset="utf-8" LANGUAGE="JavaScript1.2" SRC="'+_cafen_service_url+'charset/chinese.js"></scr'+'ipt>');
	else if (cafenGlobalConf.hl == 'en')
		document.write('<scr'+'ipt TYPE="text/JavaScript" charset="utf-8" LANGUAGE="JavaScript1.2" SRC="'+_cafen_service_url+'charset/english.js"></scr'+'ipt>');
	else if (cafenGlobalConf.hl == 'jp')
		document.write('<scr'+'ipt TYPE="text/JavaScript" charset="utf-8" LANGUAGE="JavaScript1.2" SRC="'+_cafen_service_url+'charset/japanese.js"></scr'+'ipt>');
	else
		document.write('<scr'+'ipt TYPE="text/JavaScript" charset="utf-8" LANGUAGE="JavaScript1.2" SRC="'+_cafen_service_url+'charset/korean.js"></scr'+'ipt>');
}

if (typeof cafen == 'undefined' || typeof cafen.langSet == 'undefined')
	document.write('<scr'+'ipt TYPE="text/JavaScript" charset="utf-8" LANGUAGE="JavaScript1.2" SRC="'+_cafen_service_url+'cafenLangSet.js"></scr'+'ipt>');
document.write('<link rel="stylesheet" type="text/css" href="'+_cafen_service_url+'images/cafen.css" />');

var checkSeqn = 0;
Function.prototype.bind = function() {
	var __method = this, args = $A(arguments), obj = args.shift();
	var bindFnc = function() {
		return __method.apply(obj, args.concat($A(arguments)));
	}
	bindFnc.getFunctionName = function() {
		return cafen.getFunctionName(__method)+'.bind';
	}
	return bindFnc;
}

Function.prototype._bindBreak = function() {
	var __method = this, args = $A(arguments), obj = args.shift();
	var bindFnc = function() {
		cafen.debugBreakPointCheck(bindFnc.getFunctionName());
		return __method.apply(obj, args.concat($A(arguments)));
	}
	bindFnc.getFunctionName = function() {
		return '_'+cafen.getFunctionName(__method);
	}
	return bindFnc;
}


Function.prototype.bindAsEventListener = function(obj) {
	var __method = this;
	var bindFnc = function(event) {
		return __method.call(obj, event || window.event);
	}
	bindFnc.getFunctionName = function() {
		return cafen.getFunctionName(__method)+'.bind';
	}
	return bindFnc;
}

if (Array.prototype && !Array.prototype.push) {
	Array.prototype.push = function() {
		for (var i=0; i<arguments.length; i++) this[this.length] = arguments[i];
		return this.length;
	};
}

if (Array.prototype && !Array.prototype.pop) {
	Array.prototype.pop = function() {
		var lastitem = this.length > 0 ? this[this.length - 1] : undefined;
		if (this.length > 0) this.length--;
		return lastitem;
	};
}

if (Array.prototype && !Array.prototype.shift) {
	Array.prototype.shift = function() {
		var firstitem = this.length > 0 ? this[0] : undefined;
		for (var i=0; i<this.length-1; i++) this[i] = this[i + 1];
		if (this.length > 0) this.length--;
		return firstitem;
	};
}

if (Array.prototype && !Array.prototype.join) {
	Array.prototype.join = function(separator) {
		if (typeof separator != "string") separator = ",";
		var s = "";
		for (var i=0; i<this.length; i++) {
			if (this[i] != null && this[i] != undefined) s += this[i];
			if (i != this.length - 1) s += separator;
		}
		return s;
	};
}

if (String.prototype && !String.prototype.split) {
	String.prototype.split = function(separator, limit) {
		var s = "" + this;
		var a = new Array();
		var sepIndex;
		
		if (typeof separator != "string") return new Array(s);
		if (separator == "") {
			while (s.length) {
				a[a.length] = s.substring(0, 1);
				s = s.substring(1);
				if (typeof limit == "number" && a.length >= limit) break;
			}
		}
		else {
			while (s.length) {
				sepIndex = s.indexOf(separator);
				a[a.length] = s.substring(0, sepIndex);
				s = s.substring(sepIndex+separator.length);
				if (typeof limit == "number" && a.length >= limit) break;
				if (s.length == 0) a[a.length] = s;
			}
		}
		return a;
	};
}

var $A = Array.from = function(iterable) {
  if (!iterable) return [];
  if (iterable.toArray) {
		return iterable.toArray();
  } else {
		var results = [];
		for (var i = 0; i < iterable.length; i++)
		  results.push(iterable[i]);
		return results;
  }
}

var cafen = {
	NAMESPACE:'cafen',
	build:'080131',
	Version: '2.0.0',
	getWindow : function(win) {
		return win || window;
	},
	getDocument : function(doc) {
		return doc || document;
	},
	getBody : function(body){
		return body || document.getElementsByName('BODY')[0] || document.body || document.documentElement;
	},
	getCallee : function(func) {
		func = func || arguments.callee.caller;
		var results = [];
		while(typeof func == 'function') {
			try {
				var fncName = this.getFunctionName(func);
				if (fncName.indexOf('_') != 0)
					results.push(fncName);	
			} catch(ex) {
				results.push('unknown');	
			}
			func = func.caller || null;
			if (results.length > 10)
				break;
		}
		return results;
	},
   $:function() {
		var _elements = new Array();
		for (var i = 0; i < arguments.length; i++) {
			var _element = arguments[i];
			if (typeof _element == 'string') 
				_element = document.getElementById(_element);
			if (arguments.length == 1)
				return _element;
			_elements.push(_element);
		}
		return _elements;
	},
	C$ : function(obj, tag) {
		var objs =  obj.childNodes;
		if (tag == null)
			return objs;
		else {
			tag = tag.toUpperCase();
			var tags = tag.split(' ');
			var findObj = [];
			for(var j = 0; j < tags.length; j++) {
				tag = tags[j];
				for(var i = 0; i < objs.length; i++) {
					if (objs[i].tagName == tag) {
						if (j == (tags.length -1))
							findObj.push(objs[i]);	
						else {
							objs = objs[i].childNodes;
							break;
						}	
					}
				}
			}
			return findObj;
		}
	},
	rand : function(minVal, maxVal) {
		return Math.round(Math.random() * (maxVal - minVal)+ minVal);
	},
	parseInt: function(val) {
		if (typeof val == 'number')
			return val;
		else if (typeof val == 'string'){
			val = parseInt(val.replace(/^([0]+)/gi, ''));
			if (isNaN(val))
				return 0;
			else
				return val;
		} else
			return 0;
	},
	randArray : function(val) {
		var maxLen = val.length;
		for(var i = 0 ; i < maxLen; i++) {
			var randNo = this.rand(0, maxLen - 1);
			if (randNo != i) {
				var tmpVal = val[i];
				val[i] = val[randNo];
				val[randNo] = tmpVal;
			}
		}
		return val;
	},
	numberFormat : function (nStr) {
		if (typeof nStr != 'string')
			nStr = nStr.toString();
		var x = nStr.split('.');
		var x1 = x[0] , x2 = x.length > 1 ? '.' + x[1] : '';
		var rgx = /(\d+)(\d{3})/;
		while (rgx.test(x1)) 
			x1 = x1.replace(rgx, '$1' + ',' + '$2');
		return x1 + x2;
	},
	getPage : function (items, current_no, ppage) {
		var total = items.length;
		if (current_no == null)
			current_no = 0;
		if (current_no > total) 
			current_no = total;
		var start_line = (total > current_no)?current_no:0;
		var end_line = (total > start_line + ppage)?start_line + ppage:total;
		var curr_page = parseInt(start_line/ppage) + 1;
		var total_page = Math.ceil(total/ppage);
		return {
			cline : current_no,
			total : total,
			page : curr_page,
			pages : total_page,
			start : start_line,
			end : end_line
		}
	},
	sixteenNamedColors : {
		aqua : '#00FFFF',black : '#000000',blue : '#0000FF',fuchsia : '#FF00FF',
		gray : '#808080',green : '#008000',lime : '#00FF00',maroon : '#800000',
		navy : '#000080',olive : '#808000',purple : '#800080',red : '#FF0000',
		silver : '#C0C0C0',teal : '#008080',white : '#FFFFFF',yellow : '#FFFF00'
	},
	checkHex : function(hex) {
		var m = '';
		if (hex != null) {
			if (m = hex.match(/#?([0-9a-f]{6}|[0-9a-f]{3})/i)) {
				if (m[1].length == 3) {
					var arr = m[1].match(/./g);
					m = [arr[0]+arr[0],arr[1]+arr[1],arr[2]+arr[2]];
				} else {
					m = m[1].match(/../g);
				}
				return '#'+m[0]+m[1]+m[2];
			} else if (hex.toLowerCase() == 'transparent')
				return 'transparent';
			else {
				hex = hex.toLowerCase();
				for(var colorName in this.sixteenNamedColors) {
					if (hex == colorName) {
						return this.sixteenNamedColors[colorName];
						break;
					}
				}
				return '';
			}
		} else 
			return '';
	},
	getCookie:function (name){
	    var dc = document.cookie;
	    var prefix = name + "=";
	    var begin = dc.indexOf("; " + prefix);
	    if (begin == -1) {
	        begin = dc.indexOf(prefix);
	        if (begin != 0) return null;
	    } else {
	        begin += 2;
	    }
	    var end = document.cookie.indexOf(";", begin);
	    if (end == -1) end = dc.length;
	    return unescape(dc.substring(begin + prefix.length, end));
	},
	setCookie : function(name, value, expires, path, domain, secure){
		document.cookie= name + "=" + escape(value) +
		((expires) ? "; expires=" + expires.toGMTString() : "") +
		((path) ? "; path=" + path : "") +
		((domain) ? "; domain=" + domain : "") +
		((secure) ? "; secure" : "");
   },
   getChildNodes : function(elements) {
   		elements = this.$(elements);
   		var childs = [];
   		for(var i = 0 ; i < elements.childNodes.length ; i ++ ) {
   			if (elements.childNodes[i].tagName)
   				childs.push(elements.childNodes[i]);
   		}
   		return childs;
  	},
	getDocumentLocation : function () {
		var pathname = document.location.pathname;
		if (pathname.indexOf('/') !== 0)
			pathname = '/' + pathname;
		return pathname;
	},
	insertAfter : function(newEl, tarEl) {
		tarEl.parentNode.insertBefore(newEl, tarEl.nextSibling );
	},
	getParseParam : function(params) {
		var paramDataHash = {};
		params = params.split('#')[0];
		var paramDatas = params.split('&');
		for(var i = 0; i < paramDatas.length; i++) {
			var keyVal = paramDatas[i].split('=');
			if (keyVal.length > 1 && keyVal[0] != '' && keyVal[1] != '')
				paramDataHash[keyVal[0]] = decodeURIComponent(keyVal[1]);
		}
		return paramDataHash;
	},
	getUrlHashMap : function() {
		var paramDataHash = {};
		if (cafenGlobalConf.paramForm != null && this.$(cafenGlobalConf.paramForm) != null) {
			var form = this.$(cafenGlobalConf.paramForm);
			for(var i = 0; i < form.elements.length ; i++) {
				var formObj = 	form.elements[i];
				if (formObj.value != '')
					paramDataHash[formObj.name] = formObj.value;
			}
		} else {
			var theURL = document.location.href;
			var urlVal = theURL.split('?');
			var mainUrl = urlVal[0];
			if (urlVal.length > 1 && urlVal[1] != '') {
				paramDataHash = this.getParseParam(urlVal[1]);
			}
		}
		return paramDataHash;
	},
	getUrlParam : function(nextURL, hashData, label, addRandom) {
		nextURL = nextURL || this.getDocumentLocation();
		var newData = [];
		for(var idx in hashData) {
			if (hashData[idx] != null && hashData[idx] != '')
				newData.push(idx +'=' + encodeURIComponent(hashData[idx]));
		}
		if (addRandom)
			newData.push((new Date()).getTime()+'_'+this.rand(100000,900000));
		if (newData.length > 0) 
			nextURL += '?'+newData.join('&');
		if (label != null && label != '')
			nextURL += '#'+label;
		return nextURL;
	},
	arrayMerge : function(obj1, obj2) {
		for(var i = 0; i < obj2.length; i++) {
			var oldFinded = false;
			for(var j = 0; j < obj1.length; j++) {
				if (obj2[i] == obj1[j]) {
					oldFinded = true;
					break;
				}
			}
			if (!oldFinded)
				obj1.push(obj2[i]);
		}
		return obj1;
	},
	checkArray : function(obj) {
		if (obj instanceof Array) 
			return obj;
		else if (obj != null)
			return [obj];
		else
			return [];
	},
	flashDetect : {
		installed : false,
		raw : "",
		major : -1,
		minor : -1,
		revision : -1,
		revisionStr : "",
		checked : false,
		activeXDetectRules : [
			{
				"name":"ShockwaveFlash.ShockwaveFlash.7",
				"version":function(obj){
					return cafen.flashDetect.getActiveXVersion(obj);
				}
			},
			{
				"name":"ShockwaveFlash.ShockwaveFlash.6",
				"version":function(obj){
					var version = "6,0,21";
					try{
						obj.AllowScriptAccess = "always";
						version = cafen.flashDetect.getActiveXVersion(obj);
					}catch(err){}
					return version;
				}
			},
			{
				"name":"ShockwaveFlash.ShockwaveFlash",
				"version":function(obj){
					return cafen.flashDetect.getActiveXVersion(obj);
				}
			}
		],
		getActiveXVersion : function(activeXObj){
			var version = -1;
			try{
				version = activeXObj.GetVariable("$version");
			}catch(err){}
			return version;
		},
		getActiveXObject : function(name){
			var obj = -1;
			try{
				obj = new ActiveXObject(name);
			}catch(err){
				obj = {activeXError:true};
			}
			return obj;
		},
		parseActiveXVersion : function(str){
			var versionArray = str.split(",");
			return {
				"raw":str,
				"major":parseInt(versionArray[0].split(" ")[1], 10),
				"minor":parseInt(versionArray[1], 10),
				"revision":parseInt(versionArray[2], 10),
				"revisionStr":versionArray[2]
			};
		},
		parseStandardVersion : function(str){
			var descParts = str.split(/ +/);
			var majorMinor = descParts[2].split(/\./);
			var revisionStr = descParts[3];
			return {
				"raw":str,
				"major":parseInt(majorMinor[0], 10),
				"minor":parseInt(majorMinor[1], 10), 
				"revisionStr":revisionStr,
				"revision": this.parseRevisionStrToInt(revisionStr)
			};
		},
		parseRevisionStrToInt : function(str){
			return parseInt(str.replace(/[a-zA-Z]/g, ""), 10) || this.revision;
		},
		majorAtLeast : function(version){
			return this.major >= version;
		},
		minorAtLeast : function(version){
			return this.minor >= version;
		},
		revisionAtLeast : function(version){
			return this.revision >= version;
		},
		versionAtLeast : function(major){
			var properties = [this.major, this.minor, this.revision];
			var len = Math.min(properties.length, arguments.length);
			for(i=0; i<len; i++){
				if(properties[i]>=arguments[i]){
					if(i+1<len && properties[i]==arguments[i]){
						continue;
					}else{
						return true;
					}
				}else{
					return false;
				}
			}
		},
		getInfo : function() {
			this.check();
			return {
				raw : this.raw,
				major : this.major,
				minor : this.minor, 
				revisionStr : this.revisionStr,
				revision : this.revision
			}
		},
		check : function(){
			if (!this.checked) {
				this.checked = true;
				if(navigator.plugins && navigator.plugins.length>0){
					var type = 'application/x-shockwave-flash';
					var mimeTypes = navigator.mimeTypes;
					if(mimeTypes && mimeTypes[type] && mimeTypes[type].enabledPlugin && mimeTypes[type].enabledPlugin.description){
						var version = mimeTypes[type].enabledPlugin.description;
						var versionObj = this.parseStandardVersion(version);
						this.raw = versionObj.raw;
						this.major = versionObj.major;
						this.minor = versionObj.minor; 
						this.revisionStr = versionObj.revisionStr;
						this.revision = versionObj.revision;
						this.installed = true;
					}
				}else if(navigator.appVersion.indexOf("Mac")==-1 && window.execScript){
					var version = -1;
					for(var i=0; i<this.activeXDetectRules.length && version==-1; i++){
						var obj = this.getActiveXObject(this.activeXDetectRules[i].name);
						if(!obj.activeXError){
							this.installed = true;
							version = this.activeXDetectRules[i].version(obj);
							if(version!=-1){
								var versionObj = this.parseActiveXVersion(version);
								this.raw = versionObj.raw;
								this.major = versionObj.major;
								this.minor = versionObj.minor; 
								this.revision = versionObj.revision;
								this.revisionStr = versionObj.revisionStr;
							}
						}
					}
				}
			}
		}
	},
	makeScroll : function(obj, options) {
		window.setTimeout(function() {new cafen.divScroll(obj, options);}, obj.tagName == 'IFRAME' ?  1000 : 1);
	},
	Columns : {
		singleTags : ["br", "img", "hr", "input", "!--"],
		tmpDiv : null,
		devmode : "off",	
		cols : new Array(),
		onSplitStart : new Function(),
		onSplitEnd : new Function(),
		onSplit : new Function(),
		chop : [
			'<SPAN class=colbreak></SPAN>',
			'<span class="colbreak"></span>',
			'<BR>',
			'<br>',
			'<br/>',
			'<br />',
			'<p></p>',
			'<P></P>'
		],
		splitText : function(text, width, height, tmpDiv) {
			this.tmpDiv = cafen.$(tmpDiv || 'divSizer');
			if (this.tmpDiv == null || typeof this.tmpDiv.innerHTML == 'undefined')
				return [];
			this.tmpDiv.style.width = width + "px";
			this.cols = new Array();
			this.innerHTMLHits = 0;
			var startDate = new Date();
			var x = "";
			for (var i = 0; text != ""; i++) {
				this.cols[i] = this.getFragment(text, width, height);
				text = text.slice(this.cols[i].length);
				for (var j = 0; j < this.chop.length; j++) {
					if (text.charAt(0) == "\n") text = text.slice(1);
					x = this.chop[j];
					while (text.indexOf(x) == 0) text = text.slice(x.length);
				}
				for (var k = this.openTags.length - 1; k >= 0; k--) {
					this.cols[i] += "</" + this.openTags[k].split(" ")[0] + ">";
					if (text != "") text = "<" + this.openTags[k] + ">" + text;
				}
				for (var m = 0; m < this.chop.length; m++) {
					if (text.charAt(0) == "\n") text = text.slice(1);
					x = this.chop[m];
					while (text.indexOf(x) == 0) text = text.slice(x.length);
				}
				this.onSplit(this.cols[i]);
				if (i > 10)
					break;
			}
			var endDate = new Date();
			var message = "Time taken for splitting text = " + (endDate-startDate)/1000 + " seconds";
			message += " Number of unclosed tags found = " + this.openTags.length;
			message += " innerHTMLHits = " + this.innerHTMLHits;
			cafen.debugMessage(message, 'columns');
			return this.cols;
		},
		getFragment : function(text, width, height) {
			var objSizer = this.tmpDiv;
			var i = 0;
			var limit = 0;
			var add = 0;
			var doloop = false;
			this.openTags = new Array();
			objSizer.innerHTML = text;
			if (objSizer.offsetHeight <= height) i = text.length;
			else {
				doloop = true;
				limit = text.length;
			}
			while (doloop) {
				add = Math.round((limit - i) / 2);
				if (add <= 1) doloop = false;
				i += add;
				objSizer.innerHTML = text.substr(0, i);
				if (objSizer.offsetHeight > height){
					limit = i;
					i -= add;
				}
				this.innerHTMLHits ++;
			}
			if (text.substr(0, i) != text) {
				var lastSpace = text.substr(0, i).lastIndexOf(" ");
				var lastNewline = text.substr(0, i).lastIndexOf("\n")
				var lastGreater = text.substr(0, i).lastIndexOf(">");
				var lastLess = text.substr(0, i).lastIndexOf("<");
				if (lastLess <= lastGreater && lastNewline == i - 1) i = i;
				else if (lastSpace != -1 && lastSpace > lastGreater && lastGreater > lastLess) i = lastSpace + 1;
				else if (lastLess > lastGreater) i = lastLess;
				else if (lastGreater != -1)  i = lastGreater + 1;
			}
			if (i == 0) 
				i = text.indexOf('>')+1;
			
			text = text.substr(0, i).split('<SPAN class=colbreak></SPAN>')[0];
			text = text.substr(0, i).split('<span class="colbreak"></span>')[0];
			var doPush = true;
			var tags = text.split("<");
			tags.shift();
			
			for (var j=0; j<tags.length; j++) {
				tags[j] = tags[j].split(">")[0];
				if (tags[j].charAt(tags[j].length-1) == "/") continue;
				if (tags[j].charAt(0) != "/") {
					for (var k=0; k<this.singleTags.length; k++) {
						if (tags[j].split(" ")[0].toLowerCase() == this.singleTags[k]) doPush = false;
					}
					if (doPush) this.openTags.push(tags[j]);
					doPush = true;
				}
				else this.openTags.pop();
			}
			return text;
		}
	},
	columnsSplittmpDiv : null,
	copyStyle : function(sorObj, tarObj, copyStyles) {
		if (sorObj.className)
			this.setAttribute(tarObj , {className : sorObj.className});
		copyStyles = copyStyles || [
			'border', 'borderLeft', 'borderRight', 'borderTop', 'borderBottom', 
			'padding', 'paddingLeft', 'paddingRight', 'paddingTop', 'paddingBottom',
			'margin', 'margnLeft', 'marginRight', 'marginTop', 'marginBottom',
			'lineHeight','fontSize','color','fontWeight'
		];
		for(var i = 0; i < copyStyles.length ;  i++) {
			var styleName = copyStyles[i];
			var styleValue = this.getStyle(sorObj, styleName);
			if (styleValue != null) 
				tarObj.style[styleName] = styleValue;
		}
	},
	splitColumns : function(_Objects, options) {
		_Objects = this.checkArray(_Objects);
		options = options || {width:200, height:200};
		var tarWidth = options.width || 200;
		var tarHeight = options.height || 200;
		if (this.columnsSplittmpDiv != null)
			cafen.show(this.columnsSplittmpDiv, '');
		for(var i =0; i < _Objects.length; i++) {
			var obj = this.$(_Objects[i]);
			if (obj.colObj != null) {
				obj.colObj.parentNode.removeChild(obj.colObj);
				cafen.show(obj, '');
			}
			var baseWidth = obj.offsetWidth ;
			var baseClassName = obj.className || 'rainColumns';
			if (options.width > 10)
				tarWidth = options.width;
			else {
				tarWidth = Math.floor(baseWidth/ options.width);
			}
			if (this.columnsSplittmpDiv == null) {
				this.columnsSplittmpDiv = document.createElement('div');
				obj.parentNode.insertBefore(this.columnsSplittmpDiv, obj);
				this.setStyle(this.columnsSplittmpDiv, {visibility:'hidden', height: 'auto', textAlign:'left'});
				cafen.show(this.columnsSplittmpDiv, '');
			}
			this.setAttribute(this.columnsSplittmpDiv, {className : baseClassName});
			this.copyStyle(obj, this.columnsSplittmpDiv);
			this.setStyle(this.columnsSplittmpDiv, {border:'0 none', margin:'0', padding:'0'});
			var outDiv = document.createElement('ul');
			this.setAttribute(outDiv, {className : baseClassName});
			obj.parentNode.insertBefore(outDiv, obj);
			this.setStyle(outDiv, {width : baseWidth +'px', textAlign:'left', listStyle : 'none'});
			var exampleColumns = this.Columns.splitText(obj.innerHTML, tarWidth , tarHeight, this.columnsSplittmpDiv);
			for (var i = 0; i < exampleColumns.length; i ++) {
				var colDiv = document.createElement('li');
				outDiv.appendChild(colDiv);
				this.setAttribute(colDiv, {className : baseClassName});
				this.setStyle(colDiv, {float :'left', width : tarWidth +'px', height : tarHeight +'px',textAlign:'left', overflow : 'hidden'});
				var tmpObj = document.createElement('div');
				tmpObj.innerHTML = exampleColumns[i];
				this.setStyle(tmpObj, {width : tarWidth +'px', height : tarHeight +'px',textAlign:'left', overflow : 'hidden'});
				colDiv.appendChild(tmpObj) ;
			}
	//		var colDiv = document.createElement('li');
	//		this.setStyle(colDiv, {float:'left',clear : 'both', width:'1px', height:'1px'});
	//		outDiv.appendChild(colDiv);
			cafen.hide(obj);
			obj.colObj = outDiv;
			obj.showColumns = cafen.showColumns;
			obj.getObject = function() {return this.colObj;}
			obj.getColumns = cafen.getColumns;
		}
		if (this.columnsSplittmpDiv != null)
			cafen.hide(this.columnsSplittmpDiv);
	},
	getColumns : function(num) {
		if (this.colObj == null)
			return null;
		else if (this.colObj.childNodes.length > num) {
			return 	this.colObj.childNodes[num];
		} else
			return null;
	},
	showColumns : function(start, end) {
		if (this.colObj == null)
			return ;
		for(var i = 0 ; i < this.colObj.childNodes.length ; i++) 
			cafen.hide(this.colObj.childNodes[i]);
		var tmpObj = null;
		var showObjs = [];
		end = start + (end || 1);
		for(var i = start ; i < end ; i++) {
			if (tmpObj = this.colObj.childNodes[i]) {
				cafen.show(tmpObj,'');
				showObjs.push(tmpObj);
			}
		}
		return showObjs;
	},
	simpleAttach : function(_Objects) {
		_Objects = this.checkArray(_Objects);
		for(var i =0; i < _Objects.length; i++) {
			var obj = this.$(_Objects[i]);
			if (obj == null)
				continue;
			var attrib = new cafen.Attribute(obj);
			var item_width = attrib.getInt("buttonwidth", null) || attrib.getInt("width", null) || obj.offsetWidth;
			var item_height = attrib.getInt("buttonheight", null) || attrib.getInt("height", null) || obj.offsetHeight;
			var file_type = attrib.get("attachfile_type", "all") ;
			var attachfile_size = attrib.getInt("attachfile_size", null) ;
			var attachfile_cnt = attrib.getInt("attachfile_cnt", 1) ;
			var attach_txt = attrib.get("attachtxt", null);
			var useProcess = attrib.getBoolean("useprocess", false);
			var buttonUrl = attrib.get("buttonimg", null) ;
			var bgColor = attrib.get("bgColor", null) ;
			var oldFile = attrib.get("oldvalue", "") ;
			if (oldFile == '')
				oldFile = attrib.get("value", "") ;
			var linkObj = attrib.get("linkobj", null) ;
			var outDiv = document.createElement('div');
			obj.parentNode.insertBefore(outDiv, obj);
			var outSize = (useProcess) ? item_width +7 + attrib.getInt("processwidth", 200) : item_width+7 ;
			cafen.setStyle(outDiv, {backgroundImage:'none', position:'relative', listStyle : 'none', display :'inline', width: outSize +'px', height : item_height +'px', lineHeight:'100%', padding:'0', margin:'0', overflow:'hidden'});
			obj.setObj = function(obj) {
				var fileObj = obj.getFile();
				this.value = fileObj.server + '|' + fileObj.size + '|' + fileObj.extension + '|' + fileObj.fileName + '|' + fileObj.extra;
				if ((typeof this.onchange) == 'function') {
					this.onchange();
				}
			}
			cafen.hide(obj);
			var options = {
				maxSize : attachfile_size, 
				uploadType : file_type || 'all',
				buttonText : attach_txt || null,
				fileTypes : file_type,
				fontColor : '#464646',
				bgColor : '#ffffff',
				useInputBox : useProcess,
				uploadBorder : '0 none',
				uploadWidth : item_width,
				uploadHeight : item_height,
				buttonUrl : buttonUrl,
				linkObj : linkObj,
				event : {
					end : obj.setObj.bind(obj)
				}
			}
			var uploadclass= new cafen.XUpload(outSize, file_type, oldFile, options);
			outDiv.appendChild(uploadclass.getObject());
			uploadclass.onLoad();
		}
	},
	colorPicker : function(_Objects, options) {
		options = options || {x : 'right', y : 'top'};
		_Objects = this.checkArray(_Objects);
		for(var i =0; i < _Objects.length; i++) {
			var obj = this.$(_Objects[i]);
			if (obj == null)
				continue;
			obj.linkObj = obj.getAttribute('linkObj') ? this.$(obj.getAttribute('linkObj')) : obj;
			if (typeof obj.setColor != 'function') {
				obj.setColor = function (val) {
					if (this.linkObj.tagName == 'INPUT')
						this.linkObj.value = val;
					else 
						this.linkObj.style.backgroundColor = val;
					if (this.onchange != null && typeof this.onchange == 'function') {
						try {
							this.onchange();
						} catch(ex) {
							cafen.debugMessage(ex);	
						}	
					}
				}
			}
			if (typeof obj.linkObj.getColor != 'function') {
				obj.linkObj.getColor = function() {
					if (this.tagName == 'INPUT') {
						return this.value;	
					} else {
						return this.style.backgroundColor;
					}
				}
			}
			obj.onclick = function() {
				if (this.colorPicker == null) {
					this.colorPicker = new cafen.XColorpicker({title : 'ColorPicker', sticker : {obj : this, x : options.x, y : options.y}, onClose : this.setColor.bind(this)});
				}
				this.colorPicker.setColor(this.linkObj.getColor());
				this.colorPicker.onLoad({obj : this, x : options.x, y : options.y});
			}
		}
	},
	datePicker : function(_Objects, options) {
		options = options || {x : 'right', y : 'top'}
		_Objects = this.checkArray(_Objects);
		for(var i =0; i < _Objects.length; i++) {
			var obj = this.$(_Objects[i]);
			if (obj == null)
				continue;
			obj.linkObj = obj.getAttribute('linkObj') ? this.$(obj.getAttribute('linkObj')) : obj;
			obj.setDate = function (val) {
				if (this.linkObj.tagName == 'INPUT')
					this.linkObj.value = val;
				else 
					this.linkObj.innerHTML = val;
			}
			obj.onclick = function() {
				if (this.calPicker == null) 
					this.calPicker = new cafen.XCalendar({title : 'Calendar', sticker : {obj : this , x : options.x, y : options.y}, onClose : this.setDate.bind(this)});
				if (this.linkObj.tagName == 'INPUT')
					this.calPicker.setDate(this.linkObj.value);
				else
					this.calPicker.setDate(this.linkObj.innerHTML);
				this.calPicker.onLoad();
			}
		}
	},
	selectPicker : function(_Objects) {
		if (!this.isMobile()) {
			_Objects = this.checkArray(_Objects);
			for(var i =0; i < _Objects.length; i++) {
				var obj = this.$(_Objects[i]);
				if (obj == null)
					continue;
				new cafen.selectDraw(obj);
			}
		}
	},
	mapPicker : function(_Objects, options) {
		options = options || {x : 'right', y : 'top'}
		_Objects = this.checkArray(_Objects);
		for(var i =0; i < _Objects.length; i++) {
			var obj = this.$(_Objects[i]);
			if (obj == null)
				continue;
			obj.linkObj = obj.getAttribute('linkObj') ? this.$(obj.getAttribute('linkObj')) : obj;
			obj.setMap = function (mapObj) {
				mapObj.close();
				var val =mapObj.getMap();
				if (this.linkObj.tagName == 'IMG')
					this.linkObj.src = val;
				else if (this.linkObj.tagName == 'INPUT')
					this.linkObj.value = val;
				else 
					this.linkObj.innerHTML = val;
			}
			obj.onclick = function() {
				if (this.mapPicker == null) 
					this.mapPicker = new cafen.XMapViewer({style : {width:'600px', height : '300px'}, event :{done : this.setMap.bind(this)}, sticker : {obj : this , x : options.x, y : options.y}});
				if (this.linkObj.tagName == 'IMG') 
					this.mapPicker.setMap(this.linkObj.src);
				else if (this.linkObj.tagName == 'INPUT') 
					this.mapPicker.setMap(this.linkObj.value);
				else
					this.mapPicker.setMap(this.linkObj.innerHTML);
				this.mapPicker.onLoad();
			}
		}
	},
	setFormCheck : function(bl, formEle) {
		if (formEle != null) {
			if (formEle.tagName == null && formEle.length) {
				for(var i = 0 ; i < 	formEle.length; i++ ) {
					formEle[i].checked = bl;
				}
			} else {
				switch(formEle.tagName) {
					case 'INPUT' :
						switch(formEle.getAttribute("type")) {
							case 'checkbox' :
								formEle.checked = bl;
								break;
							default :
								break;
						}	
						break;
				}				
			}
		}		
	},
	getFormValue : function(formEle) {
		var selectedValue = [];
		if (formEle != null) {
			if (formEle.tagName == null && formEle.length) {
				for(var i = 0 ; i < 	formEle.length; i++ ) {
					var currObj = formEle[i];
					if (currObj.checked && currObj.value != '')
						selectedValue.push(currObj.value);
				}
			} else if (formEle.tagName != null){
				switch(formEle.tagName) {
					case 'SELECT' :
						var selectedIndexValue = formEle.options[formEle.selectedIndex].value;
						if (selectedIndexValue != '' && formEle.selectedIndex > -1)
							selectedValue.push(selectedIndexValue);
						break;
					case 'INPUT' :
						switch(formEle.getAttribute("type")) {
							case 'radio' :
							case 'checkbox' :
								if (formEle.checked) {
									var selectedIndexValue = formEle.value;
									if (selectedIndexValue != '')
										selectedValue.push(selectedIndexValue);
								}								
								break;
							default :
								var selectedIndexValue = formEle.value;
								if (selectedIndexValue != '')
									selectedValue.push(selectedIndexValue);
								break;
						}	
						break;
				}
			}
		}
		return selectedValue;
	},
	setFormValue : function(formEle, attrValue) {
		if (formEle != null) {
			if (formEle.tagName == null && formEle.length) {
				for(var i = 0 ; i < 	formEle.length; i++ ) {
					var currObj = formEle[i];
					if (currObj.value == attrValue) {
						currObj.checked = true;
						break;
					}
				}
			} else if (formEle.tagName != null){
				switch(formEle.tagName) {
					case 'SELECT' :
						var selectedIndex = -1;
						for(var i = 0; i <  formEle.options.length ; i++ ) {
							var currObj = formEle.options[i];
							if (currObj.value == attrValue) {
								selectedIndex = i;
								break;
							}
						}
						if (typeof formEle.setValue == 'function') {
							formEle.setValue(selectedIndex);
						} else {
							formEle.selectedIndex = selectedIndex;
						}
						break;
					case 'INPUT' :
						switch(formEle.getAttribute("type")) {
							case 'radio' :
							case 'checkbox' :
								formEle.checked =  (formEle.value == attrValue);
								break;
							default :
								formEle.value = attrValue;
								break;
						}	
						break;
				}
			}
		}
	},
/*
 * Date Format 1.2.3
 * (c) 2007-2009 Steven Levithan <stevenlevithan.com>
 * MIT license
 *
 * Includes enhancements by Scott Trenda <scott.trenda.net>
 * and Kris Kowal <cixar.com/~kris.kowal/>
 *
 * Accepts a date, a mask, or a date and a mask.
 * Returns a formatted version of the given date.
 * The date defaults to the current date/time.
 * The mask defaults to dateFormat.masks.default.
 */
	dateUtil : {
		token : /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
		timezone : /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
		timezoneClip : /[^-+\dA-Z]/g,
		pad : function (val, len) {
			val = String(val);
			len = len || 2;
			while (val.length < len) val = "0" + val;
			return val;
		},
		dateFormat : function(date, mask, utc) {
			var dF = this;
			if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
				mask = date;
				date = undefined;
			}
			date = date || new Date;
			if (isNaN(date)) throw SyntaxError("invalid date");
			mask = String(dF.masks[mask] || mask || dF.masks["default"]);
			if (mask.slice(0, 4) == "UTC:") {
				mask = mask.slice(4);
				utc = true;
			}
			var	_ = utc ? "getUTC" : "get",
				d = date[_ + "Date"](),
				D = date[_ + "Day"](),
				m = date[_ + "Month"](),
				y = date[_ + "FullYear"](),
				H = date[_ + "Hours"](),
				M = date[_ + "Minutes"](),
				s = date[_ + "Seconds"](),
				L = date[_ + "Milliseconds"](),
				o = utc ? 0 : date.getTimezoneOffset(),
				flags = {
					d:    d,
					dd:   dF.pad(d),
					ddd:  dF.i18n.dayNames[D],
					dddd: dF.i18n.dayNames[D + 7],
					m:    m + 1,
					mm:   dF.pad(m + 1),
					mmm:  dF.i18n.monthNames[m],
					mmmm: dF.i18n.monthNames[m + 12],
					yy:   String(y).slice(2),
					yyyy: y,
					h:    H % 12 || 12,
					hh:   dF.pad(H % 12 || 12),
					H:    H,
					HH:   dF.pad(H),
					M:    M,
					MM:   dF.pad(M),
					s:    s,
					ss:   dF.pad(s),
					l:    dF.pad(L, 3),
					L:    dF.pad(L > 99 ? Math.round(L / 10) : L),
					t:    H < 12 ? "a"  : "p",
					tt:   H < 12 ? "am" : "pm",
					T:    H < 12 ? "A"  : "P",
					TT:   H < 12 ? "AM" : "PM",
					Z:    utc ? "UTC" : (String(date).match(dF.timezone) || [""]).pop().replace(dF.timezoneClip, ""),
					o:    (o > 0 ? "-" : "+") + dF.pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
					S:    ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
				};
			return mask.replace(dF.token, function ($0) {
				return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
			});
		},
		masks : {
			"default":      "ddd mmm dd yyyy HH:MM:ss",
			shortDate:      "m/d/yy",
			mediumDate:     "mmm d, yyyy",
			longDate:       "mmmm d, yyyy",
			fullDate:       "dddd, mmmm d, yyyy",
			shortTime:      "h:MM TT",
			mediumTime:     "h:MM:ss TT",
			longTime:       "h:MM:ss TT Z",
			isoDate:        "yyyy-mm-dd",
			isoTime:        "HH:MM:ss",
			isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
			isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
		},
		i18n : {
			dayNames: [
				"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
				"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
			],
			monthNames: [
				"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
				"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
			]
		}
	},
	stringUtil : {
		isXmlString : function(str) {
			return (str && str.indexOf('<?xml') == 0) ? true : false;
		},
		isJsonString : function(str) {
			if (str && str.charAt(0) == '{')
				return true;
			else 
				return false;
		},
		inArray : function(needle, haystack, argStrict) {
			if (haystack.length == 0)
				return false;
			var keyName = '',
				strict = !! argStrict;
			if (strict) {
				for (keyName in haystack) {
					if (haystack[keyName] === needle) 
						return true;
				}
			} else {
				for (keyName in haystack) {
					if (haystack[keyName] == needle) 
						return true;
				}
			}
			return false;
		},
		autoLink : function(s) {   
			var hlink = /(ht|f)tp:\/\/([^ \,\;\:\!\)\(\"\'\<\>\f\n\r\t\v])+/g;
			return s.replace (hlink, function ($0,$1,$2) { 
				s = $0.substring(0,$0.length); 
				while (s.length>0 && s.charAt(s.length-1)=='.') 
					s=s.substring(0,s.length-1);
				return '<a href="'+s+'" target=_blank>'+s+'</a>';
			}); 
		},
		jsonLink : function(dataJson, nameLinks) {
			var nJson = {};
			for(var keyName in dataJson) {
				if (this.inArray(keyName, nameLinks)) {
					nJson[keyName] = this.autoLink(dataJson[keyName]);
				} else
					nJson[keyName] = dataJson[keyName];
			}
			return nJson;
		},
		strPad : function(str, len, padStr, padType) {
			padType = padType || 0;
			padStr = padStr || ' ';
			if (typeof str != 'string' && str.toString)
				str = str.toString();
			if (str.length < len) {
				var seqn = 0;
				switch(	padType) {
					case 0	:
						while(str.length < len) {
							str += padStr.charAt(seqn % padStr.length);
							seqn++;
						}
						break;
					case 1 :
						while(str.length < len) {
							str = padStr.charAt(seqn % padStr.length) + str;
							seqn++;
						}
						break;
					case 2 :
						while(str.length < len) {
							if (seqn % 2 == 1)
								str = padStr.charAt(seqn % padStr.length) + str;
							else
								str += padStr.charAt(seqn % padStr.length);
							seqn++;
						}
						break;
				}
			}
			if (padStr == ' ')
				return str.replace(/ /g, "&nbsp;");
			else
				return str;
		},
		trim : function(str) {
			if (typeof str == 'string')
				return str.replace(/(^\s*)|(\s*$)/g, "");
			else
				return str;
	    },
		ltrim : function(str) {
			return str.replace(/(^\s*)/, "");
		},
		rtrim : function(str) {
			return str.replace(/(\s*$)/, "");    
		},
		byte : function(str) {
			var cnt = 0;
			for (var i = 0; i < str.length; i++) {
				if (str.charCodeAt(i) > 127)
					cnt += 2;
				else
					cnt++;
			}
			return cnt;
		},
		int : function(str) {
			if(!isNaN(str)) 
				return parseInt(str);
			else 
				return null;    
		},
		num : function(str) {
			return (this.trim(str).replace(/[^0-9]/g, ""));
		},
		str2int : function(str) {
			return this.int(this.num(str));
		},
		money : function(num) {
			num = this.trim(num);
			while((/(-?[0-9]+)([0-9]{3})/).test(num)) {
				num = num.replace((/(-?[0-9]+)([0-9]{3})/), "$1,$2");
			}
			return num;
	    },
		digits : function(cnt) {
			var digit = "";
			if (this.length < cnt) {
				for(var i = 0; i < cnt - this.length; i++) 
				  digit += "0";
			}
			return digit + this;
		},
		isLength : function(str, minLen, maxLen) {
			var min = minLen;
			var max = maxLen ? maxLen : null;
			var success = true;
			if(str.length < min) 
			  success = false;
			if(max && str.length > max) 
			  success = false;
			return success;
		},
		isByteLength : function(str, minLen, maxLen) {
			var min = minLen;
			var max = maxLen ? maxLen : null;
			var success = true;
			if(this.byte(str) < min) 
			  success = false;
			if(max && this.byte(str) > max) 
				  success = false;
			return success;
		},
		isBlank : function(str) {
			str = this.trim(str);
			for(var i = 0; i < str.length; i++) {
			  if ((str.charAt(i) != "\t") && (str.charAt(i) != "\n") && (str.charAt(i)!="\r")) 
			      return false;
			}
			return true;
		},
		isNum : function(str) {
			return (/^[0-9]+$/).test(str) ? true : false;
		},
		isEng : function(str) {
			return (/^[a-zA-Z]+$/).test(str) ? true : false;
		},
		isEngNum : function(str) {
			return (/^[0-9a-zA-Z]+$/).test(str) ? true : false;
		},
		isNumEng : function(str) {
			return this.isEngNum(str);
		},
		isUserid : function(str) {
			return (/^[a-z]{1}[0-9a-z]+$/).test(str) ? true : false;
		},
		isKor : function(str) {
			return (/^[\uAC00-\uD7A3]+$/).test(str) ? true : false;
		},
		removeSlash : function(str) {
			return (this.trim(str).replace(/[^0-9]/g, ""));
		},
		isJumin : function(str) {
			var jumin = this.removeSlash(str).match(/^[0-9]{2}[01]{1}[0-9]{1}[0123]{1}[0-9]{1}[1234]{1}[0-9]{6}$/);
			if(jumin == null) 
			  return false;
			jumin = jumin.toString();
			var birthYY = (parseInt(jumin.charAt(6)) == (1 ||2)) ? "19" : "20";
			birthYY += jumin.substr(0, 2);
			var birthMM = jumin.substr(2, 2) - 1;
			var birthDD = jumin.substr(4, 2);
			var birthDay = new Date(birthYY, birthMM, birthDD);
			if(birthDay.getYear() % 100 != jumin.substr(0,2) || birthDay.getMonth() != birthMM || birthDay.getDate() != birthDD) 
			  return false;
			var sum = 0;
			var num = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5]
			var last = parseInt(jumin.charAt(12));
			for(var i = 0; i < 12; i++) 
			  sum += parseInt(jumin.charAt(i)) * num[i];
			return ((11 - sum % 11) % 10 == last) ? true : false;
		},
		isForeign : function(str) {
			var jumin = this.removeSlash(str).match(/^[0-9]{2}[01]{1}[0-9]{1}[0123]{1}[0-9]{1}[5678]{1}[0-9]{1}[02468]{1}[0-9]{2}[6789]{1}[0-9]{1}$/);
			if(jumin == null) 
			  return false;
			jumin = jumin.toString();
			var birthYY = (parseInt(jumin.charAt(6)) == (5 || 6)) ? "19" : "20";
			birthYY += jumin.substr(0, 2);
			var birthMM = jumin.substr(2, 2) - 1;
			var birthDD = jumin.substr(4, 2);
			var birthDay = new Date(birthYY, birthMM, birthDD);
			if(birthDay.getYear() % 100 != jumin.substr(0,2) || birthDay.getMonth() != birthMM || birthDay.getDate() != birthDD) 
			  return false;
			if((parseInt(jumin.charAt(7)) * 10 + parseInt(jumin.charAt(8))) % 2 != 0) 
			  return false;
			var sum = 0;
			var num = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5];
			var last = parseInt(jumin.charAt(12));
			for(var i = 0; i < 12; i++) 
			  sum += parseInt(jumin.charAt(i)) * num[i];
			 alert((((11 - sum % 11) % 10) + 2 == last));
			 
			return (((11 - sum % 11) % 10) + 2 == last) ? true : false;
		},
		isBiznum : function(str) {
			var biznum = this.removeSlash(str).match(/[0-9]{3}[0-9]{2}[0-9]{5}$/);
			if(biznum == null) 
			  	return false;
			biznum = biznum.toString();
			var sum = parseInt(biznum.charAt(0));
			var num = [0, 3, 7, 1, 3, 7, 1, 3];
			for(var i = 1; i < 8; i++) 
				sum += (parseInt(biznum.charAt(i)) * num[i]) % 10;
			sum += Math.floor(parseInt(parseInt(biznum.charAt(8))) * 5 / 10);
			sum += (parseInt(biznum.charAt(8)) * 5) % 10 + parseInt(biznum.charAt(9));
			return (sum % 10 == 0) ? true : false;
		},
		isCorpnum : function(str) {
			var corpnum = this.removeSlash(str).match(/[0-9]{6}[0-9]{7}$/);
			if(corpnum == null) 
		  		return false;
			corpnum = corpnum.toString();
			var sum = 0;
			var num = [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2];
			var last = parseInt(corpnum.charAt(12));
			for(var i = 0; i < 12; i++) 
			  sum += parseInt(corpnum.charAt(i)) * num[i];
			return ((10 - sum % 10) % 10 == last) ? true : false;
		},
		isEmail : function(str) {
			return (/\w+([-+.]\w+)*@\w+([-.]\w+)*\.[a-zA-Z]{2,4}$/).test(str.trim());
		},
		isPhone : function(str) {
			return (/(02|0[3-9]{1}[0-9]{1})[1-9]{1}[0-9]{2,3}[0-9]{4}$/).test(str);
		},
		isMobile : function(str) {
			return (/01[016789][1-9]{1}[0-9]{2,3}[0-9]{4}$/).test(str);
		},
		isTel : function(str) {
			return this.isPhone(str) || this.isMobile(str);
		}
	},
	calObject : {
		_className : 'cafen.calObject',
		dateString : ['day0','day1','day2','day3','day4','day5','day6'],
		_DOMonth : [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], 
		_lDOMonth : [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
		_currentData : null,
		_monthDate : [],
		_textObj : null,
		zIndex : 900,
		getDaysOfMonth : function(year, month) { 
			if ((year % 4) == 0) { 
				if ((year % 100) == 0 && (year % 400) != 0) 
					return this._DOMonth[month]; 
				else
					return this._lDOMonth[month]; 
			} else 
				return this._DOMonth[month]; 
		},
		getFirstDay : function(year, month) {
			var tmpDate = new Date(); 
			tmpDate.setDate(1); 
			tmpDate.setMonth(month); 
			tmpDate.setFullYear(year); 
			return tmpDate.getDay(); 
		},
		getLastDay : function(year, month) {
			var tmpDate = new Date(); 
			tmpDate.setMonth(month); 
			tmpDate.setFullYear(year); 
			tmpDate.setDate( getDaysOfMonth(year, month) ); 
			return tmpDate.getDay(); 
		},
		moveNext : function() {
			this.showMonth(this._currentData.getFullYear(), this._currentData.getMonth() + 2);
		},
		movePrev : function() {
			this.showMonth(this._currentData.getFullYear(), this._currentData.getMonth());
		},
		clearMonth : function() {},
		getMonthYear : function() {
			var txt  = this._currentData.getFullYear() +'/';
			var month = this._currentData.getMonth() +1;
			return (month > 9) ? txt + month : txt + '0'+month;
		},
		getYear : function() {
			return this._currentData.getFullYear();
		},
		getMonth : function() {
			return this._currentData.getMonth() +1;
		},
		setYear : function(obj) {
			this.showMonth(parseInt(obj[obj.selectedIndex].value), this._currentData.getMonth()+1);
		},
		setMonth : function(obj) {
			this.showMonth(this._currentData.getFullYear(), parseInt(obj[obj.selectedIndex].value));
		},
		getOptionRange : function(start, end, endfix, def) {
			var html = [];
			if (start > end) {
				for(var i = start; i >= end; i--) {
					if (i == def)
						html.push('<option value="'+i+'" selected>'+i+' '+endfix+'</option>');	
					else
						html.push('<option value="'+i+'">'+i+' '+endfix+'</option>');	
				}
			} else {				
				for(var i = start; i <= end; i++) {
					if (i == def)
						html.push('<option value="'+i+'" selected>'+i+' '+endfix+'</option>');	
					else
						html.push('<option value="'+i+'">'+i+' '+endfix+'</option>');	
				}
			}
			return html.join('');
		},
		showMonth : function (year, month) {
			this._currentData = new Date(year,month -1,10);
			var isCurrent = (this._currentData.getFullYear() == this._baseDate.getFullYear() && this._currentData.getMonth()  == this._baseDate.getMonth()) ? true : false;
			this._monthDate = [];
			var cnt = this.getDaysOfMonth(this._currentData.getFullYear(), this._currentData.getMonth());
			var start = (this.getFirstDay(this._currentData.getFullYear(), this._currentData.getMonth())) % 7;
			for (var i =0; i < 42 ; i++)
				this._monthDate.push('');
			for (var i = 1; i <= cnt ; i++) 
				this._monthDate[start+i-1] = i;
			var html = [];
			html.push('<div style="width:182px;">');
			html.push('<div class="popCalendar top"> <label class="selectForm size90"><select onchange="'+this._className+'.setYear(this)">'+this.getOptionRange(this._baseYearStart ,this._baseYearEnd, \uB144 ,this.getYear())+'</select></label>&nbsp;<label class="selectForm size70"><select onchange="'+this._className+'.setMonth(this)">'+this.getOptionRange(1,12, \uC6D4 ,this.getMonth())+'</select></label></div>');
			html.push('<table border="0" cellpadding="0" cellspacing="0" width=100% class="popCalendar">');
			html.push('<thead><tr>');
			for(var i = 0; i < this.dateString.length; i++)
				html.push('<td class='+this.dateString[i]+'></td>');
			html.push('</tr></thead>');
			html.push('<tbody>');
			for (var i =0; i < 42 ; i++) {
				var col = i % 7;
				if (col == 0)
					html.push('<tr>');
				if (this._monthDate[i] == '')
					html.push('<td class="blank">&nbsp;</td>');
				else {
					var txt = ' onclick="'+this._className+'.setDate('+this._monthDate[i]+')">'+this._monthDate[i]+'';
					if (isCurrent && this._baseDate.getDate() == this._monthDate[i])
						html.push('<td class="today" '+txt+'</td>');
					else {
						switch(col) {
							case 0 :
								html.push('<td class="sun" '+txt+'</td>');
								break;
							case 6 :
								html.push('<td class="sat" '+txt+'</td>');
								break;
							default :
								html.push('<td '+txt+'</td>');
								break;
						}
					}
				}
				if (col == 6) {
					html.push('</tr>');
					if (this._monthDate[i] == '')
						break;
				}
			}
			html.push('</tbody>');
			html.push('</table>');
			html.push('</div>');
			cafen.showPopupHtml(html.join(''), this.zIndex, this._baseObj, 'popupNarrow', 'CAL', null, this._popArea, this.selectParse.bind(this));
		},
		selectParse : function(obj) {
	//		cafen.J$("select",obj).selectPicker();
		},
		setDate: function(i) {
			if (this._textObj != null) {
				var txt = [];
				txt.push(this._currentData.getFullYear());
				var month = this._currentData.getMonth()+1;
				txt.push((month > 9) ? month : '0'+month);
				var day = i;
				txt.push((day > 9) ? day : '0'+day);
				this._textObj.value = txt.join('.');
			} else 
				alert(this.getMonthYear()+'/'+i);
			cafen.closeFaceBox('CAL', this._popArea);
		},
		parseDate : function(obj, syear, eyear) {
			this._baseObj = obj;
			this._textObj = document.getElementById(obj.getAttribute('for')) ;
			if (this._textObj == null) {
				this._textObj = this._baseObj;
				this._popArea = null;
			} else {
				if (this._textObj != null && this._textObj.tagName && this._textObj.tagName == 'INPUT' && this._textObj.form != null) 
					this._popArea = this._textObj.form.getAttribute("popuparea") || null;
				else
					this._popArea = null;
			}	
			this._baseDate = new Date();
			this._baseYearStart = (syear != null) ? syear : (this._baseDate.getFullYear()+3);
			this._baseYearEnd = (eyear != null) ? eyear : this._baseYearStart - 20;
			
			if (this._textObj != null && this._textObj.value != '') {
				if (this._textObj.value.length == 8) {
					var txt = this._textObj.value;
					var year = txt.substring(0, 4);
					this._baseDate.setFullYear(year); 
					var month = cafen.parseInt(txt.substring(4, 6));
					this._baseDate.setMonth(month-1); 
					var day = cafen.parseInt(txt.substring(6, 8));
					this._baseDate.setDate(day); 
				} else if (this._textObj.value.length == 10) {
					var txt = this._textObj.value;
					var year = txt.substring(0, 4);
					this._baseDate.setFullYear(year); 
					var month = cafen.parseInt(txt.substring(5, 7));
					this._baseDate.setMonth(month-1); 
					var day = cafen.parseInt(txt.substring(8, 10));
					this._baseDate.setDate(day); 
				}
			}
			this.showMonth(this._baseDate.getFullYear(), this._baseDate.getMonth()+1)
		}
	},
	getCalendar : function(obj, syear, eyear) {
		this.calObject.parseDate(obj, syear, eyear);
	},
	showPopupHtml : function(html,level, obj, className, idxName, pos, popArea, onloadFnc) {
		var classObj = this.getFaceBox(idxName || 'html', level, className, popArea);
		var loadOption = null;
		if (obj != null && typeof obj == 'object') {
			if (obj.getAttribute)
				pos = (obj.getAttribute("cafenalign") || pos || 'left-bottom').split('-');
			else
				pos = (pos || 'left-bottom').split('-');
			var xPos = 'left', yPos = 'bottom'; 
			switch(pos[0]) {
				case 'left':
				case 'right':
				case 'exleft':
				case 'exright':
				case 'center':
					xPos = pos[0];
					break;
				default :
					break;
			}
			switch(pos[1]) {
				case 'top':
				case 'bottom':
				case 'extop':
				case 'exbottom':
				case 'center':
					yPos = pos[1];
					break;
				default :
					break;
			}
			loadOption = {obj:obj, x: xPos,y: yPos};
		}
		classObj.loadHtml(html , loadOption);
		classObj.onLoad();
		if (onloadFnc != null) 
			onloadFnc(classObj.contentsObj.getObject());
		return classObj;
	},
	showPopup : function(callURL, param, level, sticker, className, idxName, callFnc) {
		var classObj = this.getFaceBox(idxName || 'popup', level, className);
		if (callURL == null) 
			callURL= this.getDocumentLocation();
		classObj.loadAjax(callURL, param || {}, callFnc);
		if (sticker != null) {
			classObj.onLoad({obj : sticker, x : 'left',y : 'bottom'}, true);
		}else
			classObj.onLoad(null, true);
	},
	hidePopup : function(idxName) {
		this.closeFaceBox(idxName);
	},
	loadedPopup : {},
	loadedObj : {},
	lastSelectObj : null,
	getFaceBox : function(popupKey, level, skinName, popArea) {
		popArea = popArea || '';
		skinName = skinName ||'popupWild';
		level = level || 900 ;
		if (this.loadedPopup[popArea] == null)
			this.loadedPopup[popArea] = {};
		if (this.loadedPopup[popArea][popupKey] == null)
			this.loadedPopup[popArea][popupKey] = new cafen.XFaceBox({className :'', tplName : '', popArea : popArea, skinClass : skinName, attribute :{className : skinName}, hideClose:true, ajax_url : null, ajax_data : {},style : {zIndex : level}});
		return this.loadedPopup[popArea][popupKey];
	},
	closeFaceBox : function(popupKey, popArea) {
		popArea = popArea || '';
		if (this.loadedPopup[popArea][popupKey] != null)
			this.loadedPopup[popArea][popupKey].close();
		else {
			for(var idx in 	this.loadedPopup) {
				if (this.loadedPopup[idx][popupKey] != null)
					this.loadedPopup[idx][popupKey].close();
			}
		}
	},
	getMsg : function(msg) {
		return "<div style='padding:5px 12px 2px 12px;line-height:160%;white-space:nowrap;text-align:left'>"+msg+"</div>";
	},
	xAlert : function(msg, obj, popArea, closeTime) {
		if (cafenGlobalConf.donotUseLayerModal || this.isMobile()) {
			alert(this.html2Text(msg));
		} else {
			if (closeTime == null)
				closeTime = 3000;
			popArea = popArea || '';
			var alertObj = this.showPopupHtml(this.getMsg(msg),1000, obj , 'popupNarrow', 'ALERT', 'leftbottom', popArea);
			if (cafen.loadedObj.alert == null && popArea == '')
				this.loadedObj.alert = this.loadedPopup[popArea]['ALERT'];
			if (closeTime > 0 )
				window.setTimeout(alertObj.close.bind(alertObj),closeTime);
			try {
				if (obj != null && (obj.tagName == 'DIV' || obj.tagName == 'SPAN')) {
					obj = cafen.getElementsByTagName('BUTTON', obj)[0];
				}
				if (obj != null && (obj.tagName == 'INPUT' || obj.tagName == 'SELECT' || obj.tagName == 'TEXTAREA' || obj.tagName == 'BUTTON'))
					obj.focus();
			} catch(ex) {cafen.debugMessage(ex);	}
		}
		return false;
	},
	xAlertWithOk : function(msg, obj, popArea, options) {
		if (this.isMobile()) {
			alert(cafen.html2Text(msg));
		} else {
			msg = '<div class="cafenMsg">'+msg+'</div><div class="cafenButton"><button type=button id="popupYES" >'+cafenMsg.get('com_ok')+'</button></div>';
			msg = this.getMsg(msg);
			options = options || (typeof cafenGlobalConf.getConfirmOption == 'function') ? cafenGlobalConf.getConfirmOption() : {} ;
			msg = this.makePopupHtml(options.title ,msg, options.img);
			popArea = popArea || '';
			this.showPopupHtml(msg,1000, null , 'popupWild', 'ALERTOK', 'leftbottom', popArea, this.xAlertDraw.bind(this));
			if (cafen.loadedObj.confirmok == null && popArea == '')
				this.loadedObj.confirmok = this.loadedPopup[popArea]['ALERTOK'];
		}
	},
	xAlertDraw : function(obj) {
		cafen.J$("#popupYES",obj).click(this.xAlertCallBack.bind(this,true));
	},
	xAlertCallBack : function(opt) {
		this.closeFaceBox('ALERTOK');
	},
	xConfirm : function(msg, call_back, popArea, options) {
		if (cafenGlobalConf.donotUseLayerModal || this.isMobile()) {
			if (confirm(cafen.html2Text(msg))) {
				if (typeof call_back == 'function')
					call_back(true);
			} else {
				if (typeof call_back == 'function')
					call_back(false);
			}
		} else {
			this.lastCallBack = call_back;
			msg = '<div class="cafenMsg">'+msg+'</div><div class="cafenButton"><button type=button id="popupYES" >'+cafenMsg.get('util_0004')+'</button><button type=button id="popupNO" >'+cafenMsg.get('util_0005')+'</button></div>';
			msg = this.getMsg(msg);
			options = options || (typeof cafenGlobalConf.getConfirmOption == 'function') ? cafenGlobalConf.getConfirmOption() : {} ;
			msg = this.makePopupHtml(options.title ,msg, options.img);
			popArea = popArea || '';
			this.showPopupHtml(msg,1000, null , 'popupWild', 'CONFIRM', 'leftbottom', popArea, this.xConfirmDraw.bind(this));
			if (cafen.loadedObj.confirm == null && popArea == '')
				this.loadedObj.confirm = this.loadedPopup[popArea]['CONFIRM'];
		}
	},
	xConfirmDraw : function(obj) {
		cafen.J$("#popupYES",obj).click(this.xConfirmCallBack.bind(this,true));
		cafen.J$("#popupNO",obj).click(this.xConfirmCallBack.bind(this,false));
	},
	xConfirmCallBack : function(opt) {
		this.closeFaceBox('CONFIRM');
		if (this.lastCallBack != null)
			this.lastCallBack(opt);
	},
	xPrompt : function(msg, call_back, popArea, options) {
		if (this.isMobile()) {
			var val = null;
			if (prompt(cafen.html2Text(msg))) {
				if (typeof call_back == 'function')
					call_back(true);
			} else {
				if (typeof call_back == 'function')
					call_back(false);
			}
		} else {
			this.lastCallBack = call_back;
			msg = '<div class="cafenMsg">'+msg+'<br><input type="password" class="inputForm" id="popupInput" size=20></div><div class="cafenButton"><button type=button id="popupYES" >'+cafenMsg.get('util_0004')+'</button><button type=button id="popupNO" >'+cafenMsg.get('util_0005')+'</button></div>';
			msg = this.getMsg(msg);
			options = options || (typeof cafenGlobalConf.getConfirmOption == 'function') ? cafenGlobalConf.getConfirmOption() : {} ;
			msg = this.makePopupHtml(options.title ,msg, options.img);
			popArea = popArea || '';
			this.showPopupHtml(msg,1000, null , 'popupWild', 'PROMPT', 'leftbottom', popArea, this.xPromptDraw.bind(this));
			if (cafen.loadedObj.confirm == null && popArea == '')
				this.loadedObj.confirm = this.loadedPopup[popArea]['PROMPT'];
		}
	},
	xPromptDraw : function(obj) {
		cafen.J$("#popupYES",obj).click(this.xPromptCallBack.bind(this,true));
		cafen.J$("#popupNO",obj).click(this.xPromptCallBack.bind(this,false));
		cafen.J$("#popupInput",obj).attachEvent('keypress', this.xPromptInput.bind(this));
	},
	xPromptInput : function(obj,event) {
		event = event || window.event;
		if (event.keyCode == 13) {
			this.xPromptCallBack(true);
		} 
	},
	xPromptCallBack : function(opt) {
		if (opt && this.lastCallBack != null) {
			var passwdObj = cafen.$('popupInput');
			if (passwdObj != null) {
				var passwd = passwdObj.value;
				if (cafen.isNull(passwd)) {
					this.setFormError('기존 암호를 하여 주십시오', passwdObj);	
				} else {
					this.closeFaceBox('PROMPT');
					this.lastCallBack(passwd);
				}
			}
		} else {
			this.closeFaceBox('PROMPT');
		}
	},
	getColor : function (init_color, call_back,use_trasparent, obj) {
		if (call_back == null && obj != null && obj.tagName == 'INPUT') {
			call_back = function(opt) {
					obj.value = opt;
			}	
		}
		this.lastCallBack = call_back;
		if (use_trasparent == null)
			use_trasparent = false;
		if (this.loadedObj.colorpicker == null) 
			this.loadedObj.colorpicker = new cafen.XColorpicker({title : '색상선택', onClose : this.callBack.bind(this), useHSV : true});
		this.loadedObj.colorpicker.setColor(init_color, use_trasparent);
		this.loadedObj.colorpicker.onLoad({obj : obj, x: 'left',y:'bottom'});
	},
	callBack : function(opt) {
		if (this.lastCallBack != null)
			this.lastCallBack(opt);
	},
	ajaxCallEnd : function(channel) {
		this.submitUnLock();
		var nextURL = null, msg = null, msgtitle = null, msgsubtitle = null, closeall = null, msgtitleimg = null, msghtml = null, nextlink = null, linktype = null, msgcode = null;
		if (channel.checkMsg() && channel.getHTML) {
			this.showPopupHtml(channel.getHTML(),1201,null, 'popupWild', 'RESULTHTML');
		} else if (channel.getNode) {
			nextURL = channel.getNode('nexturl');
			msgtitle = channel.getNode('msgtitle');
			msg = channel.getNode('msg');
			msgsubtitle = channel.getNode('msgsubtitle') || channel.getNode('message') ;
			msgtitleimg = channel.getNode('msgtitleimg');
			msghtml = channel.getNode('msghtml');
			msgcode = channel.getNode('msgcode');
			closeall = channel.getNode('closeall');
			nextlink = channel.getNode('link');
			if (nextURL.indexOf("CLOSE#") == 0) {
				this.hidePopup(nextURL.split('#')[1]);
				nextURL = '';
			}
			if (nextlink != null && nextlink.indexOf("/?") == 0)
				nextlink = document.location.pathname + nextlink.substring(1);
			if (nextURL != null && nextURL.indexOf("/?") == 0)
				nextURL = document.location.pathname + nextURL.substring(1);
			linktype = channel.getNode('linktype');
			if ((msg == null || msg == "")&& msgsubtitle != null && msgsubtitle != '')
				msg = msgsubtitle;
			if (closeall == '1') 
				this.hidePopup();
			if (linktype != null && msg != null && nextlink != null && msg != "" && nextlink != "") {
				if (confirm(msg))
					top.document.location.href = nextlink;
			} else if (nextURL == 'reload' || nextURL.indexOf('#') == 0 ||  nextURL.indexOf('reload') == 0) {
				if (msg != null && msg != '') 
					alert(msg.replace(/<br\/?[^>]+>/gi, '\r\n').replace(/<\/?[^>]+>/gi, ''));
				this.reloadUrl(nextURL);
			} else if (nextURL.indexOf('javascript:') == 0) {
				if (msg != null && msg != '') 
					alert(msg.replace(/<br\/?[^>]+>/gi, '\r\n').replace(/<\/?[^>]+>/gi, ''));
				var callFnc = this.getString2Function(nextURL.substring(11));
				if (callFnc != null) {
					callFnc();	
				}
			} else if (nextURL != null && nextURL != '') {
				if (msg != null && msg != "") 
					alert(msg.replace(/<br\/?[^>]+>/gi, '\r\n').replace(/<\/?[^>]+>/gi, ''));
				if (nextURL.indexOf('mode:') == 0) {
					var urlData = nextURL.split(':');
					this.changeModeUrl(urlData[1],urlData[2]);
				} else {
					this.goUrl(nextURL);
				}
			} else if ((msg != null && msg != '') || msgsubtitle != '') {
				var txt = [];
				txt.push('<table border=0 width=200px>');
				if (msg != null && msg != '') {
					if (msgsubtitle != null && msgsubtitle != '') 
						txt.push('<tr><td class="subtitle">'+msgsubtitle+'</td></tr>');
					if (msg != null && msg != msgsubtitle)
						txt.push('<tr><td style="padding:5px;text-align:center;line-height:200%" nowrap>'+msg+'</td></tr>');
				} else if (msgsubtitle != null && msgsubtitle != '') 
					txt.push('<tr><td style="padding:5px;text-align:center;line-height:200%" nowrap>'+msgsubtitle+'</td></tr>');
				txt.push('</table>');
				this.showPopupHtml(txt.join(''),1200, null,'popupNarrow', 'RESULT');
			} else if (msghtml != null && msghtml != "") {
				if (msghtml.indexOf('popTitle') == -1) {
					if (msghtml.indexOf('#') == 0) 
						this.reloadUrl(msghtml);
					else {
						if (this.isMobile()) {
							if (msgcode != null && msgcode.indexOf('forbidden.filter') > 0) {
								if (confirm(cafen.html2Text(msghtml +'<hr>'+cafenGlobalConf.siteMsg.confirmWithoutFilter))) {
									this.sendWithoutFilter(true);
								} 
							} else {
								alert(cafen.html2Text(msghtml));
							}
						} else {
							if (msgcode != null && msgcode.indexOf('forbidden.filter') > 0) {
								this.xAlertWithOk(msghtml +'<hr>'+cafenGlobalConf.siteMsg.confirmWithoutFilter, this.sendWithoutFilter.bind(this));
//								this.xConfirm(msghtml +'<hr>'+cafenGlobalConf.siteMsg.confirmWithoutFilter, this.sendWithoutFilter.bind(this));
							} else {
								this.xAlert(msghtml);
							}
						}
					}
				} else {
					this.showPopupHtml(msghtml ,1200, null,'popupWild', 'RESULTWILD');
				}
			}
		}
	},
	sendWithoutFilter: function(bl) {
		if (bl) {
//			cafen.rainFilter.lastConfirmData.xmlOptions.doNotUseFilter = "TRUE";
//			cafen.rainFilter.submitLastData();
		}
	},
	checkFileFilter: function(fileObj) {
		if (fileObj != null && fileObj.fileName != null) {
			if (fileObj.fileName == '' && fileObj.server != '') {
				fileObj.fileName = fileObj.server;
			}
			if (fileObj.fileName.indexOf('/') > 0) {
				fileObj.fileName = fileObj.fileName.substring(fileObj.fileName.lastIndexOf('/')+1);
			}
			if (fileObj.extra != null && fileObj.extra.indexOf('forbidden.filter') > 0) {
				var message = fileObj.extra.substring(fileObj.extra.indexOf('forbidden.filter')+17);
				fileObj.extra = '';
				alert(cafen.html2Text(fileObj.fileName + ' - '+cafenGlobalConf.siteMsg.confirmFileFilterTitle+'<br/><hr/>'+message+'<hr/>'+cafenGlobalConf.siteMsg.confirmFileFilter));
				return false;
//				if (confirm(cafen.html2Text(fileObj.fileName + ' - '+cafenGlobalConf.siteMsg.confirmFileFilterTitle+'<br/><hr/>'+message+'<hr/>'+cafenGlobalConf.siteMsg.confirmFileFilter))) {
//					return true;	
//				} else {
//					return false;	
//				}
			} else if (cafenGlobalConf.siteMsg.forbiddenExt != null && cafenGlobalConf.siteMsg.forbiddenExt != '' && fileObj.fileName.match(eval(cafenGlobalConf.siteMsg.forbiddenExt))) {
				alert(cafen.html2Text(fileObj.fileName + ' - '+cafenGlobalConf.siteMsg.confirmFileExeFilter));
				return false;
			} else {
				fileObj.extra = '';
				return true;
			}
		} else {
			return true;	
		}
	},
	goUrl : function(theURL, win) {
		if (cafenGlobalConf.submitForm != null && this.$(cafenGlobalConf.submitForm) != null) {
			var form = this.$(cafenGlobalConf.submitForm);
			var urlVal = theURL.split('?');
			var mainUrl = urlVal[0];
			var paramDataHash = {}
			if (urlVal.length > 1 && urlVal[1] != '') {
				paramDataHash = this.getParseParam(urlVal[1]);
			}
			form.action = mainUrl;
			while(form.elements.length > 0) 
				form.elements[0].parentNode.removeChild(form.elements[0]);
			for(var keyName in paramDataHash) {
				var formObj = document.createElement('INPUT');
				formObj.setAttribute('type','hidden');
				formObj.setAttribute('name', keyName);
				formObj.setAttribute('value', paramDataHash[keyName]);
				form.appendChild(formObj);
			}
			if (typeof win == 'string') {
				form.target = win;
				form.submit();
				form.target = 'self';
			} else {
				form.submit();
			}
		} else {	
			win = win || self;
			win.document.location.href = theURL;
		}
	},
	reloadUrl : function(urlPattern) {
		if (urlPattern.indexOf('#') == 0) {
			if (urlPattern == '#CLOSEPOP') 
				window.close()
			else
				this.goUrl(this.getUrlParam(this.getDocumentLocation(),this.getUrlHashMap(), urlPattern.substring(1), true));
		} else if (urlPattern.indexOf('#') > 0) {
			var method = urlPattern.substring(urlPattern.indexOf('#')+1);
			var hashMapParam  = 	this.getUrlHashMap();
			switch(method) {
				case 'list' :
					hashMapParam	.method = null;
					hashMapParam	.muid = null;
					break;
				case 'view' :
					hashMapParam	.method = 'view';
					break;
			}
			this.goUrl(this.getUrlParam(this.getDocumentLocation(),hashMapParam));
		} else {
			document.location.reload();
		}
	},
	submitData : function(options, submitURL) {
		this.submitLock();
		new cafen.Ajax(options || {}, cafen.ajaxCallEnd.bind(cafen), submitURL || this.getDocumentLocation() , 'post');
	},
	SUBMIT_PROCESS : false,
	submitCheck : function() {
		if (!this.SUBMIT_PROCESS) 
			return true;
		else {
			this.submitLockMsg(cafenMsg.get('com_processsubmit'),0);
			return false;
		}
	},
	submitLock : function(timeout) {
		if (! this.SUBMIT_PROCESS) {
			this.submitLockMsg(cafenMsg.get('com_processsubmit'),timeout);
			this.SUBMIT_PROCESS = true;
		} else {
			this.submitLockMsg(cafenMsg.get('com_processsubmit'), timeout);
		}
	},
	submitUnLock : function() {
		this.SUBMIT_PROCESS = false;
		this.submitUnLockMsg();
	},
	submitLockMsg : function(msg, timeout) {
		if (!cafenGlobalConf.donotUseLayerModal && !this.isMobile()) {
			this.xAlert('<div style="width:200px;text-align:center"><div style="float:left"><img src="'+_cafen_service_url+'images/blank.gif" class="r_process"></div><div style="float:left;line-height:150%;text-align:left">' +msg+'</div></div>', null, null, timeout);
		}
	},
	submitUnLockMsg : function() {
		this.closeAllPopup();
	},
	closeAllPopup : function() {
		for(idx in this.loadedObj) {
			this.loadedObj[idx].close();
		}
		for(idx in this.loadedPopup) {
			var currObj = this.loadedPopup[idx];
			for(subId in currObj) 
				currObj[subId].close();
		}
	},
	loadXMLData : function(area_ID, options, callURL, callFnc) {
		options = options || {} ;
		options.requestType = 'xmlHTML';
		this.rainHtmlLoad.loadXMLData(area_ID, options, callURL, callFnc);
	},
	rainHtmlLoad : {
		xmlDataQueue : [],
		xmlDataQueueProcess : false,
		xmlDataQueueObj : null,
		xmlDataQueueFnc : null,
		loadXMLData : function(area_ID, options, callURL, callFnc) {
			if (typeof callURL  == 'object' && callURL.action) {
				options = options || {};
				var tmpForm = callURL;
				callURL = callURL.action;
				for(var i = 0 ; i < tmpForm.elements.length ; i++) {
					var currObj = tmpForm.elements[i];
					if (currObj.tagName && currObj.tagName == 'INPUT') {
						var currVal = currObj.getAttribute("value");	
						var currName = currObj.getAttribute("name");	
						var currType = currObj.getAttribute("type");	
						if ( (currType == 'radio' || currType == 'checkbox' ) && !currObj.checked)
							 currVal = null;
						if (currVal != null && currVal != '' && currName != null && currName != '')
							options[currName] = currVal;
					}
				}
			}
			area_ID = cafen.$(area_ID);
			if (area_ID != null && typeof area_ID.innerHTML != 'undefined') { 
					area_ID.innerHTML = '<div style="min-height:200px;text-align:center;padding:20px 0"><img src="'+_cafen_service_url+'images/blank.gif" class="r_process">'+cafenMsg.get('com_process')+'</div>';
					this.xmlDataQueue.push({obj : area_ID, params : options || {}, xmlUrl : callURL || cafen.getDocumentLocation(), callFnc : callFnc || null});
					this.checkXMLQueue();
			}
		},
		checkXMLQueue : function() {
			if (!this.xmlDataQueueProcess) {
				if (this.xmlDataQueue.length > 0) {
					var firstXMLData = this.xmlDataQueue[0];
					this.xmlDataQueueObj = cafen.$(firstXMLData.obj);
					this.xmlDataQueueFnc = firstXMLData.callFnc;
					new cafen.Ajax(firstXMLData.params, this.setXMLData.bind(this), firstXMLData.xmlUrl , 'post');
					this.xmlDataQueueProcess = true;
					this.xmlDataQueue.shift();
				}
			}
		},
		isLastProcess : function() {
			if (this.xmlDataQueue.length <= 0)
				return true;
			else
				return false;
		},
		setXMLData : function(xml) {
			this.xmlDataQueueProcess = false;
			this.xmlDataQueueObj.innerHTML = xml.getHTML();
			if (this.xmlDataQueueFnc != null)
				this.xmlDataQueueFnc(this.xmlDataQueueObj);
			this.checkXMLQueue();
		}
	},
	checkFormElement : function(form, param, callFnc, msg, checkParam, popupCall) {
		try {
			return this.rainFilter.checkFormElement(form, param, callFnc, msg, checkParam, popupCall);
		} catch(ex) { cafen.debugMessage(ex); return false;}
	},
	setFormError : function(msg, obj) {
		return this.rainFilter.xAlert(msg, this.rainFilter.setFormError(obj), obj);
	},
	rainFilter : {
		checkFormElement : function(form, param, callFnc, msg, checkParam, popupCall) {
			if (!cafen.submitCheck())
				return false;
			var xmlOptions = param || {};
			var requireForm = {};
			for(var i = 0 ; i < form.elements.length; i++) {
				var obj = form.elements[i];
				var objType = ((obj.getAttribute ) ? obj.getAttribute('type') : '') || '';
				if (obj.hasAttribute == null)
					obj.hasAttribute = function(name) { return (this.getAttribute(name) == null) ? false : true;}
				switch((obj.tagName +'_'+ objType).toLowerCase()) {
					case 'select_select-one' :
					case 'select_' :
						var selectedValue = '';
						if (obj.getAttribute('multiple')) {
							var selectedValues = [];
							for(var j = 0 ; j < obj.length; j++)
								if (obj.options[j].selected && obj.options[j].value != '')
									selectedValues.push(obj.options[j].value);
							selectedValue = selectedValues.join(',');
						} else if (obj.selectedIndex > -1)
							selectedValue = obj[obj.selectedIndex].value;
						if (obj.hasAttribute('require') && selectedValue == '') {
							var title = obj.getAttribute('title') || obj.getAttribute('name');
							return this.xAlert(cafenMsg.get('com_filter014', title), this.setFormError(obj), form);
						}
						if (obj.hasAttribute('name') && selectedValue != '') 
							xmlOptions[obj.getAttribute('name')] = selectedValue;
						break;
					case 'input_radio' :
					case 'input_checkbox' :
						if (obj.hasAttribute('name') && obj.hasAttribute('require')) {
							var objName = obj.getAttribute('name');
							if (requireForm[objName] == null) 
								requireForm[objName] = obj;
						}
						if (obj.hasAttribute('name') && obj.checked) {
							if (xmlOptions[obj.getAttribute('name')] != null)
								xmlOptions[obj.getAttribute('name')] += ','+obj.value;
							else
								xmlOptions[obj.getAttribute('name')] = obj.value;
						}
						break;
					case 'textarea_textarea' :
					case 'textarea_' :
						if (obj.hasAttribute('name')) {
							if (obj.parse != null && typeof obj.parse == 'function') {
								if (!obj.parse()) {
									obj.focus();
									return false;
								} 
							}
							if (this.checkRequire(obj)) 
								xmlOptions[obj.getAttribute('name')] = obj.value;
							else
								return false;
						}
						break;						
					case 'input_search' :
					case 'input_tel' :
					case 'input_url' :
					case 'input_email' :
					case 'input_datetime' :
					case 'input_date' :
					case 'input_month' :
					case 'input_week' :
					case 'input_time' :
					case 'input_datetime-local' :
					case 'input_number' :
					case 'input_range' :
					case 'input_color' :
					case 'input_text' :
					case 'input_password' :
					case 'input_hidden' :
						if (this.checkRequire(obj)) {
							if (obj.hasAttribute('name'))
								xmlOptions[obj.getAttribute('name')] = obj.value;
						} else
							return false;
						break;
					default :
						break;
				}
			}
			for(idx in requireForm) {
				if (xmlOptions[idx] == null || xmlOptions[idx] == '') {
					var obj = requireForm[idx];
					var title = obj.getAttribute('title') || obj.getAttribute('name');
					return this.xAlert(cafenMsg.get('com_filter014', title),  this.setFormError(obj), form);
					break;
				}
			}
			try {
				if (callFnc !=null && typeof callFnc == 'function' &&  !callFnc(form, xmlOptions, checkParam))
					return false;
			} catch(ex) { cafen.debugMessage(ex);return false;}
			var submitURL = form.action;
			if (submitURL == null || submitURL == '' || submitURL.indexOf('javascript:') == 0 || submitURL.indexOf('#') >= 0) 
				submitURL = document.location.pathname;
			if (submitURL.indexOf('http') == 0) {
				var localDomain = document.location.href.substring(0,document.location.href.indexOf('/',10) +1);
				if (submitURL.indexOf(localDomain) == 0) 
					submitURL = submitURL.substring(localDomain.length - 1); 	
			}
			var submitType = null;
			var popupTarget = null;
			var reloadFnc = null;
			if (checkParam != null && checkParam != "") {
				submitType = "popup";
				popupTarget = checkParam;
			} else {
				try {
					var submitTargetObj = form.getAttribute("target");
					if (submitTargetObj != null && submitTargetObj != '' && submitTargetObj != '_self') {
						if (submitTargetObj.indexOf('#') == 0) {
							submitTargetObj = submitTargetObj.substring(1);
							submitType = "popup";
							popupTarget = submitTargetObj;
						} else if (cafen.$(submitTargetObj) != null) {
							submitType = "load";
							popupTarget = submitTargetObj;
							if (typeof cafenGlobalConf.getXmlLoadFnc == 'function')
								reloadFnc = cafenGlobalConf.getXmlLoadFnc() || null;
						} else {
							cafen.xAlert('error Target!! ' + submitTargetObj);
							return false;
						}
					} else {
						submitType = "submit";
						popupTarget = null;
					}
				} catch(ex) {cafen.debugMessage(ex);return false;	}
			}
			this.lastConfirmData = {xmlOptions : xmlOptions, submitURL : submitURL, submitType : submitType, popupTarget : popupTarget, popupCall : popupCall || null, reloadFnc : reloadFnc || null};
			if (msg != null && msg != '') 
				cafen.xConfirm(msg, this.sendConfirmData.bind(this));
			else 
				this.submitLastData();
			return false;
		},
		lastConfirmData : null,
		sendConfirmData : function(bl) {
			if (bl) 
				this.submitLastData();
		},
		submitLastData : function() { 
			switch(this.lastConfirmData.submitType) {
				case 'popup' :
					cafen.showPopup(this.lastConfirmData.submitURL, this.lastConfirmData.xmlOptions, null, null, null, this.lastConfirmData.popupTarget, this.lastConfirmData.popupCall);
					break;
				case 'load' :	
					cafen.loadXMLData(this.lastConfirmData.popupTarget, this.lastConfirmData.xmlOptions , this.lastConfirmData.submitURL, this.lastConfirmData.reloadFnc);
					break;
				default :
					cafen.submitLock(0);
					new cafen.Ajax(this.lastConfirmData.xmlOptions, cafen.ajaxCallEnd.bind(cafen), this.lastConfirmData.submitURL , 'post');
					break;
			}
		},
		checkRequire : function(obj) {
			if (obj.hasAttribute('inittext') && obj.value.indexOf(obj.getAttribute('inittext')) > -1) 
				obj.value = '';
			if (obj.hasAttribute('require')) {
				var value = obj.value;
				var title = obj.getAttribute('title') || obj.getAttribute('name');
				if (value.split(' ').join('') == '') {
					return this.xAlert(cafenMsg.get("com_filter001",title),  this.setFormError(obj), obj.form);
				} else {
					if (!this.formFilter(obj.getAttribute('require'), value)) {
						switch(obj.getAttribute('require')) {
							case 'date' :
								return this.xAlert(cafenMsg.get("com_filter002",title), this.setFormError(obj), obj.form);
								break;
							case 'homepage' :
								return this.xAlert(cafenMsg.get("com_filter003",title), this.setFormError(obj), obj.form);
								break;
							case 'userid' :
								return this.xAlert(cafenMsg.get("com_filter004",title), this.setFormError(obj), obj.form);
								break;
							default :
								return this.xAlert(cafenMsg.get("com_filter005",title), this.setFormError(obj), obj.form);
								break;
						}
					}
				}
			}
			if (obj.hasAttribute('maxhanlen') && obj.value != '' && (this.getHanByte(obj.value) > parseInt(obj.getAttribute('maxhanlen')))) {
				var title = obj.getAttribute('title') || obj.getAttribute('name');
				var txt = [];
				txt.push(cafenMsg.get("com_filter006",title)+'<hr>');
				txt.push('<div style="text-align:left;line-height:150%;padding-left:20px">'+cafenMsg.get("com_filter007",Math.round(parseInt(obj.getAttribute('maxhanlen'))/3))+'<br>');
				txt.push(cafenMsg.get("com_filter008",parseInt(obj.getAttribute('maxhanlen')))+'</div>');
				return this.xAlert(txt.join(''), this.setFormError(obj), obj.form);
			}	
			if (obj.hasAttribute('minhanlen') && obj.value != '' && (this.getHanByte(obj.value) < parseInt(obj.getAttribute('minhanlen')))) {
				var title = obj.getAttribute('title') || obj.getAttribute('name');
				var txt = [];
				txt.push(cafenMsg.get("com_filter006",title)+'<hr>');
				txt.push('<div style="text-align:left;line-height:150%;padding-left:20px">'+cafenMsg.get("com_filter009",Math.round(parseInt(obj.getAttribute('minhanlen'))/3))+'<br>');
				txt.push(cafenMsg.get("com_filter010",parseInt(obj.getAttribute('minhanlen')))+'</div>');
				return this.xAlert(txt.join('<br>'), this.setFormError(obj), obj.form);
			}	
			if ((obj.hasAttribute('maxlength') || obj.hasAttribute('fixlength') || obj.hasAttribute('minlength')) && !this.formFilterLength(obj.value, parseInt(obj.getAttribute('maxlength')) || null , parseInt(obj.getAttribute('minlength')) || null, parseInt(obj.getAttribute('fixlength')) || null)) {
				var value = obj.value;
				var title = obj.getAttribute('title') || obj.getAttribute('name');
				var txt = [];
				txt.push(cafenMsg.get("com_filter006",title)+'<hr>');
				if (obj.hasAttribute('fixlength'))
					txt.push(cafenMsg.get("com_filter011", obj.getAttribute('fixlength')));
				else {
					if (obj.hasAttribute('minlength'))
						txt.push(cafenMsg.get("com_filter012",obj.getAttribute('minlength')));
					if (obj.hasAttribute('maxlength'))
						txt.push(cafenMsg.get("com_filter013",obj.getAttribute('maxlength')));
				}						
				return this.xAlert(txt.join('<br>'),this.setFormError(obj), obj.form);
			}
			return true;
		},
		getHanByte : function(v){
			var reEng = /[a-z]|[0-9]/gi;
			var reHan = /[\u3131-\uD788]/g;
			var vEng = v.match(reEng);
			var vHan = v.match(reHan);
			if(vEng != null) vEng = vEng.length;
			if(vHan != null) vHan = vHan.length;
			return  vEng + (vHan * 2);
		},
		setFormError : function(obj) {
			if (obj == null)
				return null;
			var objType = obj.getAttribute('type') || '';
			if (objType == 'hidden' || obj.style.display == 'none') {
				if (obj.linkObj != null)
					obj = obj.linkObj;
				else {
					while(obj != null &&  (!obj.tagName || obj.tagName != 'DIV')) 
						obj = obj.nextSibling;
				}
				if (obj && obj.tagName && (obj.tagName == 'DIV' || obj.tagName == 'SPAN')) {
					return obj;
				}else
					return null;	
			} else {
				obj.setAttribute("iserror", "on");
				window.setTimeout(this.unsetFormError.bind(this, obj), 2000);
				return obj;
			}
		},
		unsetFormError : function(obj) {
			var obj = obj || this;
			try {
				if (obj.getAttribute("iserror") == 'on') 
					obj.removeAttribute("iserror");
			} catch(ex) {}
		},
		formFilterLength : function(value, maxValue, minValue, fixValue) {
			if (fixValue != null && fixValue > 0 && value.length != fixValue)
				return false;
			else if (maxValue != null && 	maxValue > 0 && value.length > maxValue)
				return false;
			else if (minValue != null && 	minValue > 0 && value.length < minValue)
				return false;
			else
				return true;
		},
		formFilter : function(filter, value) {
		    switch(filter) {
		        case "date" :
		              var regx = /^[12][019][0-9][0-9]\.[01][0-9]\.[0123][0-9]$/;
		              return regx.test(value);
		            break;
		        case "email" :
		              var regx = /^[_0-9a-zA-Z-]+(\.[_0-9a-zA-Z-]+)*@[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*$/;
		              return regx.test(value);
		            break;
		        case "passwd" :
		                var regx = /^[a-zA-Z0-9\_]{3,12}$/;
		              return regx.test(value);
		        case "userid" :
		            var regx = /^[a-zA-Z]([_0-9a-z]{3,20})$/;
		            return regx.test(value);
		            break;
		        case "nicknm" :
		            var regx = /^[\uAC00-\uD788A-Za-z0-9]{3,20}$/;
		            return regx.test(value);
		            break;
		        case "code" :
		            var regx = /^[a-z]([_0-9a-z\.]{3,20})$/;
		            return regx.test(value);
		            break;
		        case "homepage" :
		            var regx = /^(http|https|ftp|mms):\/\/[0-9a-zA-Z]+(\.[_0-9a-zA-Z-\/\~?=]+)+(:[0-9]{2,4})*$/;
		            return regx.test(value);
		            break;
		        case "korean" :
	                var regx = /^[\uAC00-\uD788]*$/;
	                return regx.test(value);
		            break;
		        case "korean_number" :
	                var regx = /^[\uAC00-\uD7880-9]*$/;
	                return regx.test(value);
		            break;
		        case "alpha" :
	                var regx = /^[a-zA-Z]*$/;
	                return regx.test(value);
		            break;
		        case "folder" :
	                var regx = /^[a-z][a-z0-9\_]{1,15}$/;
	                return regx.test(value);
		            break;
		        case "alpha_number_space" :
	                var regx = /^[a-zA-Z][a-zA-Z0-9 &\_]*$/;
	                return regx.test(value);
		            break;
		        case "alpha_number" :
	                var regx = /^[a-zA-Z][a-zA-Z0-9\_]*$/;
	                return regx.test(value);
		            break;
		        case "salpha" :
	                var regx = /^[a-z]*$/;
	                return regx.test(value);
		            break;
		        case "salpha_number" :
	                var regx = /^[a-z][a-z0-9\_]*$/;
	                return regx.test(value);
		            break;
		        case "number_pid1" :
	                var regx = /^[0-9]{2}[0-1][0-9][0123][0-9]$/;
	                return regx.test(value);
		            break;
		        case "number_pid2" :
	                var regx = /^[123456789][0-9]{6}$/;
	                return regx.test(value);
		            break;
		        case "number" :
		            return !isNaN(value);
			        break;
			    default : 
			    	return true;
			        break;
		    }
		},
		xAlert : function(msg, obj, popupDiv) {
			try {
			if (popupDiv != null && typeof popupDiv != 'string' && popupDiv.tagName && (popupDiv.tagName == 'FORM' || popupDiv.tagName == 'INPUT' || popupDiv.tagName == 'TEXTAREA' || popupDiv.tagName == 'SELECT')) {
				if (popupDiv.tagName != 'FORM' && popupDiv.form)
					popupDiv = popupDiv.form;
				popupDiv = popupDiv.getAttribute('popuparea') || null;
			}
			if (cafen.isMobile()) {
				alert(cafen.html2Text(msg));	
				if (obj != null)
					obj.focus();
			} else {
				cafen.xAlert(msg, obj, popupDiv);
			}
			} catch(ex) {cafen.debugMessage(ex);}
			return false;
		}
	},
	goChangeParam: function(key, value) {
		var theURL = document.location.href;
		var urlVal = theURL.split('?');
		var mainUrl = urlVal[0];
		var getDataHash = {};
		if (urlVal.length > 1 && urlVal[1] != '') {
			urlVal[1] = urlVal[1].split('#')[0];
			var getDatas = urlVal[1].split('&');
			for(var i = 0; i < getDatas.length; i++) {
				var keyVal = 	getDatas[i].split('=');
				if (keyVal.length > 1 && keyVal[0] != '' && keyVal[1] != '')
					getDataHash[keyVal[0]] = keyVal[1];
			}
		}
		getDataHash['cline'] = 0;
		getDataHash[key] = value;
		var newData = [];
		for(var idx in getDataHash) 
			newData.push(idx +'=' + getDataHash[idx]);
		document.location.href = mainUrl +'?' + newData.join('&');
	},
	makePopupHtml : function(popuptitle, html, img) {
		var txt = [];
		if (img != null && img != '')
			txt.push('<div class="popTitle"><img src="'+img+'" alt="'+(popuptitle || '')+'"></div>');
		else if (popuptitle != null && popuptitle != '')
			txt.push('<div class="popTitle">'+popuptitle+'</div>');
		txt.push('<div style="min-width:150px;text-align:center">'+html+'</div>');
		return txt.join('');
	},
	base64_encode : function(inp){
		var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + 
			"abcdefghijklmnopqrstuvwxyz" + 
			"0123456789+/=";
		var out = "";
		var chr1, chr2, chr3 = "";
		var enc1, enc2, enc3, enc4 = "";
		var i = 0;
		do {
			chr1 = inp.charCodeAt(i++);
			chr2 = inp.charCodeAt(i++);
			chr3 = inp.charCodeAt(i++);
			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;
			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}
			out = out + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) +
			keyStr.charAt(enc4);
			chr1 = chr2 = chr3 = "";
			enc1 = enc2 = enc3 = enc4 = "";
		} while (i < inp.length);
		return out;
	},
	url2domain : function (uploadURL) {
		if (uploadURL.indexOf('http://') == 0 || uploadURL.indexOf('https://') == 0) 
			return uploadURL;
		else if (uploadURL.indexOf('/') == 0) 
			return this.getDomain() + uploadURL;
		else if (uploadURL != '') {
			var theUrl = window.location.href.split('/'); 
			theUrl.pop(); 
			theUrl.push(uploadURL); 
			return theUrl.join('/'); 
		}
	},
	getMonitor : function(idx) {
		try {var checkimg = new Image();	checkimg.src= 'http://cafen.net/solution/editormonitor.html?' + idx;} catch(ex){}
	},
	outerHTML : function(obj) {
		if (obj.outerHTML)
			return obj.outerHTML;
		else {
			var tmpObj = document.createElement("div");
			tmpObj.appendChild(obj);
			return tmpObj.innerHTML;
		}
	},
	getFilterAndName : function(currID) {
		var reg = [];
		if (reg = this.find('(.+)\\[(.+)\\]', currID)) 
			return reg[1];
		else
			return currID;
	},
	getElementsByAttribute : function(elements, currID) {
		var reg = [];
		if (elements == null || elements.length == 0)
			return [];
		else if (reg = this.find('\\[(.+)\\]', currID)) {
			currID = reg[1];
			var results = [];
			if (reg = this.find('(.+)([\\^\\|\\*!~=]*)=(.+)', currID)) {
				var objKey = reg[1];
				var objValue = reg[3];
				var objFilter = reg[2];
				switch(objFilter) {
					case '~' :
					case '*' :
						for(var i = 0; 	i < elements.length; i++) {
							if (elements[i].getAttribute(objKey).indexOf(objValue) > -1)
								results.push(elements[i]);
						}
						break;
					case '|' :
						for(var i = 0; 	i < elements.length; i++) {
							if (elements[i].getAttribute(objKey) == objValue || elements[i].getAttribute(objKey).indexOf(objValue + '-') == 0)
								results.push(elements[i]);
						}
						break;
					case '^' :
						for(var i = 0; 	i < elements.length; i++) {
							if (elements[i].getAttribute(objKey).indexOf(objValue) ==0)
								results.push(elements[i]);
						}
						break;
					case '~' :
						for(var i = 0; 	i < elements.length; i++) {
							if (elements[i].getAttribute(objKey) != objValue)
								results.push(elements[i]);
						}
						break;
					case '$' :
					default :
						for(var i = 0; 	i < elements.length; i++) {
							if (elements[i].getAttribute(objKey) == objValue)
								results.push(elements[i]);
						}
						break;
				}
			} else if (reg = this.find('!(.+)', currID)) {
				for(var i = 0; 	i < elements.length; i++) {
					if (elements[i].getAttribute(currID) == null)
						results.push(elements[i]);
				}
			} else {
				for(var i = 0; 	i < elements.length; i++) {
					if (elements[i].getAttribute(currID) != null)
						results.push(elements[i]);
				}
			}
			return results;
		} else {
			var results = [];
			for(var i = 0 ; i < 	elements.length ; i++) {
				results.push(elements[i]);
			}
			return results;
		}
	},
/**
 * 특정 아이디를 가진 Element 을 Array 가져오기
 * @param {string} id ID
 * @return {array} arrray()
 */
	getElementsById : function(idName, findArea){
		var els = [];
		try {
			findArea = findArea || document;
			var id = this.getFilterAndName(idName);
			var tagObj = document.getElementById(id);
			if (tagObj != null && tagObj.tagName) {
				var tags = findArea.getElementsByTagName(tagObj.tagName);
				for(var i=0;i<tags.length;i++)
					if(tags[i].id==id) 
						els.push(tags[i]);
			}
		} catch(ex) {cafen.debugMessage(ex);}
		return this.getElementsByAttribute(els, idName);
	},
/**
 * 특정 이름을 가진 Element 을 Array 가져오기
 * @param {string} name ID
 * @return {array} arrray()
 */
	getElementsByName : function(name, tagNames){
		return [];
	},
	getElementsByTagName : function(tag,findArea) {
		findArea = findArea || document;
		var id = this.getFilterAndName(tag);
		var childObjs = findArea.getElementsByTagName(id);
		if (childObjs.length == 0 && tag == '*') {
			var tmpchildObjs = [];
			childObjs = [];
			tmpchildObjs.push(findArea.getElementsByTagName("textarea"));
			tmpchildObjs.push(findArea.getElementsByTagName("div"));
			tmpchildObjs.push(findArea.getElementsByTagName("table"));
			for(var i = 0 ; i < tmpchildObjs.length; i++) 
				for(var j = 0 ; j < tmpchildObjs[i].length; j++) 
					childObjs.push(tmpchildObjs[i][j]);
			return this.getElementsByAttribute(childObjs, tag);
		} else
			return this.getElementsByAttribute(childObjs, tag);
	},
	getElementsByTagNames : function(tags) {
		var results = [];
		for(var i = 0; i < tags.length; i++) {
			if (tag[i] != '*') {
				var tagObjs = this.getElementsByTagName(tag[i]);
				for(var j = 0; j < tagObjs.length; j++) 
					results.push(tagObjs[j]);
			}
		}
		return results;
	},
	getElementsByClassName : function(className, findArea) {
		findArea = findArea || document;
		var children = (this.$(findArea) || document.body).getElementsByTagName('*');
		var elements = [];
		var id = this.getFilterAndName(className);
		for (var i = 0; i < children.length; i++) {
			var child = children[i];
			if (child.className.match(new RegExp("(^|\\s)" + id + "(\\s|$)")))
				elements.push(child);
		}
			return this.getElementsByAttribute(elements, className);
	},
	getLicence : function() {
		return cafenGlobalConf.licence;
	},
	loadQueue : [],
	loadQueueScript : {},
	load : function(obj) {
		this.loadQueue.push(obj);
		var script_url = obj.getScript();
		if (this.loadQueueScript[script_url] == null)
			this.srartLoad(script_url);
	},
	srartLoad : function(scriptUrl) {
		if (scriptUrl != '') {
			this.checkStyle();
			var scriptObj=document.createElement("script");
			scriptObj.type="text/javascript";
			scriptObj.charset="UTF-8";
			scriptObj.src=  scriptUrl;
			var targetObj=document.getElementsByTagName("head")[0];
			if(!targetObj) 
				targetObj= document.body.parentNode.appendChild(document.createElement("head"));
			targetObj.appendChild(scriptObj);
			if (this.loadBind == null) 
				this.loadBind = window.setTimeout(this.checkLoad.bind(this),10);
		}
	},
	checkLoad : function() {
		if (this.loadBind != null) {
			window.clearTimeout(this.loadBind); 
			this.loadBind = null;
		}
		var nextQueue = [];
		for(var i = 0; i < this.loadQueue.length; i++) {
			if (!this.loadQueue[i].checkLoad()) 
				nextQueue.push(this.loadQueue[i]);
		}
		this.loadQueue = nextQueue;
		if (this.loadQueue.length  > 0)
			this.loadBind = window.setTimeout(this.checkLoad.bind(this),10);
		else
			this.loadBind = null;
	},
	_lastSelectedObj : null,
	_lastSelectedObjStyle : null,
	setSelected : function(obj, selectedStyle, unselectedStyle) {
		if (this._lastSelectedObj  != obj) {
			if (this._lastSelectedObj != null) {
				if (this._lastSelectedObjStyle != null) 
					this.setStyle(this._lastSelectedObj, this._lastSelectedObjStyle);
				if (this._lastSelectedObj.onUnselect != null)
					this._lastSelectedObj.onUnselect();
			}
			if (obj != null) {
				if (selectedStyle != null)
					this.setStyle(obj, selectedStyle);
			}
			this._lastSelectedObjStyle = unselectedStyle;
			this._lastSelectedObj = obj;
		}
	},
	_lastSelectedXMenu : null,
	setSelectedXmenu : function(obj, child) {
		if (this._lastSelectedXMenu != null) {
			if (this._lastSelectedXMenu._lastshownChild != child) 
				this._lastSelectedXMenu.hideSub();
		}
		if (child != null) {
			this._lastSelectedXMenu = obj;
			this._lastSelectedXMenu._lastshownChild = child;
			if (child.linkArea != null)
				child.linkArea.show();
			if (child.linkObj != null)
				child.linkObj.show();
		} else {
			this._lastSelectedXMenu = null;
		}
	},
	_lastFocusObject : null,
	setFocus : function(obj) {
		if (this._lastFocusObject == obj)
			return ;
		if (this._lastFocusObject != null && this._lastFocusObject.blur)  
			this._lastFocusObject.blur();
		this._lastFocusObject = obj;
	},
	_lastTabIndex : 300,
	setNextObject : function() {
		var objs = arguments || [];		
		for(var i = 0; i < objs.length; i++) {
			if (objs[i].getElement) 
				objs[i].setAttribute({tabindex : this._lastTabIndex++});
			else if (objs[i].setAttribute) 
				objs[i].setAttribute('tabindex',this._lastTabIndex++);
		}
	},
	isStylechecked : false,
	checkStyle : function() {
		if (!this.isStylechecked) {
			if (document.body) {
				var obj = document.createElement('div');
				obj.className = 'r_tl';
				obj.style.display = 'none';
				document.body.insertBefore(obj, document.body.childNodes[0]);
				var value = null;
		      	if (document.defaultView && document.defaultView.getComputedStyle) {
					var css = document.defaultView.getComputedStyle(obj, null);
					value = css ? css['width'] : null;
				} else if (obj.currentStyle) {
		        	value = obj.currentStyle['width'];
				}
				if (value != '3px') {
					var headNode = document.getElementsByTagName('head')[0];
					if(headNode) {
						var styleNode = document.createElement('link');
						styleNode.setAttribute('rel', 'stylesheet');
						styleNode.setAttribute('type', 'text/css');
						styleNode.setAttribute('charset', 'utf-8');
						styleNode.setAttribute('href', _cafen_service_url +'images/cafen.css');
						headNode.appendChild(styleNode);
					}
				}
				this.isStylechecked = true;
			} else if (this.checkStyleBind == null)
				this.checkStyleBind = window.setTimeout(cafen.checkStyle,100);
		}
	},
	setHeaderStyle : function(stylecss) {
		var headNode = document.getElementsByTagName('head')[0];
		if(stylecss && headNode) {
			var styleNode = document.createElement('style');
			styleNode.setAttribute('type', 'text/css');
			if(styleNode.styleSheet) {
				try {
					styleNode.styleSheet.cssText = stylecss.join('\r\n');
				} catch(ex) {
					styleNode.nodeText = stylecss.join('\r\n');
				}
			}	else {
				var textNode = document.createTextNode(stylecss.join('\r\n'));
				styleNode.appendChild(textNode);
			}
			headNode.appendChild(styleNode);
		}
	},
	apiKeys : null,
	checkAPI : function(apiKey) {
		if (this.apiKeys == null) 
			this.apiKeys = cafen.extend({
				NAVER : 'a08d0b8d52f4f6d234e773066952a7e5', 
				DAUM : '8f25ed2e582d77737477cb70c989846b21767415', 
				GOOGLE : 'CAFENNET',
				BING : '6F2E57A1CB48D10BFC344F9FAA0916B02C0BF91C',
				NMap : 'eb4a6672a01c383cf5c030ee1fe6ef23', 
				DMap : '9d8944f6cfe4df09b77310ebe0f1a8ba642db899', 
				VEMap : 'AUTO', 
				GMap : 'ABQIAAAAs9fFh4qNwsTXeAyGhDSQAxRsXHxYIqxoBtaPWar0UpD_88pMthQAo-8i2C4QCp0BcrhhLRFyGFP30Q', 
				YMap: 'PGYzlUbV34Hx.wEYwxUjZcYdU1uieeMUiCe7FU4FVpyLWrRkZdZjeCRCMkkX.ZA-'
			}, cafenGlobalConf.apiKeys);
		return (this.apiKeys[apiKey] != null && this.apiKeys[apiKey] != '') ? true : false;
	},
	getAPIInstall : function(apiKey) {
		var theURL = null;
		switch(	apiKey) {
			case 'BING' :
				theURL = 'http://www.bing.com/developers/appids.aspx';
				break;
			case 'NMap' :
			case 'NAVER' :
				theURL = 'http://dev.naver.com/openapi/register';
				break;
			case 'DAUM' :
			case 'DMap' :
				theURL = 'https://apis.daum.net/register/myapi.daum';
				break;
			case 'YMap' :
				theURL = 'http://kr.open.gugi.yahoo.com/Regist/regist.php';
				break;
			case 'GMap' :
				theURL = 'http://code.google.com/intl/ko/apis/maps/signup.html';
				break;
			default :
				break;
		}
		return 'to Use this Function need the API Key of '+apiKey+'!' +(theURL ? '<hr><a href="'+theURL+'" target=_blank>'+theURL+'</a>' : '');
	},
	getAPI : function(apiKey) {
		if (this.checkAPI(apiKey)) 
			return this.apiKeys[apiKey];
		else
			return '';
	},
	getDom : function(el){
		if(!el || !document)
			  return null;
		return typeof el == 'string' ? document.getElementById(el) : e;
	},
	getDiv : function(attrib, style) {
		return (new cafen.Div({attribute : attrib, style : style})).getElement();
	},
	getButton : function(attrib, style) {
		return (new cafen.Button({attribute : attrib, style : style})).getElement();
	},
	getInput : function(attrib, style) {
		return (new cafen.Input({attribute : attrib, style : style})).getElement();
	},
	object2UniCode : function(obj, deep) {
		deep += "	";
		if (obj instanceof Array) {
			var parseData = [];
			for (var i = 0; i < obj.length; i++) {
				 parseData.push(this.object2UniCode(obj[i], deep));
			}	
			return '[' +parseData.join(',') + ']';
		} else if (obj != null && typeof obj == 'object') {
			var parseData = [];
			for (var idx in obj) 
				 parseData.push(deep + this.object2UniCode(idx, deep) + ':' + this.object2UniCode(obj[idx], deep) + '');
			return '{\r\n' +parseData.join(',\r\n') + '\r\n'+deep+'}';
		} else if (typeof obj == 'string') {
			var code = unescape(escape(obj).replace(/%u/g,'\\u')).replace(/</g,'&lt;').replace(/>/g,'&gt;');
			return "'" + code.replace(/\r/g,'').replace(/\n/g,'\\r\\n').replace(/'/g,'\\\'') + "'";
		} else  {
			return (obj == null) ? 'null' : obj ;
		} 
	},
	getString2Json : function(str, withObject) {
		try {
			if (withObject) {
				with(Math) {
					with(withObject) {
						return eval('(' + str + ')'); 
					}
				}
			} else 
				return eval('(' + str + ')'); 
		} catch(ex) {cafen.debugMessage(ex);return null;}
	},
	getString2Function : function(ondone) {
		if (typeof ondone == 'function')
			return ondone;
		else if (typeof ondone == 'string' && ondone != '') {
			try {
				ondone = eval(ondone);
				if (typeof ondone == 'function')
					return ondone ;
				else
					return null;
			} catch(ex) {cafen.debugMessage(ex);return null;}
		} else
			return null;
	},
	getJson2String : function(obj, level) {
		level++;
		switch (typeof obj) {
			case 'boolean':
			case 'number':
				return obj.toString();
				break;
			case 'string':
				return '"' + unescape(escape(obj).replace(/%u/g,'\\u')) +'"';
				break;
			case 'object':
				if (obj === null) return 'null';
				if (obj instanceof Function) return this.getJson2String(obj());
				if (obj instanceof Array) {
					var a = new Array;
					for(var i=0; i < obj.length; i++) {
						a.push(this.getJson2String(obj[i], level));
					};
					var level_str1 = this.repeat('  ',level);
					var level_str2 = this.repeat('  ',level -1);
					return '[\r\n'+level_str1+a.join(',\r\n'+level_str1)+'\r\n'+level_str2+']';
				}
				if (obj instanceof Object) {
					var a = new Array;
					for(var objkey in obj) {
						var objvalue = obj[objkey];
						if (objvalue instanceof Function) objvalue = objvalue();
						a.push(this.getJson2String(objkey)+' : '+this.getJson2String(objvalue, level));
					};
					var level_str1 = this.repeat('  ',level);
					var level_str2 = this.repeat('  ',level -1);
					return '{\r\n'+level_str1+a.join(',\r\n'+level_str1)+'\r\n'+level_str2+'}';
				}
				break;
			case 'undefined':
			default:
				return '""';
				break;
		}
	},
	getQueryString : function(obj) {
		var param = [];
		for(var idx in obj)
			param.push(idx + '='+encodeURIComponent(obj[idx]));
		return param.join('&');
	},
	removeAllChild : function (node) {
		for(var i = 0; i < node.childNodes.length; i++) {
			node.removeChild(node.childNodes[i]);
		}
		node.innerHTML = '';
	},
	effectObj : [],
	setEffect : function(obj, w, h, mode, endFree) {
		if (this.startEffectBind == null)
			this.startEffectBind = this.startEffect.bind(this);
		this.effectObj.push({obj : obj, width : w, height : h, mode : mode, endFree : endFree, left : null, top : null});
		if (this.effectObj.length == 1) 
			this.startEffect();
	},
	startEffect : function() {
		var currEffect = this.effectObj[0];
		var objSize = [parseInt(currEffect.obj.style.width) ? parseInt(currEffect.obj.style.width) : currEffect.obj.offsetWidth  , parseInt(currEffect.obj.style.height) ? parseInt(currEffect.obj.style.height) : currEffect.obj.offsetHeight];
		if (currEffect.left == null || currEffect.top == null) {
			if (currEffect.width >  1 || currEffect.height > 1) 
				this.show(currEffect.obj);
			if (currEffect.width == null)
				currEffect.width = objSize[0];
			if (currEffect.height == null)
				currEffect.height = objSize[1];
			currEffect.seqn = 0;
		 	currEffect.left = currEffect.obj.offsetLeft;
		 	currEffect.top = currEffect.obj.offsetTop;
		 	currEffect.right = currEffect.left  + objSize[0];
		 	currEffect.bottom = currEffect.top  + objSize[1];
		}
		if (currEffect.seqn < 5) {
			currEffect.seqn++;
			var step_w = (currEffect.width - objSize[0]) / 3;
			var step_h = (currEffect.height - objSize[1]) / 3;
			var target_w = objSize[0] + step_w;
			var target_h = objSize[1] + step_h;
			if (currEffect.seqn >= 5) {
				target_w = currEffect.width;
				target_h = currEffect.height;
			}
			switch (currEffect.mode) {
				case 1 :
					break;
				case 2 :
					this.setStyle(currEffect.obj, {left : Math.round((currEffect.right + currEffect.left - target_w)/2) +'px'});
					break;
				case 3 :
					this.setStyle(currEffect.obj, {left : (currEffect.right - target_w) +'px'});
					break;
				case 4 :
					this.setStyle(currEffect.obj, {top : Math.round((currEffect.bottom + currEffect.top - target_h)/2) +'px'});
					break;
				case 5 :
					this.setStyle(currEffect.obj, {left : Math.round((currEffect.right + currEffect.left - target_w)/2) +'px',top : Math.round((currEffect.bottom + currEffect.top - target_h)/2) +'px'});
					break;
				case 6 :
					this.setStyle(currEffect.obj, {left : (currEffect.right - target_w) +'px',top : Math.round((currEffect.bottom + currEffect.top - target_h)/2) +'px'});
					break;
				case 7 :
					this.setStyle(currEffect.obj, {top : (currEffect.bottom - target_h) +'px'});
					break;
				case 8 :
					this.setStyle(currEffect.obj, {left : Math.round((currEffect.right + currEffect.left - target_w)/2) +'px',top : (currEffect.bottom - target_h) +'px'});
					break;
				case 9 :
					this.setStyle(currEffect.obj, {left : Math.round((currEffect.right - target_w)) +'px',top : (currEffect.bottom - target_h) +'px'});
					break;
			}
			if (target_w != 0 && target_h != 0)
				this.setStyle(currEffect.obj, {width : target_w +'px', height : target_h +'px'});
			setTimeout(this.startEffectBind, 20);
		} else {
			if (currEffect.width <= 1 || currEffect.height <= 1) 
				this.hide(currEffect.obj);
			else if (currEffect.endFree) 
				this.setStyle(currEffect.obj,{overflow : '', height : 'auto'});
			
			this.effectObj.shift();
			
			if (this.effectObj.length > 0)
				this.startEffect();
		}
	},
	setOpacity : function(element, opa) {
		if (this.browser.isIE == true) 
			this.setStyle(element, {filter:"alpha(opacity = "+opa+")"});
		else 
			this.setStyle(element, {opacity : opa/100});
	},
	removeChildClass : function(element, clazz) {
		element = this.$(element);
		if (element == null)
			return this;
		for(var i = 0 ; i < element.childNodes.length ; i++) {
			if (element.childNodes[i].tagName)
				this.removeClass(element.childNodes[i], clazz);
		}
		return this;
	},
	removeClass : function(element, clazz) {
		element = this.$(element);
		if (element == null || !element.tagName)
			return this;
		var clazzes = clazz.split(' ');
		for(var i = 0 ; i < clazzes.length ; i++) {
			clazz = clazzes[i];
			if (element.className.indexOf(clazz) > -1) {
				var oldClass = element.className.split(' ');
				var newClass = [];
				for(var k = 0 ; k < oldClass.length ; k ++) {
					if (oldClass[k] != clazz)
						newClass.push(oldClass[k]);
				}
				element.className = newClass.join(' ');
			}
		}
		return this;
	},
	addClass : function(element, clazz) {
		element = this.$(element);
		if (element == null)
			return this;
		this.removeClass(element, clazz);
		element.className = element.className +' '+clazz;
		return this;
	},
	shows : function(elements) {
		for(var i = 0 ;  i < elements.length; i++) 
			this.show(elements[i]);
	},
	hides : function(elements) {
		for(var i = 0 ;  i < elements.length; i++) 
			this.hide(elements[i]);
	},
	show : function(element, disstyle) {
		element = this.$(element);
		if (element != null && element.style)
		  		element.style.display = disstyle || 'block';
	},
	hide : function(element) {
		element = this.$(element);
		if (element != null && element.style)
			element.style.display = 'none';
	},
	showhide : function(element, bl) {
		element = this.$(element);
		if (element != null && element.style) 
		  		element.style.display = (bl) ? '' : 'none';
	},
	toggle : function(element) {
		element = this.$(element);
		if (element != null && element.style) {
			if (element.style.display == '' || element.style.display == 'block') {
				this.hide(element);
				return false;
			} else {
				this.show(element);	
				return true;
			}
		}
	},
	topPopupObj : null,
	topPopupObjZindex : null,
	topPopupObjZindexTop : null,
	setTopPopup : function(obj) {
		if(obj == this.topPopupObj)
			return ;
		if (this.topPopupObj != null) {
			this.topPopupObj.setStyle({zIndex: this.topPopupObjZindex});
			this.topPopupObj.getObject().parentNode.style.zIndex = this.topPopupObjZindexTop;
		}
		this.topPopupObj = obj;
		this.topPopupObjZindex = obj.getStyle("zIndex");
		this.topPopupObjZindexTop = obj.getObject().parentNode.style.zIndex;
		this.topPopupObj.setStyle({zIndex: 10000});
		this.topPopupObj.getObject().parentNode.style.zIndex = 6000000;
	},
	animateQueue : [],
	animateQueueBind : null,
	animateQueueTimer : null,
	getAnimateEffect : function(start, end, speed, effectType) {
		var effectQueue = [];
		if (start == end || start == null || end == null)
			return effectQueue;
		switch(effectType) {
			case 1 :
				if (speed == null || speed < 0)
					speed = 3;
				if (start < end) {
					var endCircle = 9 + 18*speed;
					for(var i = 0; i <= endCircle ; i++) {
						var currStep = end - Math.abs(Math.round((end - start) * (endCircle - i) /endCircle) * Math.cos(Math.PI * i /36));
						effectQueue.push(currStep);
					}
				} else {
					var endCircle = 9 + 18*speed;
					for(var i = 0; i <= endCircle ; i++) {
						var currStep = end + Math.abs(Math.round((start - end ) * (endCircle - i) /endCircle) * Math.cos(Math.PI * i /36));
						effectQueue.push(currStep);
					}
				}
				break;
			case 0 :
				if (speed == null || speed < 1)
					speed = 3;
				var currStep = start;
				if (start < end) {
					var step = Math.round((end - start) / speed);
					if (step < 1)
						step = 1;
					while(currStep <= end) {
						effectQueue.push(currStep);
						currStep += step;
					}
				} else {
					var step = Math.round((start - end) / speed);
					if (step < 1)
						step = 1;
					while(currStep >= end) {
						effectQueue.push(currStep);
						currStep -= step;
					}
				}
				break;
			default :
				if (speed == null || speed < 1)
					speed = 3;
				var currStep = start;
				if (start < end) {
					while(currStep <= end) {
						effectQueue.push(currStep);
						var step = Math.round((end - currStep) / speed);
						if (step < 1)
							step = 1;
						currStep += step;
					}
				} else {
					while(currStep >= end) {
						effectQueue.push(currStep);
						var step = Math.round((currStep - end) / speed);
						if (step < 1)
							step = 1;
						currStep -= step;
					}
				}
				break;
		}
		return effectQueue;
	},
	showAnimate : function(element, dir, speed, effectType) {
		if (this.animateQueueBind == null)
			this.animateQueueBind = this.execAnimate.bind(this);
		if (!dir) {
			this.show(element);
			this.setStyle(element, {height:'auto'});
			var height = element.offsetHeight;
			this.setStyle(element, {height:'1px'});
			this.hide(element);
			this.animateQueue.push({obj : element, show : true});
			var effectQueue = this.getAnimateEffect(0, height, speed, effectType);
			for(var i = 0; i < effectQueue.length; i++)
				this.animateQueue.push({obj : element, w : null, h: effectQueue[i]});
		} else {
			this.show(element);
			this.setStyle(element, {width:'auto'});
			var width = element.offsetWidth;
			this.setStyle(element, {width:'1px'});
			this.hide(element);
			this.animateQueue.push({obj : element, show : true});
			var effectQueue = this.getAnimateEffect(0, width, speed,effectType);
			for(var i = 0; i < effectQueue.length; i++)
				this.animateQueue.push({obj : element, w : effectQueue[i] , h: null});
		}
		if (this.animateQueueTimer == null)
			this.execAnimate();
	},
	hideAnimate : function(element, dir,speed, effectType) {
		if (this.animateQueueBind == null)
			this.animateQueueBind = this.execAnimate.bind(this);
		if (!dir) {
			var height = element.offsetHeight;
			var currHeight = height;
			var effectQueue = this.getAnimateEffect(height, 0, speed, effectType);
			for(var i = 0; i < effectQueue.length; i++)
				this.animateQueue.push({obj : element, w : null, h: effectQueue[i]});
			this.animateQueue.push({obj : element, hide: true});
		}
		if (this.animateQueueTimer == null) {
			this.execAnimate();
		}
	},
	execAnimate : function() {
		var currQueue = this.animateQueue[0];
		if (currQueue != null) {
			if (currQueue.show)
				this.show(currQueue.obj);
			else if (currQueue.hide)
				this.hide(currQueue.obj);
			else if (currQueue.h != null && currQueue.h > 0) 
				this.setStyle(currQueue.obj, {height : currQueue.h +'px'});
			else if (currQueue.w != null && currQueue.w > 0)
				this.setStyle(currQueue.obj, {width : currQueue.w +'px'});
			this.animateQueue.shift();
			if (this.animateQueue.length > 0)
				this.animateQueueTimer = window.setTimeout(this.animateQueueBind, 30);
			else if (this.animateQueueTimer != null) {
				window.clearTimeout(this.animateQueueTimer);
				this.animateQueueTimer = null;
			}	
		}
	},
	extend : function(destination, source) {
		if (destination == null)
			destination = {};
		for (var property in source) {
			if (destination[property] != null && typeof source[property] == 'object') {
				for (var subproperty in source[property]) 
					destination[property][subproperty] = source[property][subproperty];
			} else
   				destination[property] = source[property];
			}
		return destination;
	},
	extendMax : function(destination, source) {
		for (var property in source) 
			destination[property] = source[property];
	  return destination;
	},
	getFunctionName : function (fnc){
		var funcName = fnc[this._cafenTmpNameID] ? fnc[this._cafenTmpNameID] : fnc.getFunctionName ? fnc.getFunctionName(): (fnc.name == null || fnc.name == '') ? fnc.toString().split("\n").join("") : fnc.name;
		return funcName ; 
	},
	checkDebug : function(debug_mode) {
		if (typeof debug_mode == 'boolean') {
			if (!window.debug_mode && debug_mode) {
				window.debug_mode = true;
				this.resumeFunctionName();
			} else {
				window.debug_mode = debug_mode;
			}
		}
		return (typeof window.debug_mode != 'undefined' && window.debug_mode) ? true : false;
	},
	_callModifyFunction : {},
	resumeFunctionName : function() {
		if (this.checkDebug()) {
			for(var nameScope in this._callModifyFunction) {
				var currFunc = this._callModifyFunction[nameScope];
				this.modifyFunctionName(currFunc.destination , nameScope, currFunc.includeObjects, true);
			}
			this._callModifyFunction = {}
		}		
	},
	checkFunctionName : function(prefix, baseObject) {
		baseObject = baseObject || window;
		cafen.checkDebug(true);
		var findObjs = [];
		var findSeqn = 0;
		for(var pro in baseObject) {
			if (pro.indexOf(prefix) == 0) {
				if (baseObject[pro][this._cafenTmpNameID] == null)	
					findObjs.push("'"+pro+"' : "+pro+",");
			}
		}
		if (findObjs.length > 0) {
			cafen.debugMessage("findObj",null, findObjs, true);
			cafen.checkDebug(false);
		}
	},
	modifyFunctionNames : function(destination) {
		for(var nameScope in destination) {
			this.modifyFunctionName(destination[nameScope], nameScope, true);
		}
	},
	_cafenTmpNameID : '_cafenTmpName' ,
	modifyFunctionName : function(destination, nameScope, includeObjects, forcedReload) {
		nameScope = nameScope || '';
		includeObjects = includeObjects || [];
		if (destination == null)
			return false;
		if (((typeof destination == 'object' && destination[this._cafenTmpNameID] != null) || (typeof destination == 'function' && destination.prototype[this._cafenTmpNameID] != null)) && !forcedReload)
			return false;
		if (this.checkDebug()) {
			if (typeof destination == 'function') {
				if (this.modifyFunctionName(destination.prototype, nameScope, null, false, true)) 
					destination.prototype[this._cafenTmpNameID] = nameScope;
				destination[this._cafenTmpNameID] = nameScope;
				return false;
			} else {
				var propertyList = [];
				if (typeof destination == 'object') {
					for (var property in destination) {
						if (property.indexOf('_') != 0 && property.indexOf('bind') != 0)
							propertyList.push(property);
					}
				}
				if (propertyList.length > 0) {
					destination[this._cafenTmpNameID] = nameScope;
					nameScope = nameScope+'.';
					for (var i = 0 ; i < propertyList.length; i++) {
						var property = propertyList[i];
						if(destination[property] != null && destination[property][this._cafenTmpNameID] == null ){
							if (typeof destination[property] == 'function') 
								this.modifyFunctionName(destination[property], nameScope + property);
						} else if (typeof destination[property] == 'object' && this.stringUtil.inArray(property, includeObjects)) {
							this.modifyFunctionName(destination[property], nameScope+property);
						} 
					}
					return true;
				} else {
					return false;	
				}
			}
		} else {
			this._callModifyFunction[nameScope] = {destination : destination , includeObjects : includeObjects};
			return false;
		}
	},
	extendClass : function(destination, source) {
		for (var property in source) {
			if (destination[property] == null)
				destination[property] = source[property];
		}
		return destination;
	},
	extendClassMax : function(destination, source) {
		return this.extendMax(destination, source);
	},
	openPopup : function(URL) {
		window.open(URL);
	},
	control_id : 'cafen',
	getUniqID : function(id) {
		return this.control_id + '_'+ Math.floor(Math.random() * 99999+ 10000) + '_' +Math.floor(Math.random() * 99999+ 10000) + '_' + id;
	},
	isURL : function(str) {
		if (str.length > 10 && this.find('^(http|https|mailto|ftp):\\/\\/',str))
			return true;
		else
			return false;
	},
	isNull : function(str) {
		if (str.length == 0 || str.split(' ').join('') == '')
			return true;
		else
			return false;
	},
	getSize2Short : function(in_size, per) {
		in_size = parseInt((in_size == null) ? 0 : in_size);
		if (per == null || typeof per == 'undefined')
			per = 0;
		if (in_size > 1024*1024*1024) return (in_size/ (1024*1024*1024)).toFixed(per) + " Gb";
		else if (in_size >= 1024*1024) return (in_size/ (1024*1024)).toFixed(per) + " Mb";
		else if (in_size >= 1024) return (in_size/ 1024).toFixed(per) + " Kb";
		else return in_size + " b";
	},
	browser : {
		userAgent : navigator.userAgent.toLowerCase(),
		isOpera :(navigator.userAgent.toLowerCase().indexOf('opera') != -1),
		isSafari :(navigator.userAgent.toLowerCase().indexOf('safari') != -1),
		isIE :(navigator.userAgent.toLowerCase().indexOf('msie') != -1),
		isFF:(navigator.userAgent.toLowerCase().indexOf('firefox') != -1),
		version: null,
		isMobile: null,
		isContentEditable : null,
		isFileUploadable : null
	},
	isFlashSupport : function(requiredVersion) {
		this.flashDetect.check();
		return this.flashDetect.majorAtLeast(requiredVersion);
	},
	isFileUploadable : function() {
		if (this.browser.isFileUploadable == null) {
			var checkStr = ['iphone','ipod','ipad'];
			this.browser.isFileUploadable = true;
			for(var i = 0 ; i < checkStr.length ; i++) {
				if (this.browser.userAgent.indexOf(checkStr[i]) != -1) {
					this.browser.isFileUploadable = false;
					break;
				}
			}
		}
		return this.browser.isFileUploadable;
	},
	isMobile : function() {
		if (this.browser.isMobile == null) {
			var checkStr = ['iphone','ipod','ipad','android','windows ce','blackberry','palm','mobi'];
			this.browser.isMobile = false;
			for(var i = 0 ; i < checkStr.length ; i++) {
				if (this.browser.userAgent.indexOf(checkStr[i]) != -1) {
					this.browser.isMobile = true;
					break;
				}
			}
		}
		return this.browser.isMobile;
	},
	isContentEditSupport : function() {
		return true;
	},
	isContentEditable : function(swapMode) {
		if (this.browser.isContentEditable == null) {
			if (this.isMobile()) {
				var checkStr = ['iphone','ipod','ipad'];
				this.browser.isContentEditable = false;
				for(var i = 0 ; i < checkStr.length ; i++) {
					if (this.browser.userAgent.indexOf(checkStr[i]) != -1) {
						this.browser.isContentEditable = true;
						break;
					}
				}
				if (this.browser.isContentEditable && this.getVersion() >= 5) {
					this.browser.isContentEditable = true;
				} else {
					this.browser.isContentEditable = false;
				}
			} else {
				this.browser.isContentEditable = true;
			}
		}
		return this.browser.isContentEditable && swapMode;
	},
	getVersion : function(){
		if (this.browser.version == null) {
			var str = navigator.appVersion;
			if (this.browser.isIE) {
				var bit=str.split(';');
				this.browser.version = parseFloat((bit[1].split(' '))[2]);
				if (document.documentMode) {
					this.browser.version = document.documentMode;
				} else if (document.compatMode) {
					if (document.compatMode == "CSS1Compat")
						this.browser.version = 7;
				}
				return this.browser.version;
			} else {
				var bit=str.split(' ');
				return this.browser.version = parseFloat(bit[0]);
			}
		} else 
			return this.browser.version;
	},
	getDomain : function() {
		if (this.last_domain == null)
			this.last_domain = String(document.location.href).match(/(https?:\/\/[a-z0-9_\-\.]+[:0-9]*)/i)[1];
		return this.last_domain;
	},
	toQueryString: function(hashMap) {
		var param = [];
		for(var idx in hashMap)
			param.push(idx + '=' + encodeURIComponent(hashMap[idx]));
		return param.join('&');
	},
	current_cursor : null,
	getCursor : function() {
		if (this.current_cursor == null)
			this.current_cursor = (this.browser.isIE && this.getVersion() < 9)? 'hand' : 'pointer';
		return this.current_cursor;
	},
	getRange : function(val, minval, maxval) {
		return Math.max(minval,Math.min(maxval, val));
	},
	colorTools : {
		getColor : function(color, rateHsv, moveHsv, fixHsv, opts) {
			var rgb = this.hex2rgb(color);
			var hsv = this.rgb2hsv(rgb.r, rgb.g, rgb.b);
			if (opts != null) {
				if (opts.indexOf('D') != -1) 
					hsv.v -= 5 *(opts.split('D').length -1);
				if (opts.indexOf('B') != -1) 
					hsv.v += 5 *(opts.split('B').length -1);
				if (opts.indexOf('V') != -1) {
					var vCnt = opts.split('V').length -1;
					if (hsv.v > 50)
						hsv.v -= 5 * vCnt;
					else
						hsv.v += 5 * vCnt;
				}
				if (opts.indexOf('G') != -1) 
					hsv.s = 0;
				if (opts.indexOf('R') != -1)
					hsv.v = (hsv.v > 50) ? 0 : 100;
				if (opts.indexOf('N') != -1) {
					if (hsv.s == 0) 
						hsv.v = 100 - hsv.v;
					else {
						hsv.h = (hsv.h + 180) % 360;
						var tmpS = hsv.s;
						hsv.s = hsv.v;
						hsv.v = hsv.s;
					}
				}
			}
			if (fixHsv != null) {
				if (typeof fixHsv.h == 'number') 
					hsv.h = fixHsv.h;
				if (typeof fixHsv.s == 'number') 
					hsv.s = fixHsv.s;
				if (typeof fixHsv.v == 'number') 
					hsv.v = fixHsv.v;
			}
			if (moveHsv != null) {
				if (typeof moveHsv.h == 'number') 
					hsv.h += moveHsv.h;
				if (typeof moveHsv.s == 'number') 
					hsv.s += moveHsv.s;
				if (typeof moveHsv.v == 'number') 
					hsv.v += moveHsv.v;
			}
			if (rateHsv != null) {
				if (typeof rateHsv.h == 'number') {
					rateHsv.h = Math.max(-1,Math.min(rateHsv.h, 1))
					if (rateHsv.h > 0)
						hsv.h += (360 - hsv.h) * rateHsv.h;
					else
						hsv.h += (hsv.h) * rateHsv.h;
				}
				if (typeof rateHsv.s == 'number') {
					rateHsv.s = Math.max(-1,Math.min(rateHsv.s, 1))
					if (rateHsv.s > 0)
						hsv.s += (100 - hsv.s) * rateHsv.s;
					else
						hsv.s += (hsv.s) * rateHsv.s;
				}
				if (typeof rateHsv.v == 'number') {
					rateHsv.v = Math.max(-1,Math.min(rateHsv.v, 1))
					if (rateHsv.v > 0)
						hsv.v += (100 - hsv.v) * rateHsv.v;
					else
						hsv.v += (hsv.v) * rateHsv.v;
				}
			}
			hsv.h = hsv.h % 360;
			hsv.s = Math.max(0,Math.min(hsv.s, 100));
			hsv.v = Math.max(0,Math.min(hsv.v, 100));
			rgb = this.hsv2rgb(hsv.h , hsv.s , hsv.v);
			return this.rgb2hex(rgb.r, rgb.g, rgb.b);
		},
		getMoveColor : function(color, moveHSV) {
			return this.getColor(color, null, moveHSV);
		},
		getFixColor : function(color, fixHSV) {
			return this.getColor(color, null, null, fixHSV);
		},
		getOptionColor : function(color, opt) {
			return this.getColor(color, null, null, null, opt);
		},
		hsv2hex : function(h,s,v) {
			var rgb = this.hsv2rgb(h,s,v);
			return this.rgb2hex(rgb.r,rgb.g,rgb.b);
		},
		rgb2hex : function(r, g, b) {
			r = r.toString(16); if (r.length==1) r = '0'+r;
			g = g.toString(16); if (g.length==1) g = '0'+g;
			b = b.toString(16); if (b.length==1) b = '0'+b;
			return '#' + r+g+b;
		},
		hex2rgb : function(hex) {
			hex = cafen.checkHex(hex);
			if (hex != '') {
				if (m = hex.match(/#?([0-9a-f]{6})/i))
					m = m[1];
				m = m.match(/../g);
				return {
					r : Number("0x" + m[0]),
					g : Number("0x" + m[1]),
					b : Number("0x" + m[2])
				}
			} else {
				return {
					r : Number("0xff"),
					g : Number("0xff"),
					b : Number("0xff")
				}
			}
		},
		rgb2hsv : function(r, g, b) {
			var max=Math.max(r,g,b);
			var delta=max-Math.min(r,g,b), H, S, V;
			if(max!=0) { 
				S=delta/max*100;
				if(r==max) 
					H=(g-b)/delta; 
				else if(g==max) 
					H=2+(b-r)/delta; 
				else if(b==max) 
					H=4+(r-g)/delta;
				var H=Math.min(H*60,360); 
				if(H<0) H+=360;
			}
			return {h:H?H:0,s:S?S:0,v:(max/255)*100};
		},
		hsv2rgb : function(h, s, v) {
			var R,B,G,S=s/100,V=v/100,H=h/360;
			if(S>0) { 
				if(H>=1) H=0;
				H=6*H; F=H-Math.floor(H);
				A=Math.round(255*V*(1.0-S));
				B=Math.round(255*V*(1.0-(S*F)));
				C=Math.round(255*V*(1.0-(S*(1.0-F))));
				V=Math.round(255*V); 
				switch(Math.floor(H)) {
					case 0: R=V; G=C; B=A; break;
					case 1: R=B; G=V; B=A; break;
					case 2: R=A; G=V; B=C; break;
					case 3: R=A; G=B; B=V; break;
					case 4: R=C; G=A; B=V; break;
					case 5: R=V; G=A; B=B; break;
				}
				return {r:R?R:0,g:G?G:0,b:B?B:0};
	    	} else {
	    		V=Math.round(V*255);
	    		return {r:V,g:V,b:V};
	    	}
		}
	},
	rgb2hexFF : function(value){
		if (value == null) 
			return null;
		else if (typeof value == 'number') {
			var R = value % 256;
			var G = ((value - R) % (256*256))/ 256 ;
			var B = ((value - R - G*256) % (256*256*256))/ (256*256) ;
			return this.rgb2hex(R,G,B);
		} else if (typeof value == 'string') {
			if (value.toLowerCase() == 'transparent')
				return '';
			else if (typeof value == 'string' && value.indexOf('rgb')>=0) {
				var hex="",v,h,i;
				var regexp=/([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)/;
				var h=regexp.exec(value);
				for(i=1;i<4;i++){
					v=parseInt(h[i]).toString(16);
					if(v.length==1) hex+="0"+v;
					else hex+=v;
				}
				return("#"+hex);
			} else if (value.indexOf('#') == -1 && !isNaN(parseInt(value))) {
				return this.rgb2hexFF(parseInt(value));
			} else
				return this.checkHex(value);	
		} else 
			return '';
	},
	rgb2hex : function(r, g, b) {
		r = r.toString(16); if (r.length==1) r = '0'+r;
		g = g.toString(16); if (g.length==1) g = '0'+g;
		b = b.toString(16); if (b.length==1) b = '0'+b;
		return '#' + r+g+b;
	},
	getBoolean : function(str) {
		if (typeof str == 'boolean') 
			return str;
		else if (typeof str == 'string') {
			switch(str.toLowerCase()) {
				case 'on' :
				case '1' :
				case 'true' :
					return true;
				default : 
					return false;
					break;	
			}
		} else
			return (str == null) ? false : true; 
	},
	debugConsoleID : 'cafenUtil_Console',
	debugConsoleObjects : [],
	debugMessage : function (message, debugType, mData, isForced) {
		if (this.checkDebug() || isForced) {
			var console;
			try {
				console = document.getElementById(this.debugConsoleID);
				if (!console) {
					var documentDiv = document.createElement("div");
					documentDiv.id = this.debugConsoleID+'_frm';
					var documentForm = document.createElement("form");
					document.getElementsByTagName("body")[0].appendChild(documentDiv);
					documentDiv.appendChild(documentForm);
					console = document.createElement("div");
					console.id = this.debugConsoleID;
					console.innerHTML = '<UL style="padding:0;margin:3px"></UL>';
					this.setStyle(documentForm, {margin:'0',padding:'0'});
					this.setStyle(documentDiv, {textAlign: 'left',backgroundColor :'#000000', whiteSpace : 'nowrap', border: '2px solid blue', width : '300px', padding : '5px', zIndex: '1000'});
					this.setStyle(console, {fontFamily : 'monospace', backgroundColor :'#ffffff', color:'#000000', border: '1px solid red', width : '100%', height: '230px', overflow : 'auto', margin: '0 0 5px 0',resize :'none'});
					this.setOpacity(documentDiv, 100);
					documentForm.appendChild(console);
					var command = document.createElement("input");
					command.setAttribute("type", "text");
					command.id = this.debugConsoleID+'_cmd';
					documentForm.appendChild(command)
					this.setStyle(command, {fontFamily : 'monospace', backgroundColor :'#ffffff', color:'#000000', border: '1px solid red', width : '100%', margin: '0', resize :'none'});
					documentForm.onsubmit = this.setDebugCommand;
					cafen.Event.observe(command,'keydown',this.getDebugKeyPress.bindAsEventListener(this), true);
					cafen.Event.observe(cafen.getDocument(),'keydown',this.getDebugShowHide.bindAsEventListener(this), true);
					this.setPageFixed(documentDiv,{top:'10px', left:'10px'});
					this.setDebugCommand('show all');
					this.setDebugCommand('color green');
					this.setDebugCommand('size large');
					this.setDebugCommand('jump center middle');
					this.makeScroll(console);
				}
				var messageData = null;
				if (typeof message == 'string' && (debugType == null || this.debugTraceData[debugType]))  {
						messageData = message;
				} else if (typeof message == 'object') {
					if (typeof message.getName == 'function') {
						if (this.debugTraceData[debugType])
							messageData = cafen.getDebugTabString('['+(this.debugConsoleObjects.length)+']',message.getName());
						this.debugConsoleObjects.push(message);
					} else if (debugType == null || this.debugTraceData[debugType]) {
						if (message.name && message.description)
							messageData = cafen.toString(message);
						else if (message.toString)
							messageData = message.toString();
						else
							messageData = message;
					}
				}
				if (messageData != null && messageData != '') {
					var showData = [];
					if (this.debugInfoData.showSeqn) 
						showData.push(cafen.stringUtil.strPad(this.debugInfoData.debugConsoleSeqn,5,'0',1));
					if (this.debugInfoData.showTime) {
						var currTime = null;
						try {
							currTime = cafen.dateUtil.dateFormat(new Date(), this.debugInfoData.timeFormat);
							showData.push(currTime);
						} catch(ex) {}
					}
					this.debugInfoData.debugConsoleSeqn ++;
					if (this.debugInfoData.showCallee) 
						messageData +="<br>"+cafen.getCallee().join(' &lt; ');
					if (mData != null && mData.length > 0) {
						var subData = [];
						for(var i = 0; i < mData.length; i++)
							subData.push('<li>'+mData[i]+'</li>');
						messageData += '<br><ol style="margin-bottom:7px">'+subData.join('')+'</ol>';
					}
					showData.push(messageData);
					if (showData.length > 0) {
						var lineObj = document.createElement("li");
						lineObj.innerHTML = showData.join("&nbsp; : &nbsp;");
						console.firstChild.appendChild(lineObj);
					}
					if (this.debugInfoData.autoScroll)
						console.scrollTop = console.scrollHeight - console.clientHeight;
					if (typeof console.onchange == 'function')
						console.onchange();
				}
			} catch (ex) {
				alert('Message: ' +message +" Exception: " + ex.name + " Message: " + ex.message);
			}
		}
	},
	debugTraceData : {'create' : false, 'exec' : false, 'event' : false, 'xml' : false, 'columns' : false},
	debugInfoData : {calculate : {}, show : true, autoScroll : true, debugConsoleSeqn : 1, showTime : false, showSeqn : true, keyDownSeqn : -1, showCallee : false, timeFormat :"mm/dd, HH:MM:ss.l", safeTimeFormat :"mm/dd, HH:MM:ss.l"},
	debugHistoryData : [],
	debugBreakPointData : ['_test.alert'],
	debugBreakPointCheck : function(fncName) {
		if (cafen.stringUtil.inArray(fncName, cafen.debugBreakPointData)) 
			alert('breakPoint [' +fncName.substring(1)+']\r\n\r\n' +this.getCallee(arguments.callee.caller.caller).join(' < '));
	},
	debugCmdData : {
		'clear' : 'Clear Console',
		'help' : 'Display Help',
		'open' : 'Open Console',
		'close' : 'Close Console',
		'calc' : 'show Calculate Variables or clear ex) calc [clear|variable|]',
		'calculate' : 'show Calculate Variables or clear ex) calculate [clear|variable|]',
		'goback' : 'Show/Hide Console ex) goback or ctrl + shift + D',
		'color' : 'Change Color of Console ex) color [black|white|red|green|#ff0000] -l linecolor -f fontcolor -b bordercolor -o outline',
		'alpha' : 'Change Alpha of Console ex) alpha 50%',
		'seqn' : 'Show/Hide Sequence No ex) seqn [on|off|true|false]',
		'time' : 'Show/Hide Execute Time ex) time [on|off|true|false] -f format',
		'callee' : 'Show/Hide Callee/Caller ex) callee [on|off|true|false]',
		'mouse' : 'get/stop Information of mouse clicked object ex) mouse [on|off]',
		'trace' : 'trace toggle debug infomation ex) trace [create|exec|xml]',
		'hidemark' : 'hide mark',
		'unmark' : 'hide mark alias of hidemark',
		'click' : 'send send click to object ex) click [object no]',
		'mark' : 'mark object ex) mark [object no]',
		'desc' : 'describe object ex) desc [object no]',
		'translate' : 'Translate text ex) translate -f en -t ko -q "I love you."',
		'search' : 'search web ex) search -t [vclip|image|webkr|video|news|kin] -q keyword -s [startpage] -d [display]',
		'list' : 'list created object ex) list startno-endno',
		'show' : 'show infomation ex) show [cookie|useragent|appversion|all]',
		'scroll' : 'set autoscroll mode ex) scroll [on|off]',
		'autoscroll' : 'set autoscroll mode ex) autoscroll [on|off]',
		'debug' : 'set debug mode ex) debug [on|off]',
		'move' : 'set Console position ex) move [left|right|center] [top|middle|bottom]',
		'jump' : 'set Console position ex) jump [left|right|center] [top|middle|bottom]',
		'goto' : 'set Console position ex) goto [left|right|center] [top|middle|bottom]',
		'size' : 'set Console size ex) size [small|middle|large|full]',
		'history' : 'show command history ex) history [show cnt]'
	},
	getDebugShowHide : function(event) {
		if (event.keyCode == 68 && event.shiftKey && event.ctrlKey) 
			cafen.setDebugCommand('goback');
	},
	getDebugKeyPress : function(event) {
		switch(event.keyCode) {
			case 40 :
			case 38 :
				if (event.keyCode == 38)
					cafen.debugInfoData.keyDownSeqn++;
				else
					cafen.debugInfoData.keyDownSeqn--;
				cafen.debugInfoData.keyDownSeqn = Math.min(cafen.debugHistoryData.length -1, Math.max(0,cafen.debugInfoData.keyDownSeqn));
				var cmdObj = this.getDebugObject('cmd');
				cmdObj.value = cafen.debugHistoryData[cafen.debugHistoryData.length - cafen.debugInfoData.keyDownSeqn -1];
				break;
			case 13 :
				cafen.debugInfoData.keyDownSeqn = -1;
				break;
			case 9 :
				var cmdObj = this.getDebugObject('cmd');
				var cmdValue = cmdObj.value.toLowerCase();
				if (cmdValue != '') {
					var findCmd = [];
					if (cmdValue.indexOf('!') == 0) {
						cmdValue = cmdValue.substring(1,cmdValue.length);
						for(var i = cafen.debugHistoryData.length -1; i >= 0 ; i--) {
							var currCmd = cafen.debugHistoryData[i];
							if (currCmd.indexOf(cmdValue) == 0) {
								findCmd.push(currCmd);
								break;
							}
						}
						if (findCmd.length == 1)
							cmdObj.value = findCmd[0];
					} else {
						for(var cmd in cafen.debugCmdData) {
							if (cmd.indexOf(cmdValue) == 0)
								findCmd.push(cmd);
						}
						if (findCmd.length == 1) {
							cmdObj.value = findCmd[0]+ " ";
						} else if (findCmd.length > 1) {
							var findSeqn = cmdValue.length;
							var baseCmd = findCmd[0]; 
							while(baseCmd.length >= findSeqn){
								cmdValue = baseCmd.substring(0, findSeqn);
								var findResult = true;
								for(var i = 0 ; i < findCmd.length ; i++) {
									var currCmd = findCmd[i];
									if (currCmd.indexOf(cmdValue) != 0) {
										findResult = false;
										break;
									}
								}
								if (!findResult) 
									break;	
								findSeqn++;
							}
							cmdObj.value = baseCmd.substring(0, findSeqn-1);
						}	
						if (findCmd.length > 0) {
							var showData = [];
							for(var i = 0 ; i < findCmd.length ; i++) {
								var currCmd = findCmd[i];
								showData.push(cafen.getDebugTabString(currCmd,cafen.debugCmdData[currCmd]));	
							}
							this.setDebugJoinData(showData, 'RefCommand founded '+findCmd.length);
						}
					}
				} else {
					cafen.setDebugCommand('help', true);
				}
				cafen.Event.stop(event);
				break;
			default :
				break;
		}
	},
	setDebugJoinData : function(showData, logTitle) {
		if ((logTitle != null && logTitle != '') || showData.length > 0) 
			this.debugMessage(logTitle, null, showData, true);
	},
	getDebugTabString : function(strFirst, strSecond, maxLng) {
		maxLng = maxLng || 10;
		return cafen.stringUtil.strPad(strFirst,maxLng,' ') +" : "+strSecond;
	},
	getDebugObject : function(id) {
		switch(id) {
			case 'cmd' :
				return document.getElementById(this.debugConsoleID+'_cmd');
				break;
			case 'frm' :
				return document.getElementById(this.debugConsoleID+'_frm');
				break;
			case 'console' :
			default :
				return document.getElementById(this.debugConsoleID);
				break;
		}
	},
	setDebugKeywordData : function(txt) {
		if (txt == null) {
			cafen.setDebugJoinData([], 'Search Data Recevied Failed');
		} else if (typeof txt == 'object') {
			var showData = [];
			if (txt.translation) {
				showData.push(txt.translation);
				cafen.setDebugJoinData(showData, 'Translate Data Recevied');
			} else {
				if (txt.error && txt.error.message)
					showData.push(txt.error.message);
				cafen.setDebugJoinData(showData, 'Data Call Failed');
			}
		} else if (cafen.stringUtil.isXmlString(txt)) {
			var rssObj = new cafen.xmlParser(txt);
			var contentsObj = null;
			if (contentsObj = rssObj.getNext()) {
				var showData = [];
				var item = null;
				var pageInfo = contentsObj.getJson(300);
				while(item = contentsObj.getNext()) {
					try {
						showData.push(cafen.toString(cafen.stringUtil.jsonLink(item.getJson(400),['link']), 0,2,0));
					} catch(ex) {}
				}
				if (pageInfo.total) {
					showData.push('* Total : '+pageInfo.total+' Start : '+pageInfo.start+' Display : '+pageInfo.display);
				} else if (pageInfo.totalCount) {
					showData.push('* Total : '+pageInfo.totalCount+' Display : '+pageInfo.result);
				}
				cafen.setDebugJoinData(showData, 'Search Data Recevied');
			}
		} else if (cafen.stringUtil.isJsonString(txt)) {
			var showData = [];
			var dataJson = cafen.getString2Json(txt);
			if (dataJson.channel && dataJson.channel.item) {
				var channel = dataJson.channel;
				for(var i = 0 ; i < channel.item.length; i++)
					showData.push(cafen.toString(cafen.stringUtil.jsonLink(channel.item[i],['link','cover_l_url']), 0,2,0));
				if (channel.totalCount) 
					showData.push('* Total : '+channel.totalCount+' Display : '+channel.result);
			} else {
				cafen.toStringArray(showData, dataJson, 1, 10, 300);
			}
			cafen.setDebugJoinData(showData, 'Search Data Recevied');
		} else {
			var showData = [];
			var reg = null;
			if (txt && (reg = cafen.find('<string[^>]+>(.+)<\\/string>', txt))) {
				showData.push(reg[1]);
				cafen.setDebugJoinData(showData, 'Translate Data Recevied');
			} else {
				cafen.setDebugJoinData(showData, 'Search Data Recevied Failed');
			}
		}
	},
	setDebugCmd2Jsons : function(cmd) {
		var cmds = cmd.split(' ;');
		var cmdList = [];
		for(var i = 0 ; i < cmds.length ; i++) {
			var currCmd = this.setDebugCmd2Json(cmds[i]);
			if (currCmd.cmd != null) 
				cmdList.push(currCmd);
			else if (cmds[i] != '')
				cmdList.push({cmd : this.stringUtil.trim(cmds[i])});
		}
		return cmdList;
	},
	getDebugCmd2JsonNextIndex : function(extraCmd) {
		extraCmd = this.stringUtil.trim(extraCmd);
		var firstChar = extraCmd.charAt(0);
		var endChar = (firstChar == '"' || firstChar == "'") ? firstChar+" " : " ";
		var endPos = extraCmd.indexOf(endChar);
		if (endChar != ' ' && endPos > 0) {
			while(endPos < extraCmd.length && endPos > 0) {
				if (extraCmd.charAt(endPos-1) != '\\')
					break;
				endPos = extraCmd.indexOf(endChar, endPos+1);
			}
		}
		if (endPos <= 0)
			endPos = extraCmd.length;
		return endPos;
	},
	getDebugCmd2JsonTrim : function(keyValue) {
		var subreg = null;
		if ((subreg = this.find('^"(.+)"$',keyValue, true)) || (subreg = this.find("^'(.+)'$",keyValue, true)))
			keyValue = subreg[1];
		return keyValue;
	},
	setDebugCmd2Json : function(cmd) {
		var jsonData = {org : cmd};
		cmd += ' ';
		var extraCmd = cmd;
		var reg;
		while(reg = this.find(' \\-([a-z][a-z-09]*)([ ]+)(.+)', cmd, true)) {
			var keyName = reg[1].toLowerCase();
			var endPos = cafen.getDebugCmd2JsonNextIndex(reg[3]);
			var keyValue = reg[3].substring(0,endPos);
			if (keyName != null && keyName != '') 
				jsonData[keyName] = cafen.getDebugCmd2JsonTrim(keyValue);
			extraCmd = extraCmd.substring(0,extraCmd.indexOf(reg[0])) + extraCmd.substring(extraCmd.indexOf(reg[0])+reg[1].length+2+reg[2].length+endPos ,extraCmd.length);
			cmd = cmd.substring(cmd.indexOf(reg[0])+reg[1].length+1+reg[2].length+endPos , cmd.length);
		}
		if (extraCmd != '') {
			extraCmd = cafen.stringUtil.trim(extraCmd) +" ";
			var mainCmd = null;
			var mainArgs = [];
			while(reg = this.find("(.+) ", extraCmd)) {
				var endPos = cafen.getDebugCmd2JsonNextIndex(reg[0]);
				var keyValue = extraCmd.substring(0, endPos);
				if (keyValue != '') {
					keyValue = cafen.getDebugCmd2JsonTrim(keyValue);
					if (mainCmd == null)
						mainCmd = keyValue.toLowerCase();
					else
						mainArgs.push(keyValue);
				}
				extraCmd = extraCmd.substring(endPos+1 ,extraCmd.length);
			}
			jsonData.cmd = mainCmd;
			jsonData.args = mainArgs;
		}
		return jsonData;
	},
	setDebugMouseClick : function(event) {
		var targetObj = cafen.Event.element(event);
		if (!targetObj.tagName && targetObj.parentElement)
			targetObj =targetObj.parentElement();
		var showData = [];
		for(var i = 0 ; i < this.debugConsoleObjects.length ; i++) {
			var currObj = this.debugConsoleObjects[i];
			if (currObj.getElement() == targetObj || currObj.getElement() == targetObj.parentNode)
				showData.push('['+i+"] "+currObj.getName());
		}
		this.setDebugJoinData(showData, 'Clicked Object : '+targetObj.tagName);
		this.setDebugCommand("mouse off");
		cafen.Event.stop(event);
		return false;
	},
	setDebugCommand : function(cmdStr, offHistory) {
		try {
		var cmdObj = cafen.getDebugObject('cmd');
		if (cmdObj != null) {
			if (typeof cmdStr != 'string') {
				cmdStr = cafen.stringUtil.trim(cmdObj.value);
				cmdObj.value = '';
			}
			if (cmdStr != '') {
				if (!offHistory && cmdStr != '' && cmdStr.indexOf('!') != 0 && cmdStr != cafen.debugHistoryData[cafen.debugHistoryData.length -1]) {
					cafen.debugHistoryData.push(cmdStr);
					if (cafen.debugHistoryData.length > 50)
						cafen.debugHistoryData.shift();
				}
				var jsonDatas = cafen.setDebugCmd2Jsons(cmdStr);
				var showData = [];
				for(var k = 0 ; k < jsonDatas.length; k++) {
					var jsonData = jsonDatas[k];
					var debugTitle = '';
					if (jsonData.cmd != 'grep')
						showData = [];
					switch(jsonData.cmd) {
						case 'grep' :
							var findStr = jsonData.args[0];
							if (findStr != '') {
								var newShowData = [];
								try {
									var reg = eval('/' + findStr + '/i');
									for(var i = 0 ; i < showData.length; i ++) {
										var currObjName = showData[i];
										if (currObjName.match(reg)) 
											newShowData.push(currObjName);
									}
								} catch(ex) {}
								showData = newShowData;
							} else {
								showData = [];
							}						
							if (showData.length > 0)
								debugTitle = 'Grep Result : '+ showData.length;
							else
								debugTitle = 'Grep Result : no result' + cafen.toString(jsonData);
							break;
						case '?' :		
						case 'help' :
							debugTitle = 'Help';
							for (var currCmd in cafen.debugCmdData) 
								showData.push(cafen.getDebugTabString(currCmd,cafen.debugCmdData[currCmd]));	
							break;
						case 'goback' :
							cafen.debugInfoData.show = !cafen.debugInfoData.show;
							debugTitle = 'go Background mode turn '+(cafen.debugInfoData.show ? 'On' : 'Off');
							var debugObj = cafen.getDebugObject('frm');
							if (cafen.debugInfoData.show) {
								cafen.setStyle(debugObj.parentNode, {overflow :null});
								cafen.getDebugObject('cmd').focus();
							} else {
								cafen.setStyle(debugObj.parentNode, {overflow :'hidden'});
								cafen.xAlert('To resume debug Console press <b>ctrl+shift+d</b>');
							}
							break;
						case 'breakpoint': 
							if (jsonData.args.length == 0) {
								debugTitle = 'BreakPoint List';
								cafen.toStringArray(showData, cafen.debugBreakPointData,0,2);
							} else {
								var addedCnt = [];
								for(var i = 0 ; i < jsonData.args.length ; i++) {
									var currPoint = jsonData.args[i];
									addedCnt.push(currPoint);
									cafen.debugBreakPointData.push('_'+currPoint);
								}
								debugTitle = 'BreakPoint added ';
								cafen.toStringArray(showData, addedCnt,0,2);
							}
							break;
						case 'clear' :
							var console = cafen.getDebugObject('console');
							if (console) 
								console.firstChild.innerHTML = '';
							debugTitle = 'Clear Console';
							break;
						case 'open' :
						case 'close' :
							cafen.setDebugCommand	('size '+jsonData.cmd);
							break;
						case 'now' :
							cafen.setDebugCommand	('new Date() ', true);
							break;
						case 'color' :
							var baseColor = cafen.checkHex((jsonData.args[0] || 'black').toLowerCase());
							if (baseColor != null && baseColor != '') {
								var frmObj = cafen.getDebugObject('frm');
								var console = cafen.getDebugObject('console');
								var lightBg = cafen.checkHex(jsonData.b);
								if (lightBg == '')			
									lightBg = cafen.colorTools.getOptionColor(baseColor, 'N');
								var outLineColor = cafen.checkHex(jsonData.o);
								if (outLineColor == '')
									outLineColor = cafen.colorTools.getOptionColor(lightBg, 'VVV');
								var lineColor = cafen.checkHex(jsonData.l);
								if (lineColor == '')
									lineColor = cafen.colorTools.getOptionColor(baseColor, 'VVV');
								var fontColor = cafen.checkHex(jsonData.f);
								if (fontColor == '')
									fontColor = cafen.colorTools.getOptionColor(baseColor, 'VVVVVVVVVVV');
								if (baseColor == fontColor)
									fontColor = lineColor;
								cafen.setStyle(frmObj, {backgroundColor : lightBg, borderColor : outLineColor});
								cafen.setStyle(console, {backgroundColor : baseColor, borderColor : lineColor, color : fontColor, scrollbarBaseColor : baseColor});
								cafen.setStyle(cmdObj, {backgroundColor : baseColor, borderColor : lineColor, color : fontColor});
								debugTitle = 'Change Color';
								cafen.toStringArray(showData, {bg : baseColor, line : lineColor, font :fontColor});
								if (typeof console.changeColor == 'function')
									console.changeColor();
							}
							break;
						case 'alpha' :
							var checkMode = parseInt(jsonData.args[0]);
							if (!isNaN(checkMode)) {
								checkMode = Math.min(100, Math.max(40,checkMode));
								var frmObj = cafen.getDebugObject('frm');
								cafen.setOpacity(frmObj, checkMode);
								debugTitle = 'Change Apha : '+checkMode+'%';
							}
							break;
						case 'seqn' :
							var checkMode = cafen.getBoolean(jsonData.args[0]);
							if (cafen.debugInfoData.showSeqn != checkMode) {
								cafen.debugInfoData.showSeqn = checkMode;
								debugTitle = 'Show Seqn mode turn '+(checkMode ? 'On' : 'Off');
							}
							break;
						case 'callee' :
							var checkMode = cafen.getBoolean(jsonData.args[0]);
							if (cafen.debugInfoData.showCallee != checkMode) {
								cafen.debugInfoData.showCallee = checkMode;
								debugTitle = 'Show Callee mode turn '+(checkMode ? 'On' : 'Off');
							}
							break;
						case 'time' :
							var checkMode = cafen.getBoolean(jsonData.args[0]);
							if (cafen.debugInfoData.showTime != checkMode) {
								cafen.debugInfoData.showTime = checkMode;
								debugTitle = 'Show Time mode turn '+(checkMode ? 'On' : 'Off');
							}
							if (jsonData.f != null) {
								cafen.debugInfoData.timeFormat = jsonData.f;
								try {
									showData.push("timeFormat was Changed :" +cafen.debugInfoData.timeFormat +' = ' +cafen.dateUtil.dateFormat(new Date(), cafen.debugInfoData.timeFormat));
									if (debugTitle == '')
										debugTitle = 'Show Time Format Changed';
								} catch (ex){
									cafen.debugInfoData.timeFormat = cafen.debugInfoData.safeTimeFormat;
								}
							}
							break;
						case 'mouse' :
							var checkMode = cafen.getBoolean(jsonData.args[0]);
							if (checkMode) {
								if (cafen.setDebugMouseClickBind == null)
									cafen.setDebugMouseClickBind = cafen.setDebugMouseClick.bindAsEventListener(cafen);
								if (!cafen.debugInfoData.mouseclick)
									cafen.Event.observe(document.body, "click", cafen.setDebugMouseClickBind, true);
								cafen.debugInfoData.mouseclick = true;
							} else {
								if (cafen.debugInfoData.mouseclick)
									cafen.Event.stopObserving(document.body, "click", cafen.setDebugMouseClickBind, true);
								cafen.debugInfoData.mouseclick = false;
							}
							debugTitle = 'Mouse Click turn '+(checkMode ? 'On' : 'Off');
							break;
						case 'trace' :
							switch((jsonData.args[0] || '').toLowerCase()) {
								case 'create':
								case 'exec' :
								case 'event' :
								case 'xml' :
								case 'columns' :
									cafen.debugTraceData[jsonData.args[0]] = !cafen.debugTraceData[jsonData.args[0]];
									debugTitle = 'Change Trace Mode';
									cafen.toStringArray(showData, cafen.debugTraceData);
									break;
							}
							break;
						case 'hidemark' :
						case 'unmark' :
							if (cafen.debugMarkObj != null) {
								cafen.hide(cafen.debugMarkObj);
								debugTitle = 'Mark hidden';
							}
							break;
						case 'click' :
						case 'mark' :
						case 'desc' :
							var objLength = cafen.debugConsoleObjects.length;
							var objNames = ( jsonData.args[0] || '').split('.');
							var start = cafen.stringUtil.str2int(objNames[0]);
							if (start != null && start < objLength -1) {
								var currObj = cafen.debugConsoleObjects[start];
								objNames.shift();
								if (objNames.length > 0) {
									try {
										currObj = eval("currObj."+objNames. join('.'));
									} catch(ex) {
										currObj = null;							
									}
								}
								if (currObj == null) {
									debugTitle = 'Desc Error Object not founded!';
								} else {
									if (currObj.getName) 
										debugTitle = 'Desc '+currObj.getName();
									else if (currObj.tagName)
										debugTitle = 'Desc '+typeof currObj + ' tag ' +currObj.tagName;
									else
										debugTitle = 'Desc '+typeof currObj;
									
									if (typeof currObj == 'function')
										showData.push(currObj.toString());
									else {
										switch(jsonData.cmd) {
											case 'click' :
												if (currObj.getElement)
													currObj = currObj.getElement();
												if (currObj.tagName && typeof currObj.click == 'function') {
													try {
														currObj.click();
													} catch(ex) {}
													debugTitle = 'Event Fired to Object';
												} else
													debugTitle = 'unSupported Event Object';
												break;											
											case 'mark' :
												if (currObj.getObject)
													currObj = currObj.getObject();
												if (currObj.tagName && currObj.style) {
													if (cafen.debugMarkObj == null) {
														cafen.debugMarkObj = document.createElement('DIV');
														cafen.getBody().appendChild(cafen.debugMarkObj);
														cafen.setStyle(cafen.debugMarkObj, {backgroundColor : '#ff0000', position:'absolute', zIndex : 1000, top:'0px', left : '0px'});
														cafen.setOpacity(cafen.debugMarkObj, 70);
													}
													var objSize = cafen.getSize(currObj);
													var objPos = cafen.cumulativeOffset(currObj);
													cafen.setStyle(cafen.debugMarkObj, {display : 'block',width : objSize[0]+'px', height : objSize[1]+'px', top: objPos[1]+'px', left : objPos[0]+'px'});
													debugTitle = 'Mark Object with Red';
													showData.push(cafen.toString({width : objSize[0], height : objSize[1], left : objPos[0], top : objPos[1]}));
												} else
													debugTitle = 'unMarkable Object';
												break;
											default :
												cafen.toStringArray(showData, currObj,0,2);
												break;
										}
									}
								}
							}
							break;
						case 'translate' :
							var queryData = jsonData.args[0] || jsonData.q || '';
							if (queryData == '') {
								debugTitle = 'Translate Help ex) translate -f fromlang -t tolang -q query';
								cafen.toStringArray(showData, cafenMsg.getObject('ed_translate'),0,2);
							} else {
								cafen.setDebugCommand	('search -t translate '+( jsonData.f ? ' -f '+ jsonData.f :'')+' -h '+( jsonData.t || 'en')+' -q "'+(jsonData.args[0] || jsonData.q)+'"', true);
							}
							break;
						case 'search' :
							var searchTarget = null;
							switch(jsonData.t) {
								case 'translate' :
								case 'map' :
								case 'vclip' :
								case 'image' :
								case 'webkr' :
								case 'video' :
								case 'news' :
								case 'kin' :
								case 'web' :
								case 'book' :
								case 'knowledge' :
									searchTarget = jsonData.t;
									break;
								default :
									searchTarget = 'webkr';
									break;
							}
							var keyword = jsonData.q || jsonData.args[0] || null;
							if (keyword != null) {
								switch(searchTarget) {
									case 'map' :
										if (cafen.checkAPI('GMap')) {
											var param = {
												q : keyword,
												output : 'json',
												oe:'utf8',
												hl : cafenMsg.get('com_hl'),
												sensor:'false',
												key: cafen.getAPI('GMap')
											};
											cafen.smallSWFAjax.getFlashXml(param,cafen.setDebugKeywordData.bind(cafen),'http://maps.google.com/maps/geo', true);	
										} else
											debugTitle = 'Need Google API key';
										break;
									case 'translate' :
										if (cafen.checkAPI('BING')) {
											var param = {
												text : keyword,
												from : jsonData.f || 'ko',
												to : jsonData.h || 'en',
												appId: cafen.getAPI('BING')
											};
											cafen.smallSWFAjax.getTranslate(keyword, jsonData.h || 'en', cafen.setDebugKeywordData.bind(cafen), jsonData.f);
										} else
											debugTitle = cafen.getAPIInstall("BING");
										break;
									case 'web' :
									case 'knowledge' :
									case 'book' :
									case 'vclip' :
										if (cafen.checkAPI('DAUM')) {
											var param = {
												q : keyword,
												pageno : jsonData.s || 1,
												result  :   jsonData.d || 10,
												output : 'json',
												apikey : cafen.getAPI('DAUM')
											};
											cafen.smallSWFAjax.getFlashXml(param,cafen.setDebugKeywordData.bind(cafen),'http://apis.daum.net/search/' + searchTarget, false);
										} else
											debugTitle = cafen.getAPIInstall("DAUM");
										break;
									case 'image' :
									case 'webkr' :
									case 'video' :
									case 'news' :
									case 'kin' :
										if (cafen.checkAPI('NAVER')) {
											var param = {
												query : keyword,
												target : searchTarget,
												start: jsonData.s || 1,
												display : jsonData.d || 10,
												key: cafen.getAPI('NAVER')
											};
											cafen.smallSWFAjax.getFlashXml(param,cafen.setDebugKeywordData.bind(cafen),'http://openapi.naver.com/search', false);	
										} else
											debugTitle = cafen.getAPIInstall("NAVER");
										break;
								}
							}
							break;
						case 'list' :
							var start = 0;
							var end = 0;
							var args = jsonData.args[0] || '';
							var findStr = null;
							if (args.indexOf('-') != -1) {
								var startEnd = args.split('-');
								start = cafen.stringUtil.str2int(startEnd[0] || '0') || 0;
								end = cafen.stringUtil.str2int(startEnd[1] || '0') || 0;
								if (jsonData.args[1] != null)
									findStr = jsonData.args[1];
								else
									findStr = jsonData.q;
							} else {
								start = cafen.stringUtil.str2int(jsonData.s || '0') || 0;
								end = cafen.stringUtil.str2int(jsonData.e || '0') || 0;
								findStr = (args != '') ? args : jsonData.q;
							}
							if (findStr == '')
								findStr = null;
							var objLength = cafen.debugConsoleObjects.length;
							if (objLength <= 0) {
								debugTitle = 'No List Data';
								break;	
							}
							if (end == 0)
								end =  objLength -1;
							if (start > objLength -1)
								start =  objLength -1;
							if (end > objLength -1)
								end =  objLength -1;
							if (start > end)
								end = start;
							var showData = [];
							debugTitle = 'Show List '+start +' - '+end +((findStr != null) ? '(find '+findStr+')': ' (find all)');
							
							if (findStr != null) {
								var foundCnt = 0;
								try {
									var reg = eval('/' + findStr + '/i');
									for(var i = start ; i <= end ; i++) {
										var currObj = cafen.debugConsoleObjects[i];
										var currObjName = currObj.getName();
										if (currObjName.match(reg)) {
											showData.push('['+i+"] "+currObjName);
											foundCnt++;
										}
									}
									showData.push('Founded : '+foundCnt+' '+cafen.repeat('---',10));
								} catch(ex) {}
							} else {
								for(var i = start ; i <= end ; i++) {
									var currObj = cafen.debugConsoleObjects[i];
									showData.push('['+i+"] "+currObj.getName());
								}
							}
							break;
						case 'show' :
							var cmds = jsonData.args;
							if (cmds.length == 0 || cmds[0] == 'all')
								cmds = ['cookie', 'version', 'agent', 'trace','window','body','flash'];
							debugTitle = 'Show Infomation';
							for(var i = 0 ; i < cmds.length; i++) {
								var currInfo = cmds[i] || '';
								switch(currInfo.toLowerCase()) {
									case 'window' :
										var pageSize = cafen.getPageSize();
										var objSize = {width : pageSize[0], height : pageSize[1]};
										showData.push('Window : ' +cafen.toString(objSize));
										break;
									case 'body' :
										var bodyObj = cafen.getBody();
										var pageSize = cafen.getSize(bodyObj);
										var objSize = {width : pageSize[0] , height : pageSize[1], scrollWidth : bodyObj.scrollWidth , scrollHeight : bodyObj.scrollHeight, scrollLeft : bodyObj.scrollLeft, scrollTop : bodyObj.scrollTop };
										showData.push('Body : ' +cafen.toString(objSize));
										break;
									case 'flash' :
										showData.push('Flash : ' +cafen.toString(cafen.flashDetect.getInfo()));
										break;
									case 'cookie' :
										showData.push('Cookie : ' +document.cookie);
										break;
									case 'useragent' :
									case 'agent' :
										showData.push('userAgent : ' +navigator.userAgent);
										break;
									case 'version' :
									case 'appversion' :
										showData.push('appVersion : ' +navigator.appVersion);
										break;
									case 'trace' :
										showData.push('trace :' +cafen.toString(cafen.debugTraceData));
										break;							
								}
							}
							break;
						case 'scroll' :
						case 'autoscroll' :
							var scrollMode = cafen.getBoolean(jsonData.args[0]);
							if (cafen.debugInfoData.autoScroll != scrollMode) {
								cafen.debugInfoData.autoScroll = scrollMode;
								debugTitle = 'AutoScroll mode turn '+(scrollMode ? 'On' : 'Off');
							}
							break;						
						case 'debug' :
							var debugMode = cafen.getBoolean(jsonData.args[0]);
							if (cafen.checkDebug() != debugMode) {
								cafen.checkDebug(debugMode);
								debugTitle = 'Debug mode turn '+(debugMode ? 'On' : 'Off');
							}
							break;						
						case 'move' :
						case 'jump' :
						case 'goto' :
							var cmds = jsonData.args;
							var frmObj = cafen.getDebugObject('frm');
							for(var i = 0 ; i < cmds.length; i++) {
								var currPos = cmds[i];
								switch(currPos) {
									case 'top' :
										cafen.setPageFixedPosition(frmObj, {top : '10px', bottom : null});
										break;
									case 'bottom':
										cafen.setPageFixedPosition(frmObj, {top : null, bottom : '10px'});
										break;
									case 'left':
										cafen.setPageFixedPosition(frmObj, {left : '10px', right : null});
										break;
									case 'right':
										cafen.setPageFixedPosition(frmObj, {left : null, right : '10px'});
										break;
									case 'center' :
										var pageSize = cafen.getPageSize();
										cafen.setPageFixedPosition(frmObj, {left : '50%', right : null, center: true});
										break;
									case 'middle' :
										var pageSize = cafen.getPageSize();
										var objSize = cafen.getSize(frmObj);
										cafen.setPageFixedPosition(frmObj, {top : '50%', bottom : null, center : true});
										break;
								}
							} 
							if ( jsonData.t != null || jsonData.l != null) 
								cafen.setPageFixedPosition(frmObj, {top : jsonData.t, bottom : null, left : jsonData.l, right : null, center : cafen.getBoolean( jsonData.c)});
							break;
						case 'size' :
							var cmdarg = jsonData.args[0];
							var sizeInfo = [300,250];
							switch(cmdarg) {
								case 'close' :
									if (cafen.debugInfoData.lastHeight == null) {
										cafen.debugInfoData.lastHeight = cafen.getDebugObject('frm').offsetHeight;
										sizeInfo = [null, 80];
									} else 
										sizeInfo = [null, null];
									break;
								case 'open' :
									if (cafen.debugInfoData.lastHeight != null) {
										sizeInfo = [null, cafen.debugInfoData.lastHeight];
										cafen.debugInfoData.lastHeight = null;
									} else 
										sizeInfo = [null, null];
									break;
								case 'small' :
									sizeInfo = [sizeInfo[0]/2,sizeInfo[1]/2];
									break;
								case 'middle' :
									break;
								case 'large' :
									sizeInfo = [sizeInfo[0]*1.5,sizeInfo[1]*1.5];
									break;
								case 'full' :
									var winSize = cafen.getPageSize(null);
									sizeInfo = [(winSize[0] - 30) ,(winSize[1] - 30)];
									break;
								default :
									sizeInfo = [null, null];
									if (jsonData.w != null)
										sizeInfo[0] = parseInt(jsonData.w);
									if (jsonData.h != null)
										sizeInfo[1] = parseInt(jsonData.h);
									break;
							}
							if (sizeInfo[0] != null || sizeInfo[1] != null) {
								var frmObj = cafen.getDebugObject('frm');
								var consoleObj = cafen.getDebugObject('console');
								if (sizeInfo[0] > 10) {
									cafen.setStyle(frmObj, {width : sizeInfo[0] +'px'});
									cafen.setStyle(consoleObj, {width : (sizeInfo[0] -5) +'px'});
									cafen.setStyle(cmdObj, {width : (sizeInfo[0]-5) +'px'});
								}
								if (sizeInfo[1] > 40) {
									cafen.setStyle(consoleObj, {height : (sizeInfo[1] - 30)+'px'});
								}
								debugTitle = 'Change Console Size : '+(sizeInfo[0] || '-') +'px X '+(sizeInfo[1] || '-')+'px';
								cafen.setPageFixedPosition(frmObj);
							}
							break;
						case 'history' :
							debugTitle = 'Command History '+cafen.debugHistoryData.length;
							var findStr = jsonData.args[0] || '';
							var stopLine = 0;
							var reg = null;
							if (reg = cafen.find("^([0-9]+)",findStr)) {
								stopLine = Math.max(0, cafen.debugHistoryData.length - parseInt(reg[1]));
								findStr = null;
							}
							if (findStr != null && findStr !='') {
								var foundCnt = 0;
								try {
									var reg = eval('/' + findStr + '/i');
									for(var i = cafen.debugHistoryData.length -1 ; i >= stopLine ; i--) {
										var currObjName = cafen.debugHistoryData[i];
										if (currObjName.match(reg)) {
											showData.push('['+(cafen.debugHistoryData.length -i - 1)+"] "+currObjName);
											foundCnt++;
										}
									}
									showData.push('Founded : '+foundCnt+' '+cafen.repeat('---',10));
								} catch(ex) {}
							} else {
								for(var i = cafen.debugHistoryData.length -1 ; i >= stopLine ; i--) {
									var currObjName = cafen.debugHistoryData[i];
									showData.push('['+(cafen.debugHistoryData.length -i - 1)+"] "+currObjName);
								}
							}
							break;
						case 'calc' :
						case 'calculate' :
							debugTitle = 'Calculate';
							var subCmd = jsonData.args[0] || '';
							switch(subCmd.toLowerCase()) {
								case 'clear' :
									debugTitle = 'Calculate Variables Cleared';
									cafen.debugInfoData.calculate = {}
									break;	
								default :
									debugTitle = 'Calculate Variables';
									if (subCmd != '') 
										showData.push(' '+subCmd+' = '+cafen.toString(cafen.debugInfoData.calculate[subCmd]));
									else
										cafen.toStringArray(showData,cafen.debugInfoData.calculate);
									break;
							}
							break;
						default :
							var evalCmdStr = cafen.stringUtil.trim(jsonData.org);
							if (evalCmdStr.indexOf('!') == 0) {
								var reg = null;
								var stopLine = 0;
								if (reg = cafen.find('!([a-z][0-9a-z]*)',evalCmdStr, true)) {
									var reg2 = eval('/^' + reg[1] + '/i');
									for(var i = cafen.debugHistoryData.length -1 ; i >= 0 ; i--) {
										var currObjName = cafen.debugHistoryData[i];
										if (currObjName.match(reg2)) {
											stopLine = i;
											break;
										}
									}
								} else if (reg = cafen.find('!([0-9]+)',evalCmdStr, true)) {
									stopLine = cafen.debugHistoryData.length - parseInt(reg[1]) - 1;
								} else if (reg = cafen.find('!!',evalCmdStr, true)) {
									stopLine = cafen.debugHistoryData.length -1;
								}
								stopLine = Math.min(cafen.debugHistoryData.length -1,Math.max(0, stopLine));
								var cmdValue = cafen.debugHistoryData[stopLine];
								if (cmdValue != null && cmdValue != '') {
									cafen.setDebugCommand(cmdValue, true);
									cmdObj.value = cmdValue;
								}
							} else {
								var variName = '';
								if (evalCmdStr.indexOf('=') > 0) {
									variName = cafen.stringUtil.trim(evalCmdStr.substring(0, evalCmdStr.indexOf('=')));
									evalCmdStr = evalCmdStr.substring(evalCmdStr.indexOf('=')+1, evalCmdStr.length);
									if (!cafen.find("^[a-z][a-z0-9_]+$", variName)) {
										if (evalCmdStr == '') {
											evalCmdStr = variName;
											variName = '';
										} else
											variName = '';
									}
								}
								var evalResult = cafen.getString2Json(evalCmdStr, cafen.debugInfoData.calculate);
								debugTitle = evalCmdStr +' = ' + evalResult;
								if (evalResult != null && variName != '') {
									cafen.debugInfoData.calculate[variName] = evalResult;
									showData.push(variName +' = '+cafen.toString(evalResult));
								}
							}
							break;
					}
					if (showData.length > 0 || debugTitle !='') 
						cafen.setDebugJoinData(showData, debugTitle);
				}
			}
		}
		} catch(ex) { 
			alert("Exception: " + ex.name + " Message: " + ex.message);
		}
		return false;
	},
	setDebug : function(debug_mode) {
		if (debug_mode) {
			cafen.checkDebug(true);
			this.debugMessage('Debug Start (outmind@nate.com)');
		} else {
			cafen.checkDebug(false);
		}
		return ;
	},
/**
 * 특정 노드에서 첫번째 Child 노드 가져오기
 * @param {object} root 대상 노드
 * @param {object} node 대상 노드
 * @param {object} err_node null 시 가져올 노드
 * @return {object} child Node
 */
	getFirstChildNode : function(root, node, err_node) {
		var tmp_node = this.getChildrenByTagName(root, node);
		return (tmp_node !=null && tmp_node.firstChild) ? tmp_node.firstChild.nodeValue : err_node;
	},
/**
 * 특정 Node 에서 특정 태그를 가진 Child 가져오기
 * @param {object} node 대상 node
 * @param {string} tagName 태그 명
 * @return {array} Array(ChildNodes)
 */
	getChildrensByTagName : function (node, tagName) {
		var ln = node.childNodes.length;
		var arr = [];	
		for (var z=0; z<ln; z++) {
			if (node.childNodes[z].nodeName==tagName) arr.push(node.childNodes[z]);
		}
		return arr;
	},
/**
 * 특정 Node 에서 특정 태그를 가진 첫번째 Child 가져오기 
 * @param {object} node 대상 node
 * @param {string} tagName 태그 명
 * @return {object} ChildNode
 */
	getChildrenByTagName : function (node, tagName) {
		var arr = this.getChildrensByTagName(node, tagName);
		return (arr.length > 0)?arr[0]:null;
	},
	stripTags: function(str) {
		return (str || '').replace(/&gt;/gi, '>').replace(/&lt;/gi, '<').replace(/&nbsp;/gi, ' ').replace(/<\/?[^>]+>/gi, '');
	},
/**
 * Html 을 읽기 쉬운 형태로 변환
 * @param {object} html 대상 문자
 * @return {string} 변환된 문자
 */
	html2Source : function(html) {
		html = html.replace(/\n|\r/gi, '');
		html = html.replace(/<BR>/gi, '<br>\r\n');
		html = html.replace(/<\/TD>/gi, '</td>\r\n');
		html = html.replace(/<\/TABLE>/gi, '</table>\r\n');
		html = html.replace(/<\/TR>/gi, '</tr>\r\n');
		html = html.replace(/<\/P>/gi, '</P>\r\n');
		return html;		
	},
	html2Text : function(html) {
		html = html.replace(/\r|\n/gi, '');
		html = html.replace(/<hr\/?>/gi, '\r\n');
		html = html.replace(/<br\/?>/gi, '\r\n');
		html = html.replace(/<p\/?>/gi, '\r\n');
		html = html.replace(/<\/td>/gi, '</td>\r\n');
		html = html.replace(/&nbsp;/gi, ' ');
		html = html.replace(/<\/?[^>]+>/gi, '');
		html = html.replace(/&lt;/gi, '<');
		html = html.replace(/&gt;/gi, '>');
		return cafen.stringUtil.trim(html);
	},
	text2Html : function(txt, donotconv_special, donotconv_enter) {
		if (!donotconv_special) {
			txt = txt.replace(/</gi, '&lt;');
			txt = txt.replace(/>/gi, '&gt;');
		}
		if (!donotconv_enter) {
			txt = txt.replace(/\r/g, '');
			txt = txt.replace(/\n/g, '<br>');
		}
		return txt;
	},
	longCut : function(txt, len) {
		if (len > 0) {
			txt = cafen.stripTags(txt).replace(/\r|\n/gi, ' ').replace(/[ ][ ]+/gi, ' ');
			if (txt != null && txt.length > len) {
				return txt.substring(0, len) + '...';
			}else
				return txt || '';
		} else
			return txt;
	},
	getImage : function(options, instyle) {
		var obj = this.extend(document.createElement('img'), this.extend({vspace : 0,hspace:0,border:0},options));
		var outstyle = this.extend({
			margin : '3px',
			border : '0'
		}, instyle);
		this.setStyle(obj, outstyle);
		return obj;
	},
	setAttribute: function(element, attrs) {
		element = this.$(element);
		try {
			for (var name in attrs) {
				switch(name) {
					case 'innerHTML' :
						element.innerHTML = attrs[name];
						break;
					case 'class' :
					case 'className' :
				 		element.className  = attrs[name];
						break;
					default :
				 		element.setAttribute(name, attrs[name]);
				 		break;
				}
			}
		} catch(ex) {}
	},
	setStyle: function(element, cssstyle) {
		element = this.$(element);
		if (!element)
			return ;
		if (element.setStyle) {
			element.setStyle(cssstyle);
		} else {
			for (var name in cssstyle) {
				var value = cssstyle[name];
				if (value == null)
					value = '';
				switch(name) {
					case 'alpha' :
						if (this.browser.isIE) 
							this.setStyle(element, {filter:"alpha(opacity = "+value+")"});
						else 
							this.setStyle(element, {opacity : parseInt(value)/100});
						break;
					case 'scrollbarBaseColor' :
						if (this.browser.isIE) 
							element.style[name] = value;
						else {
							var attrs = {};
							attrs[name] = value;
							this.setAttribute(element, attrs);
						}
						break;
					case 'float' :
					case 'cssFloat' :
					case 'styleFloat' :
						if (this.browser.isIE) 
							element.style['styleFloat'] = value;
						else
							element.style['cssFloat'] = value;
						break;
					default :
						try {					
						  element.style[this.camelize(name)] = value;
						 } catch(ex) {}
						break;
				}
			}
		}
	},
	setOpacity: function(element, opa) {
		element = this.$(element);
		if (this.browser.isIE) 
			this.setStyle(element,{filter:"alpha(opacity = "+opa+")"});
		else 
			this.setStyle(element, {opacity : opa/100});
	},
	getAttribute : function(element, attrName) {
		if (element.getAttribute)
			return element.getAttribute(attrName);
		else
			return '';
	},
	getStyle : function(element, styleName, doc) {
		if (element == null)
			return null;
		styleName = (styleName == 'float') ? 'cssFloat' : this.camelize(styleName);
		var value = element.style[styleName];
		if (value == null || value == '') {
			if (element.currentStyle) {
				value = element.currentStyle[styleName];
			} else if (window.getComputedStyle) {
				value = (doc || document).defaultView.getComputedStyle(element,null).getPropertyValue(styleName);
			}
		}
		switch(styleName) {
			case 'opacity' :
				return value ? parseFloat(value) : 1.0;
				break;
			case 'overflowX' :
			case 'overflowY' :
				return value ? value : this.getStyle(element, 'overflow', doc);
				break;
			case 'overflow' :
				return value ? value : 'auto';
				break;
			case 'marginTop' :
			case 'marginLeft' :
			case 'marginRight' :
			case 'marginBottom' :
				return value ? value : this.getStyle(element, 'margin', doc);
				break;
			case 'color' :
			case 'borderColor' :
			case 'backgoundColor' :
				if (value == 'inherit' || value == 'transparent' || value == null)
					value = '';
			case 'scrollbarBaseColor' :
				if (value == '' && element.parentNode && element.parentNode.style)
					return this.rgb2hexFF(this.getStyle(element.parentNode, styleName, doc));
				else
					return this.rgb2hexFF(value);
				break;
			default :
				return (!value) ? '' : value;
				break;
		}
	},
	_isPngAlphaSupport : null,
	isPngAlphaSupport : function() {
		if (this._isPngAlphaSupport != null)
			return this._isPngAlphaSupport;
		else {
			if (navigator.userAgent.indexOf('MSIE') > 0) {
				var ie_version = parseFloat(navigator.userAgent.substring(navigator.userAgent.indexOf('MSIE') + 5, navigator.userAgent.indexOf('MSIE') + 8));
				if (ie_version < 7.0) 
					this._isPngAlphaSupport = false
				else
					this._isPngAlphaSupport = true;
			} else
				this._isPngAlphaSupport = true;
			return this._isPngAlphaSupport;
		}
 	},
	_popupObj : {},
	getPopup : function(popArea) {
		popArea = popArea || '';
		if (this._popupObj[popArea])
			return this._popupObj[popArea];
		else {
			var useArea = (popArea != '') ? this.$(popArea) : null;
			if (useArea != null) {
				this._popupObj[popArea] = useArea;
				useArea.style.position = 'absolute';
				useArea.style.left = '0px';
				useArea.style.top = '0px';
				useArea.style.lineHeight = '1px';
				useArea.style.fontSize = '1px';
				useArea.style.zIndex = '10';
			} else {
				useArea = document.createElement("div");
				this._popupObj[popArea] = useArea;
				useArea.style.position = 'absolute';
				useArea.style.left = '0px';
				useArea.style.top = '0px';
				useArea.style.lineHeight = '1px';
				useArea.style.fontSize = '1px';
				useArea.style.zIndex = '10';
				var doc_area = document.getElementsByTagName("body")[0];
				try {
				doc_area.insertBefore(useArea, doc_area.lastChild);
				} catch(ex) {
					doc_area.appendChild(useArea);
				}
			}
			return this._popupObj[popArea];
		}
	},
	getChildObject : function(options) {
		var imgNode = null;
		var textNode = null;
		var childNodes = [];
		if (options == null)
			return childNodes;
		else if (options.src !=null && options.src != '') 
			imgNode = new cafen.Image(options.src, {attribute : {align:'absmiddle', hspace : '0', vspace : '0'}});
		else if (options.icon !=null) 
			imgNode = new cafen.XImage(options.icon);
		if (options.text != null && options.text != '') {
			var textNode = document.createElement('span');
			if (options.shortkey != null) 
				textNode.innerHTML = options.text +'(<u class="shortcut">'+options.shortkey+'</u>)';
			else
				textNode.innerHTML = options.text;
		}
		if (imgNode != null && textNode != null) {
			var img_align = (options.align) ?  options.align.toLowerCase() : '';
			var tableChild = new cafen.TableAuto();
			childNodes.push(tableChild);
			switch(img_align) {
				case 'top' :
					tableChild.addRow();
					tableChild.addCell(imgNode);
					tableChild.addRow();
					tableChild.addCell(textNode);
					break;
				case 'bottom' :
					tableChild.addRow();
					tableChild.addCell(textNode);
					tableChild.addRow();
					tableChild.addCell(imgNode);
					break;
				case 'right' :
					tableChild.addRow();
					tableChild.addCell(textNode);
					tableChild.addCell(imgNode);
					break;
				default :
					tableChild.addRow();
					tableChild.addCell(imgNode);
					tableChild.addCell(textNode);
					break;
			}
		} else if (imgNode != null)
			childNodes.push(imgNode);
		else if (textNode != null)
			childNodes.push(textNode);
		return childNodes;
	},
	_msgObj : null,
	_msgCloseBind : null,
	showMsg : function(msg) {
		if (this._msgObj == null) {
			this._msgObj = new cafen.Div({className : 'r_btnskin', tplName :'top',shadow : true, style :{position:'absolute', width : '230px', height : 'auto', overflowX :'hidden',overflowY : 'hidden', padding:'5px', border : '1px dotted #d0d0d0', backgroundColor : '#e0e0e0',margin:'3px'}});
			this.getPopup().appendChild(this._msgObj.getObject());
			this._msgObj.appendChild(new cafen.Div({attribute : {innerHTML : '<b>Result Message</b>'}, style: {paddingLeft:'10px'}}),'top');
		}
		this._msgObj.show();
		this._msgObj.center();
		this._msgObj.getElement().innerHTML = msg;	
		if (	this._msgCloseBind != null)
			window.clearTimeout(this._msgCloseBind);	
		this._msgCloseBind = window.setTimeout(this.closeMsg.bind(this), 3000);
	},
	closeMsg : function() {
		this._msgObj.hide();
		this._msgCloseBind = null;
	},
	getImgeTag : function(src, tags) {
		if (/png$/.test(src) && this.browser.isIE && this.getVersion() < 7) {
			return '<img src='+src+' '+tags+' style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='+ src+',sizingMethod=image);">';
		} else { 
			return '<img src="'+src + '" '+tags+'>';
		}
	},
	camelize: function(str) {
		var oStringList = str.split('-');
		if (oStringList.length == 1) return oStringList[0];
		var camelizedString = str.indexOf('-') == 0 ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) : oStringList[0];
		for (var i = 1, len = oStringList.length; i < len; i++) {
			var s = oStringList[i];
			camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
		}
		return camelizedString;
	},
	pointerX: function(event) {
		if (event == null)
			event = window.event;
		return event.pageX || (event.clientX +
		(document.documentElement.scrollLeft || document.body.scrollLeft));
	},
	pointerY: function(event) {
		if (event == null)
			event = window.event;
		return event.pageY || (event.clientY +
		(document.documentElement.scrollTop || document.body.scrollTop));
	},
	pointer: function(event) {
		if (event == null)
			event = window.event;
		return [this.pointerX(event), this.pointerY(event)];
	},
	cumulativeOffset: function(_element, _stopElement) {
		_element = this.$(_element);
		_stopElement = _stopElement || document.documentElement || document.body;
		var valueT = 0, valueL = 0, fixed = false;
		do {
			valueT += _element.offsetTop || 0;
			valueL += _element.offsetLeft || 0;
			if (this.getStyle(_element, 'position') == 'fixed') {
				fixed = true;
				break;
			}
			_element = _element.offsetParent;
		} while (_element && _element != _stopElement);
		return [valueL, valueT, fixed];
	},
	cumulativeScrollOffset: function(element) {
		var valueT = 0, valueL = 0;
		do {
			valueT += element.scrollTop  || 0;
			valueL += element.scrollLeft || 0;
			element = element.parentNode;
		} while (element);
		return [valueL, valueT];
	},
	_fixedArea : null,
	_fixedAreaSize : [0,0],
	setPageFixedSize : function() {
		if (this._fixedArea != null) {
			var newAreaSize = cafen.getPageSize();
			this._fixedAreaSize = newAreaSize;
			var popupNodes = this._fixedArea.childNodes;
			for(var i = 0 ; i < popupNodes.length ; i++) {
				var currPop = popupNodes[i];
				var currStyle = {
					left : cafen.getAttribute(currPop,'fixedStyleLeft'),
					right : cafen.getAttribute(currPop,'fixedStyleRight'),
					top : cafen.getAttribute(currPop,'fixedStyleTop'),
					bottom : cafen.getAttribute(currPop,'fixedStyleBottom')
				};
				var newStyle = {}
				if (currStyle.right != null && currStyle.right != '') 
					newStyle.right = this.getPageFixedSizeRightBottom(currStyle.right, this._fixedAreaSize[0]) +'px';					
				if (currStyle.left != null && currStyle.left != '') 
					newStyle.left = this.getPageFixedSizeLeftTop(currStyle.left, this._fixedAreaSize[0]) +'px';
				if (currStyle.bottom != null && currStyle.bottom != '') 
					newStyle.bottom = this.getPageFixedSizeRightBottom(currStyle.bottom, this._fixedAreaSize[1]) +'px';					
				if (currStyle.top != null && currStyle.top != '') 
					newStyle.top = this.getPageFixedSizeLeftTop(currStyle.top, this._fixedAreaSize[1]) +'px';
				cafen.setStyle(currPop, newStyle);
			}
		}
	},
	setPageFixedScroll : function() {
		if (this._fixedArea != null) {
			var scrollVal = cafen.getPageScroll();
			this.setStyle(this._fixedArea, {top: scrollVal[1]+'px', left: scrollVal[0]+'px'});
		}
	},
	setPageFixed : function(element, stylePos) {
		if (this._fixedArea  == null) {
			this._fixedArea = document.createElement('div');
			this.getBody().appendChild(this._fixedArea);
			this.setStyle(this._fixedArea, {top: '0px', left : '0px', width : '1px', height : '1px', position:'absolute', zIndex:'100'});
			if (!this.isSupportFixed()) 
				cafen.Event.observe(this.getWindow(), "scroll", this.setPageFixedScroll.bind(this), false);
			cafen.Event.observe(this.getWindow(), "resize", this.setPageFixedSize.bind(this), false);
			this.setPageFixedSize();
			this.setPageFixedScroll();
		}
		if (!element.parentNode || !element.parentNode.parentNode || element.parentNode.parentNode !=  this._fixedArea) {
			var tmpDiv = document.createElement('div');
			this.setStyle(tmpDiv, {position: this.isSupportFixed() ? 'fixed' : 'absolute', left : '0', top: '0', width:'1px', height : '1px'});
			tmpDiv.appendChild(element);
			this._fixedArea.appendChild(tmpDiv);
		}
		this.setStyle(element, {position : 'absolute', top:'0', left:'0'});
		if (stylePos != null)
			this.setPageFixedPosition(element,stylePos);
	},
	setPageFixedPosition : function(element, stylePos) {
		element = this.$(element);
		if (!element.parentNode || !element.parentNode.parentNode || element.parentNode.parentNode !=  this._fixedArea) {
			return ;	
		}
		var parentStyle = {};
		var selfStyle = {};
		stylePos = stylePos || { left : cafen.getAttribute(element.parentNode,'fixedStyleLeft'), right : cafen.getAttribute(element.parentNode,'fixedStyleRight'),top : cafen.getAttribute(element.parentNode,'fixedStyleTop'),bottom : cafen.getAttribute(element.parentNode,'fixedStyleBottom'), center : cafen.getAttribute(element.parentNode, 'fixedStyleCenter') == "true" ? true : false};
		if (stylePos.left != null && stylePos.left != '') {
			parentStyle.left = stylePos.left;
			parentStyle.right = '';
			selfStyle.left = '0';
			selfStyle.right = '';
		} else if (stylePos.right != null && stylePos.right != '') {
			parentStyle.left = '';
			parentStyle.right = stylePos.right;
			selfStyle.left = '';
			selfStyle.right = '0';
		}
		if (stylePos.top != null && stylePos.top != '') {
			parentStyle.top = stylePos.top;
			parentStyle.bottom = '';
			selfStyle.top = '0';
			selfStyle.bottom = '';
		} else if (stylePos.bottom != null && stylePos.bottom != '') {
			parentStyle.top = '';
			parentStyle.bottom = stylePos.bottom;
			selfStyle.top = '';
			selfStyle.bottom = '0';
		}
		if (stylePos.center) {
			var objSize = cafen.getSize(element);
			if (selfStyle.left != null && selfStyle.left != '')
				selfStyle.left = Math.round(objSize[0]/2)*(-1)+'px';
			else if (selfStyle.right != null && selfStyle.right != '')
				selfStyle.right = Math.round(objSize[0]/2)*(-1)+'px';
			if (selfStyle.top != null && selfStyle.top != '')
				selfStyle.top = Math.round(objSize[1]/2)*(-1)+'px';
			else if (selfStyle.bottom != null && selfStyle.bottom != '')
				selfStyle.bottom = Math.round(objSize[1]/2)*(-1)+'px';
			cafen.setStyle(element, selfStyle);
			cafen.setAttribute(element.parentNode, {fixedStyleCenter : "true"});
		} else {
			cafen.setStyle(element, selfStyle);
			cafen.setAttribute(element.parentNode, {fixedStyleCenter : "false"});
		}
		if (parentStyle.bottom != null && parentStyle.bottom != '') {
			cafen.setAttribute(element.parentNode, {fixedStyleBottom : parentStyle.bottom, fixedStyleTop : ""});
			parentStyle.bottom = this.getPageFixedSizeRightBottom(parentStyle.bottom, this._fixedAreaSize[1]) +'px';
		} else if (parentStyle.top != null && parentStyle.top != '') {
			cafen.setAttribute(element.parentNode, {fixedStyleTop : parentStyle.top, fixedStyleBottom : ""});
			parentStyle.top = this.getPageFixedSizeLeftTop(parentStyle.top, this._fixedAreaSize[1]) +'px';
		}
		if (parentStyle.right != null && parentStyle.right != '') {
			cafen.setAttribute(element.parentNode, {fixedStyleRight : parentStyle.right, fixedStyleLeft : ""});
			parentStyle.right = this.getPageFixedSizeRightBottom(parentStyle.right, this._fixedAreaSize[0]) +'px';
		} else if (parentStyle.left != null &&  parentStyle.left != '') {
			cafen.setAttribute(element.parentNode, {fixedStyleLeft : parentStyle.left, fixedStyleRight : ""});
			parentStyle.left = this.getPageFixedSizeLeftTop(parentStyle.left, this._fixedAreaSize[0]) +'px';
		}
		cafen.setStyle(element.parentNode, parentStyle);
	},
	getPageFixedSizeLeftTop : function(posSize, baseSize) {
		if (posSize.indexOf('%') > 0) {
			return Math.round(baseSize * parseInt(posSize)/100); 
		} else {
			return parseInt(posSize);
		}
	},
	getPageFixedSizeRightBottom : function(posSize, baseSize) {
		if (!this.isSupportFixed()) {
			if (posSize.indexOf('%') > 0) {
				return Math.round(baseSize * parseInt(posSize)/100 - baseSize); 
			} else {
				return parseInt(posSize) - baseSize;
			}
		} else {
			if (posSize.indexOf('%') > 0) {
				return Math.round(baseSize * parseInt(posSize)/100); 
			} else {
				return parseInt(posSize);
			}
		}
	},
	_supportFixed : null,
	isSupportFixed : function() {
		if (this._supportFixed == null) {
			this._supportFixed = false;
			if (!cafen.browser.isIE) 
				this._supportFixed = true;
			else if (cafen.getVersion() <= 7)
				this._supportFixed = false;
			else 
				this._supportFixed = true;
		}
		return this._supportFixed;
	},
	isFixedObject : function(forElement) {
		if (cafenGlobalConf.donotUseFixPop)
			return false;
		if (this.isSupportFixed()) {
			if (forElement == null)
				return true; 
			var element = forElement;
			do {
				if (this.getStyle(element, 'position') == 'fixed') 
					return true;
			} while (element = element.offsetParent);
			return false;
		} else {
			return false;	
		}
	},
	viewportOffset : function(forElement) {
		var valueT = 0, valueL = 0;
		var element = forElement;
		do {
			valueT += element.offsetTop  || 0;
			valueL += element.offsetLeft || 0;
			if (element.offsetParent == document.body && this.getStyle(element, 'position') == 'absolute') break;
		} while (element = element.offsetParent);
		element = forElement;
		do {
			if (!this.browser.isOpera && element.tagName != 'BODY') {
				valueT -= element.scrollTop  || 0;
				valueL -= element.scrollLeft || 0;
			}
		} while (element = element.parentNode);
		return [valueL, valueT];
	},
	getPageScroll : function(popArea) {
		var xScroll, yScroll, tarElement;
		tarElement = cafen.getPopup(popArea).parentNode;
		if (tarElement == null)
			tarElement = self;
		else if (tarElement.tagName == 'BODY') 
			tarElement = document.documentElement ? document.documentElement : document.body ;
		if (tarElement && tarElement.pageYOffset) {
			yScroll = tarElement.pageYOffset;
			xScroll = tarElement.pageXOffset;
		} else if (tarElement && window.pageYOffset) {
			yScroll = window.pageYOffset;
			xScroll = window.pageXOffset;
		} else if (tarElement && tarElement.scrollTop) {	 // Explorer 6 Strict
			yScroll = tarElement.scrollTop;
			xScroll = tarElement.scrollLeft;
		} else if (document.body) {// all other Explorers
			yScroll = document.body.scrollTop;
			xScroll = document.body.scrollLeft;	
		}
		return [xScroll,yScroll] 
	},
	// Adapted from getPageSize() by quirksmode.com
	getPageSize : function(popArea, tarElement) {
		var windowHeight,  windowWidth;
		tarElement = tarElement || cafen.getPopup(popArea).parentNode;
		if (tarElement == null) {
			tarElement = this.getBody();
		} else if (tarElement.tagName == 'BODY') 
			tarElement = document.documentElement ? document.documentElement : document.body ;
		if (window.innerHeight && tarElement.offsetWidth) {	// all except Explorer
			windowHeight = Math.min(window.innerHeight, tarElement.offsetHeight);
			windowWidth = Math.min(window.innerWidth, tarElement.offsetWidth);
		} else if (window.innerHeight) {	// all except Explorer
			windowHeight = window.innerHeight;
			windowWidth = window.innerWidth;
		} else if (tarElement && tarElement.clientHeight) { // Explorer 6 Strict Mode
			windowHeight = tarElement.clientHeight;
			windowWidth = tarElement.clientWidth;
		} else if (tarElement && window.innerHeight) {	// all except Explorer
			windowHeight = window.innerHeight;
			windowWidth = window.innerWidth;
		} else if (document.body) { // other Explorers
			windowHeight = document.body.clientHeight;
			windowWidth = document.body.clientWidth;
		}	
		return [windowWidth, windowHeight]
	},
	getSize : function(_element) {
		_element = this.$(_element);
		var w = (_element.offsetWidth || parseInt(_element.style.width));
		var h = (_element.offsetHeight || parseInt(_element.style.height));
		return [w, h];
	},
	positionedOffset: function(_element) {
		var valueT = 0, valueL = 0;
		do {
			valueT += _element.offsetTop  || 0;
			valueL += _element.offsetLeft || 0;
			_element = _element.offsetParent;
			if (_element) {
				var p = this.getStyle(_element, 'position');
				if (p == 'relative' || p == 'absolute') break;
			}
		} while (_element);
		return [valueL, valueT];
	},
	_mouse_init : [0,0],
	_zoomObjInit : [0,0],
	_zoomObjZoomInit : 1,
	_zoomObjSizeInit : [0,0],
	_zoomObj : [null, null],
	_docZoomStopEvent : null,
	_docZoomMoveEvent : null,
	_docZoomUpEvent : null,
	_isOnZooming : false,
	startZoom : function(event,pointobj, stopEvent) {
		if (this._isOnZooming)
			this.stopZoom();
		var targetobj = pointobj;
		this._mouse_init = this.pointer(event);
		this._zoomObj = [pointobj,targetobj];	
		this._zoomObjZoomInit = targetobj.getStyle('zoom');
		if (this._zoomObjZoomInit == 'normal')
			this._zoomObjZoomInit = 1;
		this._zoomObjInit = targetobj.getOffset();
		this._zoomObjSizeInit = targetobj.getSize();
		this._docZoomStopEvent = stopEvent;
		if (this._docZoomMoveEvent == null)
			this._docZoomMoveEvent =  this.moveZoom.bindAsEventListener(this);
		if (this._docZoomUpEvent == null) 
			this._docZoomUpEvent =  this.stopZoom.bindAsEventListener(this);
		cafen.Event.observe(document.body, "mousemove", this._docZoomMoveEvent, true);
		cafen.Event.observe(document.body, "mouseup", this._docZoomUpEvent, true);
		cafen.Event.observe(this._zoomObj[1].getElement(), "mouseup", this._docZoomUpEvent, true);
		this._isOnZooming = true;
		this.Event.stop(event);
	},
	moveZoom : function(event) {
		var pos = this.pointer(event);
		if (pos[0] < 0 || pos[1] < 0 || pos[0] > document.body.offsetWidth) {
			this.stopZoom(event);
			return ;	
		}
		var moveX = pos[0] - this._mouse_init[0];
		var moveY = pos[1] - this._mouse_init[1];
		var moveD = Math.sqrt(Math.pow(moveX,2) + Math.pow(moveY,2));
		if (moveD > 100) {
			var zoomLevel = moveD/100;
			var fixedZoom = 1;
			if (moveX > 0) { // zoom out
				fixedZoom = this._zoomObjZoomInit * zoomLevel;
			} else { // zoom in
				fixedZoom = this._zoomObjZoomInit / zoomLevel;
			}
			if (fixedZoom <= 2) {
				var objoffsetLeft = parseInt((this._zoomObjSizeInit[0] - this._zoomObjSizeInit[0] * fixedZoom)/2);
				var objoffsetTop = parseInt((this._zoomObjSizeInit[1] - this._zoomObjSizeInit[1] * fixedZoom)/2);
				this._zoomObj[1].setStyle({zoom : fixedZoom , left : objoffsetLeft +'px', top : objoffsetTop +'px'});
			}
		}
		this.Event.stop(event);
		
		return false;
	},
	stopZoom : function(event) {
		cafen.Event.stopObserving(document.body, "mousemove", this._docZoomMoveEvent, true);
		cafen.Event.stopObserving(document.body, "mouseup", this._docZoomUpEvent, true);
		cafen.Event.stopObserving(this._zoomObj[1].getElement(), "mouseup", this._docZoomUpEvent, true);
		if (this._docZoomStopEvent != null)
			this._docZoomStopEvent();
		this._isOnZooming = false;
		return false;
	},
	_dragObjInit : [0,0],
	_dragObj : [null, null],
	_docDragStopEvent : null,
	_docDragMoveEvent : null,
	_docDragUpEvent : null,
	_isOnDraging : false,
	startDrag : function(event,pointobj, options, stopEvent) {
		if (this._isOnDraging)
			this.stopDrag();
		var targetobj = options.link || pointobj;
		this._mouse_init = this.pointer(event);
		this._dragObj = [pointobj,targetobj, options];	
		this._dragObjInit = targetobj.getOffset();
		this._docDragStopEvent = stopEvent;
		if (this._docDragMoveEvent == null)
			this._docDragMoveEvent =  this.moveDrag.bindAsEventListener(this);
		if (this._docDragUpEvent == null) 
			this._docDragUpEvent =  this.stopDrag.bindAsEventListener(this);
		cafen.Event.observe(document.body, "mousemove", this._docDragMoveEvent, true);
		cafen.Event.observe(document.body, "mouseup", this._docDragUpEvent);
		cafen.Event.observe(this._dragObj[1].getElement(), "mouseup", this._docDragUpEvent, true);
		this._isOnDraging = true;
		this.Event.stop(event);
		return false;
	},
	moveInrange : function(x, y) {
		if (x != null && this._dragObj[2].rangeX != null && (this._dragObj[2].rangeX[0] > x || this._dragObj[2].rangeX[1] < x))
			return false;
		else if (y != null && this._dragObj[2].rangeY != null && (this._dragObj[2].rangeY[0] > y || this._dragObj[2].rangeY[1] < y))
			return false;
		else
			return true;
	},
	moveDrag : function(event) {
		var pos = this.pointer(event);
		if (pos[0] < 0 || pos[1] < 0 || pos[0] > document.body.offsetWidth) {
			this.stopDrag(event);
			return ;	
		}
		var moveX = pos[0] - this._mouse_init[0];
		var moveY = pos[1] - this._mouse_init[1];
		switch(this._dragObj[2].direction) {
			case 'X' :
				if (this.moveInrange(this._dragObjInit[0] +moveX, null))
					this._dragObj[1].setOffset(this._dragObjInit[0] +moveX,  null);
				else
					this.stopDrag(event);
				break;
			case 'Y' :
				if (this.moveInrange(null, this._dragObjInit[1] +moveY))
					this._dragObj[1].setOffset(null, this._dragObjInit[1] +moveY);
				else
					this.stopDrag(event);
				break;
			default :
				if (this.moveInrange(this._dragObjInit[0] +moveX, this._dragObjInit[1] +moveY))
					this._dragObj[1].setOffset(this._dragObjInit[0] +moveX,  this._dragObjInit[1] +moveY);
				else
					this.stopDrag(event);
				break;
		}
		this.Event.stop(event);
		return false;
	},
	stopDrag : function(event) {
		cafen.Event.stopObserving(document.body, "mousemove", this._docDragMoveEvent, true);
		cafen.Event.stopObserving(document.body, "mouseup", this._docDragUpEvent, true);
		cafen.Event.stopObserving(this._dragObj[1].getElement(), "mouseup", this._docDragUpEvent, true);
		if (this._docDragStopEvent != null)
			this._docDragStopEvent();
		this._isOnDraging = false;
		return false;
	},
	repeat : function(input_str, len) {
		var str = '';
		for(var i = 0; i < len; i++)
			str += input_str;
		return str;
	},
	showElement : function(obj) {
		var tmp = document.createElement('div');
		if (obj.getObject)
			tmp.appendChild(obj.getObject());
		else
			tmp.appendChild(obj);
	},
	find : function(reg, str,bl) {
		var m = [];
		try {
			if (m = str.match(eval('/' + reg + '/'+(bl ? 'i':'')))) 
				return m;
			else 
				return false;
		} catch(ex) {
			return false;
		}
	},
	Event : {
		KEY_BACKSPACE: 8,
		KEY_TAB:       9,
		KEY_RETURN:   13,
		KEY_ESC:      27,
		KEY_LEFT:     37,
		KEY_UP:       38,
		KEY_RIGHT:    39,
		KEY_DOWN:     40,
		KEY_DELETE:   46,
		element: function(event) {
			return event.target || event.srcElement;
		},
		isLeftClick: function(event) {
			return 1;
		},
		pointerX: function(event) {
			return event.pageX || (event.clientX +
				(document.documentElement.scrollLeft || document.body.scrollLeft));
		},
		pointerY: function(event) {
			return event.pageY || (event.clientY +
			(document.documentElement.scrollTop || document.body.scrollTop));
		},
		stop: function(event) {
			if (event != null) {
				if (event.preventDefault) {
					event.preventDefault();
					event.stopPropagation();
				} else {
					event.returnValue = false;
					event.cancelBubble = true;
				}
			}
		},
		findElement : function(event, tagName) {
			var element = cafen.Event.element(event);
			while (element.parentNode && (!element.tagName || (element.tagName.toUpperCase() != tagName.toUpperCase())))
				element = element.parentNode;
			return element;
		},
		observers: false,
		_observeAndCache: function(element, name, observer, useCapture) {
			if (!this.observers) this.observers = [];
			if (element.addEventListener) {
				this.observers.push([element, name, observer, useCapture]);
				element.addEventListener(name, observer, useCapture);
			} else if (element.attachEvent) {
				try {
					this.observers.push([element, name, observer, useCapture]);
		  			element.attachEvent('on' + name, observer);
				} catch(ex) {}
			}
		},
		unloadCache: function() {
			if (!cafen.Event.observers) return;
			for (var i = 0; i < cafen.Event.observers.length; i++) {
				cafen.Event.stopObserving.apply(this, cafen.Event.observers[i]);
				cafen.Event.observers[i][0] = null;
			}
			cafen.Event.observers = false;
		},
		observe: function(element, name, observer, useCapture) {
			if (cafen.isMobile()) {
				switch(name.toLowerCase()) {
					case 'mousemove' :
						name = 'touchmove';
						break;
					case 'mousedown' :
						name = 'touchstart';
						break;
					case 'mouseup' :
						name = 'touchend';
						break;
					default :
						break;
				}	
			} 
			var element = cafen.$(element);
			useCapture = useCapture || false;
			if (name == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || element.attachEvent))
				name = 'keydown';
			cafen.debugMessage('Event Attached type '+name+' to ' + element.tagName , 'event');
			this._observeAndCache(element, name, observer, useCapture);
		},
		stopObserving: function(element, name, observer, useCapture) {
			if (cafen.isMobile()) {
				switch(name) {
					case 'mousemove' :
						name = 'touchmove';
						break;
					case 'mousedown' :
						name = 'touchstart';
						break;
					case 'mouseup' :
						name = 'touchend';
						break;
						break;
					default :
						break;
				}	
			} 
			var element = cafen.$(element);
			useCapture = useCapture || false;
			if (name == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || element.detachEvent))
				name = 'keydown';
			cafen.debugMessage('Event removed type '+name+' from ' + element.tagName , 'event');
			if (element.removeEventListener) {
				element.removeEventListener(name, observer, useCapture);
			} else if (element.detachEvent) {
				element.detachEvent('on' + name, observer);
			}
		}
	},
	mouseSticker : function(obj) {
		cafen.stickerMouse.stickerStart(obj);
	},
	stickerMouse : {
		lastMoveObj : null,
		stickerStart : function(obj) {
			if (obj == null && this.lastMoveObj != null) {
				cafen.hide(this.lastMoveObj);
				document.body.onmousemove = null;
			} else if (obj != null) {
				this.lastMoveObj = cafen.$(obj);
				document.body.onmousemove = this.stickerMove.bindAsEventListener(this);
			}
		},
		stickerMove : function(e) {
			var pos = cafen.pointer(e);
		}
	},
	dragDropable : function(obj) {
		new cafen.dragNDrop(this.$(obj));
	},
	multiSelectable : function(obj) {
		new cafen.multiSelect(this.$(obj));
	},
	toStringArray : function(objVal, obj, level, stopLevel, cutLen) {
		objVal = objVal || [];
		if (typeof obj == 'object' || typeof obj == 'array') {
			if (obj instanceof Array) {
				for(var i = 0; i < 	obj.length ; i++) {
					objVal.push(i +' : ' +this.toString(obj[i], level+1,stopLevel,cutLen));
				}
			} else {
				for(var name in obj) {
					try {
						if (name.indexOf('_') != 0) {
							if (name == 'parentNode' || obj == obj[name])
								objVal.push(name +' : ' +'Object');
							else
								objVal.push(name +' : ' + this.toString(obj[name], level+1, stopLevel,cutLen));
						}
					} catch(ex) {}
				}
			}			
		} else
			objVal.push(this.toString(obj, level, stopLevel, cutLen));
		return objVal;
	},
	toString : function(obj, level, stopLevel, cutLen) {
		if (level == null)
			level = 0;
		if (stopLevel == null)
			stopLevel = 5;
		cutLen = isNaN(cutLen) ? 30 : cutLen;
		if ((typeof obj == 'object' || typeof obj == 'array') && level <= stopLevel) {
			var objVal = [];
			if (obj instanceof Array) {
				for(var i = 0; i < 	obj.length ; i++) {
					objVal.push('<li>'+i +' : ' +this.toString(obj[i], level+1,stopLevel,cutLen)+'</li>');
				}
				return '<ol>'+objVal.join('') +'</ol>';
			} else {
				for(var name in obj) {
					try {
						if (name.indexOf('_') != 0) {
							if (name == 'parentNode' || obj == obj[name])
								objVal.push('<li>'+name +' : ' +'Object</li>');
							else
								objVal.push('<li>'+name +' : ' + this.toString(obj[name], level+1, stopLevel,cutLen)+'</li>');
						}
					} catch(ex) {}
				}
				return '<ol>'+objVal.join('') +'</ol>';
			}
		} else if (typeof obj == 'function') 
			return '(function)'+this.getFunctionName(obj);
		else if (typeof obj == 'boolean' || typeof obj == 'number') 
			return '('+(typeof obj)+')'+obj.toString();
		else if (typeof obj == 'object')
			return '(object)'+this.longCut(obj.toString(),cutLen);
		else if (typeof obj == 'string')
			return '(string)"'+this.longCut(obj.toString(),cutLen)+'"';
		else
			return ''+this.longCut(obj,cutLen);
	},
	toStringJson : function(obj, level, stopLevel, cutLen, parentName) {
		if (level == null)
			level = 0;
		if (stopLevel == null)
			stopLevel = 5;
		parentName = parentName || 'self';
		cutLen = isNaN(cutLen) ? 30 : cutLen;
		if ((typeof obj == 'object' || typeof obj == 'function' || obj instanceof Array ) && level <= stopLevel) {
			var repeatStr = this.repeat('  ',level +1);
			var repeatStrEnd = this.repeat('  ',level);
			if (obj instanceof Array) {
				var objVal = [];
				for(var i = 0; i < 	obj.length ; i++)
					objVal.push(i +' : ' + this.toStringJson(obj[i], level+1));
				return '[\r\n' +repeatStr+ objVal.join(',\r\n'+repeatStr) +'\r\n'+repeatStrEnd+']';
			} else if (typeof obj == 'function') {
				var objVal = [];
				var funcStr = obj.toString();
				objVal.push(funcStr.split("\n").join("\n"+repeatStr));
				for(var name in obj) {
					if (name != 'prototype' && name.indexOf('_') != 0 && name.indexOf('bind') != 0) {
						objVal.push(parentName +'.'+name +' : ' + this.toStringJson(obj[name], level +1, stopLevel, cutLen, name));
					}
				}
				if (obj.prototype) {
					var funcValue = [];
					funcValue.push(objVal.join(',\r\n'+repeatStrEnd));
					funcValue.push(parentName+'.prototype : ' + this.toStringJson(obj.prototype, level +1, stopLevel, cutLen, parentName));
					return funcValue.join(',\r\n'+repeatStrEnd);
				} else
					return objVal.join(',\r\n'+repeatStr);
			} else {
				var objVal = [];
				for(var name in obj) {
					if (name.indexOf('_') != 0  && name.indexOf('bind') != 0) {
						objVal.push(name +' : ' + this.toStringJson(obj[name], level +1, stopLevel, cutLen, name));
					}
				}
				if (objVal.length > 0) 
					return '{\r\n' +repeatStr+ objVal.join(',\r\n'+repeatStr) +"\r\n"+repeatStrEnd+'}';
				else
					return '{}';
			}
		} else if (typeof obj == 'function') {
			var funcStr = obj.toString();
			var repeatStr = this.repeat('  ',level +1);
			return funcStr.split("\n").join("\n"+repeatStr);
		} else if (typeof obj == 'boolean' || typeof obj == 'number') 
			return obj.toString();
		else if (typeof obj == 'object')
			return this.longCut(obj.toString(),cutLen);
		else if (typeof obj == 'string')
			return '"'+this.longCut(obj.toString(),cutLen)+'"';
		else
			return this.longCut(obj,cutLen);
	},
	toSS : function(obj) {
		if (typeof obj == 'object') {
			var objVal = [];
			for(var name in obj) {
				var val = (typeof obj[name] == 'string' || typeof obj[name] == 'number') ? obj[name] : (typeof obj[name]);
				objVal.push(name + ' / ' + val);
			}
			return '{Object ' + objVal.join(', '+this.repeat(' ',1)) +'}';
		} else if (typeof obj == 'array') {
			var objVal = [];
			for(var i = 0; i < 	obj.length ; i++)
				objVal.push(obj[i]);
			return '[Array ' + objVal.join(',\r\n'+this.repeat(' ',1)) +']';
		} else
			return obj;
	},
	onloadUnloadEvent : null,
	onloadUnloadEventMsg : null,
	onloadUnload : function(event, obj) {
		return this.onloadUnloadEventMsg;
	},
	setloadUnload : function(bl, msg) {
		if (bl) {
			if (this.onloadUnloadEvent == null) 
				this.onloadUnloadEvent = this.onloadUnload.bindAsEventListener(this);
			if (window.onbeforeunload == null)
				window.onbeforeunload = this.onloadUnloadEvent;
			this.onloadUnloadEventMsg = msg;
		} else {
			window.onbeforeunload = null;
		}
	},
	renderElementsByClassName : function(className) {
		var objs = this.getElementsByTagName('*');
		var result = [];
		for(var i =0; i < objs.length; i++) 
			if (objs[i].className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) 
				result.push(objs[i]);
		for(var i = 0; i < result.length; i++)
				this.renderElement(result[i]);
	},
	renderElementsById : function(id) {
		if (document.getElementById(id) != null) {
			var objs = document.getElementsByTagName(document.getElementById(id).tagName);
			var result = [];
			for(var i=0;i<objs.length;i++)
				if(objs[i].id==id) 
					result.push(objs[i]);
			for(var i = 0; i < result.length; i++)
					this.renderElement(result[i]);
		}
	},
	renderElements : function(objs) {
		var result = [];
		for(var i = 0; i < objs.length; i++)
				result.push(objs[i]);
		for(var i = 0; i < result.length; i++)
				this.renderElement(result[i]);
	},
	renderElement : function(obj) {
		switch (obj.tagName) {
			case 'BUTTON' :
				var randerClassName = obj.getAttribute('cafenclass');
				var events = {}
				if (obj.onclick != null)
					events.click = obj.onclick;
				var tmpObj = new cafen.XButton({className : (randerClassName == null) ? 'r_rbtnskin' :  randerClassName , attribute : {innerHTML  : obj.innerHTML}, event : events, style : {width : obj.offsetWidth +'px', height : obj.offsetHeight +'px'}});
				obj.parentNode.insertBefore(tmpObj.getObject(), obj);
				this.hide(obj);
				break;
			case 'DIV' :
			var randerClassName = obj.getAttribute('cafenclass');
				switch(obj.getAttribute('cafentype')) {
					case 'tab' :
						var tmpTabs = [];
						for(var i = 0; i < obj.childNodes.length; i++) {
							var currObj = obj.childNodes[i];
							if (currObj.tagName == 'BUTTON') {
								var tmpTab = new cafen.XTab(
										{className : (randerClassName == null) ? 'r_tab-b' :  randerClassName ,attribute : {innerHTML :currObj.innerHTML}, style : {width : currObj.offsetWidth +'px', height : currObj.offsetHeight +'px'},event : {click: currObj.onclick.bind(currObj)}}
									);
								currObj.linkObj = tmpTab;
								tmpTabs.push(tmpTab); 
							}
						}
						var tmpDiv = new cafen.Div({style : {width : (obj.offsetWidth +6)+'px'}});
						var tmpObj = new cafen.XTabMenu(tmpTabs, {});
						if (tmpTabs.length > 0)
							tmpObj.setSelected(tmpTabs[0]);
						tmpDiv.appendChild(tmpObj);
						obj.parentNode.insertBefore(tmpDiv.getObject(), obj);
						this.hide(obj);
						break;
					default :
						var divTitle = obj.getAttribute('title');
						var tmpObj = new cafen.Div({className : (randerClassName == null) ? 'r_boxwhite' : randerClassName, tplName : (divTitle != null && divTitle != '') ?'top' : '', attribute : {border:0},style : {width:  obj.offsetWidth+'px', height : obj.offsetHeight+'px', overflowX : 'hidden', overflowY: 'auto', textAlign:'center'}});
						if (divTitle != null && divTitle != '') {
							tmpObj.appendChild(new cafen.Div({attribute:{innerHTML : '&nbsp;<b>' +divTitle +'</b>'}}),'top');
							obj.title = '';
						}
						obj.parentNode.insertBefore(tmpObj.getObject(), obj);
						tmpObj.appendChild(obj);
				}
				break;
			case 'TABLE' :
				var tmpObj = new cafen.TableAuto({style : {}, attribute : {border : 0, cellSpacing : 2}});
				var currTbody = (obj.childNodes[0].tagName == 'TBODY') ? obj.childNodes[0] : obj;
				for(var i = 0; i < currTbody.childNodes.length; i++) {
					var tmpTR = tmpObj.addRow();
					tmpTR.attachEvent('mouseover', function(obj) {obj.setStyle({backgroundColor : '#000000', color : '#FFFFFF'})});
					tmpTR.attachEvent('mouseout', function(obj) {obj.setStyle({backgroundColor : '#FFFFFF', color : '#464646'})});
					var currTR = currTbody.childNodes[i];
					var baseAlign = currTR.getAttribute('align');
					for(var j = 0; j < currTR.childNodes.length; j++) {
						if (i == 0) {
							var base_Width = currTR.childNodes[j].offsetWidth ;
							tmpObj.addCell(new cafen.XButton({attribute : {innerHTML : currTR.childNodes[j].innerHTML}, resize : 'XXXXXOXXX', style : {width: base_Width +'px'}}));
						} else {
							tmpObj.addCell(currTR.childNodes[j].innerHTML);
							tmpObj.addAttribute({align: baseAlign});
						}
					}
				}
				obj.parentNode.insertBefore(tmpObj.getObject(), obj);
				obj.style.display = 'none';
				break;
			case 'INPUT' :
			case 'TEXTAREA' :
				var randerClassName = obj.getAttribute('cafenclass');
				var cafenresize = obj.getAttribute('cafenresize');
				var validValue = obj.getAttribute('cafenvalid');
				var resize_options = null;
				switch(cafenresize) {
					case 'width' :
						resize_options = 'XXXXXOXXX';
						break;
					case 'height' :
						resize_options = 'XXXXXXXOX';
						break;
					case 'both' :
						resize_options = 'XXXXXOXOO';
						break;
				}
				var tmpObj = null;
				if (obj.tagName == 'INPUT')
					tmpObj = new cafen.XInput({renderObj : obj, className : (randerClassName == null) ? 'r_inputskin' :  randerClassName , attribute : {value  : obj.value}, style : {width : obj.offsetWidth +'px'}, resize : resize_options, validValue : validValue});
				else
					tmpObj = new cafen.XTextarea({renderObj : obj, className : (randerClassName == null) ? 'r_inputskin' :  randerClassName , attribute : {value  : obj.value}, style : {width : obj.offsetWidth +'px', height: obj.offsetHeight +'px'}, resize : resize_options, validValue : validValue});
				obj.parentNode.insertBefore(tmpObj.getObject(), obj);
				tmpObj._element.parentNode.insertBefore(obj, tmpObj._element);
				tmpObj._element.parentNode.removeChild(tmpObj._element);
				tmpObj._element = obj;
				obj.style.border = '0px';
				break;
			default :
				break;
		}
	}
}

try {
/*
	if (window.onerror == null) {
		window.onerror =  function windowOnerror(message, url, line) { 
			if (cafen.checkDebug()) {
				var scriptPath = 'Unknown';
				try {
					scriptPath =  cafen.getCallee(arguments.callee).join(' ');
				} catch(ex) {}
				cafen.debugMessage('Msg :'+message+'\r\nUrl:'+url+'\r\nLine:'+line + '\r\nScript:'+ scriptPath);	
			}
			return true;
		}
	}
*/
} catch(ex) {}

cafen.Element = function(tag, options) {
	this.setOptions(cafen.extend(options, {tag : tag}));	
}

cafen.Element.prototype = {
	options : {},
	_element : null,
	_tpl : null,
	_tplElement : [],
	_shadow : null,
	_broElement : null,
	parentNode : null,
	childNodes : [],
	_cssTable : [
		['r_tl','r_tc','r_tr'],
		['r_ml','r_mc','r_mr'],
		['r_bl','r_bc','r_br']
	],
	_cssShadowTable : [
		['r_swmc','r_swmr'],
		['r_swbc','r_swbr']
	],
	_cssTableTop : [
		['r_tl_e','r_tc_e','r_tr_e'],
		['r_ml','r_mc','r_mr'],
		['r_bl','r_bc','r_br']
	],
	_cssTableBottom : [
		['r_tl','r_tc','r_tr'],
		['r_ml','r_mc','r_mr'],
		['r_bl_e','r_bc_e','r_br_e']
	],
	_cssTableBoth : [
		['r_tl_e','r_tc_e','r_tr_e'],
		['r_ml','r_mc','r_mr'],
		['r_bl_e','r_bc_e','r_br_e']
	],
	setOptions : function(options) {
		this.childNodes = [];
		this.parentNode = null;
		this._element = null;
		this._tpl = null;
		this._tplElement = [];
		this._shadow = null;
		this._broElement = null;
		this.options = cafen.extend({
			name : '',
			tag:'', 
			className : '',
			tplName : '',
			align : '',
			style : {}, 
			childNodes : [],
			shadow : false,
			resize : 'XXXXXXXXX',
			resizeOption : {minWidth : 1, minHeight : 1, maxWidth : -1, maxHeight : -1, Increment : 1, preserveRatio: false},
			attribute : {}, 
			_event : {},
			_eventBind : {},
			_lastresizeObj : null,
			event : {}
		}, options);
		if (this.options.name == '')
			this.options.name = this.options.attribute.title ? this.options.attribute.title : cafen.longCut(this.options.attribute.innerHTML, 10);
		this.options._event = {};
		cafen.debugMessage(this, "create");
	},
	getName : function() {
		return '{tagName : '+this.options.tag +' , objName : '+(this[cafen._cafenTmpNameID] || 'unknown') +' , refName : '+((this.options.name == '') ? 'UnKnown Name' : this.options.name)+'}';
	},
	getObject : function() {
		if (this._element == null) {
			if (this.options.tag != null) {
				try { 
					this._element = document.createElement(this.options.tag);
					if (this.options.attribute.type != null) {
						this._element.setAttribute("type", this.options.attribute.type);
						this.options.attribute.type = null;
					}
				} catch(ex) {
					this._element = document.createElement("DIV");
				}
			} else 
				this._element = null;
			if (this.options.className != '') {
				this._tpl = document.createElement('table');
				this._tpl.setAttribute('border',0,0);
				this._tpl.setAttribute('unselectable','on',0);
				this._tpl.setAttribute('cellSpacing',0,0);
				this._tpl.setAttribute('cellPadding',0,0);
				this._tpl.className = 'r_off';
				var baseCssTable = [];
				switch(this.options.tplName) {
					case 'top' :
						baseCssTable = this._cssTableTop;
						break;
					case 'bottom' :
						baseCssTable = this._cssTableBottom;
						break;
					case 'both' :
						baseCssTable = this._cssTableBoth;
						break;
					default :
						baseCssTable = this._cssTable;
						break;
				}
				var baseClassName = this.options.className;
				for(var i = 0 ; i < baseCssTable.length; i++) {
					var tr_obj = this._tpl.insertRow(-1);
					for(var j = 0 ; j < baseCssTable[i].length; j++) {
						var className = baseCssTable[i][j];
						var obj = tr_obj.insertCell(-1);
						obj.className = baseClassName +' '+className;
						if (className == 'r_mc') {
							if (this._element != null)
								obj.appendChild(this._element);
						} else if (j == 1 && (className == 'r_tc_e' || className == 'r_bc_e'))
							obj.innerHTML = '<div style="text-align:left">&#160;</div>';
						else
							obj.innerHTML = '<div class="blank">&#160;</div>';
						this._tplElement.push(obj);
					}
				}
				this.makeResizeable(this.options.resize);
			} else
				this._tpl = this._element;
			if (this.options.shadow) {
				this._shadow = document.createElement('table');
				this._shadow.setAttribute('border','0',0);
				this._shadow.setAttribute('unselectable','on',0);
				this._shadow.setAttribute('cellspacing',0,0);
				this._shadow.setAttribute('cellpadding',0,0);
				this._shadow.className = 'r_shadow';
				this._shadow.className = cafen.isPngAlphaSupport() ? 'r_shadow' : 'r_shadow-ie5';
				for(var i = 0 ; i < this._cssShadowTable.length; i++) {
					var tr_obj = this._shadow.insertRow(-1);
					for(var j = 0 ; j < this._cssShadowTable[i].length; j++) {
						var className = this._cssShadowTable[i][j];
						var obj = tr_obj.insertCell(-1);
						obj.className = className;
						if (className == 'r_swmc') {
							obj.appendChild(this._tpl);
						} else {
							obj.innerHTML = '<div class="blank">&#160;</div>';
						}
					}
				}
			} else {
				this._shadow = this._tpl;
			}
			this.setAttribute(this.options.attribute);
			if (this.options.shortkey != null) 
				this.setAttribute({accessKey : this.options.shortkey}); 
			if (this.options.childNodes.length > 0) {
				for(var i = 0; i < this.options.childNodes.length; i++) 
					this.appendChild(this.options.childNodes[i]);
			}
			if (this.options.moveOption != null)
				this.makeMoveable(this.options.moveOption);
			if (this.options.zoomable != null && this.options.zoomable)	
				this.makeZoomable(this.options.zoomable);
			this.setStyle(this.options.style);
			this.setEvent(this.options.event);
			this.setAlign(this.options.align);
			if ((this.options.tag.toLowerCase() == 'div' || this.options.tag.toLowerCase() == 'textarea' || this.options.tag.toLowerCase() == 'iframe')&& !this._scrollProtected && (this.options.style.overflowY == 'auto' || this.options.style.overflowY == 'scroll')) {
				cafen.makeScroll(this._element);
			}
		}
		return this._shadow;
	},
	onChange : function(options) {
		if (this._element != null && typeof this._element.onchange == 'function') {
			this._element.onchange(options);
		}
	},
	makeMoveable : function(moveOption) {
		if (moveOption != null) {
			this.setStyle({cursor :cafen.getCursor()});
			this.attachEvent('mousedown', this.startDrag.bind(this));
		} else
			this.detachEvent('mousedown',this.startDrag.bind(this));
	},
	makeZoomable : function(bl) {
		if (bl) 
			this.attachEvent('mousedown', this.startZoom.bind(this));
		else
			this.detachEvent('mousedown',this.startZoom.bind(this));
	},
	isDragPaused : false,
	pauseDrag : function(bl) {
		this.isDragPaused = bl;
	},
	startZoom : function(obj, event) {
		if (!this.isDragPaused) {
			if (event.ctrlKey || (event.touches && event.touches.length > 1)) {
				cafen.startZoom(event, obj, this.stopZoom.bind(this));
			}
		}
	},
	stopZoom : function() {
		this.execEvent('zoomend');
	},
	startDrag : function(obj, event) {
		if (!this.isDragPaused) {
			if (!event.ctrlKey) {
				cafen.startDrag(event, obj, this.options.moveOption, this.stopDrag.bind(this));
			}
		}
	},
	stopDrag : function() {
		this.execEvent('dragend');
	},
	makeResizeable : function(str) {
		if (this._tplElement.length == 9 && str.length == 9) {
			var cursorStyle = ['nw','n','sw','e','','e','sw','n','nw'];
			for(var i = 0; i < cursorStyle.length; i++) {
				if (i == 4)
					continue;
				else if (str.charAt(i) == 'O') {
					this._tplElement[i].style.cursor = cursorStyle[i]+'-resize';
					this._tplElement[i].onmousedown = this.startReSize.bind(this, i);
				} else {
					this._tplElement[i].style.cursor = '';
					if (this._tplElement[i].onmousedown != null)
						this._tplElement[i].onmousedown = null;
				}
			}
		}
	},
	startReSize : function(dir, event) {
		if (this.options._lastresizeObj != null) 
			this.stopResize(event);
		this.options._lastresizeObj = this._tplElement[dir];
		this.options._lastresizeInfo = [dir, cafen.pointer(event || window.event), this.getSize(), this.getOffset()];
		document.body.onmousemove = this.moveResize.bindAsEventListener(this);
		document.body.onmouseup = this.stopResize.bindAsEventListener(this);
	},
	checkResize : function(w, h) {
		if ((w != null && w < 1)  || (h != null && h < 1) )
			return false;
		else if (w != null && this.options.resizeOption.maxWidth > 1 && (this.options.resizeOption.minWidth > w || this.options.resizeOption.maxWidth < w)) 
			return false;
		else if (h != null && this.options.resizeOption.maxHeight > 1 && (this.options.resizeOption.minHeight > h || this.options.resizeOption.maxHeight < h)) 
			return false;
		else
			return true;
	},
	moveResize : function(event) {
		var pos = cafen.pointer(event);
		var moveX = pos[0] - this.options._lastresizeInfo[1][0];
		var moveY = pos[1] - this.options._lastresizeInfo[1][1];
		if (this.options.resizeOption.Increment > 1) {
			moveX = Math.round(moveX / this.options.resizeOption.Increment) * this.options.resizeOption.Increment;
			moveY = Math.round(moveY / this.options.resizeOption.Increment) * this.options.resizeOption.Increment;
		}
		if (this.options.resizeOption.preserveRatio) 
			moveY = Math.round(moveX * this.options._lastresizeInfo[2][1] / this.options._lastresizeInfo[2][0]);
		switch(this.options._lastresizeInfo[0]) {
			case 0 :
				var sizeW = this.options._lastresizeInfo[2][0] - moveX;
				var sizeH = this.options._lastresizeInfo[2][1] - moveY;
				if (this.checkResize(sizeW, sizeH)) {
					this.setSize(sizeW, sizeH);
					var offsetL = this.options._lastresizeInfo[3][0] + moveX;
					var offsetT = this.options._lastresizeInfo[3][1] + moveY;
					this.setOffset(offsetL, offsetT);
				} else 
					this.stopResize(event);
				break;
			case 1 :
				var sizeH = this.options._lastresizeInfo[2][1] - moveY;
				if (this.checkResize(null, sizeH)) {
					var offsetT = this.options._lastresizeInfo[3][1] + moveY;
					this.setOffset(null, offsetT);
					this.setSize(null, sizeH);
				} else 
					this.stopResize(event);
				break;
			case 2 :
				var sizeW = this.options._lastresizeInfo[2][0] + moveX;
				var sizeH = this.options._lastresizeInfo[2][1] - moveY;
				if (this.checkResize(sizeW, sizeH)) {
					var offsetT = this.options._lastresizeInfo[3][1] + moveY;
					this.setOffset(null, offsetT);
					this.setSize(sizeW, sizeH);
				} else 
					this.stopResize(event);
				break;
			case 3 :
				var sizeW = this.options._lastresizeInfo[2][0] - moveX;
				if (this.checkResize(sizeW, null)) {
					var offsetL = this.options._lastresizeInfo[3][0] + moveX;
					this.setOffset(offsetL, null);
					this.setSize(sizeW, null);
				} else 
					this.stopResize(event);
				break;
			case 5 :
				var sizeW = this.options._lastresizeInfo[2][0] + moveX;
				if (this.checkResize(sizeW, null)) {
					this.setSize(sizeW, null);
				} else 
					this.stopResize(event);
				break;
			case 6 :
				var sizeW = this.options._lastresizeInfo[2][0] - moveX;
				var sizeH = this.options._lastresizeInfo[2][1] + moveY;
				if (this.checkResize(sizeW, sizeH)) {
					var offsetL = this.options._lastresizeInfo[3][0] + moveX;
					this.setOffset(offsetL, null);
					this.setSize(sizeW, sizeH);
				} else 
					this.stopResize(event);
				break;
			case 7 :
				var sizeH = this.options._lastresizeInfo[2][1] + moveY;
				if (this.checkResize(null, sizeH)) {
					this.setSize(null, sizeH);
				} else 
					this.stopResize(event);
				break;
			case 8 :
			default : 
				var sizeW = this.options._lastresizeInfo[2][0] + moveX;
				var sizeH = this.options._lastresizeInfo[2][1] + moveY;
				if (this.checkResize(sizeW, sizeH)) {
					this.setSize(sizeW, sizeH);
				} else 
					this.stopResize(event);
				break;
		}
	},
	stopResize : function(event) {
		if (this.options._lastresizeObj != null) {
			document.body.onmousemove = null;
			document.body.onmouseup = null;
			this.execEvent('resize', event);
			this.options._lastresizeObj = null;
		}
	},
	getElement : function(tpltaget) {
		if (this._element == null)
			this.getObject();
		if ((tpltaget == null || tpltaget == '' || this._tplElement.length != 9 ) && tpltaget != 'shadow' )
			return this._element;
		else {
			 switch(tpltaget) {
			 	case 'top' :
					return this._tplElement[1].firstChild ;
					break;
				case 'bottom' :
					return this._tplElement[7].firstChild;
					break;
				case 'shadow' :
					if (this._broElement == null) {
						this._broElement = document.createElement('div');
						this._broElement.style.position = 'relative';
						this._broElement.style.zIndex = '1000';
						this._broElement.style.left = '-3px';
						this._broElement.style.width = '1px';
						this._broElement.style.height = '1px';
						this._shadow.firstChild.childNodes[1].childNodes[1].appendChild(this._broElement);
					}
					return this._broElement;
					break;
				default :
					return (this._element) ? this._element :  this._tplElement[4];
					break;
			}
		}
	},
	setElement : function(obj) {
		if (this.getObject()) {
			this._element = obj;
			if (this._tplElement[4] != null)
				this._tplElement[4].appendChild(obj.getObject ? obj.getObject : obj);
		}
	},
	getTpl : function() {
		if (this._tpl != null)
			return this._tpl;
		else if (this.getObject() != null)
			return this._tpl;
		else
			null;
	},
	setEvent : function(events) {
		if (events != null) {
		    for (var name in events)
		      this.attachEvent(name, events[name]);
		}
	},
	setAlign : function(align) {
		if (align != '') {
			this.getObject().align = align;
			if (align =='center')
				this.getObject().setAttribute('align', 'center',0);
			else
				this.getObject().style.cssFloat = align;
		}
	},
	isBaseEvent : function(name) {
		if (
			name == 'click' 
			|| name == 'mouseover'  || name == 'mouseout' 
			|| name == 'mousemove'|| name == 'mousedown' || name == 'mouseup' 
			|| name == 'keypress'  || name == 'keydown' || name == 'keyup' 
			|| name == 'focus' || name == 'blur')
			return true;
		else
			return false;
	},
	attachEvent : function(name, observer) {
		if (this.isBaseEvent(name) && this.options._eventBind[name] == null) {
			this.options._eventBind[name] = this.execEvent.bind(this,name);
			cafen.Event.observe(this.getElement(),name, this.options._eventBind[name], true);
		}
		if (this.options._event[name] == null)
			this.options._event[name] = [];
		this.options._event[name].push(observer);
	},
	detachEvent : function(name, observer) {
		var currEvent = this.options._event[name];
		if (currEvent != null) {
			var findevent = false;
			var newEvent = [];
			if (observer == null) {
				findevent = true;
			} else {
				for(var i = 0; i < currEvent.length; i++) {
					if (currEvent[i] == observer)
						findevent = true;
					else
						newEvent.push(currEvent[i]);
				}
			}
			if (findevent) {
				this.options._event[name] = newEvent;
				if (this.isBaseEvent(name) && newEvent.length == 0 && this.options._eventBind[name] != null) {
					cafen.Event.stopObserving(this.getElement(),name, this.options._eventBind[name], true);
					this.options._eventBind[name] = null;
				}
			}
		}
	},
	execEvent : function(name, event) {
		currEvent = this.options._event[name];
		event = event || window.event;
		var result = true;
		if (currEvent != null) {
			for(var k = 0; k < currEvent.length; k++) 
				result = currEvent[k](this, event) && result;
		}
		cafen.Event.stop(event);
		return false;
	},
	setClassName : function(name) {
		this.getTpl().className = name;
	},
	setStyle : function(cssstyle) {
		if (cssstyle != null) {
			for (var name in cssstyle) {
				switch(name) {
					case 'left' :
					case 'top' :
					case 'position' :
					case 'display' :
					case 'opacity' :
					case 'filter' :
					case 'clear' :
					case 'zIndex' :
					case 'marginTop' :
					case 'marginLeft' :
					case 'marginRight' :
					case 'marginBottom' :
					case 'margin' :
						try {
							this.getObject().style[cafen.camelize(name)] = cssstyle[name];
						} catch(ex) {
							cafen.debugMessage('setStyle :' +ex +'\r\n'+cafen.camelize(name) + '/' +cssstyle[name]);
						}
						break;
					case 'float' :
					case 'cssFloat' :
					case 'styleFloat' :
						this.getObject().style['float'] = cssstyle[name];
//						if (cafen.browser.isIE) 
//							this.getObject().style['styleFloat'] = cssstyle[name];
//						else
//							this.getObject().style['cssFloat'] = cssstyle[name];
						break;
					default :
						try {
							if (this.getElement() != null)
								this.getElement().style[cafen.camelize(name)] = cssstyle[name];
						} catch(ex) {
							cafen.debugMessage('setStyle :' +ex +'\r\n'+cafen.camelize(name) + '/' +cssstyle[name]);
						}
						break;
				}
			}
		}
		return this;
	},
	getStyle : function(style) {
		style = (style == 'float') ? 'cssFloat' : cafen.camelize(style);
		switch(style) {
			case 'left' :
			case 'top' :
			case 'position' :
			case 'display' :
			case 'opacity' :
			case 'filter' :
			case 'clear' :
			case 'zIndex' :
			case 'marginTop' :
			case 'marginLeft' :
			case 'marginRight' :
			case 'marginBottom' :
			case 'margin' :
				return cafen.getStyle(this.getObject(), style);
				break;
			default :
				return cafen.getStyle(this.getElement(), style);
				break;
		}
	},
	setOpacity: function(opa) {
		if (cafen.browser.isIE) 
			this.setStyle({filter:"alpha(opacity = "+opa+")"});
		else 
			this.setStyle({opacity : opa/100});
	},
	getAttribute : function(name) {
		return this.getElement().getAttribute(name);
	},
	setAttribute : function(attrib) {
		if (attrib != null) {
		    for (var name in attrib) {
		    	switch(name) {
		    		case 'className' :
		    		case 'innerHTML' :
		    		case 'disabled' :
		    		case 'checked' :
		    		case 'unselectable' :
			    		this.getElement()[name] = attrib[name];
			    		break;
			    	case 'type' :
			    		if (attrib[name] != null)
				    		this.getElement()['type'] = attrib[name];
			    		break;
			    	default :
			    		try {
			    			if (attrib[name] == null)
			    				this.getElement().removeAttribute(name); 
			    			else
								this.getElement().setAttribute(name, attrib[name],0);
						} catch(ex) {
						}
			    		break;
				}
			}
		}
		return this;
	},
	show : function() {
		this.setStyle({display:''});
		this.onChange();
	},
	hide : function() {
		if (this.onHide != null)
			this.onHide();
		this.setStyle({display:'none'});
		this.onChange();
	},
	toggle : function() {
		if (this.getObject().style.display == '' || this.getObject().style.display == 'block')
			this.hide();
		else
			this.show();
	},
	getOffset : function() {
		var l = (this.getObject().offsetLeft || parseInt(this.getObject().style.left) || 0);
		var t = (this.getObject().offsetTop || parseInt(this.getObject().style.top) || 0);
		return [l, t];
	},
	setOffset : function(x, y) {
		if (x != null && y != null)
			this.setStyle({left : (typeof x == 'number') ? x +'px' : x, top : (typeof y == 'number') ? y +'px' : y});
		else if (x != null) 
			this.setStyle({left : (typeof x == 'number') ? x +'px' : x});
		else if (y != null) 
			this.setStyle({top : (typeof y == 'number') ? y +'px' : y});
	},
	setOffsetBy : function(x, y) {
		var pos = this.getOffset();
		this.setOffset(pos[0] + x, pos[1] +y);
	},
	cumulativeOffset : function() {
		return cafen.cumulativeOffset(this.getElement());
	},
	getSize : function() {
		var w = ((this.getObject().offsetWidth) || parseInt(this.getElement().style.width));
		var h = ((this.getObject().offsetHeight)|| parseInt(this.getElement().style.height));
		return [w || 0, h || 0];
	},
	getObjectSize : function() {
		var w = (this.getObject().offsetWidth || parseInt(this.getObject().style.width));
		var h = (this.getObject().offsetHeight || parseInt(this.getObject().style.height));
		return [w, h];
	},
	setSize : function(w, h) {
		if (w != null) {
			if (w == 'auto')
				this.setStyle({width : 'auto'});
			else if (typeof w == 'number')
				this.setStyle({width : (w || 1)+ 'px'});
		}
		if (h != null) {
			if (h == 'auto')
				this.setStyle({height : 'auto'});
			else if (typeof h == 'number')
				this.setStyle({height : (h || 1) + 'px'});
		}
	},
	setSizeBy : function(w, h) {
		var size = this.getSize();
		this.setSize(size[0] + w, size[1] + h);		
	},
	center : function(obj, options) {
		var size = this.getObjectSize();
		var objWidth = size[0];
		var objHeight = size[1];
			if (obj == null) {
			var scrollVal = cafen.getPageScroll();
			var pageVal = cafen.getPageSize();
			var selfSize = this.getSize();
			var offsetX = scrollVal[0]+(pageVal[0] -selfSize[0])/2;
			var offsetY = scrollVal[1]+(pageVal[1] -selfSize[1])/2;
			this.setOffset(offsetX , (offsetY > 0) ? offsetY : 0);
		} else {
			if (obj.getOffset) {
				var size = obj.getSize();
				var pos = obj.getOffset();
				var tarWidth = size[0];
				var tarHeight = size[1];
				this.setOffset(Math.round((tarWidth - objWidth)/2), Math.round((tarHeight - objHeight)/2));
			}
		}	
		},
		showAnimate : function(dir) {
		 this.show();
		 this.setStyle({overflowY :'visible', height:'auto'});
		 var size = this.getSize();
		 this.setStyle({overflowY :'hidden'});
		 this.setSize(null,1);
		 this.setAnimate(null, size[1], null, null);
		},
		hideAnimate : function(dir) {
		 this.setStyle({overflowY :'hidden'});
		 this.setAnimate(null, 1, null, null);
		},
		getFullSize : function() {
			try {
				return[this.getElement().scrollWidth, this.getElement().scrollHeight];
			} catch(ex) {
				return [0,0];	
			}
		},
		setAnimate : function(w, h, x, y , dur) {
			if (h == 'hidden') {
   			this.setStyle({overflowY : 'hidden'});
  			h = 0;
  		}
			if (w == 'hidden') {
   			this.setStyle({overflowX : 'hidden'});
  			w = 0;
  		}
  		if (h == 'max') {
			var fullsize = this.getFullSize();
			h = fullsize[1];
   	}
  		if (w == 'max') {
			var fullsize = this.getFullSize();
			w = fullsize[0];
   	}
 		this.options.moveSchedule = [];
		if (this.options.animateStartBind == null)
			this.options.animateStartBind = this.animateStart.bind(this);
			var pos = this.getOffset();
			var size = this.getSize();
			var sizeEffectH = [];
			var sizeEffectW = [];
			var sizeEffectX = [];
			var sizeEffectY = [];
		if (h != null) 
			sizeEffectH = cafen.getAnimateEffect(size[1], h, 1, 1);
		if (w != null) 
			sizeEffectW = cafen.getAnimateEffect(size[0], w, 1, 1);
		if (x != null) 
			sizeEffectX = cafen.getAnimateEffect(pos[0], x, 1, 1);
		if (y != null) 
			sizeEffectY = cafen.getAnimateEffect(pos[1], y, 1, 1);
		var maxAni = Math.max(sizeEffectH.length, sizeEffectW.length, sizeEffectX.length, sizeEffectY.length);
		if (maxAni > 0) {
			for(var i = 0 ; i < maxAni; i++) {
				var posW = (sizeEffectW.length <= i) ? null : sizeEffectW[i];
				var posH = (sizeEffectH.length <= i) ? null : sizeEffectH[i];
				var posX = (sizeEffectX.length <= i) ? null : sizeEffectX[i];
				var posY = (sizeEffectY.length <= i) ? null : sizeEffectY[i];
				this.options.moveSchedule.push([posW, posH ,posX,posY]);
			}
		}
			if (this.timer != null)
				window.clearTimeout(this.timer);
			if (this.options.moveSchedule.length > 0)
			this.animateStart();
		},
	animateStart : function() {
		var currMove = this.options.moveSchedule[0];
		var w = currMove[0];
		var h = currMove[1];
		var x = currMove[2];
		var y = currMove[3];
		this.options.moveSchedule.shift();
		if (w != null || h != null)
			this.setSize(w,h);
		if (x != null || y != null)
			this.setOffset(x,y);
			if (this.options.moveSchedule.length > 0) 
			this.timer = window.setTimeout(this.options.animateStartBind, 30);
		else {
			if ((w != null && w > 1) && (h != null && h > 1))  {
				this.setStyle({overflowX : 'visible', overflowY : 'visible', width : 'auto', height : 'auto'});
			}else if (w != null && w > 1)
				this.setStyle({overflowX : 'visible', width : 'auto'});
			else if (h != null && h > 1) 
				this.setStyle({overflowY : 'visible', height : 'auto'});
			else
				this.setStyle({overflowX : 'hidden', overflowY : 'hidden'});
			this.timer = null;
		}
	},
	appendChild : function(obj, tpltaget) {
		switch(tpltaget) {
			case 'top' :
			case 'bottom' :
				this.getElement(tpltaget).innerHTML = '';
				break;
		}
		if (obj == null)
			return ;
		if (obj.getElement) {
			obj.parentNode = this;
			this.childNodes.push(obj);
			this.getElement(tpltaget).appendChild(obj.getObject());
			return obj;
		} else {
			if (typeof obj == 'string') {
				this.getElement(tpltaget).innerHTML =obj;
				return this.getElement(tpltaget).childNodes[0];
			} else if (obj.getObject) {
				return this.getElement(tpltaget).appendChild(obj.getObject());
			} else 
				return this.getElement(tpltaget).appendChild(obj);
		}
	},
	removeChild : function(obj) {
		if (obj.getElement) {
			obj.parentNode = null;
			return obj.getObject().parentNode.removeChild(obj.getObject());
		} else
			obj.parentNode.removeChild(obj);
	},
	removeAllChild : function() {
		var childNodes = this.getElement().childNodes;
		for(var i = 0; i < childNodes.length; i++)
			this.removeChild(childNodes[i]);
		this.getElement().innerHTML = '';
	}
}

cafen.Image = function(src, options) {
	if (options == null)
		options = {};
	if (/png$/.test(src) && cafen.browser.isIE && cafen.getVersion() < 7) {
		options.attribute = cafen.extend(options.attribute, {src : src});
		options.style = cafen.extend(options.style, {filter : 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src='+ src+',sizingMethod=image);'});
	} else
		options.attribute = cafen.extend(options.attribute, {src : src});
	this.setOptions(cafen.extend({tag : 'img', useanimate : true}, options));	
	this._retry = this.options.retry || 0;
	this.initImage();
}

cafen.Image.prototype = cafen.extendClass({
	_imgLoaded : true,
	_retry_count : 0,
	_retry : 0,
	initImage : function() {
		if (this.options.scale != null) 
			this.setStyle({position : 'relative'});
		this.setImage(this.getElement().src);
	},
	setImage : function(src) {
		if (src == '')
			return ;
		this.setAttribute({width:null,height:null});
		this.tmpImg = new Image();
		this.tmpImg.onerror = this.loadFailure.bind(this);
		this.tmpImg.src = src;
		if (this.tmpImg.width != null && this.tmpImg.width != 0) {
			this.autoResize();
		}else {
			this.tmpImg.onload = this.autoResize.bind(this);
		}
	},
	isLoaded : function() {
		return this._imgLoaded;
	},
	getImageUrl : function() {
		return this.getElement().src;
	},
	getImageSize : function() {
		if (this.isLoaded())
			return [this.tmpImg.width, this.tmpImg.height];
		else
			return [0,0];
	},
	loadFailure : function() {
		this._retry_count ++;
		if (this._retry_count > this._retry) {
			this._retry_count = 0;
			this._imgLoaded = false;
			this.setImage(_cafen_service_url+'images/ico_err.jpg');
			this.execEvent('fail');
		} else 
			window.setTimeout(this.setImage.bind(this, this.tmpImg.src +'?'+this._retry_count), 1000);
	},
	alphaBlend : function() {
		this._tmpAlpha ++;
		if (this._tmpAlpha <= 5) 
			this.setOpacity(Math.abs(this._tmpAlpha*20));
		if (this._tmpAlpha == 0)
			this.getElement().src = this.tmpImg.src;
		if (this._tmpAlpha < 5) 
			window.setTimeout(this.alphaBlend.bind(this), 5);
	},
	playAnimate : function() {
		if (this._imgLoaded) 
			this.autoResize();
	},
	autoResize : function() {
		this._imgLoaded = true;
		var size = [parseInt(this.options.style.width), parseInt(this.options.style.height)];
		var orgsize = [this.tmpImg.width, this.tmpImg.height];
		this.setStyle({left : '0px', top : '0px', zoom :1});
		if (this.options.scale == null) 
			this.setStyle({left : '0px', top : '0px', width : this.tmpImg.width +'px' , height : this.tmpImg.height +'px'});
		try {
			if (document.all){
				if (this.getElement().parentNode != null) {
					if (this.getElement().filters.length == 0)
						this.setStyle({filter: 'progid:DXImageTransform.Microsoft.Pixelate(maxsquare=5)'});
					if (this.getElement().filters.length == 0) {
						this.setStyle({filter: null});
						this.getElement().src = this.tmpImg.src;
					} else {
						this.getElement().filters[0].Stop()
						this.getElement().filters[0].Apply()
						this.getElement().src = this.tmpImg.src;
						this.getElement().filters[0].Play();
					}
				} else
					this.getElement().src = this.tmpImg.src;
			} else {
				this._tmpAlpha = -5;
				this.alphaBlend();
			}
		} catch(ex) {
			this._tmpAlpha = -5;
			this.alphaBlend();
		}	
		if (this.options.scale == null) 
			return ;
		if (orgsize[0] == 0)
			window.setTimeout(this.autoResize.bind(this), 100);
		else if (size[0] > orgsize[0] &&  size[1] > orgsize[1]) {
			this.lastSize = orgsize;
			var leftOffset = (size[0] - orgsize[0]) /2; 
			var topOffset = (size[1] - orgsize[1]) /2;
			this.setAnimate(orgsize[0], orgsize[1], leftOffset, topOffset);
		} else {
			switch (this.options.scale) {
				case 'width' :
					var imgheight = Math.round(orgsize[1] * size[0]/orgsize[0]);
					var imgtop = (size[1] - imgheight)/2;
					this.setAnimate(size[0], imgheight, 0, imgtop);
					break;
				case 'height' :
					var imgwidth = Math.round(orgsize[0] * size[1]/orgsize[1]);
					var imgleft = (size[0] - imgwidth)/2;
					this.setAnimate(imgwidth, size[1], imgleft, 0);
					break;
				case 'max' :
					var imgRate = size[0]/size[1];
					var orgRate = orgsize[0]/orgsize[1];
					if (imgRate < orgRate) {
						var imgheight = Math.round(orgsize[1] * size[0]/orgsize[0]);
						var imgtop = (size[1] - imgheight)/2;
						this.setAnimate(size[0], imgheight, 0, imgtop);
					} else {
						var imgwidth = Math.round(orgsize[0] * size[1]/orgsize[1]);
						var imgleft = (size[0] - imgwidth)/2;
						this.setAnimate(imgwidth, size[1], imgleft, 0);
					}
					break;
				case 'min' :
					var imgRate = size[0]/size[1];
					var orgRate = orgsize[0]/orgsize[1];
					if (imgRate > orgRate) {
						var imgheight = Math.round(orgsize[1] * size[0]/orgsize[0]);
						var imgtop = (size[1] - imgheight)/2;
						this.setAnimate(size[0], imgheight, 0, imgtop);
					} else {
						var imgwidth = Math.round(orgsize[0] * size[1]/orgsize[1]);
						var imgleft = (size[0] - imgwidth)/2;
						this.setAnimate(imgwidth, size[1], imgleft, 0);
					}
					break;
			}
		}
	},
	setAnimate : function(w, h, x, y , dur) {
			if (h == 'hidden') {
   			this.setStyle({overflowY : 'hidden'});
  			h = 0;
  		}
  		if (h == 'max') {
  			var fullsize = this.getFullSize();
  			h = fullsize[1];	
   	}
   	if (this.lastSize != null &&  this.lastSize == [w,h])
   		return ;
   	this.lastSize = [w, h];
		this.options.moveSchedule = [];
		if (this.options.animateStartBind == null)
			this.options.animateStartBind = this.animateStart.bind(this);
		if (this.options.useanimate) {
			var aniBind = [0,2,4,6,8,10,12,14,16,18,20,18];
	    	var pos = this.getOffset();
	    	var size = this.getSize();
	    	var posStepX = (x != null) ? x - pos[0] : 0;
	    	var posStepY = (y != null) ? y - pos[1] : 0;
	    	var sizeStepX = (w != null) ? w - size[0] : 0;
	    	var sizeStepY = (h != null) ? h - size[1] : 0;
			this.options.moveSchedule.push([null, null, pos[0] + posStepX, pos[1] + posStepY]);
			for(var i = 0; i < aniBind.length; i++) {
				var moveRate = Math.sin(Math.PI * aniBind[i]/36);
				if (aniBind[i] > 18)
					moveRate = 2 - moveRate;
				var sizeX =  (sizeStepX != 0) ? size[0] + sizeStepX * moveRate : null;
				var sizeY =  (sizeStepY != 0) ? size[1] + sizeStepY * moveRate : null;
				if (sizeX < 1) 
					sizeX = null;
				if (sizeY < 1) 
					sizeY = null;
				this.options.moveSchedule.push([sizeX, sizeY,null,null]);
			}
		} else {
			this.options.moveSchedule.push([w, h, x, y]);
		}
			if (this.timer != null)
				window.clearTimeout(this.timer);
			if (this.options.moveSchedule.length > 0)
			this.animateStart();
		},
	animateStart : function() {
		var currMove = this.options.moveSchedule[0];
		if (currMove == null)
			return ;
		var w = currMove[0];
		var h = currMove[1];
		var x = currMove[2];
		var y = currMove[3];
		this.options.moveSchedule.shift();
		this.setSize(w,h);
		this.setOffset(x,y);
			if (this.options.moveSchedule.length > 0) 
			this.timer = window.setTimeout(this.options.animateStartBind, 5);
		else {
			if ((w != null && w <= 0) || (h != null && h <= 0))  
				this.getElement().style.display = 'none';
			this.timer = null;
		}
		}
  },cafen.Element.prototype);

cafen.XImage = function(icon, options) {
	if (options == null)
		options = {style :{}};
	if (icon.w != null)
		options.style.width = icon.w +'px';
	if (icon.w != null)
		options.style.height = icon.h +'px';
	if (icon.className != null)
		this.setOptions(cafen.extend({tag : 'div', attribute :{className : icon.className}, style : {overflow : 'hidden', backgroundPosition: '-'+icon.x+'px -'+icon.y+'px', fontSize:'1px', backgroundColor:'transparent'}},options));
	else
		this.setOptions(cafen.extend({tag : 'div', attribute :{innerHTML : icon.text}, style : {overflow : 'hidden', fontSize : '10px'}},options));
}

cafen.XImage.prototype = cafen.extendClass({
	setIcon : function(className, x, y) {
		if (className != null)
			this.setAttribute({className : className});
		this.setStyle({backgroundPosition: '-'+x+'px -'+y+'px'});		
	},
	synkIcon : function(icon) {
		if (icon != null) {
			var className = icon.options.attribute.className;
			var pos = icon.options.style.backgroundPosition;
			var posArr = pos.split(' ');
			var x = parseInt(posArr[0]) *(-1);
			var y = parseInt(posArr[1]) *(-1);
			this.setIcon(className, x, y);
		}
	}
},cafen.Element.prototype);

cafen.Input = function(options) {
	this.setOptions(cafen.extend(options, {tag : 'input'}));	
	this.initInput();
}
cafen.Input.prototype = cafen.extendClass({
	initInput : function() {
		this._nextObject = null;
		this.attachEvent('click', this.inputClick.bind(this));	
		if (this.options.tag == 'input')
			this.getElement().onkeypress =  this.keyInput.bindAsEventListener(this);
	},
	getValue : function() {
		return this.getElement().value;	
	},
	setValue : function(val) {
		this.getElement().value = val;
	},
	setNextObject : function(obj) {
		this._nextObject = obj;
	},
	keyInput : function(event) {
		if (event.keyCode == 13) {
		    try {
				this.execEvent('end', event);
			} catch(ex) {}
			cafen.Event.stop(event);
			return false;
		} else if ((event.keyCode >= 33 && event.keyCode <= 40 ) || event.keyCode == 8 || event.keyCode == 16 || event.keyCode == 18 || event.keyCode == 20 || event.keyCode == 45  || event.keyCode == 46  || event.keyCode == 229 ) {
			return true;
		} else {
			if (this.options.validValue != null) {
				if (this.options._validValue == null) {
					this.options._validValue = [];
					var tmpNum = [];
					if (	this.options.validValue.indexOf('num') != -1) {
						tmpNum.push([48,57, false]);
						tmpNum.push([96,105, false]);
					}
					if (	this.options.validValue.indexOf('alpha') != -1) {
						tmpNum.push([65,90, null]);
					}
					this.options._validValue = tmpNum;
				}
				var result = false;
				for (var i = 0; i < this.options._validValue.length; i++) {
					if ((this.options._validValue[i][2] == null || event.shiftKey == this.options._validValue[i][2]) && event.keyCode >= this.options._validValue[i][0] &&  event.keyCode <= this.options._validValue[i][1]) {
						result = true;
						break;
					}
				}
				return result;
			} else
				return true;
		}
	},
	focus : function() {
		try {
			this.getElement().focus();
			this.getElement().select();
		} catch(ex) {}
		cafen.setFocus(this);
	},
	blur : function() {
		this.getElement().blur();
	},
	setDisabled : function(bl) {
		this.setAttribute({disabled : bl});
	},
	inputClick : function() {
		this.focus();
	}
},cafen.Element.prototype);

cafen.XInput = function(options) {
	this.setOptions(cafen.extend({tag : 'input', className : 'r_inputskin', validValue: null, style : {zIndex: 1000, backgroundColor : '#ffffff'}}, options));
	this.initInput();
}
cafen.XInput.prototype = cafen.extendClass({
	isSelected : false,
	isError : false,
	initInput : function() {
		this._nextObject = null;
		this.attachEvent('blur', this.inputBlur.bind(this));	
		this.attachEvent('focus', this.onfocus.bind(this));	
		this.attachEvent('click', this.inputClick.bind(this));	
		this.attachEvent('mouseover', this.inputOver.bind(this));	
		this.attachEvent('mouseout', this.inputOut.bind(this));
		if (this.options.tag == 'input') 
			this.getElement().onkeypress =  this.keyInput.bindAsEventListener(this);
	},
	inputFocus : function() {
		this.isSelected = true;
		this.isError = false;
		this.setClassName('r_hit');
		return true;
	},
	focus : function() {
		try {
			this.getElement().focus();
			this.getElement().select();
		} catch(ex) {}
	},
	onfocus : function() {
		this.inputFocus();	
		cafen.setFocus(this);
	},
	blur : function() {
		this.getElement().blur();
		this.inputBlur();
	},
	inputBlur : function() {
		this.isSelected = false;
		if (!this.isError)
			this.setClassName('r_off');
		return true;
	},
	inputOver : function() {
		if (!this.isSelected)
			this.setClassName('r_over');
		return true;
	},
	inputOut : function() {
		if (!this.isSelected)
			this.setClassName('r_off');
		return true;
	},
	setError : function(bl) {
		if (bl == null)
			bl = true;
		this.isError = bl;
		if (this.isError)
			this.setClassName('r_on');
		else
			this.setClassName('r_off');
	},
	getValue : function() {
		return this.getElement().value;	
	},
	setValue : function(val) {
		this.getElement().value = val;
	}
},cafen.Input.prototype);


cafen.XTextarea = function(options) {
	this.setOptions(cafen.extend({tag : 'textarea', className : 'r_inputskin', validValue: null, style : {zIndex: 1000, backgroundColor : '#ffffff', border : '0 none', overflowY : 'auto', overflowX : 'auto'}}, options));
	this.initInput();
}
cafen.XTextarea.prototype = cafen.extendClass({},cafen.XInput.prototype);

cafen.Radio = function(name, value, bl, options) {
	if (options == null)
		options = {};
	options.attribute = cafen.extend(options.attribute, {type : 'radio', name : name, value : value, checked : bl});
	this.setOptions(cafen.extend(options, {tag : 'input'}));	
}


cafen.Radio.prototype = cafen.extendClass({},cafen.Input.prototype);


cafen.Checkbox = function(name, value, bl, options) {
	if (options == null)
		options = {};
	options.attribute = cafen.extend(options.attribute, {type : 'checkbox', name : name, value : value, checked : bl});
	this.setOptions(cafen.extend(options, {tag : 'input'}));	
}

cafen.Checkbox.prototype = cafen.extendClass({
	isChecked : function() {
		return this.getElement().checked;	
	},
	setChecked : function(bl) {
		this.setAttribute({checked : bl});		
	}
},cafen.Input.prototype);

cafen.Textarea = function(options) {
	this.setOptions(cafen.extend({tag : 'textarea', style : {fontSize:'11px'}, attribute:{}},options));	
}
cafen.Textarea.prototype = cafen.extendClass({
	getValue : function() {
		try {
			return this.getElement().value;
		} catch(ex) {}
	},
	setValue : function(val) {
		try {
			this.getElement().value= val;
		} catch(ex) {}
	},
	setFocus : function() {
		try {
			this.getElement().focus();
		} catch(ex) {}
	}
},cafen.Element.prototype);

cafen.Select = function(name, items, options) {
	this.setOptions(cafen.extend(options, {tag : 'select'}));	
	for(var i = 0; i < items.length; i++)
		this.addItems(items[i][0],items[i][1]);
}

cafen.Select.prototype = cafen.extendClass({
	addItems : function(txt, val) {
		var options = this.getElement().options;
		options[options.length] = new Option(txt, val, false, false);
	},
	getValue : function() {
		var element =  this.getElement();
		return element[element.selectedIndex].value;
	},
	getText : function() {
		var element =  this.getElement();
		return element[element.selectedIndex].text;
	}
},cafen.Element.prototype);

cafen.Headings = function(size, text, options) {
	if (options == null)
		options = {};
	options.attribute = cafen.extend(options.attribute, {innerHTML : text});
	this.setOptions(cafen.extend(options, {tag : 'h'+size}));	
}
cafen.Headings.prototype = cafen.extendClass({},cafen.Element.prototype);

cafen.Paragraphs = function(text, options) {
	if (options == null)
		options = {};
	options.attribute = cafen.extend(options.attribute, {innerHTML : text});
	this.setOptions(cafen.extend(options, {tag : 'p'}));	
}
cafen.Paragraphs.prototype = cafen.extendClass({},cafen.Element.prototype);

cafen.Links = function(href, text, target, options) {
	if (options == null)
		options = {};
	if (text == null || text == '')
		text = href;
	if (target == null || target == '')
		target = '_new';
	options.attribute = cafen.extend(options.attribute, {href : href, target : target, innerHTML : text});
	this.setOptions(cafen.extend(options, {tag : 'a'}));	
}
cafen.Links.prototype = cafen.extendClass({},cafen.Element.prototype);


cafen.Hr = function(options) {
	if (options == null)
		options = {};
	this.setOptions(cafen.extend(options, {tag : 'hr'}));	
}
cafen.Hr.prototype = cafen.extendClass({},cafen.Element.prototype);

cafen.Pre = function(text, options) {
	if (options == null)
		options = {};
	options.attribute = cafen.extend(options.attribute, {innerHTML : text});
	this.setOptions(cafen.extend(options, {tag : 'pre'}));	
}
cafen.Pre.prototype = cafen.extendClass({},cafen.Element.prototype);

cafen.Table = function(cols, options) {
	if (options == null)
		options = {};
	this.setOptions(cafen.extend(options, {tag : 'table', childNodes : cols}));	
}
cafen.Table.prototype = cafen.extendClass({},cafen.Element.prototype);

cafen.TableAuto = function(options) {
	if (options == null)
		options = {};
	this._currTbody = null;
	this._currTr = null;
	this._currTd = null;
	options.attribute = cafen.extend({cellPadding : 0, cellSpacing:0, border : 0, unselectable : 'on'}, options.attribute);
	this.setOptions(cafen.extend({tag : 'table', attribute : {className : 'r_table'}, style : {fontSize : '12px', width:'auto'}},options));	
}

cafen.TableAuto.prototype = cafen.extendClass({
	_currTbody : null,
	_currTr : null,
	_currTd : null,
	getCell : function(cols, rows) {
		if (this._currTd == null)
			this.addCell();
		var trObj = (rows == null || this._currTbody.childNodes.length <= rows) ? this._currTbody.childNodes[this._currTbody.childNodes.length -1] : this._currTbody.childNodes[rows];
		return (cols == null || trObj.childNodes.length <= cols) ? trObj.childNodes[trObj.childNodes.length -1] : trObj.childNodes[cols];
	},
	addChild : function(obj, cols, rows) {
		this.getCell(cols, rows).appendChild(obj);
	},
	addStyle : function(style, cols, rows) {
		this.getCell(cols, rows).setStyle(style);
	},
	addAttribute : function(style, cols, rows) {
		this.getCell(cols, rows).setAttribute(style);
	},
	addMouseEvent : function(outstyle, overstyle, cols, rows) {
		this.getCell(cols, rows).addMouseEvent(outstyle, overstyle);
	},
	clearCell : function(cols, rows) {
		var currCell = this.getCell(cols, rows);
		currCell.childNodes = [];
		currCell.getElement().innerHTML = '';
	},
	addText : function(txt, cols, rows) {
		this.getCell(cols, rows).getElement().innerHTML = txt;
	},
	getText : function(cols, rows) {
		return this.getCell(cols, rows).getElement().innerHTML;
	},
	addCell : function(obj) {
		if (this._currTr == null)
			this.addRow();
		var childNodes = (typeof obj == 'object') ? [obj] : [];
		this._currTd = new cafen.Cell('', {childNodes : childNodes, attribute:{unselectable : 'on'}, style : {lineHeight:'normal'}});
		this._currTr.appendChild(this._currTd);
		if (obj != null && typeof obj != 'object') {
			this.addText(obj);
		}
		return this._currTd;
	},
	addRow : function(obj) {
		if (this._currTbody == null)
			this.addTBody();
		this._currTr = new cafen.Row([]);
		this._currTd = null;
		this._currTbody.appendChild(this._currTr);
		if (obj != null)
			this.addCell(obj);
		return this._currTr;
	},
	addTBody : function() {
		this._currTbody =  new cafen.Tbody([]);
		this.appendChild(this._currTbody);
		this._currTr = null;
	}
},cafen.Element.prototype);

cafen.Tbody = function(cols, options) {
	if (options == null)
		options = {};
	this.setOptions(cafen.extend(options, {tag : 'tbody', childNodes : cols}));	
}

cafen.Tbody.prototype = cafen.extendClass({
	insertRow : function() {
		return this.getElement().insertRow(-1);
	},
	insertCell : function(obj, text) {
		var cell = obj.insertCell(-1);
		if (typeof text == 'string')
			cell.innerHTML = text;
		else
			cell.appendChild(text);
		return cell;
	},
	replaceCell : function(obj, text) {
		if (typeof text == 'string')
			cell.innerHTML = text;
		else {
			cell.innerHTML = "";
			cell.appendChild(text);
		}
	}
},cafen.Element.prototype);

cafen.TableSimple = function(cols, options, coloptions, celloptions) {
	if (options == null)
		options = {};
	this.setOptions(cafen.extend(options, {tag : 'table'}));	
	var colObjs = [];
	for(var i = 0 ; i < cols.length; i++) {
		var cellObjs = [];
		for(var j = 0 ; j < cols[i].length; j++) 
			cellObjs.push(new cafen.Cell(cols[i][j], celloptions));
		colObjs.push(new cafen.Row(cellObjs, coloptions));
	}
	this.appendChild(new cafen.Tbody(colObjs));
}

cafen.TableSimple.prototype = cafen.extendClass({},cafen.Tbody.prototype);


cafen.Cell = function(text, options) {
	if (options == null)
		options = {};
	options.attribute = cafen.extend(options.attribute, {innerHTML : text, unselectable : 'on'});
	this.setOptions(cafen.extend(options, {tag : 'td'}));	
}
cafen.Cell.prototype = cafen.extendClass({
	addMouseEvent : function(outstyle, overstyle) {
		if (outstyle == null && overstyle == null) {
			if (this._attachEvents != null) {
				this.detachEvent('mouseover', this._attachEvents.over);	
				this.detachEvent('mouseout', this._attachEvents.out);	
				this._attachEvents = null;
			}
		} else {
			if (this._attachEvents == null) {
				this._attachEvents = {
					over :this.cellOver.bind(this),
					out :this.cellOut.bind(this)
				};
				this._attachEventsStyle = {
					over : overstyle,
					out : 	outstyle
				}
				this.attachEvent('mouseover', this._attachEvents.over);	
				this.attachEvent('mouseout', this._attachEvents.out);	
			}
		}
	},
	cellOver : function() {
		this.setStyle(this._attachEventsStyle.over);
		return true;
	},
	cellOut : function() {
		this.setStyle(this._attachEventsStyle.out);
		return true;
	},
	addText : function(text) {
		this.getElement().innerHTML = text;
	},
	addAttribute : function(attb) {
		this.setAttribute(attb);
	}
},cafen.Element.prototype);

cafen.Row = function(cells, options) {
	if (options == null)
		options = {};
	options.attribute = cafen.extend(options.attribute, {});
	this.setOptions(cafen.extend(options, {tag : 'tr',childNodes : cells}));	
}

cafen.Row.prototype = cafen.extendClass({},cafen.Element.prototype);



cafen.Iframe = function(options) {
	this.setOptions(cafen.extend(options, {tag : 'iframe', attribute : {marginHeight :"0", marginWidth : "0", frameBorder : "0", scrolling : "auto"}, style : {overflowY :'auto',overflowX :'auto' }}));	
}
cafen.Iframe.prototype = cafen.extendClass({
	initDoc : function(htmlskin, designMode ) {
		this._isUnderEdit = false;
		if (cafen.browser.isIE) {
			var docDomain = document.domain;
			this.getElement().src = 'javascript:void( (function(){' +  
				'document.open() ;' +  
				'document.write( "'+htmlskin+'"  );' +
				'document.close() ;' +
				'if (document.domain != "'+docDomain+'") ' +  
				'	document.domain = "'+docDomain+'"; ' +  
				'})() )' ;
			if (designMode) {
				try {
					this.setDesignMode(true);
				} catch(ex) { 
					window.setTimeout(this.setDesignMode.bind(this, true),1);
				}
			}
		} else {
			this.getElement().src = 'javascript:void(0)' ;
			try {
				var editdoc = this.getDocument();
				editdoc.open() ;
				editdoc.write(htmlskin);
				editdoc.close();
				if (designMode) {
					try {
						this.setDesignMode(true);
					} catch(ex) { 
						window.setTimeout(this.setDesignMode.bind(this, true),1);
					}
				}
			} catch(ex) {}
		}
	},
	getWindow : function() {
		return this.getElement().contentWindow;
	},
	getDocument : function() {
		return this.getWindow().contentDocument || this.getWindow().document;
	},
	getBody : function() {
		return this.getDocument().body;
	},
	getScrollObject : function() {
		return this.getWindow();
	},
	getRealObject : function() {
		return this.getBody();
	},
	changeStyle : function(stylecss) {
		var headObj = this.getDocument().getElementsByTagName("head")[0];
		if (headObj != null) {
			stylecss += '?'+cafen.getUniqID('css');
			var headStyle = headObj.getElementsByTagName("link")[0];
			if (headStyle != null) 
				headStyle.setAttribute("href", stylecss);
		}
	},
	focus : function() {
		this.getWindow().focus();
	},
	appendChild : function(obj) {
		this.getRealObject().appendChild(obj);
	},
	removeChild : function(obj) {
		this.getRealObject().removeChild(obj);
	},
	getDocHeight : function() {
		return parseInt(this.getScrollObject().scrollHeight) || 0;
	},
	getDocWidth : function() {
		return parseInt(this.getScrollObject().scrollWidth) || 0;
	},
	createElement : function(tag) {
		return this.getDocument().createElement(tag);
	},
	setDesignMode : function(bl) {
		if (bl) {
			try {
				this.getDocument().designMode = 'On';
				this.getBody().contentEditable = "true";
			} catch(ex) {}
			cafen.Event.observe(this.getRealObject(),'focus',this.onFocus.bind(this));
			cafen.Event.observe(this.getRealObject(),'blur',this.onBlur.bind(this));
			cafen.Event.observe(this.getRealObject(),'keyup',this.saveFocus.bind(this));
			cafen.Event.observe(this.getRealObject(),'mouseup',this.onClick.bind(this));
		} else {
			try {
				this.getDocument().designMode = 'Off';
				this.getBody().contentEditable = "false";
			} catch(ex) {}
		}
	},
	getBaseRange : function() {
		if (document.selection) {
			this._baseRange = this.getDocument().body.createTextRange().duplicate();
			this._baseRange.moveToElementText(this.getRealObject());
		} else {
			this._baseRange = this.getDocument().createRange().cloneRange();
			this._baseRange.selectNodeContents(this.getRealObject());
		}
		return this._baseRange;
	},
	isInRange : function(range) {
		if (range != null) {
			var baseRange = this.getBaseRange();
			if (baseRange.inRange) 
				return baseRange.inRange(range);
			else if (baseRange.isPointInRange)
				return baseRange.isPointInRange(range.endContainer,range.endOffset);
			else {
				var baseObj = this.getRealObject();
				var tarObj = range.endContainer.parentNode;
				while(tarObj != null && tarObj.parentNode) {
					if (tarObj.parentNode == baseObj) 
						return true;
					else
						tarObj = tarObj.parentNode;
				}
				return false;
			}
			return true;
		} else
			return false;
	},
	getEventPointer : function(event) {
		event = (event || this.getWindow().event);
		var x = 0, y = 0;
		if (event.pageX && event.pageY) {
			x =  event.pageX - this.getRealObject().scrollLeft; y =  event.pageY  - this.getRealObject().scrollTop;
		} else {
			x = event.clientX;y = event.clientY;
		}
		return [x, y];
	},
	getSelectionCoordinates :function() {
		var x = 0, y = 0, range, start = false;
		if (window.getSelection) {
			range = this.getFocus();
			range.collapse(start);
			var dummy = document.createElement("span");
			range.insertNode(dummy);
			var rect = dummy.getBoundingClientRect();
			x = rect.left;
			y = rect.top;
			dummy.parentNode.removeChild(dummy);
		} else if (document.selection && document.selection.type != "Control") {
			range = this.getFocus();
			range.collapse(start);
			x = range.boundingLeft + this.getRealObject().scrollLeft;
			y = range.boundingTop + this.getRealObject().scrollTop;
		}
		return {x: x, y: y};
	},
	_isUnderEdit : false,
	isUnderEdit : function() {
		return this._isUnderEdit;
	},
	onFocus : function() {
		if (!this._isUnderEdit) 
			this._isUnderEdit = true;
	},
	onClick : function() {
		if (!this._isUnderEdit) 
			this._isUnderEdit = true;
		this.saveFocus();
		if (this._onChangeFocus)
			this._onChangeFocus(true);
	},
	onBlur : function() {
		if (this._isUnderEdit) 
			this._isUnderEdit = false;
	},
	setFocus : function() {
		if (!this.isUnderEdit())
			this.setDummyFocus();
	},
	_onChangeFocus : null,
	_useMobile : false,
	_mobuleQueue : [],
	setOnChangeFocus : function(callBackfunc) {
		this._onChangeFocus = callBackfunc;
		this._useMobile = true;
		this._mobuleQueue = [];
	},
	_onChangeRange : null,
	setOnChangeRange : function(callBackfunc) {
		this._onChangeRange = callBackfunc;
	},
	getFocus : function() {
		if (this.lastFocus) {
			return this.lastFocus;
		} else {
			this.lastFocus = this.getBaseRange();
			if (window.getSelection){
				this.lastFocus.setStart(this.lastFocus.startContainer, this.lastFocus.startOffset);
				this.lastFocus.setEnd(this.lastFocus.startContainer, this.lastFocus.startOffset);
			}	 
			return this.lastFocus;
		}
	},
	lastFocus : null,
	saveFocus : function() {
		if (this.isUnderEdit()) {
			var tmpRange = null;
			try {
				if (document.selection) {
					tmpRange = this.getDocument().selection.createRange();
				} else if (window.getSelection){
					tmpRange = this.getWindow().getSelection().getRangeAt(0).cloneRange();
				}
			} catch(ex) {}
			if (tmpRange != null && this.isInRange(tmpRange)) 
				this.lastFocus = tmpRange;
		}
		if (this._onChangeRange) 
			this._onChangeRange();
	},
	setDummyFocus : function() {
		this.getRealObject().focus();
	},
	restoreFocus : function() {
		if (this.lastFocus != null) {
			if (this.isInRange(this.lastFocus)) {
				if (document.selection) {
					this.lastFocus.select();	
				} else if (window.getSelection){
					var selectionObj = this.getWindow().getSelection();
					if (selectionObj.rangeCount > 0) 
						selectionObj.removeAllRanges();
					selectionObj.addRange(this.lastFocus);
				}
			} else {
				if (!this.isUnderEdit())
					this.setDummyFocus();
			}
			if (this._onChangeRange) 
				this._onChangeRange();
		}
	},
	selectNode : function(thisNode) {
		if (document.selection) {
			this.getDocument().selection.empty() ;
			var selectObj = null;
			try {
				selectObj = this.getBody().createControlRange();
				selectObj.addElement(thisNode);
			} catch(ex) {
				try {
					this.getWindow().focus();
					selectObj = this.getDocument().selection.createRange();
					selectObj.moveToElementText(thisNode);
				} catch(ex) {
					selectObj = null;
				}
			}
			try {
				if (selectObj != null)
					selectObj.select() ;
			} catch(ex) {}
		} else if (document.createRange) {
			try {
				var selectNode = this.getDocument().createRange();
				selectNode.selectNode(thisNode);
				var selectObj = this.getWindow().getSelection();
				selectObj.removeAllRanges();
				selectObj.addRange(selectNode);
			} catch(ex) {}
		}
		this.saveFocus();
	},
	getSelectedBlockTag : function () {
		var selectObj = this.getSelectedElement();
		var selectTag = selectObj;
		var fontBlocks = 'p';
		while(selectTag) {
			if (selectTag.tagName != null && selectTag.tagName.length == 2 && selectTag.tagName.indexOf('H') == 0) {
				fontBlocks = selectTag.tagName.toLowerCase();
				break;
			} else
				selectTag =  (selectTag.parentNode) ? selectTag.parentNode : null;
		}
		return fontBlocks;
	},	
	getParentElement : function(tag, tagObj) {
		tag = tag.toUpperCase();
		var findObj = null;
		tarObj = tagObj || this.getSelectedElement();
		if (tarObj == null)
			return null;
		var stopObj = this.getRealObject();
		while(tarObj && tag.indexOf(tarObj.tagName) == -1 && tarObj.parentNode) {
			if (tarObj == stopObj) 
				break;
			tarObj = tarObj.parentNode;
		}
		if (tag.indexOf(tarObj.tagName) > -1)
			return tarObj;
		else
			return null;
	},
	unsetSelectedType : function() {
		if (document.selection)
			this.getDocument().selection.empty();
	},
	getSelectedHTML : function() {
		if(cafen.browser.isIE) {
			var selectObj =  this.getDocument().selection.createRange();
			var thisHtml = "";
			if (selectObj != null && selectObj.tagName == 'BODY') 
				thisHtml = selectObj.innerHTML;
			else if (selectObj.htmlText) 
				thisHtml = selectObj.htmlText ;
		} else {
			var selectObj = this.getWindow().getSelection();
			var thisHtml  = "";
			if(selectObj.rangeCount > 0 && window.XMLSerializer) {
				selectObj = selectObj.getRangeAt(0);
				if (selectObj != null && selectObj.tagName == 'BODY') 
					thisHtml = selectObj.innerHTML;
				else				
					thisHtml  = new XMLSerializer().serializeToString(selectObj.cloneContents());
			}
		}
		return thisHtml;
	},
	getSelectedElement : function () {
		var selectObj = null;
		if(document.selection) {
			selectObj =  this.getFocus();
			if(this.getSelectedType() == "Control") {
				if(selectObj.item)
					selectObj = selectObj.item(0);
			} else if (selectObj != null) {
				if (!this.isInRange(selectObj)) 
					return null;
			}
		} else {
			selectObj = this.getFocus();
			if(this.getSelectedType() == "Control") {
				selectObj =  selectObj.anchorContainer;
			} else {
				selectObj =  selectObj.startContainer;
			}
		}
		if (selectObj != null && !selectObj.tagName) {
			try {
				if(selectObj.parentElement && document.selection) 
					selectObj = selectObj.parentElement();
				else if(typeof selectObj.parentElement == 'object') 
					selectObj = selectObj.parentElement;
				else if (selectObj.parentNode)
					selectObj = selectObj.parentNode;
			} catch(ex) {
				cafen.debugMessage(ex);	
			}
		}
		if (selectObj == this.getScrollObject())
			return null;
		else
			return selectObj;
	},
	getSelectedType : function () {
		if(document.selection)
			return this.getFocus().type;
		else {
			var selectType = "None";
			var selectRange = this.getFocus();
			if(selectRange){
				if(selectRange.startContainer == selectRange.endContainer && (selectRange.endOffset - selectRange.startOffset) == 1 && selectRange.startContainer.nodeType != Node.TEXT_NODE ) 
					selectType = "Control";
				else
					selectType = "Text";
			}
			return selectType;
		}
	},
	synkHide : function() {
		this.hide();
		if (this._onChangeFocus)
			this._onChangeFocus(false);
	},
	synkShow : function() {
		this.show();
		if (this._onChangeFocus)
			this._onChangeFocus(true);
	},
	insertHTML : function(html, beforeObj) {
		var editdoc = this.getDocument();
		if (beforeObj != null) {
			var tmpObj = editdoc.createElement('blockquote');
			tmpObj.style.border = '1px dashed #a0a0a0';
			tmpObj.style.padding = '3px';
			tmpObj.innerHTML = html;
			if (beforeObj.tagName != 'TD' && beforeObj.tagName != 'TR' && beforeObj.tagName != 'TBODY' && beforeObj.tagName != 'BODY') {
				beforeObj.parentNode.insertBefore(tmpObj, beforeObj);
			} else if (beforeObj.firstChild)
				beforeObj.insertBefore(tmpObj, beforeObj.firstChild);
			else
				beforeObj.appendChild(tmpObj);
		} else {
			this.execCommand("insertHTML", false ,html); 
		}
	},
	checkFocus : function() {
		if (!this.isUnderEdit()) {
			this._isUnderEdit = true;
			if (cafen.browser.isOpera) {
				this.getRealObject().focus();
				if (this._useMobile)
					this.restoreFocus();
			} else {
				this.getRealObject().focus();
				this.restoreFocus();
			}
		}
	},
	execCommand : function(cmd,bl, value) {
		var cmdResult = null;
		try {
			this.checkFocus();
			cafen.debugMessage('execCommand : '+ cmd , 'exec');
			switch(cmd.toLowerCase()) {
				case 'insertparagraph' :
				case 'inserthtml' :
					if(cafen.browser.isIE) {
						if (cmd.toLowerCase() == 'insertparagraph') 
							value = '<div></div>';
						var sRange = this.getDocument().selection.createRange();
						if (sRange != null) {
							if (this.isInRange(sRange)) {
								if (this._useMobile && this._mobuleQueue.length > 0) {
									var tmpNodeID = cafen.getUniqID('node');
									sRange.pasteHTML('<span id='+tmpNodeID+'>'+value+'</span>');
									sRange.collapse(false);
									var tempNode = this.getDocument().getElementById(tmpNodeID);
									sRange.moveToElementText(tempNode);
									if (this._mobuleQueue.length > 0) {
										for(var i = 0 ; i < this._mobuleQueue.length; i++) 
											sRange.execCommand(this._mobuleQueue[i].cmd, this._mobuleQueue[i].bl, this._mobuleQueue[i].value);
										this._mobuleQueue = [];
									}
									tempNode.removeNode();
									sRange = this.getDocument().selection.createRange();
								} else {
									sRange.pasteHTML(value);
									sRange.collapse(false);
								}
								if (this._useMobile) {
									this.lastFocus = sRange;
									this.restoreFocus();
								}
							}
						}
						cmdResult = true;
					} else {
						if (this._mobuleQueue.length > 0) {
							var beforeRange = this.getFocus();
							cmdResult = this.getDocument().execCommand(cmd,bl, value);
							this.saveFocus();
							var afterRange = this.getFocus();
							var selectObj = this.getWindow().getSelection();
							var range = this.getDocument().createRange();
							range.setStart(beforeRange.startContainer, beforeRange.startOffset);
							range.setEnd(afterRange.endContainer, afterRange.endOffset);
							selectObj.removeAllRanges();
							selectObj.addRange(range);
							for(var i = 0 ; i < this._mobuleQueue.length; i++) 
								this.getDocument().execCommand(this._mobuleQueue[i].cmd, this._mobuleQueue[i].bl, this._mobuleQueue[i].value);
							this._mobuleQueue = [];
							var currRange = this.getWindow().getSelection().getRangeAt(0);
							this.lastFocus.setStart(currRange.endContainer, currRange.endOffset);
							this.lastFocus.setEnd(currRange.endContainer, currRange.endOffset);
							this.restoreFocus();
						} else {
							cmdResult = this.getDocument().execCommand(cmd,bl, value);
							if (this._useMobile) {
								var currRange = this.getWindow().getSelection().getRangeAt(0);
								if (currRange.endContainer && (currRange.endContainer.parentElement || currRange.endContainer.parentNode).tagName== 'SPAN') {
									var tarObject = currRange.endContainer.parentElement || currRange.endContainer.parentNode;
									var textNode = this.getDocument().createTextNode(tarObject.innerText || tarObject.innerHTML);
									tarObject.parentNode.insertBefore(textNode, tarObject);
									tarObject.parentNode.removeChild(tarObject);
								}
							}
						}
						break;
					}
					break;
				case 'delete' :
					if(cafen.browser.isIE) {
						var sRange = this.getFocus();
						if (sRange != null) {
							if (this.isInRange(sRange)) {
								sRange.moveStart('character', -1);
								sRange.execCommand("delete");
								sRange.collapse(false);
							} else
								cmdResult = false;
						} else 
							cmdResult = false;
					} else 
						cmdResult = this.getDocument().execCommand(cmd,bl, value);
				case 'fontname' : 
				case 'fontsize' : 
				case 'hilitecolor' : 
				case 'bold' : 
				case 'underline' : 
				case 'italic' : 
				case 'strikethrough' : 
				case 'subscript' : 
				case 'strikethrough' : 
				case 'superscript' : 
				case 'forecolor' : 
				case 'backcolor' :
					if (this._useMobile)
						this._mobuleQueue.push({cmd : cmd , bl : bl, value : value});
					cmdResult = this.getDocument().execCommand(cmd,bl, value);
					break;
				default :
					cmdResult = this.getDocument().execCommand(cmd,bl, value);
					break; 
			}
			this.saveFocus();
			this.onChange();
			if (this._onChangeFocus)
				this._onChangeFocus(true);
		} catch(ex) {
			throw cafenMsg.get('ed_finderror') +'<hr>'+ex;
		}
		return cmdResult;
	},
	queryCommandValue: function(cmd) {
		switch(cmd.toLowerCase()) {
			case 'backcolor' :
				if (cafen.browser.isFF || cafen.browser.isOpera) {
					var color =  this.getDocument().queryCommandValue('hilitecolor');
					if (color == null || color == 'transparent')
						color =  this.getDocument().queryCommandValue('backcolor');
					if (color == null || color == 'transparent')
						color = cafen.getStyle(this.getSelectedElement(), 'backgroundColor', this.getDocument());
					return color;
				} else
					return this.getDocument().queryCommandValue(cmd);
					break;
			default :				
				try {
					return this.getDocument().queryCommandValue(cmd);
				} catch(ex) {
					return '';	
				}
				break;
		}
	},		
	queryCommandState : function(cmd) {
		try {
			return this.getDocument().queryCommandState(cmd);
		} catch(ex) {
			return false;	
		}
	},
	getContents : function() {
		return this.getRealObject().innerHTML;
	},
	setContents : function(html) {
		this.getRealObject().innerHTML = html;
		this.onChange({scrollTop : 0});
	}
},cafen.Element.prototype);


cafen.divEditable = function(options) {
	this.setOptions(cafen.extend(options, {tag : 'div', attribute : {spellcheck :'false'}, style : {position:'relative', left:'0',top : '0', overflowY :'auto',overflowX :'auto',outline: 'none'}}));	
}

cafen.divEditable.prototype = cafen.extendClass({
	initDoc : function(htmlskin, designMode ) {
		this._isUnderEdit = false;
		var reg = null;
		var header = '';
		if (reg = cafen.find('<head>(.+)<\\/head>', htmlskin)) {
			header = reg[1];
			var styleAdded = '';
			if (reg = cafen.find('<style>(.+)<\\/style>', header)) 
			styleAdded = reg[1];
			var styleId = cafen.getUniqID('stl');
			header = [];
			header.push('P, H1, H2, H3, H4, H5, H6 {margin-top:2px;margin-bottom:2px;}');
			header.push('FONT, P,TD, BODY {text-decoration: none;line-height:180%;}');
			header.push('BODY {color:#555555; background-color:transparent;font-family:"Dotum";}');
			header.push('P,TD, BODY {font-size:10pt;font-family:"Dotum";}');
//			header.push('marquee, {border:1px dashed #f0f0f0;cursor:default;width:auto}');
			header.push('table td{border:1px solid #f0f0f0;}');
			header.push('EMBED, iframe {background-color:#ececec}');
			header.push('.moretitle{border-bottom:3px solid #d0d0d0;padding-left:5px;cursor:pointer;font-size:12px;}');
			header.push('.morecontents{border-left: 1px solid #d0d0d0;border-bottom: 1px solid #d0d0d0;border-right: 1px solid #d0d0d0;padding :4px 10px 4px 10px;}');
			header.push('H1 {font-family:arial;font-weight:bold;color:#666633;font-size:12pt;}');
			header.push('H2 {font-family:verdana;font-weight:bold;color:#454545;font-size:12pt}');
			header.push('H3 {font-family:arial;font-weight:bold;color:#999966;font-size:11pt}');
			header.push('H4 {font-family:verdana;font-weight:bold;color:#454545;font-size:9pt}');
			header.push('H5 {font-family:verdana;font-weight:bold;color:#ff4545;font-size:9pt}');
			header.push('H6 {font-family:verdana;font-weight:bold;color:#45ff45;font-size:9pt}');
			if (styleAdded != '') {
				styleAddeds = styleAdded.split('}');
				for(var i = 0; i < styleAddeds.length; i++) {
					var tmpStyle = styleAddeds[i];
					if (cafen.stringUtil.trim(tmpStyle) != '') 
						header.push(tmpStyle+'}');
				}
			}
			for(var i = 0 ; i < header.length ; i++) {
				var currHeader =header[i].split(',');
				for(var j = 0 ; j < currHeader.length; j++) {
					currHeader[j] = 	"#"+styleId +' '+ currHeader[j];
				}
				header[i] = currHeader.join(',');
			}
			this.setAttribute({id : styleId});
			cafen.setHeaderStyle(header);	
		}
		if (reg = cafen.find('<body[^>]*>(.+)<\\/body>', htmlskin))
			this.setContents(reg[1]);
		if (designMode) {
			try {
				this.setDesignMode(true);
			} catch(ex) { 
				window.setTimeout(this.setDesignMode.bind(this, true),1);
			}
		}
	},
	getDocument : function() {
		return window.document;
	},
	getWindow : function() {
		return window;
	},
	getBody : function() {
		return window.document.body || window.document.documentElement;
	},
	getScrollObject : function() {
		return this.getElement();
	},
	getRealObject : function() {
		return this.getElement();
	},
	setDesignMode : function(bl) {
		if (bl) {
			try {
				this.getRealObject().contentEditable = "true";
				this.getRealObject().designMode = 'On';
			} catch(ex) {}
			cafen.Event.observe(this.getRealObject(),'focus',this.onFocus.bind(this));
			cafen.Event.observe(this.getRealObject(),'blur',this.onBlur.bind(this));
			cafen.Event.observe(this.getRealObject(),'keyup',this.onKeyUp.bindAsEventListener(this));
			cafen.Event.observe(this.getRealObject(),'mouseup',this.onClick.bind(this));
		} else {
			try {
				this.getRealObject().designMode = 'Off';
				this.getRealObject().contentEditable = "false";
			} catch(ex) {}
		}
	},
	setDummyFocus : function() {
		if (!this._isUnderEdit) {
			this.getRealObject().focus();
			window.setTimeout(this.saveFocus.bind(this), 1);
		}
	},
	onKeyUp : function(event) {
		if (this._useMobile) {
			cafen.Event.stop(event);
			if (this._onChangeFocus)
				this._onChangeFocus(true);
		} else {
			this.onClick();
		}
	},
	getEventPointer : function(event) {
		event = (event || this.getWindow().event);
		var x = 0, y = 0;
		if (event.pageX && event.pageY) {
			x =  event.pageX;
			y =  event.pageY;
		} else {
			x = event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft);
			y = event.clientY + (document.documentElement.scrollTop || document.body.scrollTop);
		}
		var pos = this.cumulativeOffset();
		x -= pos[0];
		y -= pos[1];
		return [x, y];
	},
	getSelectionCoordinates :function() {
		var x = 0, y = 0, range, start = false;
		if (window.getSelection) {
			range = this.getFocus();
			range.collapse(start);
			var dummy = document.createElement("span");
			dummy.innerHTML = '&nbsp;';
			range.insertNode(dummy);
			var rect = dummy.getBoundingClientRect();
			x = rect.left + (document.documentElement.scrollLeft || document.body.scrollLeft);
			y = rect.top + (document.documentElement.scrollTop || document.body.scrollTop);
			dummy.parentNode.removeChild(dummy);
		} else if (document.selection && document.selection.type != "Control") {
			var tmpPos = cafen.cumulativeOffset(this.getSelectedElement());
			range = this.getFocus();
			range.collapse(start);
			x = range.boundingLeft + (document.documentElement.scrollLeft || document.body.scrollLeft)*2;
			y = range.boundingTop + (document.documentElement.scrollTop || document.body.scrollTop)*2;
		}
		rangePos = {x: x, y: y};
		var pos = this.cumulativeOffset();
		rangePos.x -= pos[0];
		rangePos.y -= pos[1];
		return rangePos;
	}
},cafen.Iframe.prototype);

cafen.Div = function(options) {
	this.setOptions(cafen.extend({tag : 'div', style : {fontSize : '11px', overflow : 'visible', overflowX : 'visible', overflowY : 'visible'}},options));	
}

cafen.Div.prototype = cafen.extendClass({},cafen.Element.prototype);

cafen.Center = function(options) {
	this.setOptions(cafen.extend({tag : 'center', style : {fontSize : '11px', overflow : 'visible', overflowX : 'visible', overflowY : 'visible'}},options));	
}
cafen.Center.prototype = cafen.extendClass({},cafen.Element.prototype);


cafen.Button = function(options) {
	this.setOptions(cafen.extend({tag : 'button', style :{fontSize : '11px', cursor : cafen.getCursor()}, attribute : {type : 'button'}}, options));	
	this.initButton();
}

cafen.Button.prototype = cafen.extendClass({
	initButton : function() {
		this.attachEvent('focus', this.buttonFocus.bind(this));	
	},
	buttonFocus : function() {
		this.getElement().blur();
		return true;
	},
	setDisable : function(bl) {
		if (bl) {
			this.setAttribute({disabled : true});
			this.setStyle({cursor : 'default'});
		} else {
			this.setAttribute({disabled : null});
			this.setStyle({cursor : cafen.getCursor()});
		}
	}
},cafen.Element.prototype);

cafen.Container = function() {}

cafen.Container.prototype =  cafen.extendClass({
	insertBefore : function(el) {},
	insertAfter : function(el) {},
	appendChild : function(obj) {
		if (obj.parentNode != null && obj.parentNode != this)
			obj.parentNode.removeChild(obj);
		obj.parentNode = this;
		this.childNodes.push(obj);
		this.getElement().appendChild(obj.getObject());
		},
		removeChild : function(obj) {
			var childNodes_n = [];
		for(var i = 0; i < this.childNodes.length; i++) {
			if (this.childNodes[i] != obj) {
				childNodes_n.push(this.childNodes[i]);
			} else 
				obj.parentNode = null;
		}
		this.childNodes = childNodes_n;
	}
},cafen.Element.prototype);


cafen.XButton = function(options) {
	if (options == null)
		options = {};
	options.style = cafen.extend({border : '0 none', overflow:'visible', lineHeight:'100%', backgroundColor : 'transparent',fontSize:'13px', margin :'0', padding : '2px', cursor : cafen.getCursor()},options.style);
	this.setOptions(cafen.extend(
		{
			tag : 'button', 
			className :'r_rbtnskin', 
			childNodes : cafen.getChildObject(options), 
			attribute :{type : 'button', hidefocus : 'true'}
		},options));
	this.initButton();
}


cafen.XButton.prototype = cafen.extendClass({
	isSelected : false,
	initButton : function() {
		this.isSelected = false;
		if (!this.options.multiselect)
			this.attachEvent('focus', this.onfocus.bind(this));	
		this.attachEvent('mouseover', this.buttonOver.bind(this));	
		this.attachEvent('mouseout', this.buttonOut.bind(this));	
		this.attachEvent('mousedown', this.buttonDown.bind(this));	
		this.attachEvent('mouseup', this.buttonOver.bind(this));	
		this.attachEvent('click', this.buttonFocus.bind(this));	
	},
	buttonFocus : function() {
		this.focus();
		return true;
	},
	buttonOver : function() {
		this.setClassName('r_over');
		return true;
	},
	blur : function() {
		try {
			this.getElement().blur();
			this.setSelected(false);
			this.buttonOut();
		} catch(ex) {}
	},
	onfocus : function() {
		this.setSelected(true);
		cafen.setFocus(this);
	},
	focus : function() {
		if (this.getElement().focus) {
			try {
				this.getElement().focus();
			} catch(ex) {}
		}
	},
	buttonOut : function() {
		if (!this.isSelected)
			this.setClassName('r_off');
		else
			this.setClassName('r_on');
		return true;
	},
	buttonDown : function() {
		this.setClassName('r_hit');
		return true;
	},
	setSelected : function(bl) {
		this.isSelected = bl;
		if (this.isSelected)
			this.setClassName('r_on');
		else 
			this.setClassName('r_off');
	}
},cafen.Element.prototype);


cafen.XIcon = function(options) {
	this.movePos = [options.off, options.on, options.over, options.hit];
	if (options.src != null)
		this.setOptions(cafen.extend({tag : 'button', className :'', attribute :{type : 'button', unselectable : 'on'}, style : {border : '0 none', backgroundColor : 'transparent',overflow : 'hidden', backgroundImage : 'url('+options.src+')',backgroundPosition: '0px -'+options.off+'px'}},options));
	else 
		this.setOptions(cafen.extend({tag : 'button', className :'', attribute :{className:options.icon, type : 'button',unselectable : 'on'}, style : {overflowX : 'hidden', overflowY : 'hidden', backgroundPosition: '0 -'+options.off+'px'}},options));
	this.initButton();
}

cafen.XIcon.prototype = cafen.extendClass({
	movePos : null,
	isSelected : false,
	isDisabled : false,
	initButton : function() {
		this.isSelected = false;
		this.isDisabled = false;
		this.attachEvent('mouseover', this.buttonOver.bind(this));	
		this.attachEvent('mouseout', this.buttonOut.bind(this));	
		if (this.movePos[3] != null)
			this.attachEvent('mousedown', this.buttonDown.bind(this));	
		this.attachEvent('mouseup', this.buttonOver.bind(this));	
		this.attachEvent('focus', this.buttonFocus.bind(this));	
	},
	buttonFocus : function() {
		this.getElement().blur();
		return true;
	},
	setChildDisable : function(bl) {
		var mouseCursor = (!bl) ? cafen.getCursor() : 'default';
		for(var i = 0; i < this.childNodes.length; i++) {
			this.childNodes[i].setStyle({cursor : mouseCursor});
		}	
	},
	setDisable : function(bl) {
		this.isDisabled = bl;
		if (bl) {
			this.setAttribute({disabled : true});
			this.setStyle({cursor : 'default'});
		} else {
			this.setAttribute({disabled : null});
			this.setStyle({cursor : cafen.getCursor()});
		}
		this.setChildDisable(bl);
		this.setButton(false);
	},
	setButton : function(bl) {
		var x = (bl) ? this.movePos[2] : 0;
		var y = null;
		if (this.isDisabled)
			y = this.movePos[0] + this.movePos[1] * 2;
		else 
			y = (this.isSelected) ? this.movePos[0] + this.movePos[1] : this.movePos[0];
		this.setStyle({backgroundPosition : '-'+x+'px -'+y+'px'});
	},
	buttonDown : function() {
		var x = this.movePos[3];
		var y = null;
		if (this.isDisabled)
			y = this.movePos[0] + this.movePos[1] * 2;
		else 
			y = (this.isSelected) ? this.movePos[0] + this.movePos[1] : this.movePos[0];
		this.setStyle({backgroundPosition : '-'+x+'px -'+y+'px'});
		return true;
	},
	buttonOver : function() {
		this.setButton(true);
		return true;
	},
	buttonOut : function() {
		this.setButton(false);
		return true;
	},
	toggleSelect : function() {
		this.setSelected(!this.isSelected);
		return this.isSelected;
	},
	setSelected : function(bl) {
		this.isSelected = bl;
		this.setButton(false);
	}
},cafen.Element.prototype);


cafen.XTab = function(options) {
	if (options.text != null && cafen.browser.isIE && cafen.getVersion() > 7)
		options.text = options.text+' &nbsp;';
	this.setOptions(
		cafen.extend(
			{
				tag : 'button', 
				className :'r_tab', 
				childNodes : cafen.getChildObject(options), 
				attribute : {unselectable : 'on', type : 'button'}, 
				style : {
					padding : '0 2px',
					backgroundColor : 'transparent', 
					cursor : cafen.getCursor(), 
					textAlign : 'center',
					width:'auto',
					verticalAlign: 'middle',
					lineHeight: 'normal',
					height : '17px'
				}
			},options
		)
	);
	this.initTab();
}

cafen.XTab.prototype = cafen.extendClass({
	isSelected : false,
	initTab : function() {
		this.attachEvent('mouseover', this.buttonOver.bind(this));	
		this.attachEvent('mouseout', this.buttonOut.bind(this));	
		this.attachEvent('mousedown', this.buttonDown.bind(this));	
		this.attachEvent('mouseup', this.buttonOver.bind(this));
		this.attachEvent('focus', this.buttonFocus.bind(this));
		this.attachEvent('click', this.buttonFocus.bind(this));
		
	},
	buttonFocus : function() {
		this.getElement().blur();
		cafen.setFocus(this);
	},
	buttonOver : function() {
		if (!this.isSelected)
			this.setClassName('r_over');
		return true;
	},
	buttonOut : function() {
		if (!this.isSelected)
			this.setClassName('r_off');
		return true;
	},
	buttonDown : function() {
		if (!this.isSelected)
			this.setClassName('r_hit');
		return true;
	},
	setSelected : function(bl) {
		if (this.isSelected != bl) {
			this.isSelected = bl;
			if (bl)
				this.setClassName('r_on');
			else 
				this.buttonOut();
		}
	}
},cafen.Element.prototype);

cafen.XTabMenu = function(childNodes, options) {
	if (options == null)
		options = {};
	this._currTbody = null;
	this._currTr = null;
	options.attribute = cafen.extend({cellpadding : 0, cellspacing:0, border : 0, unselectable : 'on' }, options.attribute);
	this.setOptions(cafen.extend({tag : 'table', attribute : {className : 'r_table'},style : {position : 'relative', top : '1px', left : '3px'}},options));	
	this.initTabMenu(childNodes)
}

cafen.XTabMenu.prototype = cafen.extendClass({
	_lastSelected : null,
	initTabMenu : function(childNodes) {
		this.addRow();
		for(var i =0; i < childNodes.length; i++) {
			childNodes[i].parentTab = this;
			this.addCell(childNodes[i]);
			this.addStyle({verticalAlign :'bottom', fontSize:'1px', lineHeight:'1px'});
			if (cafen.browser.isIE)
				window.setTimeout(this.getChildSize.bind(this, childNodes[i]),10);
		}
	},
	getChildSize : function(obj) {
		if (obj.getElement().offsetWidth > 0)
			cafen.setStyle(obj.getElement(), { width: obj.getElement().offsetWidth+'px'});
	},
	setSelected : function(obj) {
		if (this._lastSelected != null)
			this._lastSelected.setSelected(false);
		obj.setSelected(true);
		this._lastSelected = obj;
	}
},cafen.TableAuto.prototype);


cafen.IndexTab = function(text, childNodes, indexSize, options) {
	if (options == null)
		options = {};
	this._currTbody = null;
	this._currTr = null;
	options.attribute = cafen.extend({cellPadding : 0, cellSpacing:0, border : 0, unselectable : 'on' }, options.attribute);
	this.setOptions(cafen.extend({tag : 'table', attribute : {className : 'r_table'},style : {lineHeight:'normal', margin:'0', display:'inline'}},options));	
	this.initIndexTab(text, childNodes, indexSize)
}

cafen.IndexTab.prototype = cafen.extendClass({
	initIndexTab : function(text, childNodes, indexSize) {
		this.addRow();
		if (text != null && text != '') {
			var idxObj = this.addCell(text);
			if (indexSize != null && indexSize > 0)
				idxObj.setStyle({width: indexSize +'px', textAlign : 'right', lineHeight:'normal', padding:'0', margin:'0'});
		}
		for(var i =0; i < childNodes.length; i++) {
			this.addCell(childNodes[i]);
			this.addStyle({lineHeight:'normal', padding:'0', margin:'0'});
		}
	}
},cafen.TableAuto.prototype);

cafen.XUpload = function(item_width, file_type, oldFile, options) {
	if (item_width < 50)
		item_width = 50;
	options = cafen.extend({
		maxSize : 1024*1024*100, 
		flashPath : _cafen_service_url+'images/swfupload.swf',
		uploadUrl : cafen.url2domain(cafenGlobalConf.uploadSCRIPT),
		uploadType : file_type || 'all',
		buttonText : cafenMsg.get('ed_0051'),
		fileTypes : null,
		fileTypesDescription : null,
		fontColor : '#464646',
		bgColor : '#ffffff',
		useInputBox : true,
		uploadBorder : '1px solid #d0d0d0',
		buttonUrl : _cafen_service_url+'images/ico_attach.png',
		uploadWidth : 72,
		uploadHeight : 22,
		linkObj : null
	}, options);
	this.setOptions(cafen.extend(options,{tag : 'span', style : {width :  item_width + 'px', margin : '1px 0px',textAlign:'right', padding:'0', backgroundImage:'none', overflow:'hidden'}, attribute : {}}));
	if (options.useInputBox) {
		this.baseWidth = item_width - options.uploadWidth - 7;
		var InputHeight = options.uploadHeight - 5;
		this._displayObj = new cafen.XInput({style : {width: this.baseWidth+'px', height: InputHeight +'px'}, event : {}, attribute : {readonly : true, className : 'r_editorattach'}});
	} else {
		this.baseWidth = item_width + 3;
		this._displayObj = null;
	}
	this.attachFileButton  = new cafen.Div({style:{width: options.uploadWidth +'px', height: options.uploadHeight +'px', marginLeft : '3px', marginRight : '0px',overflow: 'hidden', overflowX : 'hidden', overflowY : 'hidden', border : options.uploadBorder , backgroundImage:'none'},attribute :{unselectable : 'on'}});
	this._attachbuttonID = null;
	this.appendChild(new cafen.IndexTab('',[this._displayObj, this.attachFileButton]));
	if (oldFile != '') {
		var fileName = '';
		var fileinfo = oldFile.split('\|');
		var ufile =	{
			size : 0,
			extension : 'etc',
			server : '',
			sorce : '',
			fileName: '',
			width : 0,
			height : 0,
			extra : ''
		};
		if (fileinfo.length > 3) {
			fileName = fileinfo[3];
			ufile =	{
				size : parseInt(fileinfo[1]),
				extension : fileinfo[2],
				server : fileinfo[0],
				sorce : fileinfo[0],
				fileName: fileName,
				width : 0,
				height : 0,
				extra : ''
			};
			this.setFile(ufile);
		} else {
			fileName = fileinfo[0].substring(fileinfo[0].lastIndexOf('/')+1);
		}
	}
	if (this.options.linkObj != null) {
		var linkObj = cafen.$(this.options.linkObj);	
		if (linkObj != null) {
			linkObj.setFile = this.setValue.bind(this);
		}
	}
	
}

cafen.XUpload.prototype = cafen.extendClass({
	onLoad : function() {
		this.uploadStat  = {
			in_progress: 0,
			files_queued: 0,
			successful_uploads: 0,
			upload_errors: 0,
			uploads_cancelled: 0,
			queue_errors: 0
		};
		this.uploadProgressBar(100);
		this.setError(false);
		if (this.attachFileButton != null && this._attachbuttonID == null) {
			this._attachbuttonID = this.attachFileButton.getAttribute('id');
			if (this._attachbuttonID == null || typeof this._attachbuttonID == 'undefined' || this._attachbuttonID == '') {
				this._attachbuttonID = cafen.getUniqID('attach');
				this.attachFileButton.setAttribute({id : this._attachbuttonID});
				if (document.getElementById(this._attachbuttonID) != null) {
					var fileTypes = this.options.fileTypes;
					var fileTypesDescription = this.options.fileTypesDescription;
					if (fileTypes == null || fileTypesDescription == null) {
						var fileTypeData = cafen.SwfUpload.getFileType(this.options.uploadType || 'all');
						fileTypes = fileTypeData[0];
						fileTypesDescription = fileTypeData[1];
					}
					var upload_options = {
						upload_url : this.options.uploadUrl,
						flash_url : this.options.flashPath,
						file_size_limit : Math.round(this.options.maxSize/1024),
						file_types : fileTypes,
						file_types_description : fileTypesDescription ,
						file_upload_limit : 1000,
						file_queue_limit : 100,
						button_action : -100,
						swfupload_loaded_handler : this.autoBrowse.bind(this),
						file_dialog_start_handler : this.fileDialogStart.bind(this),
						file_queued_handler : this.fileDialogQueued.bind(this),
						file_dialog_complete_handler : this.fileDialogComplete.bind(this),
						upload_progress_handler : this.uploadProgress.bind(this),
						upload_success_handler : this.uploadFileComplete.bind(this),
						upload_complete_handler : this.uploadComplete.bind(this),
						file_queue_error_handler : this.handleErrors.bind(this),
						upload_error_handler : this.uploadError.bind(this),
						button_placeholder_id : this._attachbuttonID,
						button_width: this.options.uploadWidth,
						button_height: this.options.uploadHeight,
						button_text_style : '.theFont {color: '+this.options.fontColor+'; font-size: 11px;}',
						button_text: '<span>'+this.options.buttonText +'</span>',
						button_text_left_padding : 18,
						button_text_top_padding : 2,
						button_window_mode : cafen.browser.isIE ? 'transparent' : 'transparent',
						backgroundcolor : this.options.bgColor,
						button_cursor : -2,
						button_image_url : this.options.buttonUrl,
						debug : (!cafen.checkDebug()) ? false : true
					};
					var uploadObj = null;
					try {
						uploadObj = new SWFUpload(upload_options);
						this.last_swfuploadobj = uploadObj;
					} catch(ex) {
						return ;
					}
				}
			}
		}
	},
	setValue : function(val) {
		if (val != null) {
			var fileInfo = val.split("|");
			var ufile =	{
				size : parseInt(fileInfo[1]),
				extension : fileInfo[2],
				server : fileInfo[0],
				sorce : fileInfo[0],
				fileName: fileInfo[3],
				width : 0,
				height : 0,
				extra : ''
			}
			this.setFile(ufile);
		}
	},
	autoBrowse : function() {
		this.last_swfuploadobj.setPostParams({domain : document.domain, mode : 'upload'});
	},
	fileDialogStart : function(obj) {},
	fileDialogQueued : function(fileobj) {
		if(fileobj.size > 300000000) {
			this.last_swfuploadobj.cancelUpload(fileobj.id);
			this.handleErrors(fileobj, -500, '');
		} else {
			var ext = '.tmp';
			if (fileobj.name.lastIndexOf('.') > 0)
				ext = fileobj.name.substring(fileobj.name.lastIndexOf('.') +1).toLowerCase();
			if (ext.length > 5)
				ext = '.tmp';
			this.last_swfuploadobj.addFileParam(fileobj.id, 'save_name',cafen.getUniqID('ed'));	
			this.last_swfuploadobj.addFileParam(fileobj.id, 'save_ext',ext);	
		}
	},
/**
 * 업로드 다이아로그 종료
 * @param {int} queuelength  파일선택수
 */
	fileDialogComplete : function(queuelength) {
		this.uploadComplete();
	},
	uploadStat : {
		in_progress: 0,
		files_queued: 0,
		successful_uploads: 0,
		upload_errors: 0,
		uploads_cancelled: 0,
		queue_errors: 0
	},
	uploadedFile : null,
	setFile : function(fileObj) {
		this.uploadedFile = fileObj;
		if (this._displayObj != null)
			this._displayObj.setValue(this.uploadedFile.fileName +' / ' + cafen.getSize2Short(this.uploadedFile.size));
		this.uploadProgressBar(100);
		this.execEvent('end');
	},
	getFile : function() {
		return this.uploadedFile;
	},
/**
 * Upload 시작 
 * @param {string} id  파일ID
 */
	uploadComplete : function(ufile) {
		this.uploadStat = this.last_swfuploadobj.getStats();
		var uploaded_len = this.uploadStat.successful_uploads + this.uploadStat.upload_errors + this.uploadStat.upload_cancelled + this.uploadStat.queue_errors;
		var total_len = this.uploadStat.files_queued + this.uploadStat.successful_uploads + this.uploadStat.upload_errors + this.uploadStat.upload_cancelled + this.uploadStat.queue_errors;
		this.uploadFileStart(ufile, uploaded_len, total_len);
		if (this.uploadStat.files_queued > 0)
			this.last_swfuploadobj.startUpload();
		else 
			this.uploadQueueComplete(ufile);
	},
/**
 * 파일 Queue
 * @param {object} ufile  파일 Object
 * @param {int} queuelength  파일 Queue 갯수
 */
	fileQueued : function (ufile, queuelength) {},
/**
 * 파일 업로드 시작
 * @param {object} ufile  파일 Object
 * @param {int} position  파일 위치
 * @param {int} queuelength  파일 Queue 갯수
 */
	uploadFileStart : function (ufile, position, queuelength) {
//		this.options.uploadFileStart(ufile, position, queuelength);
	},
/**
 * 파일 업로드 진행
 * @param {object} ufile  파일 Object
 * @param {int} bytesLoaded  Upload 된 파일 크기
 */
	uploadProgress : function (ufile, bytes_complete, bytes_total) {
		if (bytes_total > 0) 
			this.uploadProgressBar(bytes_complete / bytes_total *100);
	},
	_linkObjDisplay : null,
	_linkObjProcess : false,
	uploadProgressBar : function (per) {
		if (this._displayObj != null) {
			if (per >= 100) 
				this._displayObj.setStyle({backgroundPosition :  '1000px -21px'});
			else {
				var po = (this.baseWidth * per / 100);
				this._displayObj.setStyle({backgroundPosition : (po-1000) + 'px -4px'});
			}
		} else {
			try {
				if (this.options.linkObj != null) {
					if (this._linkObjDisplay == null) {
						this._linkObjDisplay = cafen.$(this.options.linkObj);
						if (this._linkObjDisplay != null) {
							this.baseWidth = this._linkObjDisplay.offsetWidth;
							cafen.setStyle(this._linkObjDisplay, {backgroundRepeat:'no-repeat', backgroundPosition : '-1000px -3px'});
						} else {
							this.options.linkObj = null;
						}
					}
					if (this._linkObjDisplay != null) {
						if (!this._linkObjProcess && per != 100) {
							cafen.setStyle(this._linkObjDisplay, {backgroundImage : 'url('+_cafen_service_url+'images/editor_attachscale_gray.gif)'});
						} else {
							cafen.setStyle(this._linkObjDisplay, {backgroundImage : 'none'});
						}
						var po = (this.baseWidth * per / 100);
						cafen.setStyle(this._linkObjDisplay,{backgroundPosition : (po-1000) + 'px -3px'});
					}
				}
			} catch(ex) {}
		}
	},
/**
 * 파일 업로드 완료
 * @param {object} ufile  파일 Object
 * @param {string} response  결과값
 */
	uploadFileComplete : function (infile, response) {
		var channel, xml = new cafen.xmlParser(response);
		if (channel = xml.getNext()) {
			var item , msg = null;
			if (channel.checkMsg()) {
				var msg = channel.getMsg();
				this.options.handleErrors(msg.title, msg.domain, msg.contents);
			}
			while(item = channel.getNext()) {
				if (item.getNode('fileext') != '') {
					var ufile =	{
						size : parseInt(item.getNode('filesize')),
						extension : item.getNode('fileext'),
						server : item.getNode('fileserver'),
						sorce : item.getNode('filesorce'),
						fileName: item.getNode('filename'),
						width : parseInt(item.getNode('imgwidth')),
						height : parseInt(item.getNode('imgheight')),
						extra : item.getNode('extra')
					}
					if (ufile.fileName == '') 
						ufile.fileName = infile.name;
					if (cafen.checkFileFilter(ufile)) {
						this.setFile(ufile, true);
					}
				}
			}
		}
	},
/**
 * 파일 업로드 취소
 */
	uploadCancel : function() {},
	uploadQueueComplete : function (ufile) {
		this.last_options = {upload_max_size : -1, upload_filetypes : ''}
	},
/**
 * 파일 업로드 오류
 * @param {int} errno  오류번호
 */
	uploadError : function (file, error_code, message) {
		this.handleErrors(file, error_code, message);
	},
/**
 * 업로드 가능 파일 여부
 * @param {string} fileName  파일명
 * @return  {boolean} true|false
 */
	isUploadable : function(fileName) {
		return !cafen.find('(html|htm|php|php3|cgi|phtml|shtml|jsp|asp|exe|com|dll)$', fileName);
	},
/**
 * 오류 처리
 * @param {object} file  파일 Object
 * @param  {int} error_code  오류 코드
 * @param {int} msg_code  메세지 코드
 */
	handleErrors : function(ofile, error_code, msg_code) {
		if (ofile == null)
			ofile = {name :''}
		var error_info = cafen.SwfUpload.getErrorMsg(ofile, error_code);
		this.setError(true, error_info.msg, ofile.name);
	},
	setError : function(bl, msg, fileName ) {
		if (this._displayObj == null)
			return ;
		else if (bl) {
			this._displayObj.setError(true);
			if (msg != null && msg != '') {
				if (fileName != null && fileName != '')
					msg = fileName + "\r\n"+ msg; 
				this._displayObj.setAttribute({title : cafen.stripTags(msg)});
			}
			this.uploadProgressBar(100);
		} else {
			this._displayObj.setError(false);
			this._displayObj.setAttribute({title : null});
		}
	}
},cafen.Element.prototype);

cafen.XSelect = function(items, item_width, options, item_height, readOnly) {
	readOnly = (readOnly == null) ? true : false;
	this.setOptions(cafen.extend({tag : 'div', attribute :{}, defaultValue : '', style : {width: item_width +'px', textAlign:'left'}, dropDown : {}},options));
	var itemContents = new cafen.TableAuto({attribute:{width:'100%', border : '0',className : 'r_table'}});
	this.appendChild(itemContents);
	this._displayObj = new cafen.XInput({style : {width:(item_width -20) +'px', height:'17px'}, event : {end : this.sendValue.bind(this)}, attribute : {readonly : readOnly, value : this.options.defaultValue }});
	itemContents.addCell(this._displayObj);
	this._dropdownObj = new cafen.XIcon({icon :'r_iconset', on : -15, off : 75, over : 15, event : {click: this.toggleItem.bind(this)}, style :{width:'15px', height:'15px'}});
	itemContents.addCell(this._dropdownObj);
	itemContents.addStyle({paddingLeft:'3px',width:'20px'});
	this._itemObj = new cafen.Div(cafen.extend({className :'r_boxwhite', style : {display : 'none', position : 'absolute', height: 'auto', marginTop : '1px', zIndex:'500'}},this.options.dropDown));
	this.appendChild(this._itemObj);
	this.initSelect(items, item_width - 20, options, item_height);	
}

cafen.XSelect.prototype = cafen.extendClass({
	_displayObj : null,
	_itemObj : null,
	_isItemshow : false,
	_selectedItem : null,
	_selectedIndex : null,
	_selectedValue : null,
	_dropdownObj : null,
	_itemChild : [],
	_xMenu : null,
	initSelect : function(items, item_width, options, item_height) {
		this.setChildObject(items);
		this._itemwidth = item_width;
		this._itemheight = item_height || 0 ;
	},
	setChildObject : function(items) {
		this._xMenu = null;
		this._itemChild = items;
	},
	setBoxStyle : function(style) {
		this._displayObj.setStyle(style);
	},
	drawChild : function() {
		var menuItem = [];
		for(var i = 0; i < this._itemChild.length; i++) 
			menuItem.push({text: this._itemChild[i].text , icon : this._itemChild[i].icon, onclick : this.setIndex.bind(this, i)});
		if (this._itemheight > 0) 
			this._xMenu = new cafen.XMenu(menuItem, this._itemwidth, cafen.extend(this.options,{style:{overflowY : 'auto', overflowX :'hidden', height: this._itemheight + 'px'}}));
		else
			this._xMenu = new cafen.XMenu(menuItem, this._itemwidth, cafen.extend(this.options,{style:{overflowY : 'visible', overflowX :'hidden'}}));
		this._itemObj.appendChild(this._xMenu);
	},
	sendValue : function(obj) {
		if (this.getValue() != this._selectedValue)
			this._selectedIndex = null;
		this.execEvent("change",null);
	},
	toggleItem : function() {
		if (this._xMenu == null)
			this.drawChild();
		this._isItemshow = ! this._isItemshow;
		if (this._isItemshow) {
			this._itemObj.show();
			this._dropdownObj.setSelected(true);
			cafen.setSelected(this);
		} else {
			this._itemObj.hide();
			this._dropdownObj.setSelected(false);
		}
	},
	onUnselect : function() {
		if (this._isItemshow) {
			this._itemObj.hide();
			this._isItemshow = ! this._isItemshow;
			this._dropdownObj.setSelected(false);
		}
	},
	setIndex : function(no) {
		this._selectedIndex = no;
		this._selectedValue = this._itemChild[no].text;
		this._displayObj.setValue(this._selectedValue);
		this.execEvent("change",null);
		if (this._isItemshow)
			this.toggleItem();
	},
	getIndex : function() {
		return this._selectedIndex;
	},
	getValue : function() {
		return this._displayObj.getValue();
	},
	setValue : function(val) {
		this._displayObj.setValue(val);
	}
},cafen.Element.prototype);

cafen.XMenu = function(menus, menu_width, options) {
	options = options || {};
	var tplName = (options.title != null) ? 'top' : null;
	this.setOptions(cafen.extend(options,{tag : 'div', tplName : tplName, style : {width : menu_width +'px', textAlign:'left'}, attribute : {className : 'r_menu'}}));
	this.initMenu(menus, menu_width, options);	
}

cafen.XMenu.prototype = cafen.extendClass({
	_lastshownChild : null,
	_subItems : [],
	_buttonClassName : null,
	_menuWidth : null,
	isSelected : false,
	initMenu : function(menus, menu_width, options) {
		if (this.options.title != null) {
			this.appendChild(this.options.title, 'top');
			this.options.title = null;
			this.options.tplName = null;
		}
		this._lastshownChild = null;
		this._buttonClassName = (options.buttonClass == null) ? 'r_tbtnskin' : options.buttonClass;
		this.onChildSelectBind = this.onChildSelect.bind(this);
		this._subItems = [];
		this._menuWidth = (this.options.style.overflowY != 'hidden' && this.options.style.overflowY != 'show' && this.options.style.overflowY != 'visible') ? menu_width - 25 : menu_width - 7;
		for(var i = 0; i < menus.length; i++) 
			this.appendItem(menus[i]);
		this.showSub(null);
	},
	getSelected : function() {
		var selectedChild = [];
		for(var i =0 ; i < this._subItems.length; i++) {
			if (this._subItems[i].isSelected)
				selectedChild.push(this._subItems[i]);
		}
		return selectedChild;
	},
	getItems : function() {
		return this._subItems;
	},
	onChildSelect : function(obj) {
		this.execEvent('select', obj);
	},
	changeIcon : function(idx, icon) {
		var items = this.getItems();
		for(var i = 0 ; i < items.length; i++) {
			if (items[i].options.itemOptions == idx) {
				if (items[i].icon != null)
					items[i].icon.synkIcon(icon);
				break;
			}
		}
	},
	reSize : function(menu_width) {
		this._menuWidth = (this.options.style.overflowY != 'hidden' && this.options.style.overflowY != 'show') ? menu_width - 25 : menu_width - 7;
		for(var i = 0; i < this._subItems.length; i++) {
			this._subItems[i].setStyle({width: this._menuWidth +'px'});
		}
	},
	appendItem : function(currMenu) {
		if (typeof currMenu == 'string') {
			var itemObj = new cafen.Div({attribute:{className :'r_line', innerHTML :'&#160;'}, style : {overflow :'hidden', fontSize:'1px', width:'100%'}});
			this.appendChild(itemObj);
			return null;
		} else {
			var text = 	currMenu.text;
			var shortkey = currMenu.shortkey || null;
			if (shortkey != null) 
				text += '(<u class="shortcut">'+shortkey+'</u>)';
			var height = currMenu.height ?  currMenu.height : '18px';
			var itemObj = new cafen.Div({style:{marginBottom : '2px', textAlign:'left'}});
			this.appendChild(itemObj);
			var subitem = null, subItemArea = null;
			if (currMenu.items != null && currMenu.items.length > 0) {
				subitem = new cafen.XMenu(currMenu.items, (currMenu.width) ? currMenu.width : this._menuWidth+15, this.options);
				subItemArea = new cafen.Div({style:{position:'absolute', display: 'none',left :( this._menuWidth+11) +'px'}});
				subItemArea.appendChild(subitem);
				itemObj.appendChild(subItemArea);
			}
			var itemContents = new cafen.TableAuto({attribute:{border : 0, width :  this._menuWidth}, style : {tableLayout:'fixed'}});
			var iconObj = null;
			if (currMenu.icon != null) {
				iconObj = new cafen.XImage(currMenu.icon , {style : {width : '16px', height :'16px', overflow : 'hidden'}});
				itemContents.addCell(iconObj);
			} else if (currMenu.src != null)
				itemContents.addCell(new cafen.Image(currMenu.src,{}));
			else
				itemContents.addCell(new cafen.Div({style : {width:'16px'}}));
			itemContents.addStyle({width : '16px', textAlign:'center'});
			if (subitem != null) {
				var obj = itemContents.addCell(new cafen.Div({attribute:{innerHTML : text, className : 'r_submenu'}, style : {paddingLeft : '7px', paddingTop : '1px',fontSize:'11px',  width : (this._menuWidth - 6)+'px', overflowX : 'hidden'}}));
				itemContents.addStyle({textAlign:'left', width : (this._menuWidth - 6) +'px'});
			} else {
				itemContents.addCell(new cafen.Div({attribute:{innerHTML : text}, style : {paddingLeft : '7px', paddingTop : '1px',fontSize:'11px', whiteSpace: 'nowrap', width : (this._menuWidth - 6)+'px', overflowX : 'hidden'}}));
				itemContents.addStyle({textAlign:'left', width : (this._menuWidth - 6) +'px'});
			}			
			var itemButton = new cafen.XButton(cafen.extend({multiselect : true, className : this._buttonClassName , shortkey : shortkey , childNodes : [itemContents], attribute : {}, style :{height: height, width : (this._menuWidth) +'px', overflowX : 'hidden', overflowY : 'hidden'}, itemOptions : currMenu.options },{}));
			if (currMenu.disabled == true) 
				itemButton.setDisable(true);
			itemButton.attachEvent('mouseover',this.showSub.bind(this));
			itemButton.attachEvent('mouseout',this.mouseOut.bind(this));
			if (currMenu.onclick != null ) 
				itemButton.attachEvent('click',currMenu.onclick);
			else
				itemButton.attachEvent('click',this.onChildSelectBind);
			if (subitem != null) {
				itemButton.linkObj = subitem;
				itemButton.linkArea = subItemArea;
			} else {
				itemButton.linkObj = null;
				itemButton.linkArea = null;
			}
			itemButton.linkName = text;
			itemButton.icon = iconObj;
			itemButton.parentXMenu = this;
			this._subItems.push(itemButton);
			itemObj.appendChild(itemButton);
			return itemButton;
		}		
	},
	removeItem : function(obj) {
		var newChild = [];
		for(var i =0 ; i < this._subItems.length; i++) {
			if (obj == this._subItems[i])
				obj.parentNode.parentNode.removeChild(obj.parentNode);
			else
				newChild.push(this._subItems[i]);
		}
		this._subItems = newChild;
	},
	setSelectToggle : function(obj) {
		if (!obj.isSelected)
			obj.setSelected(true);
		else
			obj.setSelected(false);
	},
	showSub : function(obj) {
		if (this._lastshownChild != obj) {
			this.hideSub();
			if (obj != null) {
				if (obj.linkArea != null)
					obj.linkArea.show();
				if (obj.linkObj != null)
					obj.linkObj.show();
			}
			this._lastshownChild = obj;
		}
		return true;
	},
	hideMenu : function() {
		this.hide();
//		this.showSub(null);
		return true;
	},
	hideSub : function() {
		if (this._lastshownChild != null) {
			if (this._lastshownChild.linkArea != null)
				this._lastshownChild.linkArea.hide();
			if (this._lastshownChild.linkObj != null)
				this._lastshownChild.linkObj.hide();
			this._lastshownChild = null;
		}
	},
	onHide : function() {
		this.hideSub();
	},
	mouseOut : function(obj) {
		return true;
	}
},cafen.Element.prototype);

cafen.divScroll = function(obj, options) {
	this.initDivScroll(obj, options);
}

cafen.divScroll.prototype = {
	parentObj : null,
	obj : null,
	objWidth : null,
	objHeight : null,
	viewWidth : null,
	viewHeight : null,
	scrollHeight : null,
	scrollObj : null,
	barHeight : null,
	scrollStep : 2,
	isLoaded : false,
	scrollData : {
		weight : 18,
		overflowX : null,
		overflowY : null,
		scrollVmode : false,
		scrollHmode : false
	},
	colorData : {
		highlightcolor : '#cce4fa', lightcolor : '#95b7d8', shadowcolor : '#596e82', darkshadowcolor : '#000000', arrowcolor : '#000000', trackcolor : '#cce4fa', facecolor : '#95b7d8'
	},
	initDivScroll : function(obj, options) {
		var overflowY = cafen.getStyle(obj, 'overflowY');
		var overflowX = cafen.getStyle(obj, 'overflowX');
		if (obj.scrollParsed || (overflowY != 'scroll' && overflowY != 'auto' && overflowX != 'scroll' && overflowX != 'auto'))
			return ;
		this.parentObj = obj;
		this.parentObj.scrollParsed = true;
		if (this.parentObj.tagName == 'IFRAME') {
			this.parentDoc = this.parentObj.contentWindow.document;
			this.parentWin = this.parentObj.contentWindow;
			this.obj = obj.contentWindow.document.body || obj.contentWindow.document.documentElement ;
		} else {
			this.parentDoc = document;
			this.obj = this.parentWin = obj;
		}
		this.isLoaded = false;
		this.colorData = this.getBaseColor(options);
		this.objHeight = this.parentObj.offsetHeight || parseInt(this.parentObj.style.height);
		this.objWidth = this.parentObj.offsetWidth || parseInt(this.parentObj.style.width);
		this.skinObj = document.createElement("div");
		cafen.insertAfter(this.skinObj, this.parentObj);
		cafen.setStyle(this.skinObj, {position:'relative', width: '1px', height:'1px', border : '0 none', top :'-2px', left : '0', display : 'block', overflow : 'hidden',fontSize : '1px', lineHeight : '1px', zIndex:1});
		if (overflowY == 'auto' || overflowY == 'scroll') {
			this.barHeight = 30;
			this.scrollVObj = this.getScrollObject(true);
			this.buttonVUp = this.getScrollButton(1);
			this.scrollVObj.appendChild(this.buttonVUp);
			this.buttonVScroll = this.getScrollBar(true);
			this.scrollVObj.appendChild(this.buttonVScroll);
			this.buttonVDown = this.getScrollButton(2);
			this.scrollVObj.appendChild(this.buttonVDown);
			cafen.Event.observe(this.buttonVUp, "mousedown", this.moveUp.bindAsEventListener(this) , true);
			cafen.Event.observe(this.buttonVDown, "mousedown", this.moveDown.bindAsEventListener(this) , true);
			cafen.Event.observe(this.scrollVObj, "mousedown", this.clickVBarStart.bindAsEventListener(this), true);
			this.scrollData.overflowY = overflowY;
		} else {
			this.scrollData.overflowY = null;
		}
		if (overflowX == 'auto' || overflowX == 'scroll') {
			this.barWidth = 30;
			this.scrollHObj = this.getScrollObject(false);
			this.buttonHLeft = this.getScrollButton(3);
			this.scrollHObj.appendChild(this.buttonHLeft);
			this.buttonHScroll = this.getScrollBar(false);
			this.scrollHObj.appendChild(this.buttonHScroll);
			this.buttonHRight = this.getScrollButton(4);
			this.scrollHObj.appendChild(this.buttonHRight);
			cafen.Event.observe(this.buttonHLeft, "mousedown", this.moveLeft.bindAsEventListener(this) , true);
			cafen.Event.observe(this.buttonHRight, "mousedown", this.moveRight.bindAsEventListener(this) , true);
			cafen.Event.observe(this.scrollHObj, "mousedown", this.clickHBarStart.bindAsEventListener(this), true);
			this.scrollData.overflowX = overflowX;
		} else {
			this.scrollData.overflowX = null;
		}
		if (this.scrollVObj && this.scrollHObj) {
			this.dummyBox = 	this.getScrollObject(true);
			cafen.setStyle(this.dummyBox, {width : this.scrollData.weight +'px', height : this.scrollData.weight+'px', display:'none'});
		}
		cafen.Event.observe(this.parentWin, "scroll", this.updateScroll.bind(this), false);
		window.setTimeout(this.onLoad.bind(this),1);
		this.parentObj.onchange = this.onLoad.bind(this);
		this.parentObj.onresize = this.onResize.bind(this);
		this.parentObj.changeColor = this.changeColor.bind(this);

		if (this.parentObj.tagName == 'TEXTAREA' || this.parentObj.tagName == 'IFRAME' || (this.parentObj.tagName == 'DIV' && this.parentObj.contentEditable == 'true')) {
			cafen.Event.observe(this.obj, "keyup", this.changeScroll.bind(this), false);
			if (this.parentObj.tagName == 'TEXTAREA' && cafen.getStyle(this.parentObj, 'resize') != 'none')
				cafen.setStyle(this.parentObj, {resize : 'none'});
		} else if (options&& options.touchscroll) {
			cafen.Event.observe(this.obj, "mousedown", this.scrollMouseDown.bindAsEventListener(this), false);
		}
	},
	scrollMouseMoveBind : null,
	scrollMouseUpBind : null,
	scrollMouseInitPos:[0,0],
	scrollMouseInitScroll:[0,0],
	scrollMouseDown : function(event) {
		if (this.buttonVScroll != null && this.scrollData.scrollVmode || this.buttonHScroll != null && this.scrollData.scrollHmode) {
			if (this.scrollMouseMoveBind == null) 
				this.scrollMouseMoveBind = this.scrollMouseMove.bindAsEventListener(this);
			if (this.scrollMouseUpBind == null) 
				this.scrollMouseUpBind = this.scrollMouseUp.bindAsEventListener(this);
			this.scrollMouseInitPos = cafen.pointer(event);
			this.scrollMouseInitScroll = [this.obj.scrollLeft, this.obj.scrollTop];
			cafen.Event.observe(cafen.getBody(), "mousemove", this.scrollMouseMoveBind, false);
			cafen.Event.observe(cafen.getBody(), "mouseup", this.scrollMouseUpBind, false);
			cafen.Event.observe(this.obj, "mouseup", this.scrollMouseUpBind, false);
			cafen.Event.stop(event);
		}
	},
	scrollMouseMove : function(event) {
		var currPos = cafen.pointer(event);
		var moveX = currPos[0] - this.scrollMouseInitPos[0] ;
		var moveY = currPos[1] - this.scrollMouseInitPos[1] ;
		if (this.buttonHScroll != null && this.scrollData.scrollHmode)
			this.setHScroll(this.scrollMouseInitScroll[0] - moveX);
		if (this.buttonVScroll != null && this.scrollData.scrollVmode)
			this.setVScroll(this.scrollMouseInitScroll[1] - moveY);
		cafen.Event.stop(event);
	},
	scrollMouseUp : function(event) {
		cafen.Event.stopObserving(cafen.getBody(), "mousemove", this.scrollMouseMoveBind, false);
		cafen.Event.stopObserving(cafen.getBody(), "mouseup", this.scrollMouseUpBind, false);
		cafen.Event.stopObserving(this.obj, "mouseup", this.scrollMouseUpBind, false);
	},
	getScrollObject : function(bl) {
		var obj = document.createElement("DIV");
		this.skinObj.appendChild(obj);
		cafen.setStyle(obj, {backgroundColor: this.colorData.trackcolor, border:'0 none', position:'absolute'});
		if (bl) {
			cafen.setStyle(obj, {width:this.scrollData.weight+'px', height: this.objHeight+'px', bottom:'0', right:'0'});
		} else {
			cafen.setStyle(obj, {width:this.objWidth + 'px', height: this.scrollData.weight+'px', left:'0', bottom: '0'});
		}
		return obj;
	},
	getScrollBar : function(bl) {
		var obj = document.createElement("div");
		cafen.setAttribute(obj, {unselectable: 'on' , innerHTML: '<div style="padding:0;margin:0;font-size:1px;border-style:solid; border-width:1px;overflow:hidden;border-color:'+this.colorData.highlightcolor+' '+this.colorData.shadowcolor+' '+this.colorData.shadowcolor+' '+this.colorData.highlightcolor+'">&nbsp;</div>'});
		cafen.setStyle(obj, {padding:0, fontSize:'1px',width:'auto', height : 'auto', borderStyle:'solid', borderWidth : '1px', borderColor : this.colorData.lightcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.lightcolor, backgroundColor: this.colorData.facecolor, position:'absolute', overflow : 'visible',cursor : cafen.getCursor(), zIndex: 0});
		if (bl) {
			cafen.setStyle(obj, {top: this.scrollData.weight + 'px', left:'1px'});
			if(cafen.browser.isIE) {
				cafen.setStyle(obj.firstChild, {width: (this.scrollData.weight -5) + 'px', height: '30px'});
			} else {
				cafen.setStyle(obj.firstChild, {width: (this.scrollData.weight -6) + 'px', height: '30px'});
			}
		} else {		
			cafen.setStyle(obj, {left: this.scrollData.weight + 'px', top:'1px'});
			if(cafen.browser.isIE) {
				cafen.setStyle(obj.firstChild, {height: (this.scrollData.weight -5) + 'px', width: '30px'});
			} else {
				cafen.setStyle(obj.firstChild, {height: (this.scrollData.weight -6) + 'px', width: '30px'});
			}
		}
		return obj;
	},
	getScrollButton : function(pos) {
		var obj = document.createElement("div");
		var arrowTxt = '';
		switch(pos) {
			case 1 :
				arrowTxt = '\u25B2';
				break;	
			case 2 :
				arrowTxt = '\u25BC';
				break;	
			case 3 :
				arrowTxt = '\u25C0';
				break;	
			case 4 :
				arrowTxt = '\u25B6';
				break;	
		}
		var baseStyle = 'padding:0;margin:0;font-family:Gulim;overflow:hidden;width:'+(this.scrollData.weight -4)+'px;height:'+(this.scrollData.weight -4)+'px;line-height:normal;border-style:solid;border-width:1px;border-color:'+this.colorData.highlightcolor+' '+this.colorData.shadowcolor+' '+this.colorData.shadowcolor+' '+this.colorData.highlightcolor+';color:'+this.colorData.arrowcolor+';';
		switch(pos) {
			case 1 :
				cafen.setAttribute(obj, {unselectable: 'on' , innerHTML: '<div unselectable=on style="'+baseStyle+'font-size:9px;vertical-align:bottom;text-align:center;line-height:120%;">'+arrowTxt+'</div>'});
				break;
			case 2 :
				cafen.setAttribute(obj, {unselectable: 'on' , innerHTML: '<div unselectable=on style="'+baseStyle+'font-size:9px;vertical-align:top;text-align:center;line-height:160%">'+arrowTxt+'</div>'});
				break;
			case 3 :
				cafen.setAttribute(obj, {unselectable: 'on' , innerHTML: '<div unselectable=on style="'+baseStyle+'font-size:9px;vertical-align:middle;text-align:left;line-height:130%;">'+arrowTxt+'</div>'});
				break;
			case 4 :
				cafen.setAttribute(obj, {unselectable: 'on' , innerHTML: '<div unselectable=on style="'+baseStyle+'font-size:9px;vertical-align:middle;text-align:right;line-height:130%;">'+arrowTxt+'</div>'});
				break;
		}
		cafen.setStyle(obj, {borderCollapse:'separate',textAlign:'center', width: 'auto', height: 'auto', borderStyle:'solid', borderWidth : '1px', fontSize:'1px',lineHeight:'1px',borderColor : this.colorData.lightcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.lightcolor, backgroundColor: this.colorData.facecolor, position:'absolute', padding:0, margin:0, overflow :'visible', cursor : cafen.getCursor(), zIndex: 1});
		if(cafen.browser.isIE) {
			cafen.setStyle(obj.firstChild, {height: (this.scrollData.weight -3) + 'px', width: (this.scrollData.weight -3)+'px'});
		} else {
			cafen.setStyle(obj.firstChild, {height: (this.scrollData.weight -4) + 'px', width: (this.scrollData.weight -4)+'px'});
		}
		switch(pos) {
			case 1 :
			case 3 :
				cafen.setStyle(obj, {top:'0', left:'0'});
				break;	
			case 2 :
				cafen.setStyle(obj, {bottom:'0', left:'0'});
				break;	
			case 4 :
				cafen.setStyle(obj, {top:'0', right:'0'});
				break;	
		}
		return obj;
	},
	onResize : function() {
		window.setTimeout(this.onLoad.bind(this),100);
	},
	changeColor : function(options) {
		this.colorData = this.getBaseColor(options);
		if (this.scrollVObj != null) {
			cafen.setStyle(this.scrollVObj, {backgroundColor: this.colorData.trackcolor});
			cafen.setStyle(this.buttonVUp, {borderColor : this.colorData.lightcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.lightcolor, backgroundColor: this.colorData.facecolor});
			cafen.setStyle(this.buttonVUp.firstChild, {borderColor: this.colorData.highlightcolor+' '+this.colorData.shadowcolor+' '+this.colorData.shadowcolor+' '+this.colorData.highlightcolor , color : this.colorData.arrowcolor});
			cafen.setStyle(this.buttonVDown, {borderColor : this.colorData.lightcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.lightcolor, backgroundColor: this.colorData.facecolor});
			cafen.setStyle(this.buttonVDown.firstChild, {borderColor: this.colorData.highlightcolor+' '+this.colorData.shadowcolor+' '+this.colorData.shadowcolor+' '+this.colorData.highlightcolor , color : this.colorData.arrowcolor});
			cafen.setStyle(this.buttonVScroll, {borderColor : this.colorData.lightcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.lightcolor, backgroundColor: this.colorData.facecolor});
			cafen.setStyle(this.buttonVScroll.firstChild, {borderColor: this.colorData.highlightcolor+' '+this.colorData.shadowcolor+' '+this.colorData.shadowcolor+' '+this.colorData.highlightcolor});
		}
		if (this.scrollHObj != null) {
			cafen.setStyle(this.scrollHObj, {backgroundColor: this.colorData.trackcolor});
			cafen.setStyle(this.buttonHLeft, {borderColor : this.colorData.lightcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.lightcolor, backgroundColor: this.colorData.facecolor});
			cafen.setStyle(this.buttonHLeft.firstChild, {borderColor: this.colorData.highlightcolor+' '+this.colorData.shadowcolor+' '+this.colorData.shadowcolor+' '+this.colorData.highlightcolor , color : this.colorData.arrowcolor});
			cafen.setStyle(this.buttonHRight, {borderColor : this.colorData.lightcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.lightcolor, backgroundColor: this.colorData.facecolor});
			cafen.setStyle(this.buttonHRight.firstChild, {borderColor: this.colorData.highlightcolor+' '+this.colorData.shadowcolor+' '+this.colorData.shadowcolor+' '+this.colorData.highlightcolor , color : this.colorData.arrowcolor});
			cafen.setStyle(this.buttonHScroll, {borderColor : this.colorData.lightcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.darkshadowcolor+' '+this.colorData.lightcolor, backgroundColor: this.colorData.facecolor});
			cafen.setStyle(this.buttonHScroll.firstChild, {borderColor: this.colorData.highlightcolor+' '+this.colorData.shadowcolor+' '+this.colorData.shadowcolor+' '+this.colorData.highlightcolor});
		}
		if (this.dummyBox != null) 
			cafen.setStyle(this.dummyBox, {backgroundColor: this.colorData.trackcolor});
	},
	getBaseColor : function(options) {
		try {
			options = options || {};
			var checkColor = null, baseColor = null;
			baseColor = cafen.getStyle(this.obj, "scrollbarBaseColor", this.parentDoc);
			if (baseColor == null || baseColor == '') 
				baseColor = cafen.getAttribute(this.obj, "scrollbarBaseColor", this.parentDoc);
			if (baseColor == null || baseColor == '') {
				var checkSeqn = 0;
				var checkObj = this.parentObj;
				while(checkSeqn < 16 && checkObj && checkObj.tagName) {
					var className = checkObj.className;
					if (className != '') {
						var tmpClassName = className.split(' ');
						className = tmpClassName[0];
					}
					switch(className) {
						case 'r_boxblue' :
							baseColor = '#79b1ff';
							break;
						case 'r_boxblack' :
							baseColor = '#434343';
							break;
						case 'r_boxgreen' :
							baseColor = '#88c385';
							break;
						case 'r_boxgray' :
							baseColor = '#afafaf';
							break;
						case 'r_boxred' :
							baseColor = '#f5d7e0';
							break;
						case 'r_boxwhite' :
							baseColor = '#e4e4e4';
							break;
						default :
							break;
					}
					if (baseColor != null && baseColor != '') 
						break;
					checkObj = checkObj.parentNode;
					checkSeqn++;
				}
			}
			if (baseColor == null || baseColor == '')
				baseColor = cafen.getStyle(this.obj, "color", this.parentDoc);
			if (baseColor == null || baseColor == '')
				baseColor = '#95b7d8';
			if (options.arrowcolor == null) {
				checkColor = cafen.getStyle(this.obj, "scrollbarArrowColor", this.parentDoc);
				if (checkColor != null && checkColor != '')
					options.arrowcolor = checkColor;
				else
					options.arrowcolor = cafen.colorTools.getOptionColor(baseColor, "GN");
			}
			if (options.facecolor == null) {
				checkColor = cafen.getStyle(this.obj, "scrollbarFaceColor", this.parentDoc);
				if (checkColor != null && checkColor != '')
					options.facecolor = checkColor;
				else
					options.facecolor = baseColor;
			}
			if (options.trackcolor == null) {
				checkColor = cafen.getStyle(this.obj, "scrollbarTrackColor", this.parentDoc);
				if (checkColor != null && checkColor != '')
					options.trackcolor = checkColor;
				else
					options.trackcolor = cafen.colorTools.getOptionColor(options.facecolor || baseColor , "VVVVVV");
			}
			if (options.highlightcolor == null) {
				checkColor = cafen.getStyle(this.obj, "scrollbarHighlightColor", this.parentDoc);
				if (checkColor != null && checkColor != '')
					options.highlightcolor = checkColor;
				else 
					options.highlightcolor = cafen.colorTools.getColor(options.facecolor || baseColor, {v:0.2});
			}
			if (options.lightcolor == null) {
				checkColor = cafen.getStyle(this.obj, "scrollbar3dlightColor", this.parentDoc);
				if (checkColor != null && checkColor != '')
					options.lightcolor = checkColor;
				else 
					options.lightcolor = cafen.colorTools.getColor(options.highlightcolor || baseColor, {v: 0.9});
			}
			if (options.shadowcolor == null) {
				if (checkColor != null && checkColor != '')
					options.shadowcolor = checkColor;
				else
					options.shadowcolor = cafen.colorTools.getColor(options.facecolor || baseColor, {v: -0.2});
			}
			if (options.darkshadowcolor == null) {
				checkColor = cafen.getStyle(this.obj, "scrollbarDarkshadowColor", this.parentDoc);
				if (checkColor != null && checkColor != '')
					options.darkshadowcolor = checkColor;
				else
					options.darkshadowcolor = cafen.colorTools.getColor(options.shadowcolor || baseColor, {v: -0.8});
			}
			return cafen.extend(this.colorData, options);
		} catch(ex) {
			return this.colorData;
		}
	},
	onLoad : function(options) {
		if (options != null) {
			if (typeof options.scrollTop == 'number') 
				this.setVScroll(options.scrollTop);
			if (typeof options.scrollLeft == 'number') 
				this.setHScroll(options.scrollLeft);
		}
		if (cafen.getStyle(this.parentObj, "display") == 'none') {
			cafen.setStyle(this.skinObj, {display : 'none', overflow : 'hidden'});
		} else {
			cafen.setStyle(this.skinObj, {display : 'block', overflow : 'visible'});
			var position = cafen.getStyle(this.parentObj, 'position');
			this.objHeight = this.parentObj.offsetHeight || parseInt(this.parentObj.style.height);
			this.objWidth = this.parentObj.offsetWidth || parseInt(this.parentObj.style.width);
			cafen.copyStyle(this.parentObj, this.skinObj, ['width','marginLeft', 'marginRight']);
			switch(position) {
				case 'absolute' :
					cafen.copyStyle(this.parentObj, this.skinObj, ['position', 'left','right']);
					var topPos = parseInt(cafen.getStyle(this.parentObj, 'top')) || this.parentObj.offsetTop;
					if (!isNaN(topPos)) 
						cafen.setStyle(this.skinObj, {top : (topPos + this.objHeight) +'px'});
					var bottomPos = parseInt(cafen.getStyle(this.parentObj, 'bottom'));
					if (!isNaN(bottomPos)) {
						var marginBottom = parseInt(cafen.getStyle(this.obj, 'marginBottom')) || 0;
						cafen.setStyle(this.skinObj, {top :'auto', bottom : (bottomPos +marginBottom +1)+'px'});
					}
					break;	
				default :
					var marginBottom = parseInt(cafen.getStyle(this.obj, 'marginBottom')) || 0;
					cafen.setStyle(this.skinObj, {top: (marginBottom)*(-1)+'px', width: this.objWidth + 'px', marginBottom : '0'});
					break;
			}
			this.isLoaded = true;
			this.changeScroll();
			this.updateScroll();
			if (document.recalc) 
				document.recalc(true);	
		}
	},
	changeScroll : function() {
		try {
		this.scrollHeight = Math.max(this.obj.scrollHeight, this.objHeight);
		this.scrollWidth = Math.max(this.obj.scrollWidth, this.objWidth);
		var scrollVmode = (this.buttonVScroll != null) ? true : false;
		if (scrollVmode && (this.scrollData.overflowY == 'auto' || this.scrollData.overflowY == null))
			scrollVmode = (this.scrollHeight <= this.objHeight) ? false : true;
		this.scrollData.scrollVmode = scrollVmode;
		var scrollHmode = (this.buttonHScroll != null) ? true : false;
		if (scrollHmode && (this.scrollData.overflowX == 'auto' || this.scrollData.overflowX == null))
			scrollHmode = (this.scrollWidth <= this.objWidth) ? false : true;
		this.scrollData.scrollHmode = scrollHmode;
		if (scrollHmode) {
			this.barHeight = (this.objHeight / this.scrollHeight) * (this.objHeight - this.scrollData.weight*3);
			this.scrollVrange = this.objHeight - this.scrollData.weight;
		} else {
			this.barHeight = (this.objHeight / this.scrollHeight) * (this.objHeight - this.scrollData.weight*2) ;
			this.scrollVrange = this.objHeight;
		}
		if (scrollVmode) {
			this.barWidth = (this.objWidth / this.scrollWidth) * (this.objWidth - this.scrollData.weight*3) ;
			this.scrollHrange = this.objWidth - this.scrollData.weight;
		} else {
			this.barWidth = (this.objWidth / this.scrollWidth) * (this.objWidth - this.scrollData.weight*2) ;
			this.scrollHrange = this.objWidth;
		}
		if (this.buttonVScroll != null) {
			if (this.buttonHScroll != null && scrollHmode) {
				cafen.setStyle(this.scrollVObj, {height: this.scrollVrange + 'px', bottom : this.scrollData.weight+'px'});
			} else {
				cafen.setStyle(this.scrollVObj, {height: this.scrollVrange + 'px', bottom : '0px'});
			}
			cafen.setStyle(this.buttonVScroll, {display : ((this.objHeight - this.scrollData.weight*3) - this.barHeight) <= 0 ? 'none' : 'block'});
			cafen.setStyle(this.buttonVScroll.firstChild, {height: cafen.browser.isIE ? (this.barHeight -1): (this.barHeight-3) + 'px'});
			if (scrollVmode) {
				cafen.setStyle(this.scrollVObj, {display: 'block'});
				this.viewWidth = this.objWidth - this.scrollData.weight;
			} else {
				cafen.setStyle(this.scrollVObj, {display: 'none'});
				this.viewWidth = this.objWidth;
			}
		} else {
			this.viewWidth = this.objWidth;
		}
		if (this.buttonHScroll != null) {
			cafen.setStyle(this.scrollHObj, {width: this.scrollHrange + 'px'});
			cafen.setStyle(this.buttonHScroll, {display : ((this.objWidth - this.scrollData.weight*3) - this.barWidth) <= 0 ? 'none' : 'block'});
			cafen.setStyle(this.buttonHScroll.firstChild, {width: cafen.browser.isIE ? (this.barWidth -1): (this.barWidth-3) + 'px'});
			if (scrollHmode) {
				cafen.setStyle(this.scrollHObj, {display: 'block'});
				this.viewHeight = this.objHeight - this.scrollData.weight;
			} else {
				cafen.setStyle(this.scrollHObj, {display: 'none'});
				this.viewHeight = this.objHeight;
			}
		} else {
			this.viewHeight = this.objHeight;
		}
		cafen.setStyle(this.dummyBox, {display: (scrollVmode && scrollHmode) ? 'block' : 'none'});
		if (this.buttonVScroll != null && scrollVmode)
			this.setVScroll(this.obj.scrollTop);
		if (this.buttonHScroll != null && scrollHmode)
			this.setHScroll(this.obj.scrollLeft);
		} catch(ex) {
			alert(this);
		}
	},
	clickBarFocus : function(eve) {
		return false;		
	},
	updateScroll : function() {
		this.updateVScroll();
		this.updateHScroll();
	},
	scrollCallFnc : null,
	scrollCallTimer : null,
	execTimeScrollBind : null,
	stopTimeScrollBind : null,
	buttonPresssed : false,
	setScrollHold : function(bl) {
		this.buttonPresssed = bl;
	},
	checkScrollHold : function() {
		return !this.buttonPresssed;
	},
	startTimeScroll : function(callFnc) {
		if (this.scrollCallTimer != null) {
			this.stopTimeScroll();
		}
		this.setScrollHold(true);
		if (this.execTimeScrollBind == null)
			this.execTimeScrollBind = this.execTimeScroll.bind(this);
		if (this.stopTimeScrollBind == null)
			this.stopTimeScrollBind = this.stopTimeScroll.bind(this);
		this.scrollTimeSeqn = 300;
		this.scrollCallFnc = callFnc;
		this.execTimeScrollBind();
		cafen.Event.observe(cafen.getBody(), "mouseup", this.stopTimeScrollBind);
	},
	execTimeScroll : function() {
		if (this.scrollCallFnc != null) {
			if (this.scrollCallFnc()) {
				this.scrollTimeSeqn = Math.max(10, Math.round(this.scrollTimeSeqn * 0.6));
				window.setTimeout(this.execTimeScrollBind, this.scrollTimeSeqn);
			} else {
				this.stopTimeScroll();
			}
		}
	},
	stopTimeScroll : function() {
		if (this.scrollCallTimer != null)
   		window.clearTimeout(this.scrollCallTimer);
		this.scrollCallFnc = null;
		this.scrollCallTimer = null;
		cafen.Event.stopObserving(cafen.getBody(), "mouseup", this.stopTimeScrollBind);
		this.setScrollHold(false);
	},
	clickBarTimeStep : 30,
	clickBarTimePos : 0,
	clickBarTimeOut : 0,
	clickBarTimeScrollBind : null,
	clickBarTimeScrollDir : true,
	clickBarTimeScrollStep : 100,
	clickBarOffset : null,
	clickBarTimeScroll : function(pos, dir) {
		if ((this.scrollHeight  - this.objHeight) > 0) {
			if (typeof pos == 'number') {
				this.clickBarTimeScrollStep = (dir) ? this.objWidth / 3 : this.objHeight / 3;
				pos = Math.round(pos*1000/this.clickBarTimeStep)*this.clickBarTimeStep/1000;
				if (pos == this.clickBarTimePos)
					return ;
				this.clickBarTimePos = pos;
				this.clickBarTimeScrollDir = dir;
			}
			if (this.clickBarTimeScrollBind == null)
				this.clickBarTimeScrollBind = this.clickBarTimeScroll.bind(this);
			var tarPos = null;
			var wantPos = null;
			if (this.clickBarTimeScrollDir) {
				var currPos = this.obj.scrollTop;
				tarPos = Math.round((this.scrollHeight - this.viewHeight) * this.clickBarTimePos);
				var wantPosStep = this.clickBarTimeScrollStep * ((currPos > tarPos) ? (-1) : (+1));
				wantPos = Math.round(currPos + wantPosStep);
				if (currPos < tarPos) {
					wantPos = Math.min(wantPos, tarPos);
				} else {
					wantPos = Math.max(wantPos, tarPos);
				}
				this.setVScroll(wantPos);
			} else {
				var currPos = this.obj.scrollLeft;
				tarPos = Math.round((this.scrollWidth - this.viewWidth) * this.clickBarTimePos);
				var wantPosStep = this.clickBarTimeScrollStep * ((currPos > tarPos) ? (-1) : (+1));
				wantPos = Math.round(currPos + wantPosStep);
				if (currPos < tarPos) {
					wantPos = Math.min(wantPos, tarPos);
				} else {
					wantPos = Math.max(wantPos, tarPos);
				}
				this.setHScroll(wantPos);
			}
			if (wantPos != tarPos) {
				if (this.clickBarTimeOut != null) {
					window.clearTimeout(this.clickBarTimeOut);
					this.clickBarTimeOut = null;
				}
				this.clickBarTimeScrollStep *= 1.2;
				this.clickBarTimeOut = window.setTimeout(this.clickBarTimeScrollBind, 50);
			}
		}
	},
	clickBarTimeScrollStop : function(event) {
		if (this.clickBarTimeOut != null) {
			window.clearTimeout(this.clickBarTimeOut);
			this.clickBarTimeOut = null;
		}
		if (event != null);
			cafen.Event.stop(event);
		this.updateScroll();
		return false;
	},
	setVScroll : function(pos) {
		if (pos >= 0) {
			if (this.scrollHeight > pos)
				this.obj.scrollTop = pos;
			else
				this.obj.scrollTop = this.scrollHeight;
		} else
			this.obj.scrollTop = 0;
	},
	clickVBarStart : function(event) {
		if (this.checkScrollHold()) {
			this.clickBarOffset = cafen.viewportOffset(this.scrollVObj)[1];
			if (this.clickVBarMove(event)) {
				if (this.clickVBarMoveBind == null) {
					this.clickVBarMoveBind = this.clickVBarMove.bindAsEventListener(this);
					this.clickVBarEndBind = this.clickVBarEnd.bindAsEventListener(this);
				}
				cafen.Event.observe(cafen.getBody(), "mousemove", this.clickVBarMoveBind, true);
				cafen.Event.observe(cafen.getBody(), "mouseup", this.clickVBarEndBind, true);
			}
		}
	},
	clickVBarEnd : function(event) {
		cafen.Event.stopObserving(cafen.getBody(), "mousemove", this.clickVBarMoveBind, true);
		cafen.Event.stopObserving(cafen.getBody(), "mouseup", this.clickVBarEndBind, true);
		return this.clickBarTimeScrollStop(event);
	},
	clickVBarMove : function(event) {
		var scrollPos = cafen.pointerY(event) - this.clickBarOffset - this.scrollData.weight;
		if (scrollPos >= 0 && scrollPos <= (this.scrollVrange - this.scrollData.weight*2)) {
			cafen.Event.stop(event);
			var pos = scrollPos / (this.scrollVrange - this.scrollData.weight*2);
			this.clickBarTimeScroll(pos, true);
			return true;
		} else
			return false;
	},
	updateVScroll : function() {
		if (this.buttonVScroll != null && this.scrollData.scrollVmode) {
			var pos = Math.min(1, Math.max(this.obj.scrollTop / (this.obj.scrollHeight - this.viewHeight),0));
			var scrollTop = (this.scrollVrange - this.scrollData.weight*2 - this.barHeight)*pos + this.scrollData.weight;
			cafen.setStyle(this.buttonVScroll, {top: scrollTop + 'px'});
		}
	},
	moveUp : function(event) {
		this.buttonVUp.blur();
		this.startTimeScroll(this.moveUpStart.bind(this));
		cafen.Event.stop(event);
	},
	moveUpStart : function() {
		var scrollTop = this.obj.scrollTop - (this.objHeight / this.scrollStep);	
		this.setVScroll(scrollTop);
		return true;
	},
	moveDown : function(event) {
		this.buttonVDown.blur();
		this.startTimeScroll(this.moveDownStart.bind(this));
		cafen.Event.stop(event);
	},
	moveDownStart : function() {
		var scrollTop = this.obj.scrollTop + (this.objHeight / this.scrollStep);	
		this.setVScroll(scrollTop);
		return true;
	},
	setHScroll : function(pos) {
		if (pos > 0) {
			if (this.scrollWidth > pos)
				this.obj.scrollLeft = pos;
			else
				this.obj.scrollLeft = this.scrollWidth;
		} else
			this.obj.scrollLeft = 0;
	},
	clickHBarStart : function(event) {
		if (this.checkScrollHold()) {
			this.clickBarOffset = cafen.viewportOffset(this.scrollHObj)[0];
			if (this.clickHBarMove(event)) {
				if (this.clickHBarMoveBind == null) {
					this.clickHBarMoveBind = this.clickHBarMove.bindAsEventListener(this);
					this.clickHBarEndBind = this.clickHBarEnd.bindAsEventListener(this);
				}
				cafen.Event.observe(cafen.getBody(), "mousemove", this.clickHBarMoveBind, true);
				cafen.Event.observe(cafen.getBody(), "mouseup", this.clickHBarEndBind, true);
			}
		}
	},
	clickHBarEnd : function(event) {
		this.buttonHScroll.blur();
		cafen.Event.stopObserving(cafen.getBody(), "mousemove", this.clickHBarMoveBind, true);
		cafen.Event.stopObserving(cafen.getBody(), "mouseup", this.clickHBarEndBind, true);
		return this.clickBarTimeScrollStop(event);
	},
	clickHBarMove : function(event) {
		var scrollPos = Math.round((cafen.pointerX(event) - this.clickBarOffset - this.scrollData.weight)/5)*5;
		if (scrollPos >= 0 && scrollPos <= (this.scrollHrange - this.scrollData.weight*2)) {
			cafen.Event.stop(event);
			var pos = scrollPos / (this.scrollHrange - this.scrollData.weight*2);
			this.clickBarTimeScroll(pos, false);
			return true;
		} else
			return false;
	},
	updateHScroll : function() {
		if (this.buttonHScroll != null && this.scrollData.scrollHmode) {
			var pos = Math.min(1, Math.max(this.obj.scrollLeft / (this.scrollWidth - this.viewWidth),0));
			var scrollLeft = (this.scrollHrange - this.scrollData.weight*2 - this.barWidth)*pos + this.scrollData.weight;
			cafen.setStyle(this.buttonHScroll, {left: scrollLeft + 'px'});
		}
	},
	moveLeft : function(event) {
		this.buttonHLeft.blur();
		this.startTimeScroll(this.moveLeftStart.bind(this));
		cafen.Event.stop(event);
	},
	moveLeftStart : function(obj) {
		var scrollLeft = this.obj.scrollLeft - (this.objWidth / this.scrollStep);	
		this.setHScroll(scrollLeft);
		return true;
	},
	moveRight : function(event) {
		this.buttonHRight.blur();
		this.startTimeScroll(this.moveRightStart.bind(this));
		cafen.Event.stop(event);
	},
	moveRightStart : function() {
		var scrollLeft = this.obj.scrollLeft + (this.objWidth / this.scrollStep);	
		this.setHScroll(scrollLeft);
		return true;
	}
}

cafen.XFolder = function(menus, options) {
	options = cafen.extend({useanimate : true}, options);
	this.setOptions(cafen.extend({tag : 'div', style : {overflow : 'hidden', textAlign:'left'}, attribute : {className : 'r_folder'}},options));
	this.initFolder(menus, options);	
}

cafen.XFolder.prototype = cafen.extendClass({
	_lastshownChild : null,
	_subItems : [],
	_isFolder : true,
	_folderIcon : {'trace' : 190, 'folder' : 197, 'exe' : 176, 'bmp' : 180, 'psd' : 186, 'pdf' : 188,'ppt' : 187,'xls' : 184,'mp3' : 179,'doc' : 178,'htm' : 175,'hwp' : 173,'gif' : 175,'jpg' : 172, 'zip' : 183, 'imagefolder' : 195, 'musicfolder' : 194, 'checkfolder' : 196,'openfolder' : 199, 'text' : 192, 'textcolor' : 193, 'cd' : 198},
	initFolder : function(menus, options) {
		this._subItems = [];
		var len = menus.length;
		for(var i = 0; i < len; i++) {
			var tmpOptions = cafen.extend({},options);
			var isLast = (i == (len - 1)) ? true : false;
			var currMenu = menus[i];
			var haveChild = (currMenu.items != null && currMenu.items.length > 0 || currMenu.xmlurl != null) ? true : false;
			var text = currMenu.text;
			var itemObj = new cafen.Div({style:{height: 'auto', overflowX : 'hidden', overflowY : 'hidden'}});
			this.appendChild(itemObj);
			var itemContents = new cafen.TableAuto({attribute:{border : 0, width : '400px'}, style:{width:'400px'}});
			if (currMenu.icon != null) {
				itemContents.addCell(new cafen.XImage(currMenu.icon));
				itemContents.addStyle({width : '17px', paddingLeft : '1px', textAlign:'left'});
			} else if (currMenu.type != null && currMenu.type != '') {
				var iconInfo = {className : 'r_editorset', x : 0, y : 0, w:16, h:16};
				var no = (this._folderIcon[currMenu.type] != null) ? this._folderIcon[currMenu.type] : 192;
				iconInfo.x = (no % 10) * 16;
				iconInfo.y = (Math.floor(no / 10))*16;
				itemContents.addCell(new cafen.XImage(iconInfo));
				itemContents.addStyle({width : '17px', paddingLeft : '1px', textAlign:'left'});
			} else if (currMenu.src != null) {
				itemContents.addCell(new cafen.Image(currMenu.src,{}));
				itemContents.addStyle({width : '17px', paddingLeft : '1px', textAlign:'left'});
			}
			itemContents.addCell(new cafen.Div({attribute:{innerHTML : text}, style : {whiteSpace: 'nowrap',overflow : 'hidden', width:'200px', height :'16px', lineHeight:'normal', marginTop :'3px', marginLeft :'3px', fontSize:'12px'}}));
			itemContents.addStyle({textAlign:'left'});
			var folderClass = '';
			if (haveChild)
				folderClass = isLast ? 'r_eclose' : 'r_mclose';
			else
				folderClass = isLast ? 'r_eempty' : 'r_mempty';
			var itemButton = new cafen.Button(cafen.extend({childNodes : [itemContents], attribute : {className : folderClass, unselectable : 'on'}, style :{textAlign:'left',height: '18px'}, seqn : i},currMenu));
			if (currMenu.disabled == true) 
				itemButton.setDisable(true);
			itemButton.attachEvent('click',this.toggleFolder.bind(this));
			itemObj.appendChild(itemButton);
			var subitem = null, subItemArea = null;
			if (haveChild) {
				subItemArea = new cafen.Div({attribute:{className: isLast ? 'r_echild' : 'r_mchild'}, style :{display:'none', overflowX :'hidden'}});
				itemObj.appendChild(subItemArea);
				if (currMenu.items != null && currMenu.items.length > 0) {
					var childOptions = cafen.extend(tmpOptions, {className : '', shadow : false});
					if (currMenu.onclick != null)
						 childOptions.onclick = currMenu.onclick;
					subitem = new cafen.XFolder(currMenu.items, childOptions);
					subItemArea.appendChild(subitem);
				}
			}
			if (currMenu.onclick != null ) 
				itemButton.attachEvent('click',currMenu.onclick);
			else if (tmpOptions.onclick != null &&!haveChild) 
				itemButton.attachEvent('click',tmpOptions.onclick);
			itemButton.getParent = 	function() {
				var parentObj = this.parentNode;
				while (parentObj) {
					if (	parentObj._isFolder) {
						if (parentObj.parentNode && parentObj.parentNode.parentNode) 
							return parentObj.parentNode.parentNode.childNodes[0];
						else
							return null;
					}else
						parentObj = parentObj.parentNode;
				}
				return null;
			}
			itemButton.getData = function(txt,ids) {
				txt = txt || 'text';
				ids = ids || [];
				ids.push(this.getOption(txt));
				var parentObj = this.getParent();
				if (parentObj != null && parentObj.getData)
					parentObj.getData(txt, ids);
				return ids;
			}
			itemButton.getOption = function(txt) {
				txt = txt || 'text';
				return this.options[txt] || '';
			}
			if (subItemArea != null) {
				itemButton.linkObj = subitem;
				itemButton.linkArea = subItemArea;
			}
			itemButton.linkName = text;
			itemButton.isOpened = false;
			itemButton.linkParent = this;
			if (haveChild)
				itemButton.classOpenClose = isLast ? ['r_eclose','r_eopen'] : ['r_mclose','r_mopen'];
			else
				itemButton.classOpenClose = isLast ? ['r_eempty','r_eempty'] : ['r_mempty','r_mempty'];
			this._subItems.push(itemButton);
		}
	},
	openClose : function(bl, seqns) {
		if (seqns != null) {
			if (seqns.length > 0) {
				var findObj = this.get(seqns[0]);
				if (findObj != null) {
					seqns.shift();
					findObj.setStyle({fontWeight:'bold'});
					this.openFolder(findObj, bl, true, seqns);
				}
			}
		} else {
			for (var i = 0; i < this._subItems.length; i++) {
				var obj = this._subItems[i];
				this.openFolder(obj, bl, true, null);
			}
		}
	},
	get : function(idx) {
		if (typeof idx == 'number') {
			if (idx < this._subItems.length)
				return this._subItems[idx];
			else 
				return null;
		} else {
			for (var i = 0; i < this._subItems.length; i++) {
				var currObj = this._subItems[i];
				if (currObj.getOption('id') == idx) {
					return currObj;
					break;
				}
			}
			return null;
		}
	},
	openFolder : function(obj, bl, cascade, seqns) {
		var currBl = (bl != null) ? bl : obj.getOption('isOpen');
		if (obj.isOpened != currBl) {
			obj.isOpened = currBl;
			if (obj.isOpened) {
				if (obj.linkArea != null) {
					if (obj.linkObj == null) {
						obj.linkArea.appendChild(new cafen.Div({attribute:{innerHTML :'xml loading...'}}));
						obj.linkObj = {}
					}
					if (this.options.useanimate)
						obj.linkArea.showAnimate('Y');
					else
						obj.linkArea.show();
				}
				obj.setClassName(obj.classOpenClose[1]);
			} else {
				if (obj.linkArea != null) {
					if (this.options.useanimate)
						obj.linkArea.hideAnimate('Y');
					else
						obj.linkArea.hide();
				}
				obj.setClassName(obj.classOpenClose[0]);
			}
		}
		if (obj.linkArea != null && cascade) 
			obj.linkArea.childNodes[0].openClose(bl, seqns);
	},
	toggleFolder : function(obj) {
		cafen.setSelected(obj, {fontWeight:'bold'}, {fontWeight:'normal'});
		this.openFolder(obj, !obj.isOpened);
		return true;
	}
},cafen.Element.prototype);



cafen.Category = function(options) {
	this.options = cafen.extend(
		{
			method : 'post', 
			postData : {} , 
			xmlURL : '/BRIDGE/xml_category.html', 
			imgURL : cafenGlobalConf.imageURL,
			folderSelect : false, 
			width : 200, 
			canbenull : true,
			hideTop : true,
			onchange : function() {},
			notuseWrap : true,
			initValue : null
		},
		options
	);
	this.init();
}

cafen.Category.prototype = {
	init : function() {
		this.initcate = null;
		this.obj = new cafen.Div({style :{width:this.options.width + 'px', height: 'auto', padding : '0px'}});
		this.tmpObj = this.obj.appendChild(new cafen.Div({attribute :{innerHTML : cafenMsg.get('com_wait')},style : {width:(this.options.width -10) + 'px', height: '30px', padding: '5px', backgroundColor : '#ffffff'}}));
		new cafen.Ajax(this.options.postData, this.setFolder.bind(this), this.options.xmlURL , this.options.method);
	},
	getObject : function() {
		return this.obj.getObject();
	},
	setInit : function(initValue) {
		this.options.initValue = initValue;	
		if (this.folderMenu != null) 
			this.folderMenu.openClose(true,this.options.initValue);
	},
	setFolder : function(channel) {
		this.tmpObj.parentNode.removeChild(this.tmpObj);
		if (channel.checkMsg()) {
			var msg = channel.getMsg();
			this.onchange(null,null,'<b>' + msg.title +'</b><hr>' + msg.contents);
		} else {
			var items = this.getItems(channel);
			if (items.items.length > 0) {
				this.folderMenu = new cafen.XFolder(items.items, {onclick : this.onchange.bind(this), style :{width : this.options.width + 'px', overflowY : 'hidden'}});
				this.obj.appendChild(this.folderMenu);
				this.folderMenu.openClose(true,this.options.initValue);
			} else 
				this.obj.getElement().innerHTML = cafenMsg.get('com_nodata');
		}
	},
	getItems : function(channel) {
		var item = sitem = null;
		var cateid = channel.getNode('id');
		var catename = channel.getNode('name');
		var isopen = (channel.getNode('isopen') == 'true')? true : false;
		var isfolder = (channel.getNode('isfolder') == 'true')? true : false;
		var isunselectable = (channel.getNode('isunselectable') == 'true')? true : false;
		if (cateid == '' || catename == '')
			return null;
		var subitem = [];
		while(item = channel.getNext()) {
			sitem = this.getItems(item);
			if (sitem != null)
				subitem.push(sitem);
		}
		return {isunselectable : isunselectable, id : cateid, text : catename, type : (subitem.length > 0) ? 'folder' : '', items : subitem};
	},
	onchange : function(obj) {
		this.options.onchange(obj);
	}
}


cafen.XPopupTitle = function(poptitle, options) {
	this.setOptions(cafen.extend(options, {tag : 'table', style : {width:'100%'}}));	
	var colObjs = [];
	var titleNode = new cafen.Cell(poptitle, {style : {textAlign:'left', cursor : 'move'}});
	colObjs.push(titleNode);
	titleNode.attachEvent('mousedown', this.startMove.bind(this));
	var optionObjs = [];
	var colseBtn  = new cafen.Button({attribute : {innerHTML : 'X'}, style: {border : '1px solid #121212'}, event : {'click' : this.togglePopup.bind(this)}});
	optionObjs.push(colseBtn);
	var optionsNode = new cafen.Cell('', {style: {width : '30px', textAlign:'right'}, childNodes : optionObjs});
	colObjs.push(optionsNode);
	this.appendChild(new cafen.Tbody([new cafen.Row(colObjs, {})]));
}

cafen.XPopupTitle.prototype = cafen.extendClass({
	isOpen : true,
	startMove : function(obj, event) {
		cafen.startDrag(event, obj, this.parentNode, 'H');
		return true;
	},
	togglePopup : function() {
		this.parentNode.setStyle({height : 'auto'});
		this.isOpen = !this.isOpen;
		if (this.isOpen) 
			this.parentNode.mainObj.setAnimate(null, null, 200, 300);
		else
			this.parentNode.mainObj.setAnimate(null, null, 200, 10);
	}
},cafen.Element.prototype);

cafen.XPopup = function(mainChild, options) {
	var baseClassName = options.className;
	var childNodes = [];	
	this.titleObj = new cafen.XPopupTitle(options.title, options)
	childNodes.push(this.titleObj);
	this.mainObj = new cafen.Div({attribute :{}, style : {border : '1px solid #464646', textAlign:'left', height: '300px'}});
	childNodes.push(this.mainObj);
	this.setOptions(cafen.extend(options, {tag : 'div', className : 'r_btnskin', shadow : true, childNodes : childNodes, attribute :{}, style : {}}));
}

cafen.XPopup.prototype = cafen.extendClass({
	titleObj : null,
	mainObj : null
},cafen.Container.prototype);

cafen.Resizable = function(mainChild, options) {
	mainChild = cafen.$(mainChild);
	var orgParent = mainChild.parentNode;
	this.setOptions(cafen.extend(options, {resize : 'XOOOOOOOO', resizeOption : {minWidth : 10, minHeight : 10, maxWidth : -1, maxHeight : -1, Increment : 1, preserveRatio: false}, tag : null, className : 'r_btnskin', childNodes : [], attribute :{}, style : {}}));
	if (	orgParent != null) {
		orgParent.insertBefore(this.getObject(), mainChild);
		this.setElement(mainChild);
	}	
}

cafen.Resizable.prototype = cafen.extendClass({
},cafen.Element.prototype);


cafen.Slider = function(options) {
	options = cafen.extend({size : 100, def : 0, min : 0, max : 100, step : 1, buttonstep : null, direct : 'X', useButton : true, event : {end : function() {}}}, options);
	this._objSize = (options.useButton) ? options.size - 36 : options.size;
	this._objDirect = options.direct;
	this._objMin = options.min;
	this._objMax = options.max;
	this._objStep = options.step;
	this._objButtonStep = this.offset2Value(1) - options.min;
	var minStep = Math.abs((this._objMax - this._objMin)  / this._objSize *2);
	this._objButtonStep = Math.max(minStep, (this._objButtonStep < this._objStep) ? this._objStep : this._objButtonStep);
	switch (this._objDirect) {
		case 'Y' : 
			var tmpTable = new cafen.TableAuto({style : {width : '15px', height : options.size +'px'}});
			if (	options.useButton) {
				tmpTable.addRow();
				tmpTable.addCell(new cafen.XIcon({
					icon:'r_iconset', on : 15,  off :255, over :15, 
					style : {width : '15px', height: '15px',padding:0,margin:0},
					event : {
						mousedown : this.moveEvent.bind(this,false), 
						mouseup : this.stopMoveEvent.bind(this)}
				}));
				tmpTable.addStyle({paddingBottom:'3px'});
			}
			this.pointerObj = new cafen.XIcon(
				{
					icon:'r_iconset', on : 15,  off :330, over :15,  
					moveOption : {direction : 'Y', rangeX :null, rangeY :[-7, this._objSize -7]}, 
					event: {'dragend' : this.setMove.bind(this)},
					style:{position : 'absolute', top : '-3px', left :'-5px', width:'15px', height: '15px'}
				}
			);
			this.sliderObj = new cafen.Div({
				tag: 'div', 
				className : 'r_boxwhite',
				childNodes : [this.pointerObj], 
				style : {cursor : cafen.getCursor(), width: '5px', height: this._objSize +'px', position:'relative'},
				event : {click : this.setPointer.bind(this), keydown : this.keypress.bind(this)}
			});
			tmpTable.addRow();
			tmpTable.addCell(this.sliderObj);
			tmpTable.addStyle({paddingLeft:'2px'});
			if (options.useButton) {
				tmpTable.addRow();
				tmpTable.addCell(new cafen.XIcon({
					icon:'r_iconset', on : 15,  off :240, over :15, 
					style : {width : '15px', height: '15px',padding:0,margin:0},
					event : {
						mousedown : this.moveEvent.bind(this,true), 
						mouseup : this.stopMoveEvent.bind(this)}
				}));
				tmpTable.addStyle({paddingTop:'3px'});
			}
			this.setOptions(cafen.extend(options, {childNodes : [tmpTable]}));
			break;
		default :
			var tmpTable = new cafen.TableAuto({style : {height : '15px', width : options.size +'px', backgroundImage :'none'}});
			if (options.useButton) {
				tmpTable.addCell(new cafen.XIcon({
					icon:'r_iconset', on : 15,  off :255, over :15, 
					style : {width : '15px', height: '15px',padding:0,margin:0},
					event : {
						mousedown : this.moveEvent.bind(this,false), 
						mouseup : this.stopMoveEvent.bind(this)}
				}));
				tmpTable.addStyle({paddingRight:'3px'});
			}
			this.pointerObj = new cafen.XIcon(
				{
					icon:'r_iconset', on : 15,  off :315, over :15,  
					moveOption : {direction : 'X', rangeX :[-7, this._objSize -7], rangeY :null}, 
					event: {'dragend' : this.setMove.bind(this)},
					style:{position : 'absolute', left : '0px', top : '-5px',width:'15px', height: '15px', padding:0, margin:0}
				}
			);
			this.sliderObj = new cafen.Div({
				tag: 'div', 
				className : 'r_boxwhite',
				childNodes : [this.pointerObj], 
				style : {cursor : cafen.getCursor(), width: this._objSize +'px', height:'5px', backgroundImage:'none'},
				event : {click : this.setPointer.bind(this), keydown : this.keypress.bind(this)}
			});
			tmpTable.addCell(this.sliderObj);
			if (options.useButton) {
				tmpTable.addCell(new cafen.XIcon({
					icon:'r_iconset', on : 15,  off :240, over :15, 
					style : {width : '15px', height: '15px',padding:0,margin:0},
					event : {
						mousedown : this.moveEvent.bind(this,true), 
						mouseup : this.stopMoveEvent.bind(this)}
				}));
				tmpTable.addStyle({paddingLeft:'3px'});
			}
			this.setOptions(cafen.extend(options, {childNodes : [tmpTable]}));
			break;
	}
	this.initSlider();
	this.setValue(options.def);
}

cafen.Slider.prototype = cafen.extendClass({
	_objSize : null, 
	_objDirect : null,
	pointerObj : null,
	initSlider : function() {
		this.sliderObj.getElement().style.position = 'relative';
		this.sliderObj.getElement().style.left = '0px';
		this.sliderObj.getElement().style.top = '0px';
	},
	setPointer : function(obj, event) {
		var pos = cafen.pointer(event);
		var currPos = cafen.viewportOffset(this.sliderObj.getElement());
		switch (this._objDirect) {
			case 'Y':
				this.pointerObj.setOffset(null, this.offset2Offset(pos[1] - currPos[1]) - 7);
				break;
			default : 
				this.pointerObj.setOffset(this.offset2Offset(pos[0] - currPos[0]) - 7, null);
				break;
		}
		this.setMove(event);
	},
	moveEvent : function(bl) {
		if (bl)
			this._moveSeqnBind = this.movePlus.bind(this);
		else
			this._moveSeqnBind = this.moveMinus.bind(this);
		this._moveEventSpeed = 200;
		this._moveEventSeqnBind = this.moveEventSeqn.bind(this);
		this.moveEventSeqn();
	},
	moveEventSeqn : function() {
		if (this._moveSeqnBind != null) {
			this._moveSeqnBind();	
			this._moveEventSpeed = Math.max(10,Math.round(this._moveEventSpeed * 0.7));
			window.setTimeout(this._moveEventSeqnBind, this._moveEventSpeed);
		}
	},
	stopMoveEvent : function(obj, event) {
		this._moveSeqnBind = null;
		this._moveEventSpeed = 100;
		this.setMove(event);
	},
	moveMinus : function() {
		if (this._objMax > this._objMin)
			this.setValue(this.getValue() - this._objButtonStep);
		else
			this.setValue(this.getValue() + this._objButtonStep);
	},
	movePlus : function() {
		if (this._objMax > this._objMin)
			this.setValue(this.getValue() + this._objButtonStep);
		else
			this.setValue(this.getValue() - this._objButtonStep);
	},
	keypress : function(obj, event) {
		switch(event.keyCode) {
			case 37 :
			case 38 :
				this.moveMinus();
				this.setMove(event);
				break;
			case 39 :
			case 40 :
				this.movePlus();
				this.setMove(event);
				break;
		}
	},
	offset2Value : function(val) {
		if (this._objMax > this._objMin)
			return Math.min(this._objMax, Math.max(this._objMin, Math.round((val / this._objSize) * (this._objMax - this._objMin) / this._objStep) * this._objStep+ this._objMin));
		else
			return Math.max(this._objMax, Math.min(this._objMin, Math.round((val / this._objSize) * (this._objMax - this._objMin) / this._objStep) * this._objStep+ this._objMin));
	},
	value2Offset : function(val) {
		return Math.min(Math.max(0,Math.round((val -this._objMin) / (this._objMax - this._objMin) * (this._objSize))), this._objSize);
	},
	offset2Offset : function(val) {
		return this.value2Offset(this.offset2Value(val));
	},
	setValue : function(val) {
		val = this.value2Offset(val);
		switch (this._objDirect) {
			case 'Y' :
				this.pointerObj.setOffset(null, val -7);
				break;
			default :
				this.pointerObj.setOffset(val -7, null);
		}	
	},
	getValue : function() {
		var pos = this.pointerObj.getOffset() ;
		switch (this._objDirect) {
			case 'Y' :
				return this.offset2Value(pos[1] + 7);
				break;
			default :
				return this.offset2Value(pos[0] + 7);
				break;
		}
	},
	setMoveBy : function(posPlus) {
		var pos = this.pointerObj.getOffset();
		switch (this._objDirect) {
			case 'Y' :
				if (pos[1] + posPlus - 7 > 0 &&  pos[1] + posPlus - 7 < this._objSize)
					this.pointerObj.setOffset(null, this.offset2Offset(pos[1] + posPlus) - 7);
				break;
			default :
				if (pos[0] + posPlus - 7 > 0 &&  pos[0] + posPlus - 7 < this._objSize)
					this.pointerObj.setOffset(this.offset2Offset(pos[0] + posPlus) - 7, null);
				break;
		}
		this.setMove(event);
	},
	setMove : function(event) {
		this.execEvent('end', event);
	}
},cafen.Element.prototype);

cafen.window = function() {}

cafen.window.prototype = cafen.extendClass({
	_parentPop : null,
	_buttonObj : null,
	_titleObj : null,
	_onEndFnc : null,
	_toggleObj : null,
	_contentWidth : null,
	_isOpen : true,
	_popupSize : null,
	_contentObj : null,
	initParam : function(parent, popup_width) {
		this._parentPop = parent;
		this._contentWidth = popup_width;
		this._buttonObj = null;
		this.setOptions({className :'r_popskin', tag : 'div', tplName : 'top', style : {width:popup_width +'px',textAlign:'center', position :'absolute'}, shadow : false, resize : 'XXXOOOOOO', event :{'resize' : this.freeSize.bind(this)}});
		this._titleObj = new cafen.TableAuto({align:'center', attribute :{width:'100%', height:'auto'}});
		this.appendChild(this._titleObj, 'top');
	},
	setTitle : function(title) {
		this._titleObj.addCell(new cafen.Div({attribute :{innerHTML : title},moveOption : {direction : 'XY', rangeX :null, rangeY :null, link : this}}));
	},
	setToolBar : function(bl) {
		if (bl == null || bl) {
			this._toggleObj = new cafen.XIcon({icon:'r_winset-minmax', off :0, on : 20,  over :45, hit : 90, event:{'click' : this.setToggle.bind(this,null)}, style : {width:'26px',height:'19px'}})
			this._titleObj.addCell(this._toggleObj);
		} else {
			this._titleObj.addCell('&nbsp;');
		}
		this._titleObj.addChild(new cafen.XIcon({icon:'r_winset-close', off :40, on : 0, over :45 , hit : 90, event:{'click' : this.close.bind(this,null)}, style : {width:'44px',height:'19px'}}));
		this._titleObj.addStyle({textAlign:'right', width: '70px',verticalAlign: 'top', whiteSpace: 'nowrap'});
	},
	freeSize : function() {
		this._popupSize = null;
	},
	setToggle : function() {
		this._isOpen = ! this._isOpen;
		this._toggleObj.setSelected(!this._isOpen);
		if (this._isOpen) 
			this.setAnimate(null, 'max');
		else {
			cafen.setSelected(null);
			this.setAnimate(null, 'hidden');
		}
	},
	setContents : function(contents) {
		this.appendChild(new cafen.Div({attribute :{innerHTML : contents},style : {width:'auto',height:'auto', backgroundColor :'#f0f0f0', fontSize:'12px',padding:'5px', margin: '3px', textAlign:'center'}}));
	},
	setObject : function(obj) {
		this.appendChild(obj);
	},
	setButton : function(btnObj) {
		if (this._buttonObj == null) {
			this._buttonObj = new cafen.TableAuto({align:'center', attribute :{height:'27px', cellpadding:'2px'}});
			this.appendChild(this._buttonObj);
		}
		this._buttonObj.addCell(btnObj);
		this._buttonObj.addStyle({padding:'2px'});
	},
	fix2Center : function() {
		if (this._parentPop != null)
			this.setOffsetBy(26, 26);
		else
			this.center();
	},
	onLoad : function() {
		if (this._parentPop == null) {
			cafen.getPopup().appendChild(this.getObject());
//			window.onscroll = window.onresize = this.fix2Center.bind(this);
		} else {
			this._parentPop.appendChild(this, 'shadow');
		}
		this.fix2Center();
	},
	onClose : function(val) {
		if (this._onEndFnc != null)
			this._onEndFnc(val);
	},
	close : function(val) {
		if (this._parentPop == null) {
			this.onClose(val);
//			window.onscroll = window.onresize = null;
			cafen.getPopup().removeChild(this.getObject());
		} else
			this._parentPop.removeChild(this);
	}
},cafen.Element.prototype);

cafen.alert = function(title, contents, parent) {
	this.initParam(parent, 300);
	this.setTitle(title);
	this.setToolBar();
	this.setContents(contents);
	this.setButton(new cafen.XButton({text:'OK',className : 'r_rbtnskin' , style :{width:'40px'}, align:'center',event:{'click' : this.close.bind(this)}}));
	this.onLoad();
}

cafen.alert.prototype = cafen.extendClass({},cafen.window.prototype);


cafen.message = function(title, contents, base_width, parent) {
	this.initParam(parent, base_width);
	this.setTitle(title);
	this.setToolBar();
	this.setObject(contents);
	this.setButton(new cafen.XButton({text:'OK',className : 'r_rbtnskin' , style :{width:'40px'}, align:'center',event:{'click' : this.close.bind(this)}}));
	this.setButton(new cafen.XButton({text:'OK',className : 'r_rbtnskin' , style :{width:'40px'}, align:'center',event:{'click' : this.close.bind(this)}}));
	this.onLoad();
}

cafen.message.prototype = cafen.extendClass({},cafen.window.prototype);

cafen.confirm = function(title, contents, onEndFnc, parent) {
	this._onEndFnc = onEndFnc;
	this.initParam(parent, 300);
	this.setTitle(title);
	this.setContents(contents);
	this.setToolBar();
	this.setButton(new cafen.XButton({text:'Yes',className : 'r_rbtnskin',style :{width:'40px'},event:{'click' : this.close.bind(this,true)}}));
	this.setButton(new cafen.XButton({text:'No',style :{width:'40px'},event:{'click' : this.close.bind(this,false)}}));
	this.onLoad();
}

cafen.confirm.prototype = cafen.extendClass({},cafen.window.prototype);

cafen.prompt = function(title, contents, onEndFnc, parent) {
	this._onEndFnc = onEndFnc;
	this.initParam(parent, 300);
	this.setTitle(title);
	this.setContents(contents);
	this._inputObj = new cafen.Input({style:{width:'95%', height :'20px'}});
	this.setObject(this._inputObj);
	this.setToolBar();
	this.setButton(new cafen.XButton({text:'OK',tplName : '' , align:'center', style :{width:'40px'},event:{'click' : this.sendValue.bind(this)}}));
	this.onLoad();
}

cafen.prompt.prototype = cafen.extendClass({
	_inputObj : null,
	sendValue : function() {
		var val = this._inputObj.getElement().value;
		if (val.split(' ').join('') != '')
			this.close(val);
	}
},cafen.window.prototype);



cafen.CPoint = function(x,y) {
	this.x = x; 	this.y = y;	
}
cafen.CPoint.prototype = {x : null, y : null}

cafen._CanvasElement = function(options) {
	this.setOptions(cafen.extend(options, {tag : 'div', attribute :{}, style : {}}));
	this.initCanvas();
}


cafen._CanvasElement.prototype = cafen.extendClass({
	_canvasObject : null, 
	_canvasStyle : {
		bgColor : "#ffffff",
		strokeWeight : "1",
		strokeColor : "#000000",
		strokeJoinStyle : "miter",
		strokeDashStyle : "dotted",
		strokeOpacity : "1.0",
		strokeLineStyle : "single",
		fillColor1 : "#ffffff",
		fillColor2 : "#ffffff",
		fillType : "",
		fillMethod : "",
		fillAngle : "",
		fillOpacity : "1.0",
		shadowType : "",
		backgroundColor : "#ffffff",
		border : "solid 1px #585c6c",
		fontFamily : "dotum,sans-serif",
		fontColor : "#333333",
		fontSize : "11px",
		fontWeight : "normal",
		textAlign : "center",
		lineHeight : "16px"
	},
	initCanvas : function() {
		this._canvasObject = this.getElement();
	},
	setStrokeStyle : function(obj, _style){
		if (obj instanceof Array) {
			for(var i = 0; i < obj.length; i++)
				this._setStrokeStyle(obj[i], _style);
		} else 
			this._setStrokeStyle(obj, _style);
	},
	_setStrokeStyle : function() {},
	setFillStyle: function (obj, _style){
		if (obj instanceof Array) {
			for(var i = 0; i < obj.length; i++)
				this._setFillStyle(obj[i], _style);
		} else 
			this._setFillStyle(obj, _style);
	},
	_setFillStyle : function() {},
	createLine : function(start, end){},
	updateLine : function(line, start, end){},
	drawLine : function(start, end){},
	createRect : function(start, end){},
	updateRect : function(rect, start, end){},
	drawRect : function(start, end) {},
	createPolyLine : function(rPoints){},
	drawPolyLine : function(rPoints) {},
	createPolygon : function(rPoints){},
	addPolygonPoints : function(element, rPoints){},
	drawPolygon : function(rPoints){},
	createCircle : function(rPoint, radius){},
	updateCircle : function(circle, rPoint, radius){},
	drawCircle: function(rPoint, radius) {},
	createOval : function(rPoint, radiusX, radiusY){},
	updateOval : function(eclipse, rPoint, radiusX, radiusY){},
	drawOval : function(rPoint, radiusX, radiusY) {},
	_drawOval : function(sPoint, ePoint){},
	createText : function(rPoint, msg){},
	updateText : function(text, rPoint, msg){},
	drawText: function(rPoint, msg, options){},
	updateStar : function(star, center, radius, dir){
		this.unDraw(star);
		return star = this.drawStar(center, radius, dir);
	},
	drawStar : function(center, radius, dir){
		dir = (dir == null) ? 0 : (dir / 180) * Math.PI;
		var points = [];
		for(var i = 0 ; i < 5; i++) {
			points.push(new cafen.CPoint(Math.sin(i/2.5*Math.PI + dir)*radius + center.x , Math.cos(i/2.5*Math.PI + dir)*radius + center.y));
			points.push(new cafen.CPoint(Math.sin((i+3)/2.5*Math.PI + dir)*radius + center.x , Math.cos((i+3)/2.5*Math.PI + dir)*radius + center.y));
		}
		return this.drawPolyLine(points);
	},
	b1Bezier : function(t) { return (t*t*t); },
	b2Bezier : function(t) { return (3*t*t*(1-t)); },
	b3Bezier : function(t) { return (3*t*(1-t)*(1-t)); },
	b4Bezier : function(t) { return ((1-t)*(1-t)*(1-t)); },
	getBezier : function(percent,C1,C2,C3,C4) {
		return new cafen.CPoint(
			C1.x * this.b1Bezier(percent) + C2.x * this.b2Bezier(percent) +C3.x * this.b3Bezier(percent) + C4.x * this.b4Bezier(percent),
			C1.y * this.b1Bezier(percent) + C2.y * this.b2Bezier(percent) + C3.y * this.b3Bezier(percent) + C4.y * this.b4Bezier(percent)
		);
	},
	drawCurve : function(start, leftpo, rightpo,end, rate) {
		var points = [];
		var step = 100/rate;
		for(var i = 0; i <= 100; i += step) 
			points.push(this.getBezier(i/100, start, leftpo, rightpo, end));	
		return this.drawPolyLine(points);
	},
	unDraw : function(obj) {
		if (obj.length != null) {
			for(var i = 0; i < obj.length; i++)
				this.unDraw(obj[i]);
		} else if (obj.parentNode != null)
			obj.parentNode.removeChild(obj);
	}
},cafen.Element.prototype);

cafen._CanvasSGV = function(options) {
	this.setOptions(cafen.extend({tag : 'div', attribute :{}, style : {}},options));
	this.initCanvas();
}

cafen._CanvasSGV.prototype = cafen.extendClass({
	namespace : 'http://www.w3.org/2000/svg',
	initCanvas : function() {
		    this._canvasObject = document.createElementNS(this.namespace, "svg");
		    this.getElement().appendChild(this._canvasObject);
	},
	_setStrokeStyle : function(obj, _style){
		var _style = _style || this._canvasStyle;
		if (_style.strokeColor != null)
			obj.setAttribute("stroke", _style.strokeColor);
		if(_style.strokeDashStyle == "dash")
			obj.setAttribute("stroke-dasharray", "5, 5, 5");
		else if(_style.strokeDashStyle == "dashdot")
			obj.setAttribute("stroke-dasharray", "5, 2, 5");
		if (_style.strokeOpacity != null)
			obj.setAttribute("stroke-opacity", _style.strokeOpacity);
		if (_style.strokeWeight != null)
			obj.setAttribute("stroke-width", _style.strokeWeight);
		if (_style.strokeJoinStyle != null)
			obj.setAttribute("stroke-linejoin", _style.strokeJoinStyle);
	},
	_setFillStyle: function (parentObj, _style){
		var _style = _style || this._canvasStyle;
		if (_style.fillColor1 != null)
			parentObj.setAttribute("fill", _style.fillColor1);
		if (_style.fillOpacity != null)
			parentObj.setAttribute("fill-opacity", _style.fillOpacity)
	},
	setObjectStyle : function(obj, style) {
		for(var name in style) {
			switch(name) {
				case 'rotation' :
					var center = this.getObjectCenter(obj);
					obj.setAttribute('transform','rotate('+style[name] +','+center[0]+','+center[1]+')');
					break;
				default :
					obj.setAttribute(name,style[name]);
					break;
			}
		}
	},
	getObjectCenter : function(obj) {
		if (obj.getAttribute('points') != null) {
			var points_str = obj.getAttribute('points');
			var xMin = 0,yMin = 0, xMax = 0, yMax = 0;
			var points = points_str.split(' ');
			for(var i = 0; i < points.length; i++) {
				var xypoint = points[i].split(',');
				var currX = parseInt(xypoint[0]);
				var currY = parseInt(xypoint[1]);
				if (i == 0) {
					xMax = xMin = currX;
					xMax = yMin = currY;
				} else {
					xMin = Math.min(xMin, currX);
					xMax = Math.max(xMax, currX);
					yMin = Math.min(yMin, currY);
					yMax = Math.max(yMax, currY);
				}
			}
			var x = Math.round((xMin + xMax)/2);
			var y = Math.round((yMin + yMax)/2);
			return [x, y];
		} else if (obj.getAttribute('x1') != null)
			return [(obj.getAttribute('x1') + obj.getAttribute('x2'))/2, (obj.getAttribute('y1') + obj.getAttribute('y2'))/2];
		else if (obj.getAttribute('cx') != null)
			return [obj.getAttribute('cx'), obj.getAttribute('cy')];
		else {
			return [0,0];
		}
	},
	createLine : function(start, end){
		var line = document.createElementNS(this.namespace, "line");
		this.updateLine(line, start, end);
		return line;
	},
	updateLine : function(line, start, end){
		line.setAttribute("x1", start.x);
		line.setAttribute("y1", start.y);
		line.setAttribute("x2", end.x);
		line.setAttribute("y2", end.y);
		line.sPoint = start; line.ePoint = end;
	},
	drawLine : function(start, end){
		var line = this.createLine(start, end);
		this.setStrokeStyle(line);
		this._canvasObject.appendChild(line);
		return line;
	},
	createRect : function(start, end){
		var rect = document.createElementNS(this.namespace, "rect");
		this.updateRect(rect, start, end);
		return rect;
	},
	updateRect : function(rect, start, end){
		var xOffset = end.x - start.x;
		var yOffset = end.y - start.y;
		var width = Math.abs(xOffset);
		var height = Math.abs(yOffset);
		var x = (xOffset) > 0 ? start.x : end.x;
		var y = (yOffset) > 0 ? start.y : end.y;
		rect.setAttribute("x", x);
		rect.setAttribute("y", y);
		rect.setAttribute("width", width);
		rect.setAttribute("height", height);
		rect.setAttribute("gtype", "rect");
	},
	drawRect : function(start, end) {
		var rect = this.createRect(start, end);
		this.setStrokeStyle(rect);
		this.setFillStyle(rect);
		this._canvasObject.appendChild(rect);
		return rect;
	},
	createPolyLine : function(rPoints){
		if(rPoints.length > 0){
			var polyline = document.createElementNS(this.namespace, "polyline");
			var points = [];
			for(var i=0,len=rPoints.length; i<len; i++){
				points.push(rPoints[i].x);
				points.push(rPoints[i].y);
			}
			polyline.setAttribute("points", points.join(","));
			return polyline;
		}
	},
	drawPolyLine : function(rPoints) {
		var polyline = this.createPolyLine(rPoints);
		this.setStrokeStyle(polyline);
		this.setFillStyle(polyline, {fillColor1 : 'transparent'});
		this._canvasObject.appendChild(polyline);
		return polyline;
	},
	createPolygon : function(rPoints){
		if(rPoints.length > 0){
			var polygon = document.createElementNS(this.namespace, "polygon");
			var points = [];
			for(var i=0,len=rPoints.length; i<len; i++){
				points.push(rPoints[i].x);
				points.push(rPoints[i].y);
			}
			polygon.setAttribute("points", points);
			polygon.dpoints = rPoints;
			return polygon;
		}
	},
	addPolygonPoints : function(element, rPoints){
		for(var i=0,len=rPoints.length; i<len; i++)
			element.dpoints.push(rPoints[i]);
		var points = [];
		for(var i=0,len=element.dpoints.length; i<len; i++){
			points.push(element.dpoints[i].x);
			points.push(element.dpoints[i].y);
		}
		element.setAttribute("points", points);
	},
	drawPolygon : function(rPoints){
		var polygon = this.createPolygon(rPoints);
		this.setStrokeStyle(polygon);
		this.setFillStyle(polygon);
		this._canvasObject.appendChild(polygon);
		return polygon;
	},
	createCircle : function(rPoint, radius){
		var circle = document.createElementNS(this.namespace, "circle");
		this.updateCircle(circle, rPoint, radius);
		return circle;
	},
	updateCircle : function(circle, rPoint, radius){
		circle.setAttribute("cx", rPoint.x);
		circle.setAttribute("cy", rPoint.y);
		circle.setAttribute("r", radius);
	},
	drawCircle: function(rPoint, radius) {
		var circle = this.createCircle(rPoint, radius);
		this.setStrokeStyle(circle);
		this.setFillStyle(circle);
		this._canvasObject.appendChild(circle);
		return circle;
	},
	createOval : function(rPoint, radiusX, radiusY){
		var eclipse = document.createElementNS(this.namespace, "ellipse");
		this.updateOval(eclipse, rPoint, radiusX, radiusY);
		return eclipse;
	},
	updateOval : function(eclipse, rPoint, radiusX, radiusY){
		eclipse.setAttribute("cx", rPoint.x);
		eclipse.setAttribute("cy", rPoint.y);
		eclipse.setAttribute("rx", radiusX);
		eclipse.setAttribute("ry", radiusY);
		eclipse.setAttribute("gtype", "oval");
	},
	drawOval : function(rPoint, radiusX, radiusY) {
		var eclipse = this.createOval(rPoint, radiusX, radiusY);
		this.setStrokeStyle(eclipse);
		this.setFillStyle(eclipse);
		this._canvasObject.appendChild(eclipse);
		return eclipse;
	},
	_drawOval : function(sPoint, ePoint){
		var cx = Math.min(sPoint.x, ePoint.x) + (Math.max(sPoint.x, ePoint.x) - Math.min(sPoint.x, ePoint.x))/2;
		var cy = Math.min(sPoint.y, ePoint.y) + (Math.max(sPoint.y, ePoint.y) - Math.min(sPoint.y, ePoint.y))/2;
		var rx = (Math.max(sPoint.x, ePoint.x) - Math.min(sPoint.x, ePoint.x))/2;
		var ry = (Math.max(sPoint.y, ePoint.y) - Math.min(sPoint.y, ePoint.y))/2;
		return this.drawOval(new cafen.CPoint(cx, cy), rx, ry);
	},
	createText : function(rPoint, msg){
		var text = daum.maps.TemplateGenerator.getLayer();
		this.updateText(text, rPoint, msg);
		return text;
	},
	updateText : function(text, rPoint, msg){
		text.style.position = "absolute";
		text.style.zIndex = "50";
		text.style.left = rPoint.x + "px";
		text.style.top = rPoint.y + "px";
		text.style.color = this.style.fontColor;
		text.style.fontSize = this.style.fontSize;
		text.style.fontWeight = this.style.fontWeight;
		text.style.textAlign = this.style.textAlign;
		text.style.lineHeight = this.style.lineHeight;
		text.wrap.style.fontFamily = this.style.fontFamily;
		text.wrap.style.padding = "0 5px";
		text.wrap.style.letterSpacing = "-1px";
		text.wrap.innerHTML = msg;
	},
	drawText: function(rPoint, msg, options){
		var options = options || { align : "left", valign : "top", offsetX : 0, offsetY : 0 };
		var text = this.createText(rPoint, msg);
		this.container.appendChild(text);
		if(options.align == "right"){
			text.style.left = (parseInt(text.style.left) - text.offsetWidth)+ 'px';
		}
		if(options.valign == "bottom"){
			text.style.top = (parseInt(text.style.top) - text.offsetHeight)+ 'px';
		}
		daum.Element.setPosition(text, parseInt(text.style.top) + options.offsetY, parseInt(text.style.left) + options.offsetX);
		daum.maps.TemplateGenerator.setBackLayer(text);
		return text;
	}
},cafen._CanvasElement.prototype);


cafen._CanvasVML = function(options) {
	this.setOptions(cafen.extend(options, {tag : 'div', attribute :{}, style : {overflowY:'hidden',overflowX:'hidden',overflow:'hidden'}}));
	this.initCanvas();
}

cafen._CanvasVML.prototype = cafen.extendClass({
	namespace : 'urn:schemas-microsoft-com:vml',
	initCanvas : function() {
		document.namespaces.add("v", this.namespace);
		try {
		document.createStyleSheet().addRule("v\\:*", "behavior: url(#default#VML);");
		} catch(ex) {}
		    var tmpObj = new cafen.Div({style:{width:'100%',height:'100%', position:'absolute',overflow : 'hidden', display:'inline-block',zIndex: '1000'}});
		    this.appendChild(tmpObj);
		    this._canvasObject = tmpObj.getElement();
		var size = this.getSize();
		this.width = size[0];
		this.height = size[1];
	},
	_setStrokeStyle : function(parent, _style){
		var _style = _style || this._canvasStyle;
		var obj = null;
		if (parent.getElementsByTagName("stroke").length > 0) {
			obj = parent.getElementsByTagName("stroke")[0];
		} else {
			obj = document.createElement("v:stroke");
			parent.appendChild(obj);
		}
		if (_style.strokeDashStyle != null)
			obj.dashstyle = _style.strokeDashStyle;
		if (_style.strokeLineStyle != null)
			obj.linestyle = _style.strokeLineStyle;
		if (_style.strokeJoinStyle != null)
			obj.joinstyle = _style.strokeJoinStyle;
		if (_style.strokeOpacity != null)
			obj.opacity = _style.strokeOpacity;
		if (_style.strokeColor != null)
			parent.strokecolor = _style.strokeColor;
		if (_style.strokeWeight != null)
			parent.strokeweight = _style.strokeWeight;
		if (_style.startarrow != null)
			obj.startarrow = _style.startarrow;
		if (_style.startarrowwidth != null)
			obj.startarrowwidth = _style.startarrowwidth;
		if (_style.startarrowlength != null)
			obj.startarrowlength = _style.startarrowlength;
		if (_style.endarrow != null)
			obj.endarrow = _style.endarrow;
		if (_style.endarrowwidth != null)
			obj.endarrowwidth = _style.endarrowwidth;
		if (_style.endarrowlength != null)
			obj.endarrowlength = _style.endarrowlength;
	},
	_setFillStyle : function(parent, _style){
		var _style = _style || this._canvasStyle;
		var obj = null;
		if (parent.getElementsByTagName("fill").length > 0) {
			obj = parent.getElementsByTagName("fill")[0];
		} else {
			obj = document.createElement("v:fill");
			parent.appendChild(obj);
		}
		obj.on = "true";
		if (_style.fillColor1 != null)
			obj.color = _style.fillColor1;
		if (_style.fillColor2 != null)
			obj.color2 = _style.fillColor2;
		if (_style.fillType != null)
			obj.type = _style.fillType;
		if (_style.fillMethod != null)
			obj.method = _style.fillMethod;
		if (_style.fillAngle != null)
			obj.angle = _style.fillAngle;
		if (_style.fillOpacity != null)
			obj.opacity = _style.fillOpacity;
	},
	setObjectStyle : function(obj, style) {
		for(var name in style) 
			obj.style[name] = style[name];
	},
	createLine : function(start, end){
		var line = document.createElement("v:line");
		this.updateLine(line, start, end);
		return line;
	},
	updateLine : function(line, start, end){
		line.style.position = "absolute";
		line.from = start.x + ", " + start.y;
		line.to = end.x + ", " + end.y;
	},
	drawLine : function(start, end){
		var line = this.createLine(start, end);
		this.setStrokeStyle(line);
		this._canvasObject.appendChild(line);
		return line;
	},
	createRect : function(start, end, options){
		var rect = document.createElement(options.rectType);
		this.updateRect(rect, start, end, options || {});
		return rect;
	},
	updateRect : function(rect, start, end, options){
		var options = options || {};
		var xOffset = end.x - start.x;
		var yOffset = end.y - start.y;
		rect.style.position = "absolute";
		rect.style.left = ((xOffset) > 0 ? start.x : end.x) + "px";
		rect.style.top = ((yOffset) > 0 ? start.y : end.y) + "px";
		rect.style.width = Math.abs(xOffset) + "px";
		rect.style.height = Math.abs(yOffset) + "px";
		rect.gtype = "rect";
		if(options.arcsize) 
			rect.arcsize = options.arcsize;
	},
	drawRect: function(start, end) {
		var rect = this.createRect(start, end, {rectType : "v:rect"});
		this.setStrokeStyle(rect);
		this.setFillStyle(rect);
		this._canvasObject.appendChild(rect);
		return rect;
	},
	createPolyLine : function(rPoints){
		if(rPoints.length > 0){
			var pLine = document.createElement("v:polyline");
			pLine.style.position = "absolute";
			pLine.style.width = this.width + "px";
			pLine.style.height = this.height + "px";
			pLine.coordorigin = "0 0";
			pLine.coordsize = this.width + " " + this.height;
			var points = [];
			for(var i=0,len=rPoints.length; i<len; i++){
				points.push(rPoints[i].x);
				points.push(rPoints[i].y);
			}
			pLine.points = points.join(",");
			pLine.dpoints = rPoints;
			return pLine;
		}
	},
	drawPolyLine : function(rPoints){
		if(rPoints.length > 0) {
			var pLine = this.createPolyLine(rPoints);
			this.setStrokeStyle(pLine);
			this.setFillStyle(pLine, {fillColor1 : 'none', fillOpacity : 0});
			this._canvasObject.appendChild(pLine);
			return pLine;
		}
	},
	getPathInfo: function(points) {
		var pathInfo = [];
		for (var i=0,len=points.length; i<len;){
			if(i == 0){
				pathInfo.push("m " + points[i] + "," + points[i+1]);
			}else if(i == 2){
				pathInfo.push(" l " + points[i] + "," + points[i+1]);
			}else{
				pathInfo.push(", " + points[i] + "," + points[i+1]);
			}
			i += 2;
		}
		pathInfo.push(" x e");
		return pathInfo.join(' ');
	},
	createPolygon : function(rPoints){
		if(rPoints.length > 0){
			this.width = document.body.clientWidth;
			this.height = document.body.clientHeight;
			var pGon = document.createElement("v:shape");
			pGon.style.position = "absolute";
			pGon.style.width = this.width + "px";
			pGon.style.height = this.height + "px";
			pGon.coordorigin = "0 0";
			pGon.coordsize = this.width + " " + this.height;
			var points = [];
			for(var i=0,len=rPoints.length; i<len; i++){
				points.push(rPoints[i].x);
				points.push(rPoints[i].y);
			}
			pGon.path = this.getPathInfo(points);
			return pGon;
		}
	},
	addPolygonPoints : function(element, rPoints){
		for(var i=0,len=rPoints.length; i<len; i++){
			element.dpoints.push(rPoints[i]);
		}
		var points = [];
		for(var i=0,len=element.dpoints.length; i<len; i++){
			points.push(element.dpoints[i].x);
			points.push(element.dpoints[i].y);
		}
		element.path = this.getPathInfo(points);
	},
	drawPolygon: function(rPoints){
		if(rPoints.length > 0) {
			var pGon = this.createPolygon(rPoints);
			this.setStrokeStyle(pGon);
			this.setFillStyle(pGon);
			this._canvasObject.appendChild(pGon);
			return pGon;
		}
	},
	drawCircle : function(rPoint, radius) {
		return this.drawOval(rPoint, radius, radius);
	},
	updateCircle : function(circle, rPoint, radius){
		this.updateOval(circle, rPoint, radius, radius);
	},
	createOval : function(rPoint, radiusX, radiusY){
		var circle = document.createElement("v:oval");
		this.updateOval(circle, rPoint, radiusX, radiusY);
		return circle;
	},
	updateOval : function(circle, rPoint, radiusX, radiusY){
		circle.style.position = "absolute";
		circle.style.left = rPoint.x - radiusX + "px";
		circle.style.top = rPoint.y - radiusY + "px";
		circle.style.width = radiusX * 2  + "px";
		circle.style.height = radiusY * 2  + "px";
		circle.gtype = "oval";
	},
	drawOval : function(rPoint, radiusX, radiusY) {
		var circle = this.createOval(rPoint, radiusX, radiusY);
		this.setStrokeStyle(circle);
		this.setFillStyle(circle);
		this._canvasObject.appendChild(circle);
		return circle;
	},
	_drawOval : function(sPoint, ePoint){
		var cx = Math.min(sPoint.x, ePoint.x) + (Math.max(sPoint.x, ePoint.x) - Math.min(sPoint.x, ePoint.x))/2;
		var cy = Math.min(sPoint.y, ePoint.y) + (Math.max(sPoint.y, ePoint.y) - Math.min(sPoint.y, ePoint.y))/2;
		var rx = (Math.max(sPoint.x, ePoint.x) - Math.min(sPoint.x, ePoint.x))/2;
		var ry = (Math.max(sPoint.y, ePoint.y) - Math.min(sPoint.y, ePoint.y))/2;
		return this.drawOval(new cafen.CPoint(cx, cy), rx, ry);
	},
	createText : function(rPoint, msg){
		this.updateText(text, rPoint, msg);
		return text;
	},
	updateText : function(text, rPoint, msg){
		text.style.position = "absolute";
		text.style.zIndex = "50";
		text.style.left = rPoint.x + "px";
		text.style.top = rPoint.y + "px";
		text.style.color = this._canvasStyle.fontColor;
		text.style.fontSize = this._canvasStyle.fontSize;
		text.style.fontWeight = this._canvasStyle.fontWeight;
		text.style.textAlign = this._canvasStyle.textAlign;
		text.style.lineHeight = this._canvasStyle.lineHeight;
		text.wrap.style.styleFloat = "left";
		text.wrap.style.fontFamily = this._canvasStyle.fontFamily;
		text.wrap.style.padding = "0 5px";
		text.wrap.style.letterSpacing = "-1px";
		text.wrap.style.lineHeight = this._canvasStyle.lineHeight;
		text.wrap.style.overflow = "hidden";
		text.wrap.innerHTML = msg;
	},
	drawText: function(rPoint, msg, options){
		var options = options || { align : "left", valign : "top", offsetX : 0, offsetY : 0 };
		var text = this.createText(rPoint, msg);
		if(options.align == "right"){
			text.style.left = (parseInt(text.style.left) - text.offsetWidth)+'px';
		}
		if(options.valign == "bottom"){
			text.style.top = (parseInt(text.style.top) - text.offsetHeight)+ 'px';
		}
		return text;
	}		
},cafen._CanvasElement.prototype);


cafen.Canvas = function(options) {
	this.setOptions(cafen.extend(options, {tag : 'div', attribute :{}, style : {}}));
	this.initCanvas();
}

cafen.Canvas.prototype = (document.namespaces && document.namespaces.add) ? cafen._CanvasVML.prototype : cafen._CanvasSGV.prototype ;


cafen.XWindow = function(options) {
	this.initOptions(cafen.extend({className :'', attribute : {className : 'r_div'}, style : {left: '0px',top:'0px',width:'1px', height : '1px', fontSize : '1px',zIndex :500, position : 'relative'}, shadow : false},options));
}

cafen.XWindow.prototype = cafen.extendClass({
	_popupOptions : null,
	_parentPop : null,
	_buttonObj : null,
	_titleObj : null,
	_onEndFnc : null,
	_toggleObj : null,
	_contentWidth : null,
	_isOpen : true,
	_popupSize : null,
	_contentObj : null,
	_lastOpenChild : null,
	_scrollProtected : true,
	initOptions : function(options) {
		this.setOptions(cafen.extend({className :'r_btnskin', tag : 'div', style : { textAlign:'center', position :'absolute',zIndex:500}, shadow : true}, options));
	},
	initParam : function(parent, popup_width) {
		this._parentPop = parent;
		this._contentWidth = popup_width;
		this._buttonObj = null;
		this.setOptions({className :'r_btnskin', tag : 'div', tplName : 'top', style : {width:popup_width +'px',textAlign:'center', position :'absolute'}, shadow : false, resize : 'XXXOOOOOO', event :{'resize' : this.freeSize.bind(this)}});
		this._titleObj = new cafen.TableAuto({align:'center', attribute :{width:'100%', height : '19'}});
		this.appendChild(this._titleObj, 'top');
	},
	addChild : function(obj, bl) {
		this.appendChild(obj);
	},
	closeChild : function(obj) {
		if (this._lastOpenChild != null) {
			this._lastOpenChild.closeHide();
			this._lastOpenChild = null
		}
	},
	checkTitleObject : function() {
		if (this._titleObj == null) {
			this._titleObj = new cafen.TableAuto({align:'center', attribute :{width:'100%', height:'20', border:0}, style : {position:'relative', top : '0px', width : '100%'}});
			this.appendChild(this._titleObj, 'top');
		}
	},
	setTitle : function(title) {
		this.checkTitleObject();
		if (!cafen.getLicence()) {
			this._titleObj.addCell(new cafen.XIcon({icon:'r_winset-logo', off :184, on : 20,  over :45, event : {click : cafen.openPopup.bind(cafen, 'http://cafen.net')}, style : {width:'16px',height:'16px'}}));
			title += ' <a href="http://www.cafen.net" target=_blank><img src="'+_cafen_service_url+'images/ico_pwbycafen2.gif" border=0 hspace=5 vspace=3 align=absmiddle></a>'; 
		} else
			this._titleObj.addCell(new cafen.XIcon({icon:'r_winset-logo', off :222, on : 20,  over :45}));
		this._titleObj.addStyle({width: '20px'});
		this._titleTxtObj = new cafen.Div({attribute :{innerHTML:'<font size=2>' +title+'</font>'} ,moveOption : {direction : 'XY', rangeX :null, rangeY :null, link : this}, event :{click : this.clickTitle.bind(this)}, style : {whiteSpace: 'nowrap'}});
		this._titleObj.addCell(this._titleTxtObj);
	},
	clickTitle : function() {
		cafen.setTopPopup(this);
	},
	setToolBar : function(bl) {
		this.checkTitleObject();
		if (bl == null || bl) {
			this._toggleObj = new cafen.XIcon({icon:'r_winset-minmax', off :0, on : 20,  over :45, hit : 90, event:{'click' : this.setToggle.bind(this,null)}, style : {width:'26px',height:'19px'}})
			this._titleObj.addCell(this._toggleObj);
		} else {
			this._titleObj.addCell('&nbsp;');
		}
		this._titleObj.addChild(new cafen.XIcon({icon:'r_winset-close', off :40, on : 0, over :45, hit : 90 ,event:{'click' : this.close.bind(this,null)}, style : {width:'44px',height:'19px'}}));
		this._titleObj.addStyle({textAlign:'right', width: '70px',verticalAlign: 'top', whiteSpace: 'nowrap'});
	},
	setToggle : function() {
		this._isOpen = ! this._isOpen;
		this._toggleObj.setSelected(!this._isOpen);
		this.closeChild();
		if (this._isOpen)
			this.setAnimate(null, 'max');
		else {
			cafen.setSelected(null);
			this.setAnimate(null, 'hidden');
		}
	},
	setAutoScroll : function(bl) {
		if (bl) 
			window.onscroll = window.onresize = this.move2Cetner.bind(this);
		else
			window.onscroll = window.onresize = null;
	},
	move2Cetner : function() {
		var scrollVal = cafen.getPageScroll();
		var pageVal = cafen.getPageSize();
		var selfSize = this.getSize();
		var offsetY = scrollVal[1]+(pageVal[1] -selfSize[1])/2;
		this.setOffset(null , (offsetY > 0) ? offsetY : 0);
	},
	setContents : function(contents, pos, title, titleimg) {
		if (this.options.sticker != null && pos != null) {
			if (pos.x != null)
				this.options.sticker.x = pos.x;
			if (pos.y != null)
				this.options.sticker.y = pos.y;
			if (pos.plus != null)
				this.options.sticker.plus = pos.plus;
		}
		if (this.contentsObj == null) {
			if (this.options.skinClass != null) {
				var skinTable = new cafen.TableAuto({attribute : {border : 0, className : this.options.skinClass}});
				var skinData = [
					['topleft','topmid','topright'],
					['midleft','midmid','midright'],
					['botleft','botmid','botright']
				];
				for(var i = 0; i < skinData.length; i++) {
					skinTable.addRow();	
					for(var j = 0; j < skinData[i].length; j++) {
						var skinClass = skinData[i][j];
						var cellObj = skinTable.addCell('<i>&#160;</i>');
						cellObj.addAttribute({className : skinClass});
						if (skinClass == 'midmid') 
							this.contentsObj = cellObj;
						else if (skinClass == 'topmid') 
							this._titleTxtObj = cellObj;
					}
				}
				this.appendChild(skinTable);
			} else {
				this.contentsObj = new cafen.Div({attribute :{innerHTML : ''},style : {lineHeight:'170%',fontSize:'12px', textAlign:'center'}});
				this.appendChild(this.contentsObj);
			}
		}
		if (this._titleTxtObj != null && title != null) 
			this._titleTxtObj.addText('<font class="title">' + title+ '</font>');
		if (typeof contents == 'object') {
			this.contentsObj.removeAllChild();
			this.contentsObj.appendChild(contents);
			if (contents.setParent)
				contents.setParent(this);
			if (contents.onLoad)
				contents.onLoad();
		} else {
			this.contentsObj.removeAllChild();
			this.contentsObj.getElement().innerHTML = contents;
		}
	},
	setObject : function(obj) {
		this.appendChild(obj);
	},
	setButton : function(btnObj) {
		if (this._buttonObj == null) {
			var tmpDiv = new cafen.TableAuto({style:{height:'35px', width:'100%'}});
			this._buttonObj = new cafen.TableAuto({attribute :{align:'center',height:'35px', cellpadding:'2'}});
			tmpDiv.addCell("&nbsp;");
			tmpDiv.addStyle({width:'50%'});
			tmpDiv.addCell(this._buttonObj);
			tmpDiv.addStyle({padding:'2px', textAlign:'center'});
			tmpDiv.addCell("&nbsp;");
			tmpDiv.addStyle({width:'50%'});
			this.appendChild(tmpDiv);
		}
		this._buttonObj.addCell(btnObj);
		this._buttonObj.addStyle({padding:'2px'});
	},
	setLastOpenChild : function(obj) {
		if (this._lastOpenChild != null && this._lastOpenChild != obj && this._lastOpenChild.close)
			this._lastOpenChild.close();
		this._lastOpenChild = obj;
	},
	onLoad : function(sticker, bl) {
		if (sticker != null) 
			this.options.sticker = sticker;
		else if (bl)
			this.options.sticker = null;
		if (this.parentNode != null) {
			if (this.parentNode.closeChild && this.parentNode._lastOpenChild != null)
				this.parentNode.closeChild();
			this.parentNode._lastOpenChild = this;
		} else {
			this.parentNode = cafen.getPopup(this.options.popArea);
			this.parentNode.appendChild(this.getObject());
		}
		this.show();
		if (this.contentsObj != null) {
			var orgSize = this.contentsObj.getFullSize();
			if (!this.options.donotresize) {
				this.contentsObj.setSize('auto','auto');
			} else {
				if (!this.options.resized) {
					this.contentsObj.setSize('auto','auto');
					this.options.resized = true;
				}
			}
			var realSize = this.contentsObj.getFullSize();
			if (orgSize[0] > realSize[0])
				cafen.setStyle(this.contentsObj.getObject().childNodes[0], {width:'auto'});
			var sizeInfo = this.contentsObj.getFullSize();
			this.contentsObj.setSize(sizeInfo[0],null);
			this.setSize(sizeInfo[0]+10);
			if (this.topArea != null) {
				this.topArea.setSize(sizeInfo[0]+10,null);
			}
		}
		if (this.options.sticker != null && this.options.sticker.obj != null) {
			var parentOffset = (this.parentNode.cumulativeOffset) ? this.parentNode.cumulativeOffset() : cafen.cumulativeOffset(this.parentNode);
			var stickerOffset = (this.options.sticker.obj.cumulativeOffset) ? this.options.sticker.obj.cumulativeOffset() : cafen.cumulativeOffset(this.options.sticker.obj);
			var stickerSize = (this.options.sticker.obj.getSize) ?  this.options.sticker.obj.getSize() : cafen.getSize(this.options.sticker.obj);
			var selfSize = this.getSize();
			var offsetX = stickerOffset[0] - parentOffset[0]	;
			var offsetY = stickerOffset[1] - parentOffset[1];
			switch(this.options.sticker.x) {
				case 'left' :
					offsetX += 0;
					break;
				case 'exleft' :
					offsetX -= selfSize[0];
					break;
				case 'right' :
					offsetX += stickerSize[0];
					break;
				case 'exright' :
					var tmpoffsetX = offsetX + (stickerSize[0] - selfSize[0]);
					if (this.options.sticker.obj != null && tmpoffsetX < 0) {

					} else {
						offsetX = tmpoffsetX;
					}
					break;
				default :
					offsetX += (stickerSize[0] - selfSize[0])/2;
					break;
			}
			switch(this.options.sticker.y) {
				case 'top' :
					offsetY += 0;
					break;
				case 'extop' :
					offsetY -= selfSize[1];
					break;
				case 'bottom' :
					offsetY += stickerSize[1];
					break;
				case 'exbottom' :
					offsetY += (stickerSize[1] - selfSize[1]);
					break;
				default :
					offsetY += (stickerSize[1] - selfSize[1])/2;
					break;
			}
			if (this.options.sticker.plus != null) {
				offsetX += this.options.sticker.plus[0];
				offsetY += this.options.sticker.plus[1];
			}
			this.setOffset(Math.round(offsetX), offsetY);
			
			if (stickerOffset[2]) {
				cafen.setStyle(this.getObject(), {position:'fixed'});
			} else {
				cafen.setStyle(this.getObject(), {position:'absolute'});
			}
			if (this.options.linkButton != null)
				this.options.linkButton.setSelected(true);
			if (this.onPopup != null)
				this.onPopup();
		} else {
			var scrollVal = cafen.getPageScroll(this.parentNode);
			var pageVal = cafen.getPageSize(this.parentNode);
			var selfSize = this.getFullSize();
			if (cafen.isFixedObject()) {
				var offsetX = (pageVal[0] -selfSize[0])/2;
				var offsetY = (pageVal[1] -selfSize[1])/2;
				cafen.setStyle(this.getObject(), {position:'fixed', left: offsetX +'px', top : offsetY+'px'});
			} else {				
				var offsetX = scrollVal[0]+(pageVal[0] -selfSize[0])/2;
				var offsetY = scrollVal[1]+(pageVal[1] -selfSize[1])/2;
				this.setOffset(offsetX , (offsetY > 0) ? offsetY : 0);
			}
			if (this.onPopup != null) 
				this.onPopup();
		}
		if (this._titleTxtObj != null) {
			if (selfSize[0] < 250) {
				cafen.setStyle(this._titleTxtObj.getElement(), {width:'95px', overflowX:'hidden'});
			}
		}
		if (!this._isOpen)
			this.setToggle();
		cafen.setTopPopup(this);
	},
	sendValue : function(val) {
		this.close();
		if (this._popupOptions.onClose != null) 
			this._popupOptions.onClose(val);
	},
	close : function() {
		if (this.onClose != null)
			this.onClose();
		if (this.parentNode != null && this.parentNode.closeChild)
			this.parentNode.closeChild(this);
		else
			this.closeHide();
	},
	closeHide : function() {
		this.hide();
		if (this.options.linkButton != null)
			this.options.linkButton.setSelected(false);
	},
	setAjaxContents : function(html, obj, title, titleimg) {
		this.setSize('auto','auto');
		if (obj != null)
			this.options.sticker = obj;
		this.setContents(html, null, title, titleimg);

		this.onLoad(this.options.sticker);
		var selfSize = this.getFullSize();
		if (this.topArea) 
			this.topArea.setSize(selfSize[0]-7);
	},
	loadAjax : function(theURL, data) {
		cafen.smallSWFAjax.getFlashXml(data || {},this.setAjaxContents.bind(this), theURL);
	},
	loadHtml : function(html, obj, title, titleimg) {
		this.setAjaxContents(html, obj, title, titleimg);
	}
},cafen.Element.prototype);

cafen.XAlert = function(options) {
	options = options || {}
	this._popupOptions = options;
	this.initOptions(cafen.extend({className :'r_popskin', tag : 'div', tplName : 'top', style : {width:'200px',textAlign:'center', position :'absolute'}, shadow : true, resize : 'XXXOOOOOO'}, options));
	if (options.title != null)
		this.setTitle(options.title);
	this.setToolBar();
	if (options.contents != null)
		this.setContents(options.contents);
	this.setButton(new cafen.XButton({text: cafenMsg.get('com_close'), shortkey : 'C', style :{width:'60px'}, align:'center',event:{'click' : this.close.bind(this)}}));
}

cafen.XAlert.prototype = cafen.extendClass({

},cafen.XWindow.prototype);

cafen.XPrompt = function(options, bl) {
	options = options || {}
	this._popupOptions = options;
	this.initOptions(cafen.extend({className :'r_popskin', tag : 'div', tplName : 'top', style : {width:'200px',textAlign:'center', position :'absolute'}, shadow : true, resize : 'XXXOOOOOO'}, options));
	if (options.title != null)
		this.setTitle(options.title);
	this.setToolBar();
	if (options.contents != null)
		this.setContents(options.contents);
	if (bl) {
		this._inputObj = new cafen.XInput({attribute : {type : 'password'}, style:{width:'160px', marginLeft: '5px'}, event : {end : this.sendValue.bind(this)}});
	} else
		this._inputObj = new cafen.XInput({style:{width:'170px', marginLeft: '5px'}, event : {end : this.sendValue.bind(this)}});
	this.setObject(this._inputObj);
	this.setButton(new cafen.XButton({text: cafenMsg.get('com_ok'), style :{width:'60px'}, align:'center',event:{'click' : this.sendValue.bind(this)}}));
}

cafen.XPrompt.prototype = cafen.extendClass({
	sendValue : function(val) {
		this.close();
		if (this._popupOptions.onClose != null) {
			this._popupOptions.onClose(this._inputObj.getValue());
		}
	}
},cafen.XWindow.prototype);

cafen.XPromptText = function(options) {
	options = options || {}
	this._popupOptions = options;
	this.initOptions(cafen.extend({className :'r_popskin', tag : 'div', tplName : 'top', style : {width:'200px',textAlign:'center', position :'absolute'}, shadow : true, resize : 'XXXOOOOOO'}, options));
	if (options.title != null)
		this.setTitle(options.title);
	this.setToolBar();
	if (options.contents != null)
		this.setContents(options.contents);
	this._inputObj = new cafen.XTextarea({style:{width:'170px', height :'50px', margin: '5px'}});
	this.setObject(this._inputObj);
	this.setButton(new cafen.XButton({text: cafenMsg.get('com_ok'), style :{width:'50px'}, align:'center',event:{'click' : this.sendValue.bind(this)}}));
}

cafen.XPromptText.prototype = cafen.extendClass({
	sendValue : function(val) {
		this.close();
		if (this._popupOptions.onClose != null) {
			this._popupOptions.onClose(this._inputObj.getValue());
		}
	}
},cafen.XWindow.prototype);


cafen.XFaceBox = function(options) {
	options = options || {}
	this._popupOptions = options;
	var tmpOptions = cafen.extend({className :'r_popskin', popArea : null, tag : 'div', tplName : 'top', style : {width:'200px',textAlign:'center', position :'absolute'}, shadow : true, resize : 'XXXOOOOOO'}, options);
	this.initOptions(tmpOptions);
	if (this.options.tplName != '') {
		if (options.title != null)
			this.setTitle(options.title);
		this.setToolBar();
	} else {
		var tmp = new cafen.Div({attribute :{className : 'topButton'}, style : {position:'relative'}});
		this.topArea = new cafen.Div({attribute :{className : 'moveBtn'}, moveOption : {direction : 'XY', rangeX :null, rangeY :null, link : this}, style : {}});
		tmp.appendChild(this.topArea);
		this.topArea.appendChild(new cafen.Div({attribute :{className : 'closeBtn'},event:{'click' : this.close.bind(this)}}));
		this.appendChild(tmp);
		options.hideClose = true;
	}
	if (options.contents != null)
		this.setAjaxContents(options.contents);
	else if (options.ajax_url != null) {
		this.loadAjax(options.ajax_url, options.ajax_data || {});
	}
	if (!options.hideClose)
		this.setButton(new cafen.XButton({text: cafenMsg.get('com_close'), style :{width:'50px'}, align:'center',event:{'click' : this.close.bind(this)}}));
}

cafen.XFaceBox.prototype = cafen.extendClass({
	_lastLoadUrl : null,
	_callEndFnc : null,
	setAjaxContents : function(html, obj, title, titleimg) {
		if (obj != null)
			this.options.sticker = obj;
		else
			this.options.sticker = null;
		this.setSize('auto','auto');
		this.setContents(html, null, title, titleimg);
		this.onLoad(this.options.sticker);
		var objs = this.contentsObj.getElement().getElementsByTagName('div');
		var fileObjs = [];
		for(var i = 0; i < objs.length; i++) {
			var child = objs[i];
			if (child.className.match(new RegExp("(^|\\s)formFile(\\s|$)"))) 
				fileObjs.push(child);
		}
		var selfSize = this.getFullSize();
		if (this.topArea) 
			this.topArea.setSize(selfSize[0]-7);
		if (typeof cafenGlobalConf.onFaceBox == 'function') {
				cafenGlobalConf.onFaceBox(this.contentsObj.getObject());
		} else if (this._callEndFnc != null)
			this._callEndFnc(this.contentsObj.getObject());
		
	},
	onClose : function() {},
	loadAjax : function(theURL, data, callEndFnc) {
		if (callEndFnc != null)
			this._callEndFnc = callEndFnc;
		else
			this._callEndFnc = null;
		data = data || {} ;
		data.requestType = 'xmlPOPUP';
		cafen.smallSWFAjax.getFlashXml(data || {},this.setAjaxContents.bind(this), theURL);
		if (this._lastLoadUrl != theURL) {
			this.setContents('<div style="width:300px"><img src="'+_cafen_service_url+'images/blank.gif" class="r_process">' +cafenMsg.get('com_process')+'</div>');
		if (this.topArea) 
				this.topArea.setSize(300 - 7);
		}
		this._lastLoadUrl = theURL;
	},
	loadHtml : function(html, obj, title, titleimg) {
		this.setAjaxContents(html, obj, title, titleimg);
	}
},cafen.XWindow.prototype);

cafen.XImageViewer = function(options, editorObj) {
	this._popupOptions = options;
	if (editorObj != null) {
		this.initOptions(cafen.extend({className :'r_popskin',  donotresize : true, tag : 'div', tplName : 'top', signTxt : '', maxSize : 1024*1024*1.5 , style : {width:'600px',textAlign:'center', position :'absolute'}, shadow : true}, options));
		this.imgViewer = null;
		this.setTitle(cafenMsg.get('com_imageview') +'(Editor)');
		this.setToolBar();
		this._editorObj = editorObj;
		this._uploadScript = this._editorObj.getUploadScript();
		this._uploadUrl = this._editorObj.getUploadUrl();
		if (this._editorObj.getUploadedUrl)
			this._uploadedUrl = this._editorObj.getUploadedUrl();
		else
			this._uploadedUrl = null;
		this._previewWidth = parseInt(this.options.style.width) - 175;
		this._previewHeight = parseInt(this.options.style.height) - 10;
		var tmpTable = new cafen.TableAuto({style : {}});
		var tmpTable2 = new cafen.TableAuto({className : 'r_boxblue', style : {width : '150px', margin :'2px'}});
		tmpTable.addCell(tmpTable2);
		tmpTable.addStyle({verticalAlign: 'top'});
		tmpTable2.addRow();
		this.skinArea = new cafen.Div({className : 'r_boxwhite', style :{width:'144px', height: '70px',overflowX : 'auto', overflowY : 'hidden', display:'none'}});
		tmpTable2.addCell(this.skinArea);
		tmpTable2.addRow();
		this.buttonArea = new cafen.TableAuto({style : {}});
		tmpTable2.addCell(this.buttonArea);
		tmpTable2.addStyle({verticalAlign: 'top'});
		this.viewerObj = new cafen.Div(cafen.extend({className : 'r_boxwhite'},{style:{width : this._previewWidth+'px', height : this._previewHeight+'px', overflow:'hidden', overflowY:'auto', overflowX:'auto', position :'relative', textAlign:'left', margin :'2px'}}));
		tmpTable.addCell(this.viewerObj);
		tmpTable.addStyle({verticalAlign: 'top'});
		this.setObject(tmpTable);
		this.drawMenu();	
	} else {
		this.initOptions(cafen.extend({className :'r_popskin', donotresize : true, tag : 'div', tplName : 'top', signTxt : '', maxSize : 1024*1024*1.5 , style : {width:'200px',textAlign:'center', position :'absolute'}, shadow : true}, options));
		this.imgViewer = null;
		this.setTitle(cafenMsg.get('com_imageview'));
		this.setToolBar();
		this._previewWidth = parseInt(this.options.style.width) - 6;
		this._previewHeight = parseInt(this.options.style.height) - 6;
		var tmpObj = new cafen.Div(cafen.extend({style : {}},{style:{width : (this._previewWidth +6)+ 'px', height : (this._previewHeight +6)+'px',overflow:'hidden', overflowY:'hidden', overflowX:'hidden', textAlign:'left'}}));
		this.contentsObj = new cafen.Div(cafen.extend({style : {}},{style:{width : (this._previewWidth +6)+ 'px', height : (this._previewHeight +6)+'px',overflow:'hidden', overflowY:'hidden', overflowX:'hidden', textAlign:'left', margin : '3px', left:'0', top : '0'}, attribute :{className : 'r_gride'}}));
		this.viewerObj = new cafen.Div(cafen.extend({style : {}},{style:{width : this._previewWidth + 'px', height : this._previewHeight +'px',overflow:'hidden', overflowY:'hidden', overflowX:'hidden', position :'relative', textAlign:'left'}}));
		this.contentsObj.appendChild(this.viewerObj);
		tmpObj.appendChild(this.contentsObj);
		this.setObject(tmpObj);
	}
	this.getElement().style['position'] = 'relative';
}

cafen.XImageViewer.prototype = cafen.extendClass({
	_underProcess : false,
	_nextProcess : false,
	_infoData : {'M' : false, 'D' : false, 'T' : false, 'S' : false},
	_saveasExt : 'jpg',
	drawMenu : function() {
		if (this.options.signTxt != null && this.options.signTxt != '')
			this._infoData.S = true;
		if (cafenGlobalConf.saveAsExt != null) 
			this._saveasExt = cafenGlobalConf.saveAsExt;
		this._lastSkinNo = null;
		this._skinOptions = {};
		this.menuInfo = [
			{cmd : 'R', name :cafenMsg.get('ed_0062'), min : 0, max : 4, step : 1, def : 0 },
			{cmd : 'E', name :cafenMsg.get('ed_0067'), min : 0, max : 3, step : 1, def : 0},
			{cmd : 'M', name :cafenMsg.get('ed_0054'), min : 30, max : 100, step : 5, def : 100},
			{cmd : 'W', name :cafenMsg.get('ed_0055'), min : 0, max : 200, step : 10, def : 100 },
			{cmd : 'A', name :cafenMsg.get('ed_0056'), min : 0, max : 200, step : 10, def : 100 },
			{cmd : 'H', name :cafenMsg.get('ed_0057'), min : 0, max : 360, step : 10, def : 0 },
			{cmd : 'G', name :cafenMsg.get('ed_0058'), min : 0, max : 1, step : 1, def : 0 },
			{cmd : 'N', name :cafenMsg.get('ed_0059'), min : 0, max : 1, step : 1, def : 0 },
			{cmd : 'C', name :cafenMsg.get('ed_0060'), min : 50, max : 150, step : 10, def : 100 },
			{cmd : 'B', name :cafenMsg.get('ed_0061'), min : 5, max : 15, step : 1, def : 10 }
		];
		this.skin_obj = new cafen.TableAuto({style : {tableLayout:'fixed', cursor : cafen.getCursor(), width : 'auto'}});
		this.skinArea.appendChild(this.skin_obj);
		var setValueBind = this.setValue.bind(this);
		var maxSize = this.options.maxSize;
		this.uploadImg = new cafen.XUpload(140,'image', '', {event : {end : this.setImageUpload.bind(this)}});
		this.buttonArea.addCell(this.uploadImg);
		this.buttonArea.addAttribute({colSpan :2});
		this.buttonArea.addStyle({padding:'1px', textAlign:'right'});
		for(var i = 0 ;  i < this.menuInfo.length; i++) {
			var currObj = this.menuInfo[i];
			this.buttonArea.addRow();
			switch(currObj.cmd) {
				case 'E' :
				case 'R' :
					var iconMargin = null;
					if(cafen.browser.isIE) 
						iconMargin = '0 0 0 3px';
					else if(cafen.browser.isFF) 
						iconMargin = '-1 0 0 0px';
					else
						iconMargin = '3px 0px 3px 2px';
					var actionBind = null;
					var subDataInfo = null;
					currObj.obj = new cafen.Div();
					if (currObj.cmd == 'R') {
						actionBind = this.setRotate.bind(this);
						this.rotateObj = [];
						subDataInfo = cafenMsg.getObject('ed_imgrotate');
					} else {
						actionBind = this.setInfo.bind(this);
						this.infoObj = [];
						subDataInfo = {
							'M' : cafenMsg.get('ed_0065'),
							'D' : cafenMsg.get('ed_0066'),
							'T' : cafenMsg.get('ed_0067'),
							'S' : cafenMsg.get('ed_0068')
						};
					}
					for(var idx in subDataInfo) {
						var x = 0, y = 240 ,bgPos = 330;
						if (currObj.cmd == 'R') {
							switch(idx) {
								case '0' : 
									bgPos = 264;x = 96;
									break;
								case '1' : 
									bgPos = 330;x = 80;
									break;
								case '2' : 
									bgPos = 330;x = 64;
									break;
								case '3' : 
									bgPos = 330;x = 48;
									break;
								case '4' : 
									bgPos = 396;x = 32;
									break;
							}
						} else {
							y = 176;
							switch(idx) {
								case 'M' : 
									bgPos = 264;x = 32;
									break;
								case 'D' : 
									bgPos = 330;x = 48;
									break;
								case 'T' : 
									bgPos = 330;x = 64;
									break;
								case 'S' : 
									bgPos = 396;x = 80;
									break;
							}
						}
						var rotTitle = subDataInfo[idx];
						var icon = new cafen.XImage({className :'r_editorset',x: x,y : y}, {style:{cssFloat : 'left',margin : iconMargin, width:'16px', height:'16px'},attribute :{unselectable : 'on'}});
						var tmpButton = new cafen.XIcon({icon : 'r_wordset', value : idx, off : bgPos, on : 22 , over : 100, style :{width:'24px', paddingRight: '0px'}, attribute :{unselectable : 'on', title : rotTitle}, event :{click : actionBind}, childNodes : [icon]}) ;
						if (currObj.cmd == 'R') 
							this.rotateObj.push({value : idx, obj : tmpButton});
						else
							this.infoObj.push({value : idx, obj : tmpButton});
						currObj.obj.appendChild(tmpButton);
					}
					this.buttonArea.addCell(currObj.obj);
					this.buttonArea.addAttribute({colSpan :2});
					this.buttonArea.addStyle({padding:'1px', textAlign:'right'});
					break;
				default :
					this.buttonArea.addCell('<font size=2 style="line-height:normal">' + currObj.name+'</font>');
					this.buttonArea.addStyle({textAlign:'right',width:'60px'});
					currObj.obj = new cafen.Slider({cmd : currObj.cmd , className : 'r_boxwhite',def : currObj.def, min : currObj.min, max : currObj.max , step : currObj.step, size : 80, event : {end : setValueBind}});
					this.buttonArea.addCell(currObj.obj);
					this.buttonArea.addStyle({padding:'1px'});
					break;
			}
		}
		this.buttonArea.addRow();
		var tmpButtonArea = new cafen.TableAuto({style : {marginTop:'3px'}, attribute :{align:'center', cellSpacing:2}});
		tmpButtonArea.addCell(
			new cafen.XButton({text: cafenMsg.get('com_done'), style :{width : '40px', marginLeft:'1px'},event:{'click' : this.send2Editor.bind(this)}})
		);
		tmpButtonArea.addCell(
			new cafen.XButton({text: cafenMsg.get('com_init'), style :{width : '40px', marginLeft:'1px'},event:{'click' : this.initOption.bind(this)}})
		);
		tmpButtonArea.addCell(
			new cafen.XButton({text: cafenMsg.get('com_close'), style :{width : '40px', marginLeft:'1px'},event:{'click' : this.close.bind(this)}})
		);
		this.buttonArea.addCell(tmpButtonArea);
		this.buttonArea.addAttribute({colspan : 2});
		cafen.smallSWFAjax.getFlashXml({mode:'SKIN'}, this.setSkinType.bind(this), this._uploadScript, false);
	},
	setImageUpload : function(obj) {
		var ufile = obj.getFile();
		if (ufile.server != '') 
			this.setFileObj(ufile, false);
	},
	initOption : function() {
		if (this._editorObj != null) {
			for(var i = 0; i < this.menuInfo.length; i++) {
				if (this.menuInfo[i].obj.setValue)
					this.menuInfo[i].obj.setValue(this.menuInfo[i].def);
				else
					this.setRotateValue(this.menuInfo[i].def +'');
			}
			this._skinOptions = {};
			this.setSkin(null);
		}
	},
	getImagePath : function(src) {
		if (this._uploadedUrl != null && 	this._uploadedUrl != this._uploadUrl ) {
			if (src.indexOf("junk/") == 0)
				return this._uploadUrl + src;
			else
				return this._uploadedUrl + src;
		} else
			return this._uploadUrl + src;
	},
	preViewImage : function(bl) {
		var imgurl = this.getImageUrl();
		if (imgurl != '') {
			if (bl)
				this._send2Editor = true;
			else
				this._send2Editor = false;
			if (!this._underProcess) {
				this.showProcess(true);
				this._nextProcess = false;
				cafen.smallSWFAjax.getFlashXml({mode:'THUMB', base_dir : 'thumb_junk/', makenew : (bl) ? 'Y' : 'N', name : imgurl}, this.setImageUrl.bind(this), this._uploadScript, false);
			} else {
				this._nextProcess = true;
			}
		} else {
			if (this._isEditorImage) {
				if (this.baseFileObj != null && this.baseFileObj != '') {
					if (bl) {
						var html_tag = '<div align=center width=100%><img class="cafenimg_resize" src='+this.getImagePath(this.baseFileObj)+' border=0></div>';
						if (this._editorObj.insertHTML)
							this._editorObj.insertHTML(html_tag);
						this.close();
					} else
						this.setImage(this.getImagePath(this.baseFileObj));
				} else {
					this.setImage(null, cafenMsg.get('util_0021'));
				}
			} else {
				if (this.baseFileObj != null && this.baseFileObj != '') {
					if (bl) {
						this.baseFileOrg.html_tag = '<div align=center width=100%><img class="cafenimg_resize" src='+this.getImagePath(this.baseFileOrg.server)+'></div>';
						if (this._editorObj.execCommand('attach',true,this.baseFileOrg)) {
							this._send2Editor = false;
							this.close();
						} else {
							this.showMsg(cafenMsg.get('ed_0019', cafen.getSize2Short(this._editorObj.editorAttachView.attachSize,2), cafen.getSize2Short(this._editorObj.editorAttachView.maxUpload,2), cafen.getSize2Short(this.baseFileOrg.size,2)), true);
						}
						this.baseFileOrg = {};
					} else
						this.setImage(this.getImagePath(this.baseFileObj));
				} else {
					this.setImage(null, cafenMsg.get('util_0021'));
				}
			}
		}
	},
	send2Editor : function() {
		this.preViewImage(true);
	},
	setFileObj : function(obj, bl) {
		if (bl == null)
			bl = true;
		this._send2Editor = false;
		if (obj != null && obj.server != null) {
			this.baseFileObj = obj.server;
			this.baseFileOrg = obj;
			this.tmpImage = new Image();
			this.tmpImage.src = this._uploadUrl+this.baseFileObj;
			this._imageMax = null;
			this._isEditorImage = bl;
		} else {
			this.baseFileObj = null;
			this.baseFileOrg = null;
			this.tmpImage = null;
			this._isEditorImage = false;
		}
		this.initOption();
	},
	setSkinType : function(xml) {
		var rssObj = new cafen.xmlParser(xml);
		var contentsObj = null;
		var datas = [];
		var skinurl = null;
		if (contentsObj = rssObj.getNext()) {
			var item = null;
			skinurl = contentsObj.getNode('skinurl');
			if (skinurl == null || skinurl == '') 
				skinurl = cafenGlobalConf.uploadURL +'skin/' || '';
			while(item = contentsObj.getNext()) {
				var name = item.getNode('name');
				var seqn = item.getNode('seqn');
				var icon = 'icon/' +item.getNode('icon');
				var description = item.getNode('description');
				datas.push({name : name, seqn : seqn, icon : icon, text : description});
			}			
		}
		this.skinObject = datas;
		this.skin_obj.addRow();
		this.skin_obj.setStyle({width : (this.skinObject.length*70) +'px'});
		for(var i = 0; i < this.skinObject.length; i++) {
			var currObj = this.skinObject[i];
			var tmpCell = this.skin_obj.addCell('&nbsp;');
			this.skin_obj.addStyle({border : '2px solid transparent',width : '70px', height: '45px', backgroundImage: 'url('+skinurl + currObj.icon+')', backgroundRepeat : 'no-repeat', backgroundPosition : '4px 4px'});
			tmpCell.attachEvent("click", this.setSkin.bind(this, i));
			currObj.obj = tmpCell;
		}
		if (this.skinObject.length > 0)
			this.skinArea.show();
	},
	setSkin : function(no) {
		if (this._lastSkinNo != null) 
			this.skinObject[this._lastSkinNo].obj.setStyle({border : '2px solid transparent', backgroundColor:''}); 
		if (no != null && this._lastSkinNo != no) {
			this.skinObject[no].obj.setStyle({border : '2px solid #89c771', backgroundColor:'#89c771'}); 
			this._lastSkinNo = no;
		} else 
			this._lastSkinNo = null;
		this.setInfoDisable();
		this.preViewImage(false);
	},
	setValue : function(obj) {
		var cmd = obj.options.cmd;
		this._skinOptions[cmd] = obj.getValue();
		this.preViewImage(false);
		return true;
	},
	setRotate : function(obj) {
		this.setRotateValue(obj.options.value);
		this.preViewImage(false);
		return true;
	},
	setInfo : function(obj) {
		var val = obj.options.value;
		this._infoData[val] = ! this._infoData[val];
		obj.setSelected(this._infoData[val]);	
		this.preViewImage(false);
	},
	setInfoValue : function(txt) {
		for(var i = 0; i < this.infoObj.length; i++) {
			var currObj = this.infoObj[i];
			var val = currObj.value;
			this._infoData[val] = (txt.indexOf(val) > -1)  ?  true : false;
			currObj.obj.setSelected(this._infoData[val]);	
		}
	},
	setInfoDisable : function() {
		var infoTxt = [];
		var bl = false;
		var sign = false;
		if (this._lastSkinNo == null || this.baseFileOrg == null || this.baseFileOrg.server == '') {
			bl = false;
			sign = false;	
		} else {
			if (this.options.signTxt != null && this.options.signTxt != '') 
				sign = true;
			if (this.baseFileOrg.server.match(/(jpg|jpeg)$/i)) 
				bl = true;
		}
		for(var i = 0; i < this.infoObj.length; i++) {
			var currObj = this.infoObj[i];
			var val = currObj.value;
			if (val == 'S') {
				if (sign) 
					currObj.obj.setDisable(false);
				else 
					currObj.obj.setDisable(true);
			} else 
				currObj.obj.setDisable(!bl);
			if (this._infoData[val])
				infoTxt.push(val);
		}
		this.setInfoValue(infoTxt.join(''));
	},
	setRotateValue : function(val) {
		this._skinOptions['R'] = parseInt(val);
		for(var i = 0; i < this.rotateObj.length; i++) {
			var currObj = this.rotateObj[i];
			if (currObj.value == val) 
				currObj.obj.setSelected(true);	
			else
				currObj.obj.setSelected(false);	
		}
	},
	getImageUrl : function() {
		var theUrl = [];
		if (this._imageMax == null && this.tmpImage != null) 
			this._imageMax = Math.max(this.tmpImage.width, this.tmpImage.height);
		if (this._imageMax != null && this._skinOptions['M'] != null && this._skinOptions['M'] != 100) {
			var tmpWidth = Math.round(this._imageMax * this._skinOptions['M']/100);
			theUrl.push('M'+Math.max(100,Math.min(tmpWidth,900)));
		}
		if (this._skinOptions['W'] != null && this._skinOptions['W'] != 100)
			theUrl.push('W'+this._skinOptions['W']);
		if (this._skinOptions['A'] != null && this._skinOptions['A'] != 100)
			theUrl.push('A'+this._skinOptions['A']);
		if (this._skinOptions['H'] != null && this._skinOptions['H'] != 0)
			theUrl.push('H'+this._skinOptions['H']);
		if (this._skinOptions['G'] != null && this._skinOptions['G'] != 0) 
			theUrl.push('G');
		if (this._skinOptions['N'] != null && this._skinOptions['N'] != 0)
			theUrl.push('N');
		if (this._skinOptions['C'] != null && this._skinOptions['C'] != 100)
			theUrl.push('C'+this._skinOptions['C']);
		if (this._skinOptions['B'] != null && this._skinOptions['B'] != 10)
			theUrl.push('B'+this._skinOptions['B']);
		if (this._skinOptions['R'] != null && this._skinOptions['R'] != 4)
			theUrl.push('R'+this._skinOptions['R']);
		if (this._lastSkinNo != null) {
			theUrl.push('K'+this._lastSkinNo+'');
			if (this.baseFileObj !=null && this.baseFileOrg.server.match(/(jpg|jpeg)$/i))  {
				if (this._infoData.M)
					theUrl.push('M');
				if (this._infoData.D)
					theUrl.push('D');
				if (this._infoData.T)
					theUrl.push('T');
			}
			if (this._infoData.S && this.options.signTxt != null && this.options.signTxt != '') 
				theUrl.push('B=' + cafen.base64_encode(encodeURIComponent(this.options.signTxt)) + '=');
		}
		if (theUrl.length > 0 && this.baseFileObj != null && this.baseFileObj != '') 
			return this.baseFileObj +'_'+theUrl.join('')+'.' + this._saveasExt;
		else
			return '';
	},
	setImageUrl : function(xml) {
		var rssObj = new cafen.xmlParser(xml);
		var contentsObj = null;
		var fileObj = {};
		var servermsg = null;
		if (contentsObj = rssObj.getNext()) {
			var item = null;
			servermsg = contentsObj.getNode('servermsg');
			if (servermsg == null || servermsg == '') {
				while(item = contentsObj.getNext()) {
					fileObj = {
						fileName : item.getNode('filename'),
						extension : item.getNode('fileext'),
						server : item.getNode('fileserver'),
						size : parseInt(item.getNode('filesize')),
						extra : item.getNode('extra'),
						html_tag : ''
					}
				}
			}
		}
		this.showProcess(false);
		if (fileObj.server != null) {
			this.setImage(this._uploadUrl+fileObj.server);
			if (this._nextProcess) {
				this.preViewImage(this._send2Editor);
			} else {
				if (this._send2Editor) {
					fileObj.html_tag = '<div align=center width=100%><img  class="cafenimg_resize" src="'+this._uploadUrl+fileObj.server+'" border=0></div>';
					if (this.baseFileOrg.fileName.indexOf(cafenMsg.get('ed_0074')) > -1)
						fileObj.fileName = this.baseFileOrg.fileName; 
					else
						fileObj.fileName = cafenMsg.get('ed_0074') +this.baseFileOrg.fileName; 
					if (this._isEditorImage && this.baseFileOrg != null && this.baseFileOrg.server != null)
						fileObj.orgName = this.baseFileOrg.server;
					if (this._editorObj.execCommand('attach',true,fileObj)) {
						this._send2Editor = false;
						this.close();
					} else {
						this.showMsg(cafenMsg.get('ed_0019', cafen.getSize2Short(this._editorObj.editorAttachView.attachSize,2), cafen.getSize2Short(this._editorObj.editorAttachView.maxUpload,2), cafen.getSize2Short(fileObj.size,2)), true);
					}
				}
			}
		} else {
			var msg = null;
			if (servermsg != null && servermsg != '') {
				var msgInfo = servermsg.split('|');	
				msg = msgInfo[2];
			}
			this.setImage(null, msg);
		}
	},
	showProcess : function(bl) {
		this._underProcess = bl;
		if (bl) {
			if (this.processViewer == null) {
				this.processViewer = new cafen.TableAuto({style : {width : '100% !important', height: '100% !important'}, attribute :{align:'center', cellSpacing:2, width : '100%', height: '100%'}});
				this.processViewer.addRow();
				this.processViewer.addCell('<img src="'+_cafen_service_url+'images/blank.gif" class="r_process">' +cafenMsg.get('com_process'));
				this.processViewer.addStyle({textAlign:'center', width : '100% !important', height: '100% !important'});
				this.processViewer.addAttribute({className:'r_gride'});
				this.viewerObj.appendChild(this.processViewer);
			}
			if (this.processViewer != null)
				this.processViewer.show();
			if (this.imgViewer != null)
				this.imgViewer.hide();
		} else {
			if (this.processViewer != null)
				this.processViewer.hide();
			if (this.imgViewer != null)
				this.imgViewer.show();
		}
	},
	setImage : function(src, msg) {
		if (msg != null) 
			msg = '<div style="padding:30px;font-size:13px">' +msg+ '</div>';
		if (this.imgViewer == null) {
			if (this._editorObj) {
				this.imgViewer = new cafen.Div(
					{style : 
						cafen.extend(
							this.options.style,
							{position :'relative', width : (this._previewWidth -10) +'px', height : (this._previewHeight -10) +'px', textAlign:'center'}
						),
						attribute : {className:'r_gride'}	
					});
				if (src != null) {
					this.imgViewer.getElement().innerHTML = '<img src="'+src+'" border=0>';
					this.checkImageSize(src);
				} else {
					this.imgViewer.getElement().innerHTML = msg;
				}
			} else {
				this.imgViewer = new cafen.Image(src, 
					{	style : cafen.extend(this.options.style,{position :'relative', width : (this._previewWidth) +'px', height : (this._previewHeight)+'px'}), 
						scale : 'max',
						useanimate : true,
						event : {click : this.close.bind(this)}
					}
				);
			}
			this.viewerObj.appendChild(this.imgViewer);
		} else {
			if (this._editorObj) {
				if (src != null) {
					this.imgViewer.getElement().innerHTML = '<img src="'+src+'" border=0>';
					this.checkImageSize(src);
				} else {
					this.imgViewer.getElement().innerHTML = msg;
				}
			}else
				this.imgViewer.setImage(src);
		}
	},
	checkImageSize : function(src) {
		if (src != null) {
			this.tmpImageload = new Image();
			this.tmpImageload.src = src;
			if (this.tmpImageload.width != null && this.tmpImageload.width != 0)
				this.resizePreview();
			else {
				this.tmpImageload.onload = this.resizePreview.bind(this);
			}
		}
	},
	toggleImageSize : function() {
		this._issmallSize = ! this._issmallSize;
		if (this.imgViewer.getElement().childNodes[0] != null && this.imgViewer.getElement().childNodes[0].tagName == 'IMG') {
			if (this._issmallSize) {
				this.imgViewer.getElement().childNodes[0].style.width = this._previewSizeInfo[0] + 'px';
				this.imgViewer.getElement().childNodes[0].style.height = this._previewSizeInfo[1] + 'px';
			} else {
				this.imgViewer.getElement().childNodes[0].style.width = this._previewSizeInfo[2] + 'px';
				this.imgViewer.getElement().childNodes[0].style.height = this._previewSizeInfo[3] + 'px';
			}
		}
	},
	errorPreview : function() {
		this.imgViewer.getElement().innerHTML = '<div style="background-color:#ffffff;padding:10px;margin:30px 10px 10px 10px;font-size:13px">'+cafenMsg.get('util_0052') +'</div>';
	},
	resizePreview : function() {
		var imgWidth = parseInt(this.tmpImageload.width) || 10;
		var imgHeight = parseInt(this.tmpImageload.height) || 10;
		var imgRate = imgWidth / imgHeight;
		var resizeWidth = this._previewWidth - 10;
		var resizeHeight = this._previewHeight - 10;
		var previewRate = this._previewWidth / this._previewHeight;
		if (imgWidth > resizeWidth|| imgHeight > resizeHeight) {
			var resizeW = imgWidth;
			var resizeH = imgHeight;
			if (imgRate > previewRate) {
				resizeW = resizeWidth;
				resizeH = resizeW / imgRate;
			} else {
				resizeH = resizeHeight;
				resizeW = resizeH * imgRate;
			}
			if (this.imgViewer.getElement().childNodes[0] != null && this.imgViewer.getElement().childNodes[0].tagName == 'IMG') {
				this.imgViewer.getElement().childNodes[0].style.width = Math.round(resizeW) + 'px';
				this.imgViewer.getElement().childNodes[0].style.height = Math.round(resizeH) + 'px';
				this.imgViewer.getElement().childNodes[0].style.cursor = cafen.getCursor();
				this._issmallSize = true;
				this._previewSizeInfo = [Math.round(resizeW), Math.round(resizeH), imgWidth, imgHeight];
				this.imgViewer.getElement().childNodes[0].onclick = this.toggleImageSize.bind(this);
			}
		}
	},
	showMsg : function(msg) {
		if (this.msgObj == null) {
			this.msgObj = new cafen.XAlert({title :cafenMsg.get('com_alert'), contents :'', sticker : {obj : this, x : 'center', y : 'middle'}, style : {width: '300px'}});
			this.addChild(this.msgObj);
		}
		this.msgObj.setContents(msg, {x : 'center', y : 'middle', plus : [0, 5]});
		this.msgObj.onLoad();
	},
	onPopup : function() {
		if (this._editorObj != null && this._editorObj.saveFocus) 
			this._editorObj.saveFocus();
		if (	this._editorObj != null && this.uploadImg != null) 
			this.uploadImg.onLoad();
	}
},cafen.XWindow.prototype);


cafen.selectDraw = function(obj) {
	var item_width = obj.offsetWidth;
	var item_height =obj.offsetHeight;
	var className = (obj.className || null);
	if (className != null && className != 'rainselect')
		className = className+' rainselect';
	else if (className == null)
		className = 'rainselect';
	this.skinObj = document.createElement('span');
	if (item_height > 20)
		item_height = 20; // todo ie6.0 fix
	cafen.setStyle(this.skinObj, {position : 'relative', height: item_height+'px',display :'inline-block' ,  fontSize: item_height+'px', verticalAlign: 'top',width: item_width+'px', padding : '0', margin:'0'});
	obj.parentNode.insertBefore(this.skinObj, obj);
	cafen.setAttribute(this.skinObj, {className : className});
	this.outButton = document.createElement('button');
	this.outButton.setAttribute("type", "button");
	this.outButton.onfocus = function() {this.blur()}
	var objTitle = obj.getAttribute('title');
	if (objTitle != null)
		this.outButton.setAttribute("title", objTitle);
	
	this.skinObj.appendChild(this.outButton);
	cafen.setStyle(this.outButton, {width: item_width +'px', height: item_height +'px',overflow : 'hidden', textAlign:'left', cursor : cafen.getCursor(), display:'inline-block', padding:'0', margin: '0', fontSize:'12px', zIndex: '0'});
	this.textObj = this.outButton.appendChild(document.createElement('div'));
	cafen.setStyle(this.textObj, {display:'inline',position:'relative',padding:0,margin:0, marginTop:'-1px'});
	cafen.setAttribute(this.outButton, {type : 'button'});
	this.outButton.onclick = this.showSelectOptions.bind(this);
	this.linkObj = obj;
	for(var i = 0; i < this.linkObj.childNodes.length ;  i++) {
		if (this.linkObj.childNodes[i].tagName != 'OPTION') 
			this.linkObj.removeChild(this.linkObj.childNodes[i]);
	}
	cafen.hide(obj);
	obj.show = this.show.bind(this);
	obj.hide = this.hide.bind(this);
	obj.reloadData = this.reloadData.bind(this);
	obj.linkObj = this.skinObj;
	obj.setValue = this.setValue.bind(this);
	this.isParsed = false;
	this.selectItems = null;
	this.setValue(this.linkObj.selectedIndex);
}

cafen.selectDraw.prototype = {
	drawSeqn : 40, 
	skinObj : null,
	outButton : null,
	textObj : null,
	linkObj : null,
	isParsed : false,
	selectItems : null,
	lastSelectedOption : null,
	show : function() {
		cafen.show(this.skinObj,'inline-block');
	},
	hide : function() {
		this.onUnselect();
		cafen.hide(this.skinObj);
	},
	reloadData : function(options) {
		this.linkObj.options.length = 0;
		this.linkObj.innerHTML = '';
		var selectedValue = -1;
		for(var i = 0 ; i < options.length; i++) {
			var currOption = options[i];
			var optionObj = document.createElement('option');
			optionObj.setAttribute("value", currOption.value || '');
			optionObj.innerText = currOption.text || '';
			this.linkObj.appendChild(optionObj);	
			if (currOption.selected)
				selectedValue = i;
		}
		this.isParsed = false;
		this.setValue(selectedValue);
	},
	showSelectOptions : function() {
		if (!this.isParsed) {
			var outUL = document.createElement('ul');
			var baseObj = this.outButton;
			var checkOld = this.selectItems;
			if (checkOld != null) 
				checkOld.parentNode.removeChild(checkOld);
			this.skinObj.insertBefore(outUL,this.outButton);
			cafen.setStyle(outUL, {position:'absolute', width: (this.outButton.offsetWidth-2)+'px', display:'block', zIndex:'3'});
			switch(this.linkObj.getAttribute('behavior')) {
				case 'top' :
					cafen.setStyle(outUL, {bottom: (this.outButton.offsetHeight +3)+'px', left: 0});
					break;
				case 'right' :
					cafen.setStyle(outUL, {top: '0', left: (this.outButton.offsetWidth+4) +'px'});
					break;
				case 'left' :
					cafen.setStyle(outUL, {top: '0', left: '-'+(this.outButton.offsetWidth+4) +'px'});
					break;
				default :
					cafen.setStyle(outUL, {top: (this.outButton.offsetHeight +3)+'px', left: 0});
					break;
			}
			var maxheight = parseInt(this.linkObj.getAttribute('maxheight'));
			if (isNaN(maxheight))
				maxheight = 100;
			cafen.setStyle(outUL, {maxHeight : maxheight+'px'});
			var minheight = parseInt(this.linkObj.getAttribute('minheight'));
			var options = this.linkObj.options;
			if (!isNaN(minheight))
				cafen.setStyle(outUL, {minHeight : minheight+'px'});
			else
				cafen.setStyle(outUL, {minHeight : ((options.length > 6) ? 120 : options.length *20)+'px'});
			for(var i = 0 ; i < options.length ; i++) {
				var currOption = options[i];
				var optionsLI = document.createElement('li');
				outUL.appendChild(optionsLI);
				optionsLI.appendChild(document.createTextNode(currOption.innerText || currOption.innerHTML));
				cafen.setAttribute(optionsLI, {value :currOption.value, selectedIndex : i});
				cafen.setStyle(optionsLI, {padding:'1px', margin:'0'});
				optionsLI.onclick = this.setSelectOptions.bind(this,optionsLI);
			}
			if (maxheight < options.length * 21) {
				cafen.setStyle(outUL, {height : maxheight+'px', minHeight: maxheight+'px', overflowY:'auto', overflowX:'hidden'});
			}
			this.isParsed = true;
			this.selectItems = outUL;
			this.setValue(this.linkObj.selectedIndex);
		}
		this.isOpen = ! this.isOpen;
		if (this.isOpen) {
			try {
				if (this.linkObj.onclick != null && typeof this.linkObj.onclick == 'function') 
					this.linkObj.onclick();
			} catch(ex) {}
			cafen.setSelected(this);
			cafen.show(this.selectItems);
			cafen.setStyle(this.skinObj, {zIndex:'2'});
			if (this.skinObj.parentNode.tagName == 'LABEL')
				cafen.setStyle(this.skinObj.parentNode, {zIndex:'1'});
			this.outButton.setAttribute("isopen", "true");
		} else {
 			cafen.hide(this.selectItems);
			cafen.setStyle(this.skinObj, {zIndex:'1'});
			if (this.skinObj.parentNode.tagName == 'LABEL')
				cafen.setStyle(this.skinObj.parentNode, {zIndex:'0'});
			this.outButton.removeAttribute("isopen");
 		}
 		return false;
	},
	onUnselect : function() {
		if (this.isOpen) {
			this.showSelectOptions();
		}
	},
	setSelectOptions : function(obj) {
		window.setTimeout(this.onUnselect.bind(this), 1);
		this.setValue(parseInt(obj.getAttribute("selectedIndex")));
	},
	setValue : function(idx) {
		if (typeof idx == 'string') {
			var options = this.linkObj.options;
			var selectedIndex = -1;
			for(var i = 0 ; i < options.length ; i++) {
				if (options[i].getAttribute('value') == idx) {
					selectedIndex = i;
					break;	
				}
			}
			idx = 	selectedIndex;	
		}	
		if (this.linkObj != null && this.linkObj.selectedIndex != idx) {
			this.linkObj.selectedIndex = idx;
			try {
				if (this.linkObj.onchange != null && typeof this.linkObj.onchange == 'function') 
					this.linkObj.onchange();
			} catch(ex) {}
		}
		if (this.lastSelectedOption != null) {
			this.lastSelectedOption.removeAttribute("selected");
			this.lastSelectedOption = null;
		}
		this.textObj.innerHTML = '';
		if (this.linkObj.selectedIndex != -1) {
			this.textObj.appendChild(document.createTextNode(this.linkObj[this.linkObj.selectedIndex].text));
			if (this.selectItems != null) {
				this.lastSelectedOption = this.selectItems.childNodes[this.linkObj.selectedIndex];
				if (this.lastSelectedOption != null)
					this.lastSelectedOption.setAttribute("selected", "true");
			}
		}
	}
}

cafen.XMovieViewer = function(options, editorObj) {
	this._popupOptions = options;
	this.setOptions(cafen.extend({className :'r_popskin', tag : 'div', tplName : 'top', donotresize : true, maxSize : 1024*1024*10, style : {width:'200px',textAlign:'center', position :'absolute'}, shadow : true}, options));
	if (editorObj) {
		this.setTitle(cafenMsg.get('com_movieview') + '(Editor)');
		this.setToolBar(false);
		this._editorObj = editorObj;
		this._uploadScript = this._editorObj.getUploadScript();
		this._uploadUrl = this._editorObj.getUploadUrl();
		this._mediaparam = (this._editorObj.getMediaPlayerParam) ? this._editorObj.getMediaPlayerParam(true) : '';
		this._previewWidth = parseInt(this.options.style.width) - 170;
		this._previewHeight = parseInt(this.options.style.height) - 10;
		var tmpTable = new cafen.TableAuto({style : {}});
		var tmpTable2 = new cafen.TableAuto({className : 'r_boxblue', style : {width : '150px', margin :'2px'}});
		tmpTable.addCell(tmpTable2);
		tmpTable.addStyle({verticalAlign: 'top'});
		tmpTable2.addRow();
		this.buttonArea = new cafen.TableAuto({style : {}});
		tmpTable2.addCell(this.buttonArea);
		tmpTable2.addStyle({verticalAlign: 'top'});
		this.contentsObj = new cafen.Div(cafen.extend({className : 'r_boxwhite', style : this.options.style},{style:{width : this._previewWidth+'px', height : this._previewHeight+'px', overflow:'hidden', overflowY:'auto', overflowX:'auto', position :'relative', textAlign:'left', margin :'2px'}}));
		tmpTable.addCell(this.contentsObj);
		tmpTable.addStyle({verticalAlign: 'top'});
		this.setObject(tmpTable);
		this.drawMenu();	
	} else {
		this.setTitle(cafenMsg.get('com_movieview'));
		this.setToolBar(true);
		this._previewWidth = parseInt(this.options.style.width) - 6;
		this._previewHeight = parseInt(this.options.style.height) - 6;
		this.contentsObj = new cafen.Div(cafen.extend({style : this.options.style},{style:{width : this._previewWidth + 'px',height : this._previewHeight + 'px', overflow:'hidden', overflowY:'hidden', overflowX:'hidden', position :'relative', textAlign:'center', margin:'3px'}, attribute :{className : 'r_gride'}}));
		this.setObject(this.contentsObj);
	}
}

cafen.XMovieViewer.prototype = cafen.extendClass({
	drawMenu : function() {
		this._lastSkinNo = null;
		this._skinOptions = {};
		this.menuInfo = [
			{cmd : 'S', name :cafenMsg.get('ed_0080'), min : 0, max : 100, step : 5, def : 0},
			{cmd : 'T', name :cafenMsg.get('ed_0081'), min : 0, max : 100, step : 5, def : 100},
			{cmd : 'Q', name :cafenMsg.get('ed_0079'), min : 0, max : 1, step : 1, def : 0 },
			{cmd : 'P', name :cafenMsg.get('ed_0082'), min : 0, max : 100, step : 5, def : 0 }
		];
		var setValueBind = this.setValue.bind(this);
		var maxSize = this.options.maxSize;
		this.uploadMovie = new cafen.XUpload(140,'video', '', {maxSize : maxSize ,event : {end : this.setMovieUpload.bind(this)}});
		this.buttonArea.addCell(this.uploadMovie);
		this.buttonArea.addAttribute({colSpan :2});
		this.buttonArea.addStyle({padding:'1px', textAlign:'right'});
		for(var i = 0 ;  i < this.menuInfo.length; i++) {
			var currObj = this.menuInfo[i];
			this.buttonArea.addRow();
			this.buttonArea.addCell('<font size=2>' + currObj.name+'</font>');
			this.buttonArea.addStyle({textAlign:'right', width: '60px'});
			currObj.obj = new cafen.Slider({cmd : currObj.cmd , className : 'r_boxwhite',def : currObj.def, min : currObj.min, max : currObj.max , step : currObj.step , size : 80, event : {end : setValueBind}});
			this.buttonArea.addCell(currObj.obj);
			this.buttonArea.addStyle({padding:'1px'});
		}
		this.buttonArea.addRow();
		var tmpButtonArea = new cafen.TableAuto({style : {}, attribute :{align:'center', cellSpacing:2}});
		tmpButtonArea.addCell(
			new cafen.XButton({text: cafenMsg.get('com_done'), style :{width : '40px', marginLeft:'1px'},event:{'click' : this.send2Editor.bind(this)}})
		);
		tmpButtonArea.addCell(
			new cafen.XButton({text: cafenMsg.get('com_init'), style :{width : '40px', marginLeft:'1px'},event:{'click' : this.initOption.bind(this)}})
		);
		tmpButtonArea.addCell(
			new cafen.XButton({text: cafenMsg.get('com_close'), style :{width : '40px', marginLeft:'1px'},event:{'click' : this.close.bind(this)}})
		);
		this.buttonArea.addCell(tmpButtonArea);
		this.buttonArea.addAttribute({colspan : 2});
	},
	initOption : function() {
		for(var i = 0; i < this.menuInfo.length; i++) 
			this.menuInfo[i].obj.setValue(this.menuInfo[i].def);
		this._skinOptions = {};
		this.preViewMovie(false);
	},
	setMovieUpload : function(obj) {
		var ufile = obj.getFile();
		if (ufile.server != '') 
			this.setFileObj(ufile, false);
	},
	setValue : function(obj) {
		var cmd = obj.options.cmd;
		this._skinOptions[cmd] = obj.getValue();
		switch (cmd) {
			case 'S' :
				var startValue = this._skinOptions[cmd];
				if (this._skinOptions['T'] != null && startValue >= this._skinOptions['T']) {
					this._skinOptions['T'] = Math.min(startValue + 5, 100);
					this.menuInfo[1].obj.setValue(this._skinOptions['T']);
				}
				break;
			case 'T' :
				var endValue = this._skinOptions[cmd];
				if (this._skinOptions['S'] != null && endValue <= this._skinOptions['S']) {
					this._skinOptions['S'] = Math.max(endValue - 5, 0);
					this.menuInfo[0].obj.setValue(this._skinOptions['S']);
				}
				break;
		}
		this.preViewMovie(false);
		return true;
	},
	preViewMovie : function(bl) {
		var movie_url = this.getMovieUrl();
		if (movie_url != '') {
			var img_url = this.getThumbUrl();
			if (bl)
				this._send2Editor = true;
			else
				this._send2Editor = false;
			if (!this._underProcess) {
				this.showProcess(true);
				this._nextProcess = false;
				cafen.smallSWFAjax.getFlashXml({mode:'MOVIE', base_dir : 'thumb_junk/', makenew : (bl) ? 'Y' : 'N', name : movie_url, img : img_url}, this.setMovieUrl.bind(this), this._uploadScript, false);
			} else {
				this._nextProcess = true;
			}
		} else {
			if (this.baseFileOrg != null && this.baseFileOrg != '') {
				if (bl) {
					var str = _cafen_service_url+'images/mediaplayer.swf?file='
							+ this._uploadUrl + baseFileOrg.server +'&amp;image='
							+ this._uploadUrl + baseFileOrg.extra + this._mediaparam;
					var objs = [];
					objs.push('<embed type="application/x-shockwave-flash" wmode="transparent" align=center ');
					objs.push('src="'+str+'" ');
					objs.push('allowFullScreen="true" width="440px" height="320px" quality="high"  ');
					objs.push(' ></embed>');
					var html_tag = '<div align=center width=100%><img src='+objs.join('')+'></div>';
					if (this._editorObj.insertHTML)
						this._editorObj.insertHTML(html_tag);
					this.close();
				} else
					this.setMovie(this._uploadUrl+this.baseFileObj);
			} else {
				this.setMovie(null, cafenMsg.get('util_0021'));
			}
		}
	},
	getMovieUrl : function() {
		var theUrl = [];
		if (this._skinOptions['S'] != null && this._skinOptions['S'] != 0)
			theUrl.push('S'+this._skinOptions['S']);
		else
			theUrl.push('S0');
		if (this._skinOptions['T'] != null && this._skinOptions['T'] != 100)
			theUrl.push('T'+this._skinOptions['T']);
		else
			theUrl.push('T100');
		if (this._skinOptions['Q'] != null && this._skinOptions['Q'] != 0)
			theUrl.push('Q1');
		else
			theUrl.push('Q0');
		if (theUrl.length > 0 && this.baseFileObj != null && this.baseFileObj != '') 
			return this.baseFileObj +'_'+theUrl.join('')+'.flv';
		else
			return '';
	},
	setMovieUrl : function(xml) {
		var rssObj = new cafen.xmlParser(xml);
		var contentsObj = null;
		var fileObj = {};
		var servermsg = null;
		if (contentsObj = rssObj.getNext()) {
			var item = null;
			servermsg = contentsObj.getNode('servermsg');
			if (servermsg == null || servermsg == '') {
				while(item = contentsObj.getNext()) {
					fileObj = {
						fileName : item.getNode('filename'),
						extension : item.getNode('fileext'),
						server : item.getNode('fileserver'),
						size : parseInt(item.getNode('filesize')),
						extra : item.getNode('extra'),
						html_tag : ''
					}
				}
			}
		}
		this.showProcess(false);
		if (fileObj.server != null) {
			var str = _cafen_service_url+'images/mediaplayer.swf?file='
					+ this._uploadUrl + fileObj.server +'&amp;image='
					+ this._uploadUrl + fileObj.extra + this._mediaparam;
			this.setMovie(str);
			if (this._nextProcess) {
				this.preViewMovie(this._send2Editor);
			} else {
				if (this._send2Editor) {
					var objs = [];
					objs.push('<embed type="application/x-shockwave-flash" wmode="transparent" align=center ');
					objs.push('src="'+str+'" ');
					objs.push('allowFullScreen="true" width="440px" height="320px" quality="high"  ');
					objs.push(' ></embed>');
					fileObj.html_tag = '<div align=center width=100%>' +objs.join('')+'</div>';
					fileObj.fileName = cafenMsg.get('ed_0074') +this.baseFileOrg.fileName; 
					if (this._editorObj.execCommand('attach',true,fileObj)) {
						this._send2Editor = false;
						this.close();
					} else {
						this.showMsg(cafenMsg.get('ed_0019', cafen.getSize2Short(this._editorObj.editorAttachView.attachSize,2), cafen.getSize2Short(this._editorObj.editorAttachView.maxUpload,2), cafen.getSize2Short(fileObj.size,2)), true);
					}
				}
			}
		} else {
			var msg = null;
			if (servermsg != null && servermsg != '') {
				var msgInfo = servermsg.split('|');	
				msg = msgInfo[2];
			}
			this.setMovie(null, msg);
		}
	},
	getThumbUrl : function() {
		var theUrl = [];
		if (this._skinOptions['P'] != null && this._skinOptions['P'] != 0)
			theUrl.push('S'+this._skinOptions['P']);
		else
			theUrl.push('S0');
		if (theUrl.length > 0) 
			return this.baseFileObj +'_'+theUrl.join('')+'.png';
		else
			return '';
	},
	showProcess : function(bl) {
		this._underProcess = bl;
		if (bl) {
			if (this.processViewer == null) {
				this.processViewer = new cafen.TableAuto({style : {width : '100% !important', height: '100% !important'}, attribute :{align:'center', cellSpacing:2, width : '100%', height: '100%'}});
				this.processViewer.addRow();
				this.processViewer.addCell('<img src="'+_cafen_service_url+'images/blank.gif" class="r_process">' + cafenMsg.get('com_process'));
				this.processViewer.addStyle({textAlign:'center', width : '100% !important', height: '100% !important'});
				this.processViewer.addAttribute({className:'r_gride'});
				this.contentsObj.appendChild(this.processViewer);
			}
			if (this.processViewer != null)
				this.processViewer.show();
			if (this.movieViewer != null)
				this.movieViewer.hide();
		} else {
			if (this.processViewer != null)
				this.processViewer.hide();
			if (this.movieViewer != null)
				this.movieViewer.show();
		}
	},
	send2Editor : function() {
		this.preViewMovie(true);
	},
	setFileObj : function(obj) {
		this._send2Editor = false;
		if (obj != null && obj.server != null) {
			this.baseFileObj = obj.server;
			this.baseFileOrg = obj;
		} else {
			this.baseFileObj = null;
			this.baseFileOrg = null;
		}
		this.initOption();
	},
	setMovie : function(src, msg) {
		if (msg != null) 
			msg = '<div style="padding:30px;font-size:13px">' +msg+ '</div>';
		if (this.movieViewer == null) {
			this.movieViewer = new cafen.Div({style :{width:this._previewWidth +'px', height : this._previewHeight +'px', textAlign:'center'},	attribute : {className:'r_gride'}});
			this.contentsObj.appendChild(this.movieViewer);
		}
		if (src != null && src != '') {
			var objs = [];
			objs.push('<embed type="application/x-shockwave-flash" wmode="transparent" align=center ');
			objs.push('src="'+src+'" ');
			objs.push('allowFullScreen="true" width="'+this._previewWidth+'px" height="'+this._previewHeight+'px" quality="high"  ');
			objs.push(' ></embed>');
			this.movieViewer.getElement().innerHTML = objs.join('');
		} else {
			this.movieViewer.getElement().innerHTML = (msg != null) ? msg : '';
		}
	},
	showMsg : function(msg) {
		if (this.msgObj == null) {
			this.msgObj = new cafen.XAlert({title :cafenMsg.get('com_alert'), contents :'', sticker : {obj : this, x : 'center', y : 'middle'}, style : {width: '300px'}});
			this.addChild(this.msgObj);
		}
		this.msgObj.setContents(msg, {x : 'center', y : 'middle', plus : [0, 5]});
		this.msgObj.onLoad();
	},
	onPopup : function() {
		if (	this._editorObj != null && this._editorObj.saveFocus) 
			this._editorObj.saveFocus();
		if (	this._editorObj != null && this.uploadMovie != null) 
			this.uploadMovie.onLoad();
	}
},cafen.XWindow.prototype);


cafen.XMapViewer = function(options) {
	if (options == null || options.style == null)
		options = cafen.extend({style :{width:'530px', height : '300px'}}, options);
	if (options.style.width != null) {
		var basewidth = parseInt(options.style.width);
		if (basewidth < 530) 
			options.style.width = '530px';
	}
	this._popupOptions = options;
	this.setOptions(cafen.extend({donotresize : true, className :'r_popskin', tag : 'div', tplName : 'both', style : {width:'200px',textAlign:'center', position :'absolute'}, shadow : true}, options));
	this.setTitle(cafenMsg.get('com_mapview'));
	this.setToolBar(!this.options.offclose);
	this.contentsObj = new cafen.Div(cafen.extend({style : this.options.style},{style:{overflow:'hidden', overflowY:'hidden', overflowX:'hidden', position :'relative', textAlign:'left'}}));
	this.setObject(this.contentsObj);
	this.initMapViewer();
}

cafen.XMapViewer.prototype = cafen.extendClass({
	keyMapShortCut : {
		'zoomin' : 'I',
		'zoomout' : 'O',
		'moveleft' : 'H',
		'moveup' : 'U',
		'movedown' : 'J',
		'moveright' : 'K'
	},
	initMapViewer : function() {
		this.buttonArea = new cafen.TableAuto({className : 'r_boxblue', style : {margin :'2px'}});
		this.contentsObj.appendChild(this.buttonArea);
		this.mapInfo = {apitype : 'google',lat:34.949738, lon : 127.7822176, zoom : 15, marker : [], poly : [], maptype : 'satellite', width : parseInt(this.options.style.width)-12, height : parseInt(this.options.style.height)-40};
		this.clickStatus = {};
		this.mapObj = new cafen.Div({className : 'r_boxwhite', style : {width : (this.mapInfo.width +10)+'px', height : this.mapInfo.height +'px', margin :'2px', textAlign:'left', overflowX:'hidden', overflowY:'hidden'}});
		this.contentsObj.appendChild(this.mapObj);
		this.drawToolbar();
		if (!cafen.checkAPI('DMap') && this.actionButton['apidaum'] != null) {
			this.setButtonSelect('apidaum', false);
			this.setButtonDisabled(['apidaum'], true);
		}
		this.getElement().style['position'] = 'relative';
	},
	_menusetData : null,
	getMenuSet : function() {
		if (this._menusetData == null) {
			var menuData = [];
			menuData.push('group');
			menuData.push('search');
			menuData.push('mtmap');
			menuData.push('mtsat');
			menuData.push('mthyb');
			if (cafen.checkAPI('DMap')) 
				menuData.push('apidaum');
			if (cafen.checkAPI('NMap')) 
				menuData.push('apinaver');
			if (cafen.checkAPI('GMap')) 
				menuData.push('apigoogle');
			menuData.push('save');
			menuData.push('break');
			menuData.push('group');
			menuData.push('moveleft');
			menuData.push('moveup');
			menuData.push('movedown');
			menuData.push('moveright');
			menuData.push('break');
			menuData.push('group');
			menuData.push('zoomin');
			menuData.push('zoomout');
			menuData.push('break');
			menuData.push('group');
			menuData.push('user');
			menuData.push('userdel');
			menuData.push('poly');
			menuData.push('polydel');
			menuData.push('break');
			cafenGlobalConf.mapToolbarSet = cafen.extendMax({staticmap : menuData}, cafenGlobalConf.mapToolbarSet)
			this._menusetData = cafen.extendMax(cafenMsg.getObject('map_menu'), cafenGlobalConf.mapToolbarSet);
		}
		return this._menusetData;
	},
	drawToolbar : function() {
		var buttonInfo = cafenMsg.getObject('map_buttonInfo');
		var groupstart = false;
		var groupmiddle = false;
		var groupend = false;
		var toolbarSet = this.getMenuSet().staticmap;
		var cnt = toolbarSet.length;
		var currRowObj = null;
		this.statusButton = [];
		this.actionButton = {};
		var iconMargin = null;
		if(cafen.browser.isIE) 
			iconMargin = '0 0 0 3px';
		else if(cafen.browser.isFF) 
			iconMargin = '-1 0 0 0px';
		else
			iconMargin = '3px 0px 3px 2px';
		for(var i = 0; i < cnt ; i++) {
			if (currRowObj == null) {
				currRowObj = new cafen.TableAuto({align:'left', attribute : {border:0},style : {}});
				this.buttonArea.addRow();
				this.buttonArea.addCell(currRowObj);
				currRowObj.addRow();
			}
			var idx = toolbarSet[i];
			switch(idx) {
				case 'separator':
					break;
				case 'group' :
				case '[' :
					groupstart = true;
					groupmiddle = false;
					groupend = false;
					break;
				case 'break' :
				case ']' :
					groupstart = false;
					groupmiddle = false;
					groupend = false;
					currRowObj.addCell();
					currRowObj.addStyle({width:'3px'});
					currRowObj.addText('<div style="width:3px;font-size:1px;line-height:1px;display:block;overflow:hidden;">&nbsp;</div>');
					break;
				case 'blank' :
					currRowObj.addCell();
					currRowObj.addStyle({width:'3px'});
					currRowObj.addText('<div style="width:3px;font-size:1px;line-height:1px;display:block;overflow:hidden;">&nbsp;</div>');
					break;
				case 'linebreakb' :
				case 'linebreak' :
					groupstart = false;
					groupmiddle = false;
					groupend = false;
					this.buttonArea.addRow();
					this.buttonArea.addCell();
					this.buttonArea.addStyle({height:'3px'});
					currRowObj = null;
					break;
				default :
					var currButton = buttonInfo[idx];
					var buttonNo = currButton[2];
					var x = (buttonNo % 10) * 16;
					var y = Math.floor(buttonNo /10) * 16;
					var icon = null;
					var bindCommand = null;
					switch(idx) {
						case 'polycolor':
							icon = new cafen.XImage({className :'r_mapset',x: x,y : y}, {style:{cssFloat : 'left',margin : iconMargin, width:'16px', height:'16px'},attribute :{unselectable : 'on'}, childNodes : [new cafen.RMap.ButtonColor()]});
							bindCommand = (currButton[0] != null) ? this.execCommand.bind(this,currButton[0],'','') : this.actionCommand.bind(this,idx,'','');
							break;
						case 'search' :
							icon = new cafen.TableAuto({style:{cssFloat : 'left',margin : '3px 5px 3px 3px', position :'relative'}});
							this.inputSearch = new cafen.Input({style:{width:'75px', height:'16px',fontSize:'11px',padding :'0px'},attribute :{}, event :{end : this.searchKeyword.bind(this)}});
							icon.addCell(this.inputSearch);
							icon.addCell(new cafen.Button({style:{width:'20px', height:'16px'},attribute :{unselectable : 'on'}, event : {click : this.showSearchResult.bind(this)}}));
							break;
						default :
							icon = new cafen.XImage({className :'r_mapset',x: x,y : y}, {style:{cssFloat : 'left',margin : iconMargin, width:'16px', height:'16px'},attribute :{unselectable : 'on'}});
							bindCommand = (currButton[0] != null) ? this.execCommand.bind(this,currButton[0],'','') : this.actionCommand.bind(this,idx,'','');
							break;
					}
					var tmpButton = null;
					var baseBgPos = 0,baseSize =0 , basePadding = 0; 
					if (currButton[5] != null ) {
						if (currButton[5] > 60) {
							baseBgPos = 792;
							baseSize  = 100;
						} else if (currButton[5] > 30) {
							baseBgPos = 528;
							baseSize  = 56;
						} else {
							baseBgPos = 0;
							baseSize  = 33;
						}
						basePadding = 0;
					} else {
						baseBgPos = 264;
						baseSize  = 24;
						basePadding = 0;
					}
					if (icon != null) {
						var nextidx = (cnt -1 >= i +1) ? toolbarSet[i+1] : '';
						var tagButton = (bindCommand != null ) ? 'button' : 'div';
						var eventBind = (bindCommand == null ) ? {} : {click:bindCommand};
						if (!groupstart) {
							tmpButton = new cafen.XIcon({tag : tagButton, icon : 'r_wordset', off : baseBgPos+132, on : 22 , over : 100, style :{width:baseSize +'px', paddingRight:  basePadding + 'px'}, attribute :{unselectable : 'on'}, event :eventBind, childNodes : [icon]}) ;
							currRowObj.addCell(tmpButton);
							currRowObj.addStyle({width:baseSize +'px'});
							currRowObj.addCell();
							currRowObj.addStyle({width:'3px'});
							currRowObj.addText('<div style="width:3px;font-size:1px;line-height:1px;display:block;overflow:hidden;">&nbsp;</div>');
						} else {
							if (nextidx == 'group' || nextidx == 'break' || nextidx == ']'  || nextidx == ']' || nextidx == 'linebreak' || nextidx == 'linebreakb')
								groupend = true;
							var title = currButton[1];
							var shortkey = null;
							if (this.keyMapShortCut[idx] != null) {
								shortkey = this.keyMapShortCut[idx];
								title += ' ('+this.keyMapShortCut[idx]+')'
							}
							if (!groupmiddle && groupend) {
								tmpButton = new cafen.XIcon({tag : tagButton, shortkey : shortkey, icon : 'r_wordset', off : baseBgPos+198, on : 22 , over : 100, style :{width:baseSize +'px', paddingRight:  basePadding + 'px'}, attribute :{unselectable : 'on', title : title}, event :eventBind, childNodes : [icon]}) ;
								currRowObj.addCell(tmpButton);
								currRowObj.addStyle({width:baseSize +'px'});
							} else if (!groupmiddle) {
								tmpButton = new cafen.XIcon({tag : tagButton, shortkey : shortkey, icon : 'r_wordset', off : baseBgPos, on : 22 , over : 100, style :{width:baseSize +'px', paddingRight:  basePadding + 'px'}, attribute :{unselectable : 'on', title : title}, event :eventBind, childNodes : [icon]}) ;
								currRowObj.addCell(tmpButton);
								currRowObj.addStyle({width:baseSize +'px'});
							} else if (groupend) {
								tmpButton = new cafen.XIcon({tag : tagButton, shortkey : shortkey, icon : 'r_wordset', off : baseBgPos+132, on : 22 , over : 100, style :{width:baseSize +'px', paddingRight:  basePadding + 'px'}, attribute :{unselectable : 'on', title : title}, event :eventBind, childNodes : [icon]}) ;
								currRowObj.addCell(tmpButton);
								currRowObj.addStyle({width:baseSize +'px'});
							} else {
								tmpButton = new cafen.XIcon({tag : tagButton, icon : 'r_wordset', off : baseBgPos+66, on : 22 , over : 100, style :{width:baseSize +'px', paddingRight:  basePadding + 'px'}, attribute :{unselectable : 'on', title : currButton[1]}, event :eventBind, childNodes : [icon]}) ;
								currRowObj.addCell(tmpButton);
								currRowObj.addStyle({width:baseSize +'px'});
							}
							this.actionButton[idx] = {classObj : null, obj : tmpButton};
							if (currButton[4])
								this.statusButton.push({cmd : idx, obj : tmpButton});
							groupmiddle = true;
						}
					}
					break;
			}
		}	
	},
	setMapType : function(no) {
		switch(no) {
			case 0 :
				this.mapInfo.maptype = 'roadmap';
				this.setButtonSelect('mtmap', true);
				this.setButtonSelect('mtsat', false);
				this.setButtonSelect('mthyb', false);
				break;
			case 1 :
				this.mapInfo.maptype = 'satellite';
				this.setButtonSelect('mtmap', false);
				this.setButtonSelect('mtsat', true);
				this.setButtonSelect('mthyb', false);
				break;
			case 2 :
				if (this.mapInfo.maptype == 'mobile')
					this.mapInfo.maptype = 'terrain';
				else if (this.mapInfo.maptype == 'terrain')
					this.mapInfo.maptype = 'hybrid';
				else 
					this.mapInfo.maptype = 'mobile';
				this.setButtonSelect('mtmap', false);
				this.setButtonSelect('mtsat', false);
				this.setButtonSelect('mthyb', true);
				break;
		}
		this.preView();
	},
	setButtonDisabled : function(buttons, bl) {
		for(var i = 0; i <buttons.length; i++) {
			var cmdName = buttons[i];
			if (this.actionButton[cmdName] != null)
				this.actionButton[cmdName].obj.setDisable(bl);
		}
	},
	setButtonSelect : function(btnID, bl) {
		if (this.actionButton[btnID] != null)
			this.actionButton[btnID].obj.setSelected(bl);
	},
	setApiType : function(api, bl) {
		if (api != null)
			this.mapInfo.apitype = api;
		switch(this.mapInfo.apitype) {
			case 'daum' :
				this.setButtonSelect('apidaum', true);
				this.setButtonSelect('apigoogle', false);
				this.setButtonSelect('apinaver', false);
				this.setButtonDisabled(['mtmap','mtsat','mthyb','user','userdel','poly','polydel'], true);
				if (this.imgview != null) {
					if (this.clickStatus['poly'] || this.clickStatus['user']) {
						this.clickStatus['poly'] = false;
						this.clickStatus['user'] = false;
						this.setButtonSelect('user', false);
						this.setButtonSelect('poly', false);
						if (this.clickStatus.click) {
							this.clickStatus.click = false;
							if (this.clickBind == null)
								this.clickBind = this.setMarker.bind(this);
							if (this.clickBind != null)
								this.imgview.detachEvent('click' , this.clickBind);
						}
					}
				}
				break;
			case 'naver' :
				this.setButtonSelect('apinaver', true);
				this.setButtonSelect('apidaum', false);
				this.setButtonSelect('apigoogle', false);
				this.setButtonDisabled(['mtmap','mtsat','mthyb','user','userdel'], false);
				this.setButtonDisabled(['poly','polydel'], true);
				if (this.imgview != null) {
					if (this.clickStatus['poly']) {
						this.clickStatus['poly'] = false;
						this.setButtonSelect('poly', false);
						if (this.clickStatus.click) {
							this.clickStatus.click = false;
							if (this.clickBind == null)
								this.clickBind = this.setMarker.bind(this);
							if (this.clickBind != null)
								this.imgview.detachEvent('click' , this.clickBind);
						}
					}
				}
				break;
			default :
				this.setButtonSelect('apinaver', false);
				this.setButtonSelect('apidaum', false);
				this.setButtonSelect('apigoogle', true);
				this.setButtonDisabled(['mtmap','mtsat','mthyb','user','userdel','poly','polydel'], false);
				break;
		}
		if (bl) 
			this.preView();
	},
	setZoom : function(level) {
		this.mapInfo.zoom -= level;
		if (this.mapInfo.zoom > 20)
			this.mapInfo.zoom = 20;
		else if (this.mapInfo.zoom < 5)
			this.mapInfo.zoom = 5;
		this.preView();
	},
	execCommand : function(cmd) {
		switch(cmd.toLowerCase()) {
			case 'apinaver' : 
				this.setApiType('naver', true);
				break;
			case 'apidaum' : 
				this.setApiType('daum', true);
				break;
			case 'apigoogle' : 
				this.setApiType('google', true);
				break;
			case 'typemap' : 
				this.setMapType(0);
				break;
			case 'typesat' : 
				this.setMapType(1);
				break;
			case 'typehyb' : 
				this.setMapType(2);
				break;
			case 'zoomout' : 
				this.setZoom(1);
				break;
			case 'zoomin' : 
				this.setZoom(-1);
				break;
			case 'moveup' :
				this.setMap(this.pixelToLatLng(0,(this.mapInfo.height/3)*(-1), this.mapInfo.zoom), true);
				break;
			case 'movedown' :
				this.setMap(this.pixelToLatLng(0,this.mapInfo.height/3, this.mapInfo.zoom), true);
				break;
			case 'moveleft' :
				this.setMap(this.pixelToLatLng((this.mapInfo.width/3)*(-1),0, this.mapInfo.zoom),true);
				break;
			case 'moveright' :
				this.setMap(this.pixelToLatLng(this.mapInfo.width/3,0, this.mapInfo.zoom), true);
				break;
			case 'deleteuser' :
				this.mapInfo.marker = [];
				this.preView();				
				break;
			case 'deletepoly' :
				this.mapInfo.poly = [];
				this.preView();				
				break;
			case 'poly' :
			case 'user' :
				if (this.imgview != null) {
					this.clickStatus[cmd] = this.actionButton[cmd].obj.toggleSelect();
					if (this.clickStatus['poly'] || this.clickStatus['user']) {
						if (!this.clickStatus.click) {
							this.clickStatus.click = true;
							if (this.clickBind == null)
								this.clickBind = this.setMarker.bind(this);
								
							if (this.imgview != null) {
								this.imgview.attachEvent('click' , this.clickBind);
								this.imgview.detachEvent("dragend", this.setMoveDragBind);
								this.imgview.pauseDrag(true);
							}
						}
					} else {
						this.clickStatus.click = false;
						if (this.imgview != null) {
							this.imgview.detachEvent('click' , this.clickBind);
							this.imgview.attachEvent("dragend", this.setMoveDragBind);
							this.imgview.pauseDrag(false);
						}
					}
				}
				break;
			default :
				break;
		}
	},
	latLngToPixel : function(lat, lng, zoom) {
 		var centerPoint=Math.pow(2,zoom+7),
 			totalPixels=centerPoint*2,
 			pixelsPerLngDegree=totalPixels/360,
 			pixelsPerLngRadian=totalPixels/(2*Math.PI),
 			siny=Math.min(Math.max(Math.sin(lat*(Math.PI/180)),-0.9999),0.9999);
 		return{
 			x:Math.round(centerPoint+lng*pixelsPerLngDegree),
 			y:Math.round(centerPoint-0.5*Math.log((1+siny)/(1-siny))*pixelsPerLngRadian)
 		}
	},
	pixelToLatLng : function(x, y, zoom) { 
 		var centerPoint=Math.pow(2,zoom+7),
 			totalPixels=centerPoint*2,
 			pixelsPerLngDegree=totalPixels/360,
 			pixelsPerLngRadian=totalPixels/(2*Math.PI);
		var oldxy = this.latLngToPixel(this.mapInfo.lat, this.mapInfo.lon,zoom);
		y  += oldxy.y; 
		x  += oldxy.x; 
		return {
			lat : (2*Math.atan(Math.exp(-(y-centerPoint)/pixelsPerLngRadian))-Math.PI/2) /(Math.PI/180), 
			lon : (x-centerPoint)/pixelsPerLngDegree
		};
	},
	actionCommand : function(cmd,obj) {
		switch(cmd) {
			case 'save' :
				if (this.mapImg != null ) 
					this.execEvent('done');
				break;
		}
	},	
	showMsg : function(msg) {
		if (this.statusObj == null) {
			this.statusObj = new cafen.Div({style : {marginTop:'5px', paddingLeft: '4px'}});
			this.appendChild(this.statusObj, 'bottom');
		}
		this.statusObj.getElement().innerHTML = msg;
	},
	searchKeyword : function(obj) {
		var keyword = obj.getValue();
		if (keyword.split(' ').join('') == '') {
			this.showMsg(cafenMsg.get('map_0005'));
			this.inputSearch.focus();
		} else {
			if (cafen.checkAPI('GMap')) {
				var param = {
					q: keyword,
					output : 'json',
					oe:'utf8',
					hl :'ko',
					sensor:'false',
					key: cafen.getAPI('GMap')
				};
				cafen.smallSWFAjax.getFlashXml(param,this.setkeywordResult.bind(this),'http://maps.google.com/maps/geo', true);	
			} else {
				this.showMsg(cafenMsg.get('com_nullkey'));
			}
		}
	},
	setkeywordResult : function(txt) {
		var json = cafen.getString2Json(txt);
		if (json.Status) {
			if (json.Status.code == 200 && json.Placemark)  {
				if (json.Placemark.length > 0) {
					var Lon = json.Placemark[0].Point.coordinates[0];
					var Lat = json.Placemark[0].Point.coordinates[1];
					this.setMap({lat: Lat, lon : Lon});
				} else
					this.showMsg(cafenMsg.get('com_nodata'));
			} else
				this.showMsg(cafenMsg.get('com_nodata'));
		} else
			this.showMsg(cafenMsg.get('com_nodata'));
	},
	showSearchResult : function() {

	},
	setMarker : function(obj, event) {
		var pos1 = cafen.pointer(event || window.event);
		var pos2 = obj.cumulativeOffset();
		var x =  (pos1[0] - pos2[0]) - this.mapInfo.width / 2;
		var y =  (pos1[1] - pos2[1]) - this.mapInfo.height / 2;
		var latlon = this.pixelToLatLng(x,y, this.mapInfo.zoom);
		if (this.clickStatus['user'])
			this.mapInfo.marker.push(latlon);
		if (this.clickStatus['poly'])
			this.mapInfo.poly.push(latlon);
		this.preView();
	},
	setMap : function(mapInfo, keepInfo) {
		if (mapInfo != null && typeof mapInfo == 'string') {
			var tmpUrl = 	mapInfo.split('?');
			mapInfo = {};
			if (tmpUrl[1] != null) {
				var mapData =tmpUrl[1].split('&');
				for(var i = 0 ; i < mapData.length; i++) {
					var tmpVal = 	mapData[i].split('=');
					switch(tmpVal[0]) {
						case 'center' :
							var latLon = tmpVal[1].split(',');
							mapInfo.lat = parseFloat(latLon[0]);
							mapInfo.lon = parseFloat(latLon[1]);
							break;
						case 'zoom' :
							mapInfo.zoom = parseInt(tmpVal[1]);
							break;
						case 'maptype' :
							mapInfo.maptype = tmpVal[1];
							break;
					}
				}
			}
		}
		if (mapInfo != null && mapInfo.lat != null && mapInfo.lon) {
			this.mapInfo.lat = mapInfo.lat;
			this.mapInfo.lon = mapInfo.lon;
			if (mapInfo.maptype != null) 
				this.mapInfo.maptype = mapInfo.maptype;
			if (mapInfo.zoom != null) 
				this.mapInfo.zoom = mapInfo.zoom;
			if (!keepInfo) {
				this.mapInfo.marker = [];
				this.mapInfo.poly = [];
			}
		}
		this.setApiType(this.mapInfo.apitype);
		switch(this.mapInfo.maptype) {
			case 'roadmap' :
				this.setMapType(0);
				break;
			case 'mobile' :
			case 'terrain' :
			case 'hybrid' :
				if (this.mapInfo.maptype == 'hybrid')
					this.mapInfo.maptype = 'terrain';
				else if (this.mapInfo.maptype == 'terrain')
					this.mapInfo.maptype = 'mobile';
				else 
					this.mapInfo.maptype = 'terrain';
				this.setMapType(2);
				break;
			case 'satellite' :
			default :
				this.setMapType(1);
				break;
		}
	},
	previewDaumMap : function() {
		if (typeof CS == 'undefined') {
			window.csSchedule = this.previewDaumMap.bind(this);
			cafen.srartLoad(_cafen_service_url+'images/map/lib/rainMapUtil.js');
		} else {
			if (this.TM128_naver == null || this.KOREA_center == null  || this.WGS84_google== null) {
				this.TM128_naver = new CS(csList.TM128_katech_3param);
				this.WGS84_google = new CS(csList.GOOGLE_WGS84);
				this.KOREA_center = new CS(csList.KOREA_CENTER_TM_3param);
			}
			var params = [];
			var p = new PT(this.mapInfo.lon, this.mapInfo.lat);
			cs_transform(this.WGS84_google, this.KOREA_center, p);
			params.push('MX='+Math.round(p.x*2.5)+'&MY='+Math.round(p.y*2.5));
			params.push('IW='+this.mapInfo.width+'&IH='+this.mapInfo.height);
			if (this.mapInfo.zoom > 6) {
				var zoom = 5120 / Math.pow(2,this.mapInfo.zoom - 6);
				params.push('SCALE='+zoom);
			} else
				params.push('SCALE=5120');
			params.push('COORDSTM=WCONGNAMUL');
			this.mapImg = 'http://map2.daum.net/map/mapservice?'+ params.join('&');
			this.setPreviewImg(this.mapImg);
		}
	},
	previewGoogleMap : function() {
		if (cafen.checkAPI('GMap')) {
			var params = [];
			params.push('center='+this.mapInfo.lat+','+this.mapInfo.lon);
			params.push('size='+this.mapInfo.width+'x'+this.mapInfo.height);
			params.push('key='+cafen.getAPI('GMap'));
			params.push('maptype='+this.mapInfo.maptype);
			params.push('zoom='+this.mapInfo.zoom);
			if (this.mapInfo.marker.length > 0) {
				var colorInfo = ['brown', 'green', 'purple', 'yellow', 'blue', 'gray', 'orange','red', 'white','black'];
				var alphaInfo = 'abcdefghijklmnopqrstuvwxyz1234567890';
				var markerparam = [];
				for(var i = 0 ; i < this.mapInfo.marker.length; i++) {
					var marker = this.mapInfo.marker[i];
					markerparam.push(marker.lat+','+marker.lon+','+colorInfo[i %10]+alphaInfo.charAt(i%36));
				}
				params.push('markers='+markerparam.join('|'));
			}
			if (this.mapInfo.poly.length > 0) {
				var markerparam = [];
				for(var i = 0 ; i < this.mapInfo.poly.length; i++) {
					var marker = this.mapInfo.poly[i];
					markerparam.push(marker.lat+','+marker.lon);
				}
				params.push('path=rgb:0xff0000,weight:3|'+markerparam.join('|'));
			}
			params.push('sensor=false');
			params.push('format=png');
			this.mapImg = 'http://maps.google.co.kr/staticmap?'+ params.join('&');
			this.setPreviewImg(this.mapImg);
		} else {
			this.mapObj.getElement().innerHTML = cafenMsg.get('com_nullkey');
			this.mapObj.setStyle({textAlign:'center', paddingTop:'20px'});
		}		
	},
	setPreviewImg : function(imgurl) {
		if (this.imgview == null) {
			this.setMoveDragBind = this.setMoveDrag.bind(this);
			this.setMoveZoomBind = this.setMoveZoom.bind(this);
			this.imgview = new cafen.Image(this.mapImg, {zoomable : true, style :{width : this.mapInfo.width +'px' , height : this.mapInfo.height +'px'}, scale : 'max', moveOption : {direction: 'XY'}, event : {zoomend : this.setMoveZoomBind, dragend : this.setMoveDragBind}});
			this.mapObj.appendChild(this.imgview);	
		} else
			this.imgview.setImage(this.mapImg);
	},
	setMoveZoom : function(obj) {
		var zoomEnd = parseFloat(obj.getStyle('zoom')) || 1;
		if (zoomEnd > 1) {
			this.setZoom(-1);
		} else {
			this.setZoom(1);
		}
	},
	setMoveDrag : function(obj) {
		var objOffset = obj.getOffset();
		this.setMap(this.pixelToLatLng(objOffset[0] *(-1), objOffset[1] *(-1), this.mapInfo.zoom), true);
	},
	previewNaverMap : function() {
		if (cafen.checkAPI('NMap')) {
			var params = [];
			params.push('version=1.1');
			params.push('crs=EPSG:4326');
			params.push('center='+this.mapInfo.lon+','+this.mapInfo.lat);
			params.push('w='+this.mapInfo.width);
			params.push('h='+this.mapInfo.height);
			params.push('key='+cafen.getAPI('NMap'));
			switch(this.mapInfo.maptype) {
				case 'satellite' :
					params.push('baselayer=satellite');
					break;
				case 'hybrid' :
				case 'mobile' :
				case 'terrain' :
					params.push('baselayer=satellite');
					params.push('overlayers=anno_satellite');
					break;
				default :
					params.push('baselayer=default');
					break;
			} 
			params.push('exception=inimage');
			params.push('level='+(this.mapInfo.zoom - 5));
			if (this.mapInfo.marker.length > 0) {
				var markerparam = [];
				for(var i = 0 ; i < this.mapInfo.marker.length; i++) {
					var marker = this.mapInfo.marker[i];
					markerparam.push(marker.lon+','+marker.lat);
				}
				params.push('markers='+markerparam.join(','));
			}
			params.push('format=png');
			params.push('uri='+document.location.host);
			this.mapImg = 'http://openapi.naver.com/map/getStaticMap?'+ params.join('&');
			this.setPreviewImg(this.mapImg);
		} else {
			this.mapObj.getElement().innerHTML = cafenMsg.get('com_nullkey');
			this.mapObj.setStyle({textAlign:'center', paddingTop:'20px'});
		}		
	},
	preView : function() {
		switch(this.mapInfo.apitype) {
			case 'daum' :
				this.previewDaumMap();
				break;
			case 'naver' :
				this.previewNaverMap();
				break;
			default :
				this.previewGoogleMap();
				break;
		}
	},
	getMap : function() {
		return this.mapImg;
	},
	getApi : function() {
		return this.mapInfo.apitype;
	},
	getMapInfo : function() {
		return this.mapInfo;
	},
	getType : function() {
		return this.mapInfo.maptype;
	},
	getLat : function() {
		return this.mapInfo.lat;
	},
	getLng : function() {
		return this.mapInfo.lon;
	},
	getZoom : function() {
		return this.mapInfo.zoom;
	},
	getMarker : function() {
		return this.mapInfo.marker;	
	},
	getPolyline : function() {
		return this.mapInfo.poly;	
	}
},cafen.XWindow.prototype);


cafen.XConfirm = function(options) {
	this._popupOptions = options;
	this.setOptions(cafen.extend({className :'r_popskin', tag : 'div', tplName : 'top', style : {width:'300px',textAlign:'center', position :'absolute'}, shadow : true, resize : 'XXXOOOOOO'}, options));
	if (options.title != null)
		this.setTitle(options.title);
	this.setToolBar();
	if (options.contents != null)
		this.setContents(options.contents);
	this.setButton(new cafen.XButton({text: cafenMsg.get('util_0004'), shortkey : 'Y', style :{width : '60px'}, align:'center',event:{'click' : this.sendValue.bind(this,true)}}));
	this.setButton(new cafen.XButton({text: cafenMsg.get('util_0005'), shortkey : 'N', style :{width : '60px'}, align:'center',event:{'click' : this.sendValue.bind(this, false)}}));
}

cafen.XConfirm.prototype = cafen.extendClass({

},cafen.XWindow.prototype);


cafen.XCalendar = function(options) {
	this._popupOptions = options;
	this.setOptions(cafen.extend({className :'r_popskin', tag : 'div', tplName : 'top', style : {width:'170px',textAlign:'center', position :'absolute', padding: '2px'}, shadow : true}, options));
	if (options.title != null)
		this.setTitle(options.title);
	this.setToolBar();
	this.initCalendar();
}

cafen.XCalendar.prototype = cafen.extendClass({
	_calTable : null,
	_topObj : null,
	_inputObj : null,
	_currentData : null,
	_DOMonth : [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], 
	_lDOMonth : [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
	_NameEng : null,
	_monthDate : [], 
	initCalendar : function() {
		this._NameEng = cafenMsg.getObject('com_dayname');
		this._currentData = new Date();
		this._topObj = new cafen.TableAuto({attribute:{border :'0', cellPadding:'2', align:'center'}, style:{width:'175px'}});
		this._inputObj = new cafen.XInput({style : {width: '70px'}, event : {blur : this.setDateInput.bind(this), end : this.setDateInput.bind(this)}});
		this._topObj.addCell(this._inputObj);
		this._topObj.addStyle({textAlign:'left', width :'70px'});
		this._topObj.addCell();
		this._topObj.addStyle({textAlign:'left', width :'70px'});
		var tmpDiv = new cafen.Div({style:{position:'absolute', bottom:0, right:0}});
		this._topObj.addCell(tmpDiv);
		this._topObj.addStyle({textAlign:'right', width :'40px', verticalAlign: 'bottom', position:'relative'});
		tmpDiv.appendChild(new cafen.XIcon({icon: 'r_iconset', off : 180, on : 0, over : 15, event : {click : this.movePrev.bind(this)}, style : {width : '15px', height : '15px'}}));
		tmpDiv.appendChild(new cafen.XIcon({icon: 'r_iconset', off : 165, on : 0, over : 15, event : {click : this.moveNext.bind(this)}, style : {width : '15px', height : '15px'}}));
		this.appendChild(this._topObj);
		this._calTable = new cafen.TableAuto({attribute:{border :0, width :'100%', cellpadding : 2, cellspacing:1, align:'center'}, style : {marginTop : '3px', width:'175px'}});
		this.appendChild(this._calTable);
		for (var i =0 ; i < 7; i++) {
			this._calTable.addRow();
			for (var j =0 ; j < 7; j++) {
				var cell = this._calTable.addCell();
				if (i == 0) { 
					this._calTable.addText(this._NameEng[j]);
					this._calTable.addStyle({textAlign:'center', padding:'2px', lineHeight:'normal' , fontSize : '12px',border : '1px solid #d0d0d0',width : '14.28%'});
				} else {
					cell.attachEvent('click',this.setDate.bind(this, (i -1) * 7 +j));
					this._calTable.addStyle({textAlign:'right', cursor : cafen.getCursor(), lineHeight:'normal', padding: '3px',fontSize : '12px', borderRight : '1px dotted #d0d0d0', borderLeft: '1px none transparent', borderTop: '1px none transparent', borderBottom: '1px dotted #d0d0d0'});
				}
			}
		}
		this.showMonth(this._currentData.getFullYear(), this._currentData.getMonth() +1);
	},
	getDaysOfMonth : function(year, month) { 
		if ((year % 4) == 0) { 
			if ((year % 100) == 0 && (year % 400) != 0) return this._DOMonth[month]; 
			return this._lDOMonth[month]; 
		} else return this._DOMonth[month]; 
	},
	getFirstDay : function(year, month) {
		var tmpDate = new Date(); 
		tmpDate.setDate(1); 
		tmpDate.setMonth(month); 
		tmpDate.setFullYear(year); 
		return tmpDate.getDay(); 
	},
	getLastDay : function(year, month) {
		var tmpDate = new Date(); 
		tmpDate.setMonth(month); 
		tmpDate.setFullYear(year); 
		tmpDate.setDate( getDaysOfMonth(year, month) ); 
		return tmpDate.getDay(); 
	},
	moveNext : function() {
		this.showMonth(this._currentData.getFullYear(), this._currentData.getMonth() + 2);
	},
	movePrev : function() {
		this.showMonth(this._currentData.getFullYear(), this._currentData.getMonth());
	},
	clearMonth : function() {
		for (var i =1 ; i < 7; i++) 
			for (var j =0 ; j < 7; j++) 
				this._calTable.addText('&nbsp;', j, i);
	},
	getMonthYear : function() {
		var txt  = this._currentData.getFullYear() +'/';
		var month = this._currentData.getMonth() +1;
		return (month > 9) ? txt + month : txt + '0'+month;
	},
	setDate : function(no) {
		if (typeof no == 'number') {
			var day  = this._monthDate[no];
			if (day != null) {
				var dayTxt = [];
				dayTxt.push(this._currentData.getFullYear());
				var month = this._currentData.getMonth() +1;
				month = (month > 9) ? month : '0' +month;
				dayTxt.push(month);
				day = (day > 9) ? day : '0' +day;
				dayTxt.push(day);
				this.sendValue(dayTxt.join('/'));
			}
		} else {
			var reg = null;
			if (reg = cafen.find('([0-9][0-9][0-9][0-9])[\\/\\.\\-][0]*([0-9]+)', no)) {
				this.showMonth(parseInt(reg[1]), parseInt(reg[2]));	
			} else if (reg = cafen.find('([0-9][0-9][0-9][0-9])', no)) {
				this.showMonth(parseInt(reg[1]), this._currentData.getMonth()+1 );	
			} else {
				this._inputObj.setValue(this.getMonthYear());
			}
		}
	},
	setDateInput : function(obj) {
		var txt = obj.getValue();
		var reg = null;
		if (reg = cafen.find('([0-9][0-9][0-9][0-9])[\\/\\.\\-][0]*([0-9]+)', txt)) {
			this.showMonth(parseInt(reg[1]), parseInt(reg[2]));	
		} else if (reg = cafen.find('([0-9][0-9][0-9][0-9])', txt)) {
			this.showMonth(parseInt(reg[1]), this._currentData.getMonth()+1);	
		} else {
			this._inputObj.setValue(this.getMonthYear());
		}
	},
	showMonth : function (year, month) {
		this._currentData = new Date(year,month -1,1);
		this._monthDate = [];
		var cnt = this.getDaysOfMonth(this._currentData.getFullYear(), this._currentData.getMonth());
		this._inputObj.setValue(this.getMonthYear());
		this.clearMonth();
		var start = (this.getFirstDay(this._currentData.getFullYear(), this._currentData.getMonth())) % 7;
		for (var i =0; i < 42 ; i++)
			this._monthDate.push(null);
		for (var i = 1; i <= cnt ; i++) {
			this._monthDate[start] = i;
			var row = Math.floor(start/7) +1;
			var col = start % 7;
			this._calTable.addText(i, col, row);
			start++;
		}
	}
},cafen.XWindow.prototype);

cafen.XColorpicker = function(options) {
	this._popupOptions = options;
	this.setOptions(cafen.extend({className :'r_popskin', tag : 'div', tplName : 'both', useHSV : true, style : {width:'auto',textAlign:'left', position :'absolute', overflowX : 'hidden', padding: '2px'}, shadow : true}, options));
	if (options.title != null)
		this.setTitle(options.title);
	this.setToolBar();
	this.initColorpicker();
}

cafen.XColorpicker.prototype = cafen.extendClass({
	_colorTable : null,
	_buttonObj : null,
	_currColorIdx : null,
	_toggleObj : null,
	_hsvObj : null,
	_chartBase : [
		{
			title : 'Normal',
			obj : null,
			color : [
		 		'#000000', '#444444', '#666666','#999999','#cccccc','#eeeeee','#f3f3f3','#ffffff',
		 		'#ff0000', '#ff9900', '#ffff00','#00ff00','#00ffff','#0000ff','#9900ff','#ff00ff',
		 		'#f4cccc', '#fce5cd', '#fff2cc','#d9ead3','#d0e0e3','#cfe2f3','#d9d2e9','#ead1dc',
		 		'#ea9999', '#f9cb9c', '#ffe599','#b6d7a8','#a2c4c9','#9fc5e8','#b4a7d6','#d5a6bd',
		 		'#e06666', '#f6b26b', '#ffd966','#93c47d','#76a5af','#6fa8dc','#b4a7d6','#c27ba0',
		 		'#cc0000', '#e69138', '#f1c232','#6aa84f','#45818e','#3d85c6','#674ea7','#a64d79',
		 		'#990000', '#b45f06', '#bf9000','#38761d','#134f5c','#0b5394','#351c75','#741b47',
		 		'#660000', '#783f04', '#7f6000','#274e13','#0c343d','#073763','#20124d','#4c1130'
			]
		},
		{
			title : 'Black',
			obj : null,
			color : [
				'#000000','#4D1A00','#1A1A00','#001A00','#001A33','#000040','#1A1A4D','#1A1A1A',
				'#400000','#803300','#404000','#004000','#004040','#000080','#33334D','#404040',
				'#800000','#804C00','#4D6600','#1A4D33','#1A6666','#1A3380','#400040','#4D4D4D',
				'#80007F','#806500','#7F8000','#668066','#668080','#4D6680','#4D1A33','#606060',
				'#804D66','#80664D','#80804D','#668066','#668080','#4D6680','#664D80','#808080'
			]
		},
		{
			title : 'White',
			obj : null,
			color : [
				'#7F7F7F','#CC997F','#99997F','#7F997F','#7F99B2','#7F7FBF','#9999CC','#999999',
				'#BF7F7F','#FFB27F','#BFBF7F','#7FBF7F','#7FBFBF','#7F7FFF','#B2B2CC','#BFBFBF',
				'#FF7F7F','#FFCB7F','#CCE57F','#99CCB2','#99E5E5','#99B2FF','#BF7FBF','#CCCCCC',
				'#FF7FFE','#FFE47F','#FEFF7F','#7FFF7F','#7FFEFF','#7FE4FF','#CC99B2','#DFDFDF',
				'#FFCCE5','#FFE5CC','#FFFFCC','#E5FFE5','#E5FFFF','#CCE5FF','#E5CCFF','#FFFFFF'
			]
		}
	],
	_currentData : null,
	initColorpicker : function() {
		this._topObj = new cafen.TableAuto({attribute:{border :'0', width :'auto',height:'30px',cellpadding : '0'}, style : {width:'190px'}});
		if (this.options.useHSV)
			this._previewObj = new cafen.Div({style : {width: '30px', height:'20px', border : '1px dotted #d0d0d0', cursor: cafen.getCursor()}, attribute : {title : cafenMsg.get('com_morecolor')},event:{click: this.toggleHSV.bind(this)}});
		else
			this._previewObj = new cafen.Div({style : {width: '30px', height:'20px', border : '1px dotted #d0d0d0'}});
		this._topObj.addCell(this._previewObj);
		this._inputObj = new cafen.XInput({style : {width: '60px', marginLeft:'3px'}, event : {blur : this.setColorInput.bind(this), end : this.setColorInput.bind(this)}});
		this._topObj.addCell(this._inputObj);
		this._buttonObj = new cafen.XButton({text:cafenMsg.get('com_ok'), event : {click : this.sendColor.bind(this)}, style : { marginLeft:'3px'}});
		this._topObj.addCell(this._buttonObj);
		this._checkObj = new cafen.Checkbox('transparent','transparent',false,{attribute : {title : cafenMsg.get('com_settrans')},style : {marginLeft:'3px'}, event : {click : this.setTransparent.bind(this)}});
		this._topObj.addCell(this._checkObj);
		this.appendChild(this._topObj);
		var tabInfo = [];
		for(var i = 0; i < this._chartBase.length; i++) {
			this._chartBase[i].obj = new cafen.XTab({text: this._chartBase[i].title, align:'left', event : {click : this.setColorChart.bind(this, i), style : {width:'auto'}}});
			tabInfo.push(this._chartBase[i].obj);
		}
		this._tabObj = new cafen.XTabMenu(tabInfo);
		this.appendChild(this._tabObj);
		this.tmpTableSkin = new cafen.Div({className :'r_boxwhite', attribute:{}, style : {width:'185px'}});
		this.appendChild(this.tmpTableSkin);
		this._colorTable = new cafen.TableAuto({attribute:{className :'r_table r_sboxselected', border :0, width :'100%', cellpadding : 1, cellspacing:1}, style : {width : '175px', cursor : cafen.getCursor()}});
		this.tmpTableSkin.appendChild(this._colorTable);
		for (var i =0 ; i < 8; i++) {
			this._colorTable.addRow();
			for (var j =0 ; j < 8; j++) {
				var cell = this._colorTable.addCell();
				cell.attachEvent('click',this.setColor.bind(this, i * 8 +j));
				cell.attachEvent('mouseover',this.showColor.bind(this, i * 8 +j));
				this._colorTable.addText('&nbsp;');
				this._colorTable.addStyle({textAlign:'center', width: '12.5%',cursor : 'hand', fontSize : '1px', height : '17px'});
			}
		}
		this._statusObj = new cafen.Div({style:{width:'90%', marginTop:'5px'}});
		this.appendChild(this._statusObj, 'bottom');
		this.setColorChart(0);
	},
	setTransparent : function() {
		if (this._checkObj.isChecked()) {
			this.setColor('transparent');
			this.sendColor();
		} else {
			this.setColor('');
		}
	},
	useTransparent : function(bl) {
		this._checkObj.setDisabled(bl);
	},
	toggleHSV : function() {
		if (!this.options.useHSV)
			return ;
		if (this._hsvObj == null) {
			this._hsvObj = new cafen.XColorpickerHSV({event :{end : this.setHSVColor.bind(this)}});
			this.appendChild(this._hsvObj);
			this._hsvObj.setColor(this.getColor());
			this._hsvObj._isShown = false;
		}
		if (!this._hsvObj._isShown) {
			this._tabObj.hide();
			this.tmpTableSkin.hide();
		}else {
			this._tabObj.show();
			this.tmpTableSkin.show();
		}
		this._hsvObj.toggleHSV();
	},
	setHSVColor : function(obj) {
		var incolor = obj.getColor();
		this._inputObj.setValue(incolor);
		this._previewObj.setStyle(this.getColorStyle(incolor));
	},
	setColorInput : function(obj) {
		var incolor = this._inputObj.getValue();
		if (incolor.toLowerCase() == 'transparent') {
			this.setPreivew(incolor);
		} else if (cafen.find('^#[0-9a-fA-F]{6}$', incolor)) {
			this.setPreivew(incolor);
		} else  {
			this._inputObj.setError();
		}
	},
	setColorChart : function(no) {
		this._currentData = [];
		var currColor = this._chartBase[no].color;
		if (this._currColorIdx != null)
			this._chartBase[this._currColorIdx].obj.setSelected(false);
		this._chartBase[no].obj.setSelected(true);
		this._currColorIdx = no;
		for(var i = 0; i < 64; i++) {
			var row = Math.floor(i/8);
			var col = i % 8;
			var color = currColor[i];
			if (color != null) {
				this._currentData.push(color);
				this._colorTable.addStyle({backgroundColor :color},col, row);
			} else {
				this._currentData.push(null);
				this._colorTable.addStyle({backgroundColor :'transparent'},col, row);
			}
		}
	},
	getColorStyle : function(color) {
		if ('transparent' != color.toLowerCase()) {
			return {
				backgroundImage : 'none',
				backgroundColor : color
			};
		} else {
			return {
				backgroundImage : 'url('+_cafen_service_url+'images/bg_transparent.gif)',
				backgroundPosition : 'center center',
				backgroundRepeat : 'no-repeat',
				backgroundColor : '#ffffff'
			};
		}
	},
	setPreivew : function(color) {
		this._previewObj.setStyle(this.getColorStyle(color));
		if (this._hsvObj != null)
			this._hsvObj.setColor(color.toLowerCase());
	},
	sendColor : function() {
		var incolor = this.getColor();
		if (incolor.toLowerCase() == 'transparent') {
			this.sendValue(incolor);
		} else if (cafen.find('^#[0-9a-fA-F]{6}$', incolor)) 
			this.sendValue(incolor);
		else
			this._inputObj.setError();
	},
	setColor : function(no, bl) {
		if (bl != null) 
			this.useTransparent(!bl);
		if (typeof no == 'number') {
			if (this._currentData[no] != null) {
				var incolor = this._currentData[no].toLowerCase();
				this._inputObj.setValue(incolor);
				this.setPreivew(incolor);
				var row = Math.floor(no/8);
				var col = no % 8;
			}
			return true;
		} else if (no != null){
			if (no.toLowerCase() == 'transparent') {
				this._checkObj.setChecked(true);
				this._inputObj.setValue('transparent');
				this.setPreivew('transparent');
			} else {
				this._checkObj.setChecked(false);
				no = cafen.rgb2hexFF(no);
				if (no != null) {
					this._inputObj.setValue(no);
					this.setPreivew(no);
				}
			}
		}
	},
	showColor : function(no) {
		if (this._currentData[no] != null) {
			var incolor = this._currentData[no].toUpperCase();
			this._statusObj.getElement().innerHTML = incolor;
		}
		return true;
	},
	getColor : function () {
		return this._inputObj.getValue();
	}
},cafen.XWindow.prototype);



cafen.XColorpickerHSV = function(options) {
	this.setOptions(cafen.extend(options, {tag : 'div', className : 'r_boxwhite',attribute :{}, style : {width:'185px', textAlign:'center', height:'auto', overflow : 'hidden',position : 'relative'}}));
	this.initColorpicker();
}

cafen.XColorpickerHSV.prototype = cafen.extendClass({
	_colorSatValObj : null, 
	_cursorObj : null,
	_hueObj : null,
	_satObj : null,
	_briObj : null,
	_isShown : false,
	_currentHSV : null,
	initColorpicker : function() {
		var contentsObj = new cafen.TableAuto({attribute :{width:'170px', height:'auto', cellpadding: 3, align : 'center'}, style : {position : 'relative', width : '170px'}});
		this.appendChild(contentsObj);
		if (cafen.isPngAlphaSupport()) {
			this._colorSatValObj = new cafen.Div({align:'center', style :{
				margin:'2px',
				width:'170px',
				height:'170px',
				backgroundColor : '#FF0000',
				cursor:'crosshair',
				position : 'relative',
				backgroundImage : 'url('+_cafen_service_url+'images/SatVal.png)'
			}});
		} else {
			this._colorSatValObj = new cafen.Div({align:'center', style : {
				margin:'2px',
				width:'170px',
				height:'170px',
				textAlign: 'left',
				backgroundColor : '#FF0000',
				cursor:'crosshair',
				position : 'relative',
				filter : "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+_cafen_service_url+"images/SatVal.png')"
			}});
		}
		this._colorSatValObj.attachEvent('click',this.setSVColor.bind(this));
		contentsObj.addRow();
		contentsObj.addCell(this._colorSatValObj);
		contentsObj.addStyle({textAlign:'center'});
		this._cursorObj = new cafen.XIcon({icon :'r_iconset', on : 0, off : 375, over : 15, moveOption : {direction: 'XY', rangeX : [-8,162], rangeY :[-8,162]}, style :{width:'15px', height:'15px', position:'absolute', left : '0px', top: '0px'}, event : {dragend : this.setSVPColor.bind(this)}});
		this._colorSatValObj.appendChild(this._cursorObj);
		contentsObj.addRow();
		var hsvObj = new cafen.TableAuto({attribute :{className : 'r_cell2px', width:'auto', height:'auto', cellPadding: 1, cellSpacing : 2}, style : {}});
		contentsObj.addCell(hsvObj);
		contentsObj.addStyle({textAlign:'center'});
		hsvObj.addCell();
		hsvObj.addStyle({textAlign:'right', fontSize :'12px', width: '30px'});
		hsvObj.addText(cafenMsg.get('ed_0057'));
		this._hueObj = new cafen.Slider({size : 120, direct : 'X', event:{end : this.setHue.bind(this)}});
		hsvObj.addCell(this._hueObj);
		hsvObj.addStyle({textAlign:'left'});
		hsvObj.addRow();
		hsvObj.addCell();
		hsvObj.addStyle({textAlign:'right', fontSize :'12px'});
		hsvObj.addText(cafenMsg.get('ed_0056'));
		this._satObj = new cafen.Slider({size : 120, direct : 'X', event:{end : this.setSat.bind(this)}});
		hsvObj.addCell(this._satObj);
		hsvObj.addStyle({textAlign:'left'});
		hsvObj.addRow();
		hsvObj.addCell();
		hsvObj.addStyle({textAlign:'right', fontSize :'12px'});
		hsvObj.addText(cafenMsg.get('ed_0055'));
		this._briObj = new cafen.Slider({size : 120, direct : 'X', event:{end : this.setBri.bind(this)}});
		hsvObj.addCell(this._briObj);
		hsvObj.addStyle({textAlign:'left'});
	},
	toggleHSV : function() {
		this._isShown = ! this._isShown;
		if (this._isShown) { 
			this.show();
		} else {
			this.hide();
		}
	},
	setColor : function(color) {
		this._currentHSV = {h:0,s:0,v:0}
		if (color = null && color.toLowerCase() != 'transparent') {
			var rgb = this.hex2rgb(color);
			var hsv = this.rgb2hsv(rgb.r, rgb.g, rgb.b);
			this._currentHSV = hsv;
			var bgColor = this.hsv2hex(hsv.h, 100, 100);
			this._colorSatValObj.setStyle({backgroundColor : bgColor});
			var x = hsv.s /100*170;
			var y = (100 -hsv.v) /100*170;
			this._hueObj.setValue(this._currentHSV.h / 360 * 100);
			this._satObj.setValue(this._currentHSV.s);
			this._briObj.setValue(100 - this._currentHSV.v);
			this._cursorObj.setStyle({left: (x - 9) +'px', top : (y -9) +'px'});
		}
	},
	updateHSV : function() {
		var bgColor = this.hsv2hex(this._currentHSV.h, 100, 100);
		this._colorSatValObj.setStyle({backgroundColor : bgColor});
		var x = this._currentHSV.s /100*170;
		var y = (100 -this._currentHSV.v) /100*170;
		this._cursorObj.setStyle({left: (x - 7) +'px', top : (y -7) +'px'});
		this.execEvent('end');
	},
	setHue : function(obj) {
		this._currentHSV.h = obj.getValue() * 360 /100;
		this.updateHSV();
	},
	setSat : function(obj) {
		this._currentHSV.s = obj.getValue();
		this.updateHSV();
	},
	setBri : function(obj) {
		this._currentHSV.v = 100 - obj.getValue();
		this.updateHSV();
	},
	setSVColor : function(obj, event) {
		var posPoint = cafen.pointer(event);
		var posObj = cafen.cumulativeOffset(obj.getElement());
		var x = Math.max(0,Math.min(170,(posPoint[0] - posObj[0])));
		var y = Math.max(0,Math.min(170,(posPoint[1] - posObj[1])));
		this._currentHSV.s = (x/170)*100; 
		this._currentHSV.v = (170-y)/170*100;
		this._cursorObj.setStyle({left: (x - 7) +'px', top : (y -7) +'px'});
		this._satObj.setValue(this._currentHSV.s);
		this._briObj.setValue(100 - this._currentHSV.v);
		this.execEvent('end');
		return true;
	},
	setSVPColor : function() {
		
	},
	getColor : function() {
		return this.hsv2hex(this._currentHSV.h, this._currentHSV.s, this._currentHSV.v);
	},
	hsv2hex : function(h,s,v) {
		return cafen.colorTools.hsv2hex(h,s,v);
	},
	rgb2hex : function(r, g, b) {
		return cafen.colorTools.rgb2hex(r, g, b);
	},
	hex2rgb : function(hex) {
		return cafen.colorTools.hex2rgb(hex);
	},
	rgb2hsv : function(r, g, b) {
		return cafen.colorTools.rgb2hsv(r, g, b);
	},
	hsv2rgb : function(h, s, v) {
		return cafen.colorTools.hsv2rgb(h, s, v);
	}
},cafen.Element.prototype);

cafen.XLayer = function(options) {
	this._popupOptions = options;
	this.setOptions(cafen.extend({className :'r_btnskin', tag : 'div', style : { textAlign:'center', position :'absolute'}, shadow : true}, options));
	this.setObject(options.childNode);
}

cafen.XLayer.prototype = cafen.extendClass({

},cafen.XWindow.prototype);



/**
 * xml 파싱 
 * @class xml 파싱 
 * @constructor 
 * @param {object} feed 대상 Feed
 */


cafen.xmlParser = function(feed) {
	this.initxmlParser(feed);	
};

cafen.xmlParser.prototype = {
	initxmlParser : function(feed) {
		var tmp_feed = null;
		if (typeof feed == 'string')
			cafen.debugMessage(feed, 'xml');
		else
			cafen.debugMessage(feed.responseText, 'xml');
		if (typeof feed != 'string' && typeof feed.responseText != 'undefined') 
			feed = feed.responseText;
		if (typeof feed == 'string') {
			if (typeof DOMParser != 'undefined') {
				tmp_feed =  new DOMParser().parseFromString(feed, "text/xml");
			} else {
				try {
					var xml = new window.ActiveXObject("Microsoft.XMLDOM");
					xml.async = "false";
					xml.loadXML(feed); 
					tmp_feed= xml;
				} catch(ex) {
					cafen.debugMessage(ex);
				}
			}
		} else {
			if (typeof DOMParser != 'undefined')
				tmp_feed =  new DOMParser().parseFromString(feed.responseText, 'text/xml');
			else {
				tmp_feed =  feed.responseXML;
			}
		}
		this.feed = tmp_feed;
		this.current_no = 0;
		try {
			var xml_channels = tmp_feed.documentElement.getElementsByTagName("channel");
			if (xml_channels == null || xml_channels.length == 0) 
				xml_channels = [{childNodes :tmp_feed.documentElement.childNodes}];
		} catch(ex) {
			cafen.debugMessage(ex);
		}
		this.channels = (xml_channels != null) ? xml_channels : [];
	},
	getChildNodes : function() {
		return new cafen.xmlParser.node(this.feed);
	},
/**
 * 채널 가져오기
 * @param {int} no 대상 순번
 * @return {cafen.xmlParser.Channel} cafen.xmlParser.Channel
 */
	getChannel : function(no) {
		if (this.channels.length > no) 
			return new cafen.xmlParser.Channel(this.channels[no]);
		else
			return null;
	},
/**
 * 다음채널 가져오기
 * @return {cafen.xmlParser.Channel} cafen.xmlParser.Channel
 */
	getNext : function() {
		var channel = this.getChannel(this.current_no);
		if (channel) {
			this.current_no++;
			return channel;
		} else 
			return null
	}
}

cafen.xmlParser.node = function(feed) {
	this.initNode(feed);	
};

cafen.xmlParser.node.prototype = {
	initNode : function(feed) {
		this.feed = feed;
	},
	getObject : function () {
		return this.feed;
	},
	getElements : function (name) {
		var objs = this.feed.getElementsByTagName(name);
		if (objs.length > 0) {
			var childNodes = [];
			for(var i = 0; i < objs.length; i++)
				childNodes.push(new cafen.xmlParser.node(objs[i]));
			return childNodes;
		} else
			return null;
	},
	getElement : function() {
		var obj = this.getObject();
		var len = (arguments.length -1);
		var seqn = 0 ;
		while(len >= seqn) {
			var nextTag = arguments[seqn];
			if (obj != null) {
				var objs = obj.getElementsByTagName(nextTag);
				if (objs.length > 0)
					obj = objs[0];
				else
					obj = null;
				seqn++;
			}
		}
		if (obj != null)
			return new cafen.xmlParser.node(obj);
		else
			return null;
	},
	getAttribute : function(name) {
		return this.feed.getAttribute(name);	
	},
	getInt : function(name) {
		return parseInt(this.getAttribute(name));
	},
	get : function(name) {
		return this.getAttribute(name);
	}
}

/**
 * xml 오류 채널
 * @class xml 오류 채널 통제
 * @constructor 
 * @param {object} options 오류 Object
 */
cafen.xmlParser.Error = function(options) {
	this.initError(options);	
};
cafen.xmlParser.Error.prototype = {
	options : {title : '', domain : '', contents : ''},
	initError : function(options) {
		this.options = cafen.extend(this.options, options);
	},
	getNext : function() {
		return null;
	},
	checkMsg : function() {
		return true;
	},
	getMsg : function() {
		return this.options;
	},
	getHTML : function() {
		return this.options.contents;
	}
}

/**
 * xml 채널 통제
 * @class xml 채널 통제
 * @constructor 
 * @param {object} obj 대상 Channel
 * @param {object} items 대상 Item [강제 Item 설정시에만 사용]
 */
cafen.xmlParser.Channel = function(obj, items) {
	this.initChannel(obj, items);	
};
cafen.xmlParser.Channel.prototype = {
	initChannel : function(obj, items) {
		this.channel = obj;
		this.current_no = 0;
		if (items != null)
			this.items = items;
		else {
			this.setItemTag('item');
		}
	},
/**
 * 특정 조건을 만족하는 Item 가져오기
 * @param {function} func 조건 함수
 * @return {cafen.xmlParser.Channel}
 */
	findAll : function(func) {
		this.current_no = 0;
		var result = [];
		for(var i = 0; i < this.items.length; i++) {
			var item = new cafen.xmlParser.Channel(null,this.items[i]);
			if (func(item)) result.push(item);
		}
		return new cafen.xmlParser.Channel(null,result);
	},
/**
 * 특정 Node 명을 가진 첫번째 객체 가져오기
 * @param {object} nodeName Node 명
 * @return {object} node Object
 */
	getNode : function(nodeName) {
		var nodeValue = cafen.getFirstChildNode(this.channel,nodeName);
		return (nodeValue) ? nodeValue : '';
	},
	getJson : function(maxLength) {
		var jsonData = {};
		maxLength = maxLength || 0;
		for(var i = 0 ; i < this.channel.childNodes.length ;  i++) {
			var currNode = this.channel.childNodes[i];
			var nodeName = 	currNode.nodeName;
			var nodeValue = (currNode !=null && currNode.firstChild.nodeValue) ? currNode.firstChild.nodeValue : '';
			jsonData[nodeName] = (maxLength > 0) ? cafen.longCut(nodeValue, maxLength) : nodeValue;
		}
		return jsonData;
	},
	getAttribute : function(attr) {
		return this.channel.getAttribute(attr);
	},
/**
 * 특정 Node 명을 가진 첫번째 객체 가져오기
 * @param {object} nodeName Node 명
 * @return {object} node Object
 */
	getChannel : function(nodeName) {
		var nodeValue = cafen.getChildrenByTagName(this.channel,nodeName);
		if (nodeValue) 
			return new cafen.xmlParser.Channel(nodeValue);
		else 
			return null;
	},
/**
 * 메세지 여부 확인
 * @return {boolean}
 */
	checkMsg : function() {
		return (this.getNode('servermsg') == '') ? false : true;
	},
/**
 * 메세지 가져오기
 * @return {object} {title:제목, domain : 도메인 , contents : 메세지}
 */
	getMsg : function() {
		var msg = this.getNode('servermsg');
		var msginfo = msg.split('|');
		return {title : msginfo[0], domain : msginfo[1], contents : msginfo[2]}
	},
/**
 * 특정 번째의 Item 가져오기
 * @param {int} no 순번
 * @return {cafen.xmlParser.item}
 */
	getItem : function(no) {
		if (this.getItems().length > no) 
			return new cafen.xmlParser.Channel(this.items[no]);
		else
			return null
	},
	setItemTag : function(tagName) {
		this.items = [];
		for(var i = 0 ; i < this.channel.childNodes.length; i++)
			if (this.channel.childNodes[i].tagName == tagName)
				this.items.push(this.channel.childNodes[i]);
	},
/**
 * 다음 Item 가져오기
 * @return {cafen.xmlParser.item}
 */
	getNext : function() {
		var item = this.getItem(this.current_no);
		if (item) {
			this.current_no++;
			return item;
		} else 
			return null
	},
/**
 * 전체 Item 가져오기
 * @return {array}
 */
	getItems : function() {
		return this.items;
	},
/**
 * 페이지 정보 가져오기
 * @param {int} current_no 현재 번호
 * @param {int} ppage 페이지당 표시수
 * @return {object} {cline : 현재번호,total : 전체수,page : 현재페이지,pages : 전체페이지,start : 시작 시점,end : 마지막시점}
 */
	getPage : function (current_no, ppage) {
		if (current_no != undefined) 
			this.current_no = current_no;
		else 
			current_no = this.current_no;
		var total = this.getItems().length;
		if (current_no > total) 
			this.current_no = current_no = total;
		var start_line = (total > current_no)?current_no:0;
		var end_line = (total > start_line + ppage)?start_line + ppage:total;
		var curr_page = parseInt(start_line/ppage) + 1;
		var total_page = Math.ceil(total/ppage);
		return {
			cline : current_no,
			total : total,
			page : curr_page,
			pages : total_page,
			start : start_line,
			end : end_line
		}
	},
/**
 * 현재 channel 을 Object 형으로 가져오기
 * @return {object} Object
 */
	getObject : function() {
		var result_obj = null;
		var rsstype = this.getNode('rsstype');
		var description = this.getNode('description');
		switch(rsstype) {
			case 'html' : 	
			case 'text' : 	
				result_obj = document.createElement('div');
				this.setStyle(result_obj, {width:'100%',border:'1px solid #464646',padding:'3px'});
				if (rsstype == 'html')
					result_obj.innerHTML = description
				else {
					description = description.replace(/\r/g, '');
					description = description.replace(/\n/g, '<br>');
					result_obj.innerHTML = description;
				}
				break;
			case 'object' : 	
					try {
						eval('var testevalfunc = function(){' +description+ '} ');
						result_obj = testevalfunc();
					} catch(ex) {}
				break;
				
		}
		return result_obj;
	}
}


cafen.Ajax_basexmlurl = '/BLOGJS/UPLOAD_SRC/upload_fileswf.php';

/**
 * Ajax 통신
 * @class Ajax 통신
 * @constructor 
 * @param {object} send_data 전송할 데이타 {}
 * @param {function} call_back 전송완료시 호출 함수
 * @param {string} base_url 호출 프로그램 URL
 * @param {string} xml_method 호출 Method [get|post]
 */
cafen.Ajax = function(send_data, call_back, base_url, xml_method) {
	this.initAjax(send_data, call_back, base_url, xml_method);
};

cafen.Ajax.prototype = {
	initAjax : function(send_data, call_back, base_url, xml_method) {
		try {		
		if (typeof send_data.domain == 'undefined')
			send_data.domain = document.domain;
		} catch(ex) {}
		if (xml_method == undefined)
			xml_method = 'post';
		if (typeof base_url == 'undefined' || base_url == null || base_url == '') 
			base_url = cafen.Ajax_basexmlurl;
		send_data = send_data || {};
		if (send_data.requestType == null)
			send_data.requestType = 'xmlResult';
		this.base_url = base_url;
		if (typeof call_back == 'function') {
			this.call_back  = call_back;
			this.obj = new cafenAjax.Ajax(base_url, {params :send_data, method : xml_method, onLoad : this.onComplete.bind(this), onError: this.onFailure.bind(this)});
		} else {

		}
	},
/**
 * 완료
 * @param {object} response 호출 결과
 */
	onComplete : function(response) {
		if (response.res
