Array.prototype.copy=function() {
	var ret=new Array(this.length);
	for(i=0;i<this.length;i++) {
		var obj=this[i];
		if (obj instanceof Array) ret[i]=this[i].copy();
		else ret[i]=obj;
	}
	return ret;
};
String.prototype.setParameter=function(name,value) {
	var regexp=new RegExp('\\{\\$'+name+'\\}','gm');
	return this.replace(regexp, value);
};
String.prototype.bytecut=function(maxlen,encoding) {
	encoding=encoding.toLocaleLowerCase();
	var mbl=(encoding=='utf-8')?3:2;
	var len=0;
	var strlen=this.length;
	var ret='';
  for(var i=0;i<strlen;i++) {
      var c=this.charAt(i);
      if (escape(c).length>4) len+=mbl;
      else len++;
      if (len<=maxlen) ret+=c;
      else break;
  }
  return ret;
};
String.prototype.bytelen=function(encoding) {
	encoding=encoding.toLocaleLowerCase();
	var mbl=(encoding=='utf-8')?3:2;
	var len=0;
	var strlen=this.length;
  for(var i=0;i<strlen;i++) {
      var c=this.charAt(i);
      if (escape(c).length>4) len+=mbl;
      else len++;
  }
  return len;
};
var _swaf_g_trim_regexp=/(^\s*)|(\s*$)/g;
String.prototype.trim=function() {
   return this.replace(_swaf_g_trim_regexp,'');
};
Number.prototype.toStringFixedLen=function(len) {
	var tmp='000000000000'+this;
	return tmp.substr(tmp.length-len,len);
};

var Swaf={
author:'reizes',
license:'SK Communications co.ltd.',
version:'0.98',
build:'0610',
// 2006.11.5
instanceCache:null,
pushInstance:function(inst) {
	if (!this.instanceCache) this.instanceCache=new Array();
	this.instanceCache.push(inst);
	return this.instanceCache.length-1;
},
linkInstance:function(elid,cacheId) {
	var instnum,strtmp;
	var el=document.getElementById(elid);
	if (el) {
		strtmp=el.getAttribute('swaf_system:SwafInstanceNum');
		if (strtmp) instnum=parseInt(strtmp,10);
		else instnum=0;
		el.setAttribute('swaf_system:SwafInstance'+instnum,cacheId);
		el.setAttribute('swaf_system:SwafInstanceNum',instnum+1);
	}
	el=null;
},
unlinkInstance:function(element) {
	var i,stri,num;
	if (element.getAttribute==undefined) return null;
	stri=element.getAttribute('swaf_system:SwafInstanceNum');
	if (stri) {
		var ret=[];
		num=parseInt(stri,10);
		for(i=0;i<num;i++) {
			stri=element.getAttribute('swaf_system:SwafInstance'+i);
			if (stri) {
				this.instanceCache[parseInt(stri,10)]=null;
			}
			element.removeAttribute('swaf_system:SwafInstance'+i);
		}
		element.removeAttribute('swaf_system:SwafInstanceNum');
	} else {
		stri=element.getAttribute('swaf_system:SwafInstance');
		if (stri) {
			element.removeAttribute('swaf_system:SwafInstance');
			this.instanceCache[parseInt(stri,10)]=null;
		}
	}
	element=null;
},
getInstance:function(element) {
	var i,stri,num;
	if (element.getAttribute==undefined) return null;
	stri=element.getAttribute('swaf_system:SwafInstanceNum');
	if (stri) {
		var ret=[];
		num=parseInt(stri,10);
		for(i=0;i<num;i++) {
			stri=element.getAttribute('swaf_system:SwafInstance'+i);
			if (stri) {
				ret.push(this.instanceCache[parseInt(stri,10)]);
			}
		}
		element=null;
		if (ret.length==1) return ret[0];
		return ret;
	}
	stri=element.getAttribute('swaf_system:SwafInstance');
	if (stri) {
		element=null;
		return this.instanceCache[parseInt(stri,10)];
	}
	element=null;
	return null;
},
removeAllInstance:function() {
	for (var i=0;i<this.instanceCache.length;i++) {
		if (this.instanceCache[i]&&this.instanceCache[i].onDestroy) this.instanceCache[i].onDestroy.call(this.instanceCache[i]);
		this.instanceCache[i]=null;
	}
	delete this.instanceCache;
	this.instanceCache=null;
}
};
var _i$a=new Array();
var _i$$o={};
$include=function(url,once,id,pw) {
	
	var bonce=(once==undefined)?true:once;
	
	if (bonce && _i$$o[url]!=undefined) return;		// already included
	
	var msxmlProgId=["MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"];

	var xhr = null;
	try
	{
		if (window.XMLHttpRequest) xhr = new XMLHttpRequest();
		else if (window.ActiveXObject)
		{
			for (var i = 0; !xhr && i < msxmlProgId.length; i++)
			{
				try { 
					xhr = new ActiveXObject(msxmlProgId[i]); 
				} catch (e) 
				{ 
					xhr = null; 
					msxmlProgId.splice(i, 1);	// ���� ���ϴ� object ���� (���� �ӵ��� ����)
				}
			} // for
		} // else
	}
	catch (e) { 
		return false;
	}
	
		xhr.open('get',url,false,id,pw);
		if (xhr.overrideMimeType) xhr.setRequestHeader('Connection','close');	// Mozilla Bugzilla #246651 ����
		xhr.send(null);
		
		if (xhr.getResponseHeader('Content-type')=='application/x-javascript') {
			var text=xhr.responseText;
			if (text) {
				_i$$o[url]=true;
				_i$a.push(text);
			}
			else return false;
			return true;
		}
		return false;
};

$dec=function(str) {
	var word=[
		/F\$/g,'for',
		/V\$/g,'var',
		/L\$/g,'length',
		/E\$/g,'eval',
		/#/g,' ',
		/@/g,');',
		/&/g,'};'
	];
	var ret=str;
	for (var i=0;i<word.length;i+=2) {
		ret=ret.replace(word[i],word[i+1]);
	}
	return ret;
};

// SWAF Window Global Storage
Swaf.globalStorage={
	storage:{},
	nameCache:{},
	window:window,
	opener:null,
	enableOpener:false,
	get:function(name) {
		if (this.window) {
			return this.window.Swaf.globalStorage.storage[name];
		}
		if (this.enableOpener && this.opener) {
			return this.opener.Swaf.globalStorage.get(name);
		}
		return null;
	},
	create:function(name,deleteOnUnload) {
		var ret=this.get(name);
		if (!ret) {
			ret=this.window.Swaf.globalStorage.storage[name]={};
			if (!ret && this.enableOpener && this.opener) {
				ret=this.opener.Swaf.globalStorage.create(name);
			}
		}
		if (ret) this.nameCache[name]=(deleteOnUnload==undefined)?true:deleteOnUnload;
		return ret;
	},
	remove:function(name,removeMine) {
		if (removeMine==true) {
			if (this.nameCache[name]!=true && this.nameCache[name]!=false) return;
		}
		if (this.window.Swaf.globalStorage.storage[name]) this.window.Swaf.globalStorage.storage[name]=null;
		else if (this.enableOpener && this.opener) {
			this.opener.Swaf.globalStorage.remove(name);
		}
		this.nameCache[name]=null;
	},
	unload:function() {
		if (this.nameCache) {
			for(selector in this.nameCache) {
				if (this.nameCache[selector]==true) {
					this.window.Swaf.globalStorage.storage[name]=null;
				}
			}
		}
	},
	$:function() {
	  return this.window.$frame.apply(this.window,arguments);
	}
};

{
	var win=window;
	for(;win.parent;win=win.parent) {
		try {
			if (!win.parent.document || win.parent.document.body==null || !win.parent.Swaf) break;
		} catch(e) { break;}
		if (win.parent.document.body.tagName!='BODY') break;
		if (window.top==win) break;
	}
	Swaf.globalStorage.window=win;
  Swaf.globalStorage.opener=Swaf.globalStorage.window.opener;

  if (window.addEventListener) {
    window.addEventListener('unload', Swaf.globalStorage.unload, false);
  } else if (window.attachEvent) {
    window.attachEvent('onunload', Swaf.globalStorage.unload);
  }
}

var _c2dev = false;

/*Object.prototype.getSwaf=function() {
	var stri=this.getAttribute('swaf_system:SwafInstance');
	if (stri) {
		return Swaf.getInstance(parseInt(stri,10));
	}
	return null;
};*/

Swaf.Base = Class.create();
Object.extend(Swaf.Base.prototype, {
	classname:'Swaf.Base',
	id:null,
//	element:null,
	// cache attribute
	cacheIndex:-1,
	// factory attribute
	factoryId:null,
	contextId:null,
	bSingleton:true,
	exceptionProcessor:null,
	initialize:function() {
		args=$A(arguments);
		if (this.init) this.init.apply(this,args);
		this.cacheIndex=Swaf.pushInstance(this);
	},
	isClass:function(classname) { return (classname==this.classname);},
	getClass:function() {return this.classname;},
	getElementId:function() {return this.id;},
	setElementId:function(strId) {
		//var el=document.getElementById(strId);
		this.id=strId;
//		this.element=$(strId);
		Swaf.linkInstance(strId,this.cacheIndex);
//		if (el) el.setAttribute('swaf_system:SwafInstance',this.cacheIndex);
		if (this.cbAfterSetElement) this.cbAfterSetElement();
//		this.element.getSwaf=(function() {return this.SwafInstance;}).bind(this.element);	// 2006.10.26
//		el=null;
	},
	getElement:function() {return document.getElementById(this.id);},
	setFactoryId:function(strId) {this.factoryId=strId;},
	getFactoryId:function() {return this.factoryId;},
	getContextId:function() {return this.contextId;},
	setExceptionProcessor:function(processor) {
		this.exceptionProcessor=processor;
		processor.setOwner(this);
	},
	getExceptionProcessor:function() {return this.exceptionProcessor;},
	isSingleton:function() {return this.bSingleton;},
	evalScript:function(script) {return eval(script);},
	
	getSetter:function(obj,property) {
		var setter,setterName;
		var firstchar=property.substr(0,1);
		firstchar=firstchar.toUpperCase();
		setterName='set'+firstchar+property.substr(1,property.length-1);
		setter=obj[setterName];
		return setter;
	},
	getGetter:function(obj,property) {
		var setter,setterName;
		var firstchar=property.substr(0,1);
		firstchar=firstchar.toUpperCase();
		setterName='get'+firstchar+property.substr(1,property.length-1);
		setter=obj[setterName];
		return setter;
	},
	getProperty:function(property) {
		var getter=this.getGetter(this,property);
		if (getter) return getter.call(this);
		else {
			alert('class '+this.classname+' property '+property+' not implemented getter method');
		}
		return null;
	},
	setProperty:function(property,value) {
		var setter=this.getSetter(this,property);
		if (setter) setter.call(this,value);
		else {
			alert('class '+this.classname+' property '+property+' not implemented setter method');
		}
	}
});


	// Swaf.UTIL
	Swaf.Util = {
		/* API Interface */
		isSwaf:function(obj) {
			return (obj && typeof obj=='object' && obj.isClass);
		},
		toArray:function(obj) {
			if (typeof obj == 'string' || obj.length==undefined) {
				var ret=new Array();
				ret.push(obj);
				return ret;
			}
			return obj;
		},
		ptInRect:function(x,y,rx,ry,rwidth,rheight) {
			return (x>=rx && x<=(rx+rwidth) && y>=ry && y<=(ry+rheight));
		},
		getIntersect:function(rect1,rect2) {
			var x1,y1,x2,y2;
			x1=Math.max(rect1.x,rect2.x);
			y1=Math.max(rect1.y,rect2.y);
			x2=Math.min(rect1.x+rect1.width,rect2.x+rect2.width);
			y2=Math.min(rect1.y+rect1.height,rect2.y+rect2.height);
			if (y2>y1 && x2>x1) {
				return {x:x1,y:y1,width:x2-x1,height:y2-y1};
			}
			return null;
		},
		getUnion:function(rect1,rect2) {
			var x1,y1,x2,y2;
			x1=Math.min(rect1.x,rect2.x);
			y1=Math.min(rect1.y,rect2.y);
			x2=Math.max(rect1.x+rect1.width,rect2.x+rect2.width);
			y2=Math.max(rect1.y+rect1.height,rect2.y+rect2.height);
			return {x:x1,y:y1,width:x2-x1,height:y2-y1};
		},
		dumpObject:function(obj,separator) {
			var msg='';
			for (selector in obj) {
				msg+=selector+' : '+obj[selector]+separator;
			}
			return msg;
		},
		debugMsg:'',
		outputDebug:function(msg) {
			if (_c2dev!=true) return;
			var el=document.getElementById('SwafDebugMessageLayer');
			if (!el) {
				el=document.createElement('div');
				el.id='SwafDebugMessageLayer';
				el.style.position='absolute';
				el.style.left='0px';
				el.style.top='0px';
				el.style.background='white';
				el.style.border='1px solid red';
				el.style.zIndex=9999;
				el.style.width='35px';
				el.style.height='15px';
				el.style.overflow='hidden';
				el.dragMode=false;
				document.body.appendChild(el);
				el.innerHTML='<table width="100%" border="0" cellspacing="0" cellpadding="0" id="SwafDebugMessageTable"><tr style="height:15px;background:#ff0000;font-weight:600;">\
				<td><a onclick="Swaf.Dom.setSize($(\'SwafDebugMessageLayer\'),500,350);$(\'SwafDebugMessageLayer\').style.overflow=\'scroll\';" style="cursor:pointer;">VIEW</a>&nbsp;<a onclick="Swaf.Dom.setSize($(\'SwafDebugMessageLayer\'),35,15);$(\'SwafDebugMessageLayer\').style.overflow=\'hidden\';" style="cursor:pointer;">MIN</a>&nbsp;<a onclick="$(\'SwafDebugMessageContents\').innerHTML=\'\';Swaf.Util.clearDebug();" style="cursor:pointer;">CLEAR</a></td>\
				</tr><tr><td id="SwafDebugMessageContents"></td></tr></table>';
				Swaf.Dom.setStyle(el,'opacity',0.9);
				var tbl=document.getElementById('SwafDebugMessageTable'); 
				tbl.onmousedown=(function(evt) {
					this.dragMode=true;var pos=Swaf.Dom.getPosition(this);
					this.origOffset={x:Event.pointerX(evt)-pos.x,y:Event.pointerY(evt)-pos.y};
					}).bindAsEventListener(el);
				tbl.onmouseup=(function(evt) {
					this.dragMode=false;
				}).bindAsEventListener(el);
				tbl.onmouseout=(function(evt) {
					this.dragMode=false;
				}).bindAsEventListener(el);
				tbl.onmousemove=(function(evt) {
					if (this.dragMode==true) Swaf.Dom.setPosition(this,Event.pointerX(evt)-this.origOffset.x,Event.pointerY(evt)-this.origOffset.y);}).bindAsEventListener(el);
				tbl=null;
			}
			this.debugMsg+=msg;
			document.getElementById('SwafDebugMessageContents').innerHTML=this.debugMsg;
			el=null;
		},
		outputDebugLn:function(msg) {
			//alert(msg);
			this.outputDebug(msg+'<br>');
		},
		clearDebug:function() {
			this.debugMsg='';
		}
	};
	
	Swaf.Util.Point = Class.create();
	Object.extend(Swaf.Util.Point.prototype, Swaf.Base.prototype);
	Object.extend(Swaf.Util.Point.prototype, {
		classname:'Swaf.Util.Point',
		/* API Interface */
		x:0,
		y:0,
		init:function(x,y) {
			if (arguments.length>0) {
				this.x=x;
				this.y=y;
			}
		},
		applyConstraint:function(rect) {	// this가 rect에 포함되도록 position 변경
			var bRet=false;
			if (this.x<rect.x1) { this.x=rect.x1; bRet=true;}
			else if (this.x>rect.x2) { this.x=rect.x2; bRet=true;}
			if (this.y<rect.y1) { this.y=rect.y1;  bRet=true;}
			else if (this.y>rect.y2) { this.y=rect.y2; bRet=true;}
			return bRet;
		},
		move:function(dx,dy) {
			this.x+=dx;
			this.y+=dy;
		},
		copy:function() {
			return new Swaf.Util.Point(this.x,this.y);
		}
	});

	Swaf.Util.Rect = Class.create();
	Object.extend(Swaf.Util.Rect.prototype, Swaf.Base.prototype);
	Object.extend(Swaf.Util.Rect.prototype, {
		classname:'Swaf.Util.Rect',
		applyConstraint:function(rect,bApplySize) {	// this가 rect에 포함되도록 size 및 position 변경 (bApplySize가 true이면 size를 변경, 아니면 position을 변경)
			if (this.Width>=rect.Width) {
				if (bApplySize) {
					this.x1=rect.x1;
					this.x2=rect.x2;
					this.Width=rect.Width;
				}
			} else {
				if (bApplySize) {
					if (this.x1<rect.x1) { this.x1=rect.x1;}
					if (this.x2>rect.x2) { this.x2=rect.x2;}
					this.Width=this.x2-this.x1;
				}
				else {
					if (this.x1<rect.x1) { this.x1=rect.x1; this.x2=this.x1+this.Width;}
					if (this.x2>rect.x2) { this.x2=rect.x2; this.x1=this.x2-this.Width;}
				}
			}
			if (this.Height>=rect.Height) {
				if (bApplySize) {
					this.y1=rect.y1;
					this.y2=rect.y2;
					this.Height=rect.Height;
				}
			} else {
				if (bApplySize) {
					if (this.y1<rect.y1) { this.y1=rect.y1;}
					if (this.y2>rect.y2) { this.y2=rect.y2;}
					this.Height=this.y2-this.y1;
				}
				else {
					if (this.y1<rect.y1) { this.y1=rect.y1; this.y2=this.y1+this.Height;}
					if (this.y2>rect.y2) { this.y2=rect.y2; this.y1=this.y2-this.Height;}
				}
			}
			return this;
		},
		applyMinSizeConstraint:function(w,h) {	// this의 사이즈가 최소한 w,h만큼은 되도록 조정
			if (this.Width<w) { this.Width=w; this.x2=this.x1+w;}
			if (this.Height<h) { this.Height=h; this.y2=this.y1+h;}
			return this;
		},
		/* API Interface */
		x1:0,
		y1:0,
		x2:0,
		y2:0,
		Width:0,
		Height:0,
		init:function(x,y,w,h) {
			if (arguments.length>0) {
				this.x1=x;
				this.y1=y;
				this.Width=w;
				this.Height=h;
				this.x2=x+w;
				this.y2=y+h;
			}
		},
		setCoord:function(x1,y1,x2,y2) {
			this.x1=Math.min(x1,x2);
			this.y1=Math.min(y1,y2);
			this.x2=Math.max(x1,x2);
			this.y2=Math.max(y1,y2);
			this.Width=this.x2-this.x1;
			this.Height=this.y2-this.y1;
			return this;
		},
		setRect:function(x,y,w,h) {
			this.x1=x;
			this.y1=y;
			this.Width=w;
			this.Height=h;
			this.x2=x+w;
			this.y2=y+h;
			return this;
		},
		setSize:function(w,h) {
			this.Width=w;
			this.Height=h;
			this.x2=this.x1+w;
			this.y2=this.y1+h;
			return this;
		},
		setPosition:function(x,y) {
			this.x1=x;
			this.y1=y;
			this.x2=x+this.Width;
			this.y2=y+this.Height;
			return this;
		},
		move:function(dx,dy) {
			this.x1+=dx;
			this.y1+=dy;
			this.x2+=dx;
			this.y2+=dy;
			return this;
		},
		union:function(rect) {
			var ret=new Swaf.Util.Rect();
			ret.setCoord(
				Math.min(this.x1,rect.x1),
				Math.min(this.y1,rect.y1),
				Math.max(this.x2,rect.x2),
				Math.max(this.y2,rect.y2));
			return ret;
		},
		intersect:function(rect) {
			var ret=new Swaf.Util.Rect();
			var x1,y1,x2,y2;
			x1=Math.max(this.x1,rect.x1);
			y1=Math.max(this.y1,rect.y1);
			x2=Math.min(this.x2,rect.x2);
			y2=Math.min(this.y2,rect.y2);
			ret.setCoord(x1,y1,x2,y2);
			if (y2>y1 && x2>x1) return ret;
			else return null;
		},
		inflate:function(dx,dy) {
			this.x1-=dx;
			this.x2+=dx;
			this.y1-=dy;
			this.y2+=dy;
			this.Width=this.x2-this.x1;
			this.Height=this.y2-this.y1;
			return this;
		},
		getExtent:function() {
			return this.Width*this.Height;
		},
		getCenter:function() {
			return new Swaf.Util.Point(this.x1+this.Width/2,this.y1+this.Height/2);
		},
		ptInRect:function(x,y) {
			return (x>=this.x1 && x<=this.x2 && y>=this.y1 && y<=this.y2);
		},
		isInclude:function(rect) {
			return (this.x1<=rect.x1 && this.x2>=rect.x2 && this.y1<=rect.y1 && this.y2>=rect.y2);
		},
		isIntersect:function(rect) {
			return (this.intersect(rect)!=null);
		},
		copy:function() {
			return new Swaf.Util.Rect(this.x1,this.y1,this.Width,this.Height);
		}
	});
	
	Swaf.Util.Browser = {};
		/* API Interface */
	Swaf.Util.Browser.userAgent=navigator.userAgent.toLowerCase();
	Swaf.Util.Browser.isOpera=(Swaf.Util.Browser.userAgent.indexOf('opera') != -1);
	Swaf.Util.Browser.isSafari=(Swaf.Util.Browser.userAgent.indexOf('safari') != -1);
	Swaf.Util.Browser.isIE=(Swaf.Util.Browser.userAgent.indexOf('msie') != -1 && !Swaf.Util.Browser.isOpera);
	Swaf.Util.Browser.isFF=(Swaf.Util.Browser.userAgent.indexOf('firefox') != -1);
	Swaf.Util.Browser.getVersion=function() {
		var ver,bit,str=navigator.appVersion;
		if (Swaf.Util.Browser.isIE) {
			bit=str.split(';');
			ver=(bit[1].split(' '))[2];
		} else {
			bit=str.split(' ');
			ver=bit[0];
		}
		return parseFloat(ver);
	};
	Swaf.Util.Browser.getStyle=function(element,property) {
          var value = null;
            var dv = document.defaultView;
            if (element.style[property]) {return element.style[property];}
            else if (element.currentStyle && element.currentStyle[property]) { return element.currentStyle[property];}
            else if ( dv && dv.getComputedStyle )
            {
               var converted = '';
               for(var i = 0, len = property.length;i < len; ++i) {
                  if (property.charAt(i) == property.charAt(i).toUpperCase()) 
                  {
                     converted = converted + '-' + property.charAt(i).toLowerCase();
                  } else {
                     converted = converted + property.charAt(i);
                  }
               }
               if (dv.getComputedStyle(element, '') && dv.getComputedStyle(element, '').getPropertyValue(converted)) {
                  value = dv.getComputedStyle(element, '').getPropertyValue(converted);
               }
            }
            return value;
};
Swaf.Util.Browser.getDocumentRect=function() {
	// c2 specific logic
				var heightGetter=document.getElementById('heightGetter');
				var wrap=document.getElementById('wrap');
				if (heightGetter) {
					return Swaf.Dom.getSize(heightGetter);
				} else if (wrap) {
					return Swaf.Dom.getSize(wrap);
				}
				
         var docHeight=-1,winHeight=-1,bodyHeight=-1;
         var docWidth=-1,bodyWidth=-1,winWidth=-1;
         var marginTop = parseInt(this.getStyle(document.body, 'marginTop'), 10);
         marginTop=isNaN(marginTop )?0:marginTop;
         var marginBottom = parseInt(this.getStyle(document.body, 'marginBottom'), 10);
         marginBottom=isNaN(marginBottom )?0:marginBottom;
         var marginRight = parseInt(this.getStyle(document.body, 'marginRight'), 10);
         marginRight=isNaN(marginRight )?0:marginRight;
         var marginLeft = parseInt(this.getStyle(document.body, 'marginLeft'), 10);
         marginLeft=isNaN(marginLeft )?0:marginLeft;
         var mode = document.compatMode;
         if ( (mode || this.isIE) && !this.isOpera ) { // (IE, NS)
            switch (mode) {
               case 'CSS1Compat': 
                  docWidth = document.documentElement.clientWidth;
                  docHeight = ((window.innerHeight && window.scrollMaxY) ?  window.innerHeight+window.scrollMaxY : -1);
                  winWidth = self.innerWidth || -1;
                  winHeight = [document.documentElement.clientHeight,self.innerHeight||-1].sort(function(a, b){return(a-b);})[1];
                  bodyWidth = document.body.offsetWidth + marginLeft + marginRight;
                  bodyHeight = document.body.offsetHeight + marginTop + marginBottom;
                  break;
               
               default: 
                  winWidth = document.body.scrollWidth;
                  winHeight= document.body.scrollHeight;
                  //docHeight = document.body.docHeight;
                  bodyWidth = document.body.clientWidth;
                  bodyHeight = document.body.clientHeight;
                  break;
            }
         } else { // Safari & Opera
            winWidth = self.innerWidth;
            winHeight = self.innerHeight;
            docWidth = document.documentElement.clientWidth;
            docHeight = document.documentElement.docHeight;
            bodyWidth = document.body.offsetWidth + marginLeft + marginRight;
            bodyHeight = document.documentElement.clientHeight;
         }
         var w = [docWidth,bodyWidth,winWidth].sort(function(a, b){return(a-b);});
         var h = [docHeight,winHeight,bodyHeight].sort(function(a, b){return(a-b);});
				return {width:w[2],height:h[2]};
	};
	Swaf.Util.Browser.getClientRect=function() {
    var w=-1,h=-1;
		if (self.innerHeight) {	// none IE 
			w=self.innerWidth;
			h=self.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) {	// IE6 strict mode
    	w=document.documentElement.clientWidth;
    	h=document.documentElement.clientHeight;
    } else if (document.body) {	// other IE
    	w=document.body.clientWidth;
    	h=document.body.clientHeight;
    }
    return {width:w,height:h};
	};
	Swaf.Util.Browser.getScrollPosition=function() {
		var x,y;
		if (self.pageYOffset) {	// none IE
			x=self.pageXOffset;
			y=self.pageYOffset;
		} else if (document.documentElement && document.documentElement.scrollTop) {	// IE6 strict
			x=document.documentElement.scrollLeft;
			y=document.documentElement.scrollTop;
		} else if (document.body) {	// other IE
			x=document.body.scrollLeft;
			y=document.body.scrollTop;
		}
		return {x:x,y:y};
	};
	Swaf.Util.Browser.getWindowPosition=function() {
		var x,y;
		if (window.screenLeft) {
			x=window.screenLeft;
			y=window.screenTop;
		} else if (window.screenX){
			x=window.screenX;
			y=window.screenY;
		} else {
			x=0;
			y=0;
		}
		return {x:x,y:y};
	};

// 2006.12.05
Swaf.Util.getBytes=function() {
            for(var i=0;i<text.length;i++) {
                c=text.charAt(i);
                if (escape(c).length>4) len+=2;
                else len++;
                if (len<20) ret+=c;
                else break;
            }
};
// 2007.2.13
Swaf.Util.loadWebFont=function(faceName,src) {
	var head=document.getElementsByTagName("head");
	if (head) {
		var linkel=document.createElement('link');
		linkel.setAttribute('href', '/js/swaf/loadWebFont.php?face='+encodeURIComponent(faceName)+'&src='+encodeURIComponent(src));
		linkel.setAttribute('rel', 'stylesheet');
		linkel.setAttribute('type', 'text/css');
		head[0].appendChild(linkel);
	}
	head=null;
};
	Swaf.Dom = Class.create();
	Object.extend(Swaf.Dom, Swaf.Base.prototype);

		/* API Interface */
	Swaf.Dom.setCSSClass=function(element,className) {
		var classname=Element.classNames(element);
		classname.set(className);
	};
	Swaf.Dom.addCSSClass=function(element,className) {
		var classname=Element.classNames(element);
		classname.add(className);
	};
	Swaf.Dom.removeCSSClass=function(element,className) {
		var classname=Element.classNames(element);
		classname.remove(className);
	};
	Swaf.Dom.setStyle=function(element,property,value) {
		if (property=='opacity') {
			if (Swaf.Util.Browser.isIE && typeof element.style.filter == 'string') {
				element.style.filter = 'alpha(opacity=' + (value*100) + ')';
				if (!element.currentStyle || !element.currentStyle.hasLayout) {element.style.zoom = 1;}
			} else {
				element.style.opacity = value;
			  element.style['-moz-opacity'] = value;
			  element.style['-khtml-opacity'] = value;
			}
		} else {
			element.style[property] = value;
		}
	  element=null;
	};
	Swaf.Dom.getStyle=function(element,property) {
          var value = null;
            var dv = document.defaultView;
            if (property == 'opacity' && Swaf.Util.Browser.isIE/*element.filters*/) 	// IE
            {
               value = 1;
               try {
                  value = element.filters.item('DXImageTransform.Microsoft.Alpha').opacity;
               } catch(e) {
                  try {
                     value = element.filters.item('alpha').opacity/100;
                  } catch(e) {}
               }
            }
            else if (element.style[property]) {return element.style[property];}
            else if (element.currentStyle && element.currentStyle[property]) { return element.currentStyle[property];}
            else if ( dv && dv.getComputedStyle )
            {
               var converted = '';
               for(var i = 0, len = property.length;i < len; ++i) {
                  if (property.charAt(i) == property.charAt(i).toUpperCase()) 
                  {
                     converted = converted + '-' + property.charAt(i).toLowerCase();
                  } else {
                     converted = converted + property.charAt(i);
                  }
               }
               if (dv.getComputedStyle(element, '') && dv.getComputedStyle(element, '').getPropertyValue(converted)) {
                  value = dv.getComputedStyle(element, '').getPropertyValue(converted);
               }
            }
            element=null;
            return value;
	};
	Swaf.Dom.setPosition=function(element,x,y,parentElement) {
			var pos=this.getStyle(element,'position');
			var relative=(pos=='relative');
			var position=this.getPosition(element);
			var dx=parseInt(element.style.left,10);
			var dy=parseInt(element.style.top,10);
			if (isNaN(dx)) {dx=(relative)?0:element.offsetLeft;}
			if (isNaN(dy)) {dy=(relative)?0:element.offsetTop;}
			if (parentElement) {
				var ppos=this.getPosition(parentElement);
				dx+=ppos.x;
				dy+=ppos.y;
				parentElement=null;
			}
			position.x=x-position.x+dx;
			position.y=y-position.y+dy;

			element.style.left = position.x+'px';
			element.style.top = position.y+'px';
			element=null;
	};
	Swaf.Dom.getPosition=function(element,parentElement) {
            var parent = null;
            var pos = {x:0,y:0};
            
            if (element.getBoundingClientRect) { // IE
               var rect = element.getBoundingClientRect();
               pos.x=rect.left + Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
               pos.y=rect.top + Math.max(document.documentElement.scrollTop, document.body.scrollTop);
               rect=null;
            }
            else if (document.getBoxObjectFor) { // FF
               var rect = document.getBoxObjectFor(element);
//               pos = {x:rect.x - parseInt(Swaf.Dom.getStyle(element,'borderLeftWidth')), y:rect.y - parseInt(Swaf.Dom.getStyle(element,'borderTopWidth'))};
               pos = {x:rect.x, y:rect.y};
               rect=null;

	            if (element.parentNode) { parent = element.parentNode; }
  	          else { parent = null; }
      
    	        while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML') 
      	      {
        	       pos.x -= parent.scrollLeft;
          	     pos.y -= parent.scrollTop;
      
	               if (parent.parentNode) { parent = parent.parentNode; } 
  	             else { parent = null; }
    	        }
           }
            else { // opera
               pos = {x:element.offsetLeft, y:element.offsetTop};
               parent = element.offsetParent;
               if (parent != element) {
                  while (parent) {
                     pos.x += parent.offsetLeft;
                     pos.y += parent.offsetTop;
                     parent = parent.offsetParent;
                  }
               }
               if (Swaf.Util.Browser.isOpera||( Swaf.Util.Browser.isSafari && element.style.position == 'absolute')) {
                  pos.x -= document.body.offsetLeft;
                  pos.y -= document.body.offsetTop;
               } 
            }
            
			if (parentElement) {
				var ppos=this.getPosition(parentElement);
				pos.x-=ppos.x;
				pos.y-=ppos.y;
				parentElement=null;
				ppos=null;
			}
			element=null;
			parent=null;
			return {x:isNaN(pos.x)?0:pos.x,y:isNaN(pos.y)?0:pos.y};
	};
	Swaf.Dom.setWidth=function(element,w) {
		element.style.width=w+'px';
	};
	Swaf.Dom.setHeight=function(element,h) {
		element.style.height=h+'px';
	};
	Swaf.Dom.getWidth=function(element) {
		return element.offsetWidth;;
	};
	Swaf.Dom.getHeight=function(element) {
		return element.offsetHeight;
	};
	Swaf.Dom.setSize=function(element,w,h) {
		var els=element.style;
		els.width=w+'px';
		els.height=h+'px';
		els=null;
	};
	Swaf.Dom.getSize=function(element) {
		w=element.offsetWidth;
		h=element.offsetHeight;
		return {width:w,height:h};
	};
	Swaf.Dom.setRect=function(element,x,y,width,height,parentElement) {
		this.setPosition(element,x,y,parentElement);
		this.setSize(element,width,height);
		element=null;
	};
	Swaf.Dom.getRect=function(element,parentElement) {
		var pos=this.getPosition(element,parentElement);
		var size=this.getSize(element);
		element=null;
    return {x:pos.x,y:pos.y,width:size.width,height:size.height};
	};
	Swaf.Dom.getBorderWidth=function(element) {
		var l,t,r,b;
		l=parseInt(Swaf.Dom.getStyle(element,'borderLeftWidth'),10);
		t=parseInt(Swaf.Dom.getStyle(element,'borderTopWidth'),10);
		r=parseInt(Swaf.Dom.getStyle(element,'borderRightWidth'),10);
		b=parseInt(Swaf.Dom.getStyle(element,'borderBottomWidth'),10);
		return {left:isNaN(l)?0:l,top:isNaN(t)?0:t,right:isNaN(r)?0:r,bottom:isNaN(b)?0:b};
	};
	Swaf.Dom.getPadding=function(element) {
		var l,t,r,b;
		l=parseInt(Swaf.Dom.getStyle(element,'paddingLeft'),10);
		t=parseInt(Swaf.Dom.getStyle(element,'paddingTop'),10);
		r=parseInt(Swaf.Dom.getStyle(element,'paddingRight'),10);
		b=parseInt(Swaf.Dom.getStyle(element,'paddingBottom'),10);
		return {left:isNaN(l)?0:l,top:isNaN(t)?0:t,right:isNaN(r)?0:r,bottom:isNaN(b)?0:b};
	};
	Swaf.Dom.getMargin=function(element) {
		var l,t,r,b;
		l=parseInt(Swaf.Dom.getStyle(element,'marginLeft'),10);
		t=parseInt(Swaf.Dom.getStyle(element,'marginTop'),10);
		r=parseInt(Swaf.Dom.getStyle(element,'marginRight'),10);
		b=parseInt(Swaf.Dom.getStyle(element,'marginBottom'),10);
		return {left:isNaN(l)?0:l,top:isNaN(t)?0:t,right:isNaN(r)?0:r,bottom:isNaN(b)?0:b};
	};
	Swaf.Dom.fireEvent=function(el,type,evt) {
		if (el.fireEvent) el.fireEvent('on'+type,evt);	// IE
		else if (el.dispatchEvent) {		// FF, NS, Opera ...
			var e;
			// DOM3 Event
			switch(type) {
				case 'focus'	:
				case 'blur'		:
				case 'resize' :
				case 'scroll' :
					e=document.createEvent('UIEvents');
					e.initUIEvent(type,true,true,evt.view,evt.detail);
					break;
				case 'textInput' :
					e=document.createEvent('TextEvent');
					e.initTextEvent(type,true,true,evt.view,evt.detail);			// 함수 정의가 developer.mozilla.org에도 없다. ㅠㅠ
					break;
				case 'click' :
				case 'mousedown' :
				case 'mouseup' :
				case 'mouseover' :
				case 'mousemove' :
				case 'mouseout' :
					e=document.createEvent('MouseEvents');
					e.initMouseEvent(type,true,true,evt.view,evt.detail,evt.screenX,evt.screenY,evt.clientX,evt.clientY,evt.ctrlKey,evt.altKey,evt.shiftKey,evt.metaKey,evt.button,evt.relatedTarget);
					break;
				case 'keydown' :
				case 'keyup' :
					e=document.createEvent('KeyboardEvent');
					e.initKeyboardEvent(type,true,true,evt.view,evt.detail);			// 함수 정의가 developer.mozilla.org에도 없다. ㅠㅠ
					break;
				case 'load' :
				case 'unload' :
				case 'abort' :
				case 'error' :
				case 'select' :
				case 'change' :
				case 'submit' :
				case 'reset' :
					e=document.createEvent('Event');
					e.initEvent(type,true,true);
					break;
				
			}
			el.dispatchEvent(e);
		}
	};
	// 2006.10.11 iframe 관련 지원 추가
	Swaf.Dom.setIFrame=function(element,html) {
		var doc=Swaf.Dom.getIFrameDoc(element);
		doc.open();
		doc.write(html);
		doc.close();
	};
	Swaf.Dom.writeIFrame=function(element,html) {
		var doc=Swaf.Dom.getIFrameDoc(element);
		doc.write(html);
	};
	// 2006.10.13 추가
	Swaf.Dom.getDocumentRect=function(doc) {
         var docHeight=-1,winHeight=-1,bodyHeight=-1;
         var docWidth=-1,bodyWidth=-1,winWidth=-1;
         var marginTop = parseInt(this.getStyle(doc.body, 'marginTop'), 10);
         var marginBottom = parseInt(this.getStyle(doc.body, 'marginBottom'), 10);
         var marginRight = parseInt(this.getStyle(doc.body, 'marginRight'), 10);
         var marginLeft = parseInt(this.getStyle(doc.body, 'marginLeft'), 10);
         var mode = doc.compatMode;
         if ( (mode || this.isIE) && !this.isOpera ) { // (IE, NS)
            switch (mode) {
               case 'CSS1Compat': 
                  docWidth = doc.docElement?doc.docElement.clientWidth:0;
                  docHeight = ((window.innerHeight && window.scrollMaxY) ?  window.innerHeight+window.scrollMaxY : -1);
                  winWidth = self.innerWidth || -1;
                  winHeight = Math.max((doc.docElement)?doc.docElement.clientHeight:0,self.innerHeight||-1);
                  bodyWidth = doc.body.offsetWidth + marginLeft + marginRight;
                  bodyHeight = doc.body.offsetHeight + marginTop + marginBottom;
                  break;
               
               default: 
                  winWidth = doc.body.scrollWidth;
                  winHeight= doc.body.scrollHeight;
                  //docHeight = doc.body.docHeight;
                  bodyWidth = doc.body.clientWidth;
                  bodyHeight = doc.body.clientHeight;
                  break;
            }
         } else { // Safari & Opera
            winWidth = self.innerWidth;
            winHeight = self.innerHeight;
            docWidth = doc.docElement.clientWidth;
            docHeight = doc.docElement.docHeight;
            bodyWidth = doc.body.offsetWidth + marginLeft + marginRight;
            bodyHeight = doc.docElement.clientHeight;
         }
         var w = [docWidth,bodyWidth,winWidth].sort(function(a, b){return(a-b);});
         var h = [docHeight,winHeight,bodyHeight].sort(function(a, b){return(a-b);});
				return {width:w[2],height:h[2]};
	};	
	// 2006.10.13 iframe 추가
	Swaf.Dom.getIFrameDoc=function(element) {
		var doc;
		try {
			if (element.contentWindow) {doc=element.contentWindow.document}	// IE
			else if (element.contentDocument) {doc=element.contentDocument.documentElement}
		} catch(e) {
			doc=null;
		}
	  return doc;
	};
	// iframe의 element 얻기
	$iframe=function(iframe,element) {
		var doc=Swaf.Dom.getIFrameDoc(document.getElementById(iframe));
		
	  var elements = new Array();

	  for (var i = 1; i < arguments.length; i++) {
  	  var element = arguments[i];
  	  var tmpid=element;
    	if (typeof element == 'string')
	      element = doc.getElementById(element);

			if (_c2dev==true) {
		  	if (!element) {
					Swaf.Util.outputDebugLn('Warning : not exist iframe element : '+tmpid);
		  	} else {
		  		if (tmpid!=element.id) Swaf.Util.outputDebugLn('Warning (case) : '+tmpid+' != '+element.id);
		  	}
	  	}
  	  if (arguments.length == 2) 
    	  return element;

	    elements.push(element);
  	}

  return elements;
	};
	
//	var g_$$replace=/##/;
	
	$$=function(elementName,end,stopAtError) {
	  var elements = new Array();
		var i,el;
		var findi=elementName.indexOf('##');
		if (findi==-1) return $(elementName);
		if (end==undefined) end=-1;
		if (end==-1 || stopAtError==undefined) stopAtError=true;
		var pre=elementName.substring(0,findi);
		var post=elementName.substring(findi+2,elementName.length);
		
		for(i=1;;i++) {
			var num=(i<10?'0':'')+i;
			var name=pre+num+post;//elementName.replace(g_$$replace,num);
			el=$(name);
			if (el) {
				elements.push(el);
				el=null;
			}
			else {
				if (stopAtError) break;
			}
			if (end>0 && i==end) break;
		}
		return elements;
	};
	
	$search=function(regexp,root,matchExactly) {
	var id,node,matches;
	var ret=new Array();
	var bMatch=(matchExactly!=undefined)?matchExactly:false;

	root= root || document.body;
	var arr=root.childNodes;
	
	for(var i=0;i<arr.length;i++) {
		node=arr[i];
		if (node.nodeType==1) {	// ELEMENT NODE
			ret=ret.concat($search(regexp,node,bMatch));
		}
		id=node.id;
		if (id==undefined || !id) continue;
		matches=regexp.exec(id);
		if (matches&&matches.length>0) {
			if (bMatch && matches[0]!=id) continue;
			ret.push($(id));
		}
	}
	
	return ret;
};
// 2006.10.16 추가
	Swaf.Dom.showElement=function(element,x,y,parentElement) {
		Swaf.Dom.setStyle(element,'display','block');
		if (x && y) Swaf.Dom.setPosition(element,x,y,parentElement);
	};
	Swaf.Dom.showElementInline=function(element,x,y,parentElement) {
		Swaf.Dom.setStyle(element,'display','inline');
		if (x && y) Swaf.Dom.setPosition(element,x,y,parentElement);
	};
	Swaf.Dom.hideElement=function(element) {
		Swaf.Dom.setStyle(element,'display','none');
	};
	Swaf.Dom.toggleShowElement=function(element,x,y,parentElement) {
		var show=Swaf.Dom.getStyle(element,'display');
		if (show=='none') Swaf.Dom.showElement(element,x,y,parentElement);
		else Swaf.Dom.hideElement(element);
	};

// 2006.10.17 추가
$attr=function(el,attrname) {
	if (el instanceof Array) {
		var ret=new Array();
		for (var i=0;i<el.length;i++) {
			ret.push((el[i])?el[i].getAttribute('swaf:'+attrname):null);
		}
		return ret;
	}
	if (el) return el.getAttribute('swaf:'+attrname);
	return null;
};

// 2006.10.19 추가
Swaf.Dom.getContentsHeight=function(element) {
	return (element.innerHTML)?element.scrollHeight:0;
};
Swaf.Dom.getContentsWidth=function(element) {
	return (element.innerHTML)?element.scrollWidth:0;
};
Swaf.Dom.setStyleObject=function(element,objStyle) {
	for(selector in objStyle) {
		Swaf.Dom.setStyle(element,selector,objStyle[selector]);
	}
};

// 2006.10.24 추가 
Swaf.Dom.setCSS=function(element,css) {
	if (typeof css == 'string') {
		this.setCSSClass(element,css);
	} else {
		this.setStyleObject(element,css);
	}
}

// 2006.11.3 추가
$setattr=function(el,attrname,value) {
	if (el instanceof Array) {
		for (var i=0;i<el.length;i++) {
			if (el[i]) el[i].setAttribute('swaf:'+attrname,value);
		}
	}
	else if (el) el.setAttribute('swaf:'+attrname,value);
};
// 2006.11.3 추가
Swaf.Dom.autoWidthIFrame=function(element,minW,maxW) {
		var doc=Swaf.Dom.getIFrameDoc(element);
		var size=0,w1=0;
		var ret=true;
		if (doc) {
			var heightGetter = doc.getElementById('heightGetter');
			if (heightGetter) {
				w1=Swaf.Dom.getWidth(heightGetter);
				if (typeof minW=='number') w1=(w1<minW)?minW:w1;
				if (typeof maxW=='number') w1=(w1>maxW)?maxW:w1;
				Swaf.Dom.setWidth(element, w1);
			} else {
//				var rect=Swaf.Dom.getDocumentRect(doc);
				var width=doc.body.scrollWidth+(doc.body.offsetWidth-doc.body.clientWidth);
				if (typeof minW=='number') size=(width<minW)?minW:width;
				if (typeof maxW=='number') size=(width>maxW)?maxW:width;
				Swaf.Dom.setWidth(element,size);
			}
			//Swaf.Dom.setWidth(element,Math.max(size,w1));
		} else ret=false;
		element=null;
		return ret;
};
Swaf.Dom.autoHeightIFrame=function(element,minH,maxH) {
		var doc=Swaf.Dom.getIFrameDoc(element);
		var size=0,h1=0;
		var ret=true;
		if (doc) {
			var heightGetter = doc.getElementById('heightGetter');

			if (heightGetter) {
				h1=Swaf.Dom.getHeight(heightGetter);
				if (typeof minH=='number') h1=(h1<minH)?minH:h1;
				if (typeof maxH=='number') h1=(h1>maxH)?maxH:h1;
				Swaf.Dom.setHeight(element, h1);
			} else {
				//var rect=Swaf.Dom.getDocumentRect(doc);
				var height=doc.body.scrollHeight+(doc.body.offsetHeight-doc.body.clientHeight);
				if (typeof minH=='number') size=(height<minH)?minH:height;
				if (typeof maxH=='number') size=(height>maxH)?maxH:height;
				Swaf.Dom.setHeight(element,size);
			}
			//Swaf.Dom.setHeight(element,Math.max(size,h1));
		} else ret=false;
		element=null;
		return ret;
};
	Swaf.Dom.autoResizeIFrame=function(element,minW,minH) {
		var doc=Swaf.Dom.getIFrameDoc(element);
		var w1=0,h1=0,w=0,h=0;
		var ret=true;
		
		if (doc) {
			var heightGetter = doc.getElementById('heightGetter');
			if (heightGetter) {
				var size=Swaf.Dom.getSize(heightGetter);
				w1=size.width;
				h1=size.height;
				Swaf.Dom.setSize(element,(minW!=undefined && minW>0 && minW>w1)?minW:w1,(minH!=undefined && minH>0 && minH>h1)?minH:h1);
			} else {
				//var rect=Swaf.Dom.getDocumentRect(doc);
				w=doc.body.scrollWidth+(doc.body.offsetWidth-doc.body.clientWidth);
				h=doc.body.scrollHeight+(doc.body.offsetHeight-doc.body.clientHeight);
				Swaf.Dom.setSize(element,(minW!=undefined && minW>0 && minW>w)?minW:w,(minH!=undefined && minH>0 && minH>h)?minH:h);
			}
			//Swaf.Dom.setSize(element, Math.max(w1,w),Math.max(h1,h));
		} else ret=false;
		element=null;
		return ret;
	};

//2006.11.4 추가

Swaf.Dom.deleteElement=function(element) {
	try {
		element.innerHTML='';
  } catch(e) {
  }
	try {
    var garbageBin = document.getElementById('IELeakGarbageBin');
    if (!garbageBin) {
        garbageBin = document.createElement('DIV');
        garbageBin.id = 'IELeakGarbageBin';
        garbageBin.style.display = 'none';
        document.body.appendChild(garbageBin);
    }
    // move the element to the garbage bin
    garbageBin.appendChild(element);
    garbageBin.innerHTML = '';
  } catch(e) {
//  	Swaf.Util.outputDebugLn(Swaf.Util.dumpObject(e,'<br>'));
//  	Swaf.Util.outputDebugLn(element.tagName+' ['+element.id+']');
//  	Swaf.Util.outputDebugLn('parent - '+element.parentElement.tagName+' ['+element.parentElement.id+']');
  }
    element=null;
};

//2006.11.8 추가
Swaf.Dom.getCSSRule=function(selectorname) {
		var i,j,msg,selname;
		var css=document.styleSheets;
		var rules,rule;
		selname=selectorname;
		for(i=css.length-1;i>=0;i--) {
			try {
				if (css[i].cssRules) rules=css[i].cssRules;
				else if (css[i].rules) rules=css[i].rules;
			} catch(e) {
				continue;
			}
			for(j=0;j<rules.length;j++) {
				rule=rules[j];
				if (rule.selectorText && rule.selectorText==selname) {
					return rule.style;
				}
			}
		}
		return null;
};

Swaf.Dom.getElementsByClassName = function(className, rootel) {
  var children = (document.getElementById(rootel) || document.body).getElementsByTagName('*');
  var regexp=new RegExp("(^|\\s)" + className + "(\\s|$)");
  var elements=new Array();
  for(var i=0;i<children.length;i++) {
  	var child=children[i];
  	if (child.className.match(regexp)) elements.push(child);
  }
  children=null;
  regexp=null;
	return elements;
}

Swaf.Dom.setStyleByClassname=function(selectorname,styleobj,parentid) {
	var els=Swaf.Dom.getElementsByClassName(selectorname,parentid);
	if (els) {
		for(var i=0;i<els.length;i++) {
			Swaf.Dom.setStyleObject(els[i],styleobj);
		}
	}
	els=null;
};
//11.9 추가
$win=function() {
  var elements = new Array();

  for (var i = 0; i < arguments.length; i++) {
    var element = arguments[i];
    var tmpid=element;
    if (typeof element == 'string') {
      element = document.getElementById(element);
      if (element == null) {
      	if (window.parent) element=window.parent.$win(arguments[i]);
      }
    }
		if (_c2dev==true) {
	  	if (!element) {
				Swaf.Util.outputDebugLn('Warning : not element in $win() : '+tmpid);
	  	} else {
	  		if (tmpid!=element.id) Swaf.Util.outputDebugLn('Warning (case) : '+tmpid+' != '+element.id);
	  	}
	  }
    if (arguments.length == 1)
      return element;

    if (element instanceof Array) elements=elements.concat(element);
    else elements.push(element);
  }

  return elements;
};
// 11.15 추가
Swaf.Dom.getFirstChildNode=function(element) {
	var ELEMENT_NODE=1;
	var node;
	for(node=element.firstChild;node.nodeType!=ELEMENT_NODE;node=node.nextSibling);
	return node;
};
// 11.16 추가
Swaf.Dom.swapNode=function(el1,el2) {
	if (el1.swapNode) {
		el1.swapNode(el2);
	} else {
		var p=el2.parentNode;
		var s=el2.nextSibling;
		el1.parentNode.insertBefore(el2,el1.nextSibling);
		p.insertBefore(el1,s);
	}
};
// 11.23 추가
Swaf.Dom.pointerToRelative=function(x,y,element) {
	var pos={x:x,y:y};
	var ppos=this.getPosition(element);
	pos.x-=ppos.x;
	pos.y-=ppos.y;
	element=null;
	ppos=null;
	return pos;
};
// 12.4 추가
Swaf.Dom.hideSelect=function(element) {
	var arrSelect=element.getElementsByTagName('select');
	for(var i=0;i<arrSelect.length;i++) {
		if (arrSelect[i].style.display=='none') continue;
		arrSelect[i].style.visibility='hidden';
	}
	arrSelect=null;
};
Swaf.Dom.showSelect=function(element) {
	var arrSelect=element.getElementsByTagName('select');
	for(var i=0;i<arrSelect.length;i++) {
		arrSelect[i].style.visibility='visible';
	}
	arrSelect=null;
};
// 12.11 추가
$frame=function() {
  var elements = new Array();
  var findel;
  var arglen=arguments.length;

  for (var i = 0; i < arglen; i++) {
    var element = arguments[i];
    var tmpid=element;
    if (typeof element == 'string') {
    	findel = document.getElementById(element);
    	if (findel) {
	    	if (arglen == 1) return findel;
		    elements.push(findel);
		  } else {
	      for(var j=0;j<window.frames.length;j++) {
	      	try {
	      		var fn=window.frames[j].$frame;
	      	} catch(e) { continue; }
	      	if (!fn) continue;
	      	findel = fn(element);
	      	if (findel) {
	      		if (tmpid!=findel.id) Swaf.Util.outputDebugLn('Warning (case) : '+tmpid+' != '+findel.id);
				    if (arglen== 1) return findel;
				    elements.push(findel);
				  } else {
							Swaf.Util.outputDebugLn('Warning : not element in $frame() : '+tmpid);
				  }
	      }
	      var iframes=document.body.getElementsByTagName('iframe');
	      for(var j=0;j<window.frames.length;j++) {
	      	try {
	      		var fn=Swaf.Dom.getIFrameWindow(iframes[j]).$frame;
	      	} catch(e) { continue; }
	      	if (!fn) continue;
	      	findel = fn(element);
	      	if (findel) {
	      		if (tmpid!=findel.id) Swaf.Util.outputDebugLn('Warning (case) : '+tmpid+' != '+findel.id);
				    if (arglen== 1) return findel;
				    elements.push(findel);
				  } else {
							Swaf.Util.outputDebugLn('Warning : not element in $frame() : '+tmpid);
				  }
	      }
    	}
		}
  }
  return elements;
};
// 2007.1.10 - document의 하위 iframe들의 모든 select를 숨기고 보인다.
Swaf.Dom.hideAllSelect=function(doc) {
	var d=doc || document;
	if (d.body) {
		Swaf.Dom.hideSelect(d.body);
		var arrIFrame=d.body.getElementsByTagName('iframe');
		for(var i=0;i<arrIFrame.length;i++) {
			try {
				var iframewin=Swaf.Dom.getIFrameWindow(arrIFrame[i]);
				if (iframewin.Swaf) {
					var iframedoc=iframewin.Swaf.Dom.getIFrameDoc(arrIFrame[i]);
					iframewin.Swaf.Dom.hideAllSelect(iframedoc);
				}
			} catch(e) {
				continue;
			}
		}
	}
};
Swaf.Dom.showAllSelect=function(doc) {
	var d=doc || document;
	if (d.body) {
		Swaf.Dom.showSelect(d.body);
		var arrIFrame=d.body.getElementsByTagName('iframe');
		for(var i=0;i<arrIFrame.length;i++) {
			try {
				var iframewin=Swaf.Dom.getIFrameWindow(arrIFrame[i]);
				if (iframewin.Swaf) {
					var iframedoc=iframewin.Swaf.Dom.getIFrameDoc(arrIFrame[i]);
					iframewin.Swaf.Dom.showAllSelect(iframedoc);
				}
			} catch(e) {
				continue;
			}
		}
	}
};
// 2007.1.11
	Swaf.Dom.getIFrameWindow=function(element) {
		return element.contentWindow;
	};

// 2007.1.15 추가
Swaf.Dom.hideObject=function(element) {
	var arrSelect=element.getElementsByTagName('object');
	for(var i=0;i<arrSelect.length;i++) {
		if (arrSelect[i].style.display=='none') continue;
		arrSelect[i].style.visibility='hidden';
	}
	var arrSelect=element.getElementsByTagName('embed');
	for(var i=0;i<arrSelect.length;i++) {
		if (arrSelect[i].style.display=='none') continue;
		arrSelect[i].style.visibility='hidden';
	}
	arrSelect=null;
};
Swaf.Dom.showObject=function(element) {
	var arrSelect=element.getElementsByTagName('object');
	for(var i=0;i<arrSelect.length;i++) {
		arrSelect[i].style.visibility='visible';
	}
	arrSelect=null;
};
// 2007.1.24
Swaf.Dom.changeImageSrc=function(el,src,bPng) {
	if (Swaf.Util.Browser.isIE==true && bPng==true && Swaf.Util.Browser.getVersion()<7) {
		el.style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\''+ src+'\', sizingMethod=\'image\');';
	} else { 
		el.src=src;
	}
};
// 2007.1.25
Swaf.Dom.resetID=function(element) {
	var arr=element.childNodes;
	for(var i=0;i<arr.length;i++) {
		node=arr[i];
		if (node.nodeType==1 && node.id) {	// ELEMENT NODE
			node.id='';
			Swaf.Dom.resetID(node);
		}
	}
};
Swaf.Dom.cloneNode=function(element) {
	var retEl=element.cloneNode(true);
	Swaf.Dom.resetID(retEl);
	return retEl;
};
//2007.2.13
Swaf.Dom.addCSSStyle=function(strName,strRule) {
	if (Swaf.Util.Browser.isIE) {
		var head=document.getElementsByTagName("head");
		if (head) {
			var style=document.createElement('style');
			style.setAttribute('type','text/css');
			if(style.styleSheet){// IE
			style.styleSheet.cssText = strName+' {'+strRule+'}';
			} else {// w3c
			var cssText = document.createTextNode(strName+' {'+strRule+'}');
			style.appendChild(cssText);
			cssText=null;
			}
			head[0].appendChild(style);
			style=null;
		}
		head=null;
	} else {
		var head=document.getElementsByTagName("head");
		if (head) {
			var style=document.createElement('style');
			style.setAttribute('type','text/css');
			style.innerHTML=strName+' {'+strRule+'}';
			head[0].appendChild(style);
			style=null;
		}
		head=null;
	}
};

SwafListenerCache={
	elementCache:null,
	listenerCache:null,
	closureCache:null,
	ownerCache:null,
	evttypeCache:null,
	freeSlot:null,
		addListener:function(oOwner,evtType,element,listener) {
			var cacheId;
			if (!this.listenerCache) {
				this.listenerCache=new Array();
				this.closureCache=new Array();
				this.elementCache=new Array();
				this.ownerCache=new Array();
				this.evttypeCache=new Array();
			}

			if (this.freeSlot&&this.freeSlot.length>0) {
				cacheId=this.freeSlot.shift();
			} else {
				cacheId=this.listenerCache.length;
			}
			this.listenerCache[cacheId]=listener;
			this.elementCache[cacheId]=element;
			this.ownerCache[cacheId]=oOwner;
			this.evttypeCache[cacheId]=evtType;
			this.closureCache[cacheId]=(function(evt) {if (SwafListenerCache.listenerCache && SwafListenerCache.listenerCache[cacheId]) {SwafListenerCache.listenerCache[cacheId].call(SwafListenerCache.ownerCache[cacheId],evt,SwafListenerCache.elementCache[cacheId]);} else {SwafListenerCache.listenerCache=null;SwafListenerCache.closureCache=null;SwafListenerCache.elementCache=null;SwafListenerCache.ownerCache=null;SwafListenerCache.evttypeCache=null;}}).bindAsEventListener(SwafListenerCache.ownerCache[cacheId]);

			Event.observe(this.elementCache[cacheId],this.evttypeCache[cacheId],this.closureCache[cacheId],false);
			return cacheId;
		},
		removeListener:function(cacheId) {
			if (this.elementCache&&this.elementCache[cacheId]) {
				try {
					Event.stopObserving(this.elementCache[cacheId],this.evttypeCache[cacheId],this.closureCache[cacheId],false);
				} catch(e) {
					Swaf.Util.outputDebugLn('Exception occurred in removeListener!<br>'+Swaf.Util.dumpObject(e,'<br>'));
				}
				this.elementCache[cacheId]=null;
				this.listenerCache[cacheId]=null;
				this.closureCache[cacheId]=null;
				this.ownerCache[cacheId]=null;
				this.evttypeCache[cacheId]=null;
				if (!this.freeSlot) this.freeSlot=new Array();
				this.freeSlot.push(cacheId);
			}
		},
		removeAll:function() {
			var i;
			if (this.listenerCache) {
				for(i=0;i<this.listenerCache.length;i++) {
					this.removeListener(i);
				}
				this.listenerCache=null;
				this.closureCache=null;
				this.elementCache=null;
				this.ownerCache=null;
				this.evttypeCache=null;
			}
			if (this.freeSlot) this.freeSlot.length=0;
		}
};

	// Message Listener
	Swaf.Listener = Class.create();
	Object.extend(Swaf.Listener.prototype, Swaf.Base.prototype);
	Object.extend(Swaf.Listener.prototype, {
		classname:'Swaf.Listener',
		listenerType:'base',
		listener:null,
		owner:null,
		init:function(listener) {
			this.initListener(listener);
		},
		initListener:function(listener) {
			if (listener!=undefined) { this.setListener(listener); }
		},
		/* API Interface */
		setListener:function(listener) {
			if (this.listener==undefined) this.listener=listener;
			else {
				for(var i=0;i<listener.length;i++) {this.listener.push(listener[i]); }
			}
		},
		getListener:function() {
			return this.listener;
		},
		setOwner:function(owner) {
			this.owner=owner;
		},
		getOwner:function() {
			return this.owner;
		},
		getListenerType:function() {
			return this.listenerType;
		}
	});
	
	Swaf.Listener.Msg = Class.create();
	Object.extend(Swaf.Listener.Msg.prototype, Swaf.Listener.prototype);
	Object.extend(Swaf.Listener.Msg.prototype, {
		classname:'Swaf.Listener.Msg',
		listenerType:'messageBase',
		/* API Interface */
		addListener:function(msg,listener,oInstance) {
			// apply AOP
			var exptProcessor=this.getOwner().getExceptionProcessor();
			if (exptProcessor) {
				listener=(exptProcessor)?exptProcessor.getExceptionProxy(listener):listener;
			}
			if (this.listener_vector==undefined) this.listener_vector=new Array();
			if (!this.listener_vector[msg]) this.listener_vector[msg]=new Array();
			this.listener_vector[msg].unshift(listener.bind(oInstance));
		},
		applyListener:function(oInstance) {
			if (oInstance) {
				this.owner=oInstance;
				if (this.listener) {
					for(var i=0;i<this.listener.length;i++) {
						pair=this.listener[i];
						if (pair.message) {
							var arrMsg=Swaf.Util.toArray(pair.message);
							for(j=0;j<arrMsg.length;j++) {
								this.addListener(arrMsg[j],pair.listener,oInstance);
							}
						}
					} // for
				} // if
			}
		},
		getHandler:function(msg) { return (this.listener_vector)?this.listener_vector[msg]:null;}
	});
	
	
	Swaf.Listener.Event = Class.create();
	Object.extend(Swaf.Listener.Event.prototype, Swaf.Listener.prototype);
	Object.extend(Swaf.Listener.Event.prototype, {
		classname:'Swaf.Listener.Event',
		listenerType:'eventBase',
		observerCache:null,
		listenerCacheIds:null,
		/* API Interface */
		addListener:function(evtType,scope,listener) {
			var oOwner=(this.owner || scope);
			var oScope=(typeof scope=='string')?document.getElementById(scope):scope;
			if (!this.listenerCacheIds) this.listenerCacheIds=new Array();
			this.listenerCacheIds.push(SwafListenerCache.addListener(oOwner,evtType,oScope,listener));
		},
		removeListener:function() {
			for (var i=0;i<this.listenerCacheIds.length;i++) {
				SwafListenerCache.removeListener(this.listenerCacheIds[i]);
			}
			delete this.listenerCacheIds;
			this.listenerCacheIds=null;
		},
		applyListener:function(element) {
			var i,el;
			if (element==undefined || !element) return;
			if (element.getElement) el=element.getElement();
			else el=element;
			this.owner=Swaf.getInstance(el);
			if (this.listener) {
				for(i=0;i<this.listener.length;i++) {
					pair=this.listener[i];
					if (pair.event) {
						var arrMsg=Swaf.Util.toArray(pair.event);
						for(j=0;j<arrMsg.length;j++) {
							this.addListener(arrMsg[j],pair.source || el,pair.listener||'default');
						}
					} 
				}
			}
			el=null;
		},
		stopPropagation:function(evt) {
			Event.stop(evt);
		},
		getEventPosition:function(evt) {
			return {x:Event.pointerX(evt),y:Event.pointerY(evt)};
		}
	});

function $listener(element,evttype,listenerFn,owner) {
	var i;
	if (!element) {
		return null;
	}
	var listener=[
	{ event:evttype,
		listener:listenerFn
	}];

	if (element instanceof Array) {
		var arrObj=new Array(element.length);
		for(i=0;i<element.length;i++) {
			var obj=new Swaf.Listener.Event(listener);
			if (owner) obj.setOwner(owner);
			obj.applyListener(element[i]);
			arrObj.push(obj);
		}
		return arrObj;
	} else {
		var obj=new Swaf.Listener.Event(listener);
		if (owner) obj.setOwner(owner);
		obj.applyListener(element);
		return obj;
	}
}

function _swaf_clearObjects() {
	SwafListenerCache.removeAll();
	Swaf.removeAllInstance();
}

$listener(window,'unload',_swaf_clearObjects);

Swaf.XMLDocument = Class.create();
Object.extend(Swaf.XMLDocument.prototype, Swaf.Base.prototype);
Object.extend(Swaf.XMLDocument.prototype, {
	classname:'Swaf.XMLDocument',
	xmlobj:null,
	init:function(xmlObject) {
		if (xmlObject) this.xmlobj=xmlObject;
	},
	setXMLObject:function(xmlObject) {
		this.xmlobj=xmlObject;
	},
	getXMLObject:function() {
		return this.xmlobj;
	},
	loadXML:function(xmlString) {
		var xmlDoc=
		Try.these(
      function() {return new ActiveXObject('Microsoft.XMLDOM')},
      function() {return new XMLDocument()}
    );
    if (xmlDoc) {
    	xmlDoc.loadXML((typeof xmlString=='string'?xmlString:xmlString.toString()));
    	this.xmlobj=xmlDoc;
    	return true;
    }
    return false;
 	},
  $:function(node,index) {	// Node의 Child Array를 리턴
		var obj;
			if (this.xmlobj) {
				if (index!=null) obj=this.xmlobj.getElementsByTagName(node)[index];
				else obj=this.xmlobj.getElementsByTagName(node)[0];
	  		if (obj) return new Swaf.XMLNode(obj);
			}
  	return new Swaf.XMLNode(null);
  }
});

Swaf.XMLNode = Class.create();
Object.extend(Swaf.XMLNode.prototype, Swaf.Base.prototype);
Object.extend(Swaf.XMLNode.prototype, {
	classname:'Swaf.XMLNode',
	ELEMENT_NODE:1,
	ATTRIBUTE_NODE:2,
	TEXT_NODE:3,
	CDATA_SECTION:4,
	ENTITY_REFERENCE:5,
	ENTITY_NODE:6,
	COMMENT_NODE:8,
	init: function(obj) {
		this.node=obj;
		if (obj) {
			this.tagName=obj.tagName;
			this.nodeType=obj.nodeType;
		}
	},
	setXMLNode:function(obj) {
		this.node=obj;
		if (obj) {
			this.tagName=obj.tagName;
			this.nodeType=obj.nodeType;
		}
	},
	getXMLNode:function() {
		return this.node;
	},
  getChildNode:function(tagName) {	// 현재 node의 child node들을 Array로 구성하여 return
  	var arr=new Array();
		var cnode;
		for(cnode=this.node.firstChild;cnode;cnode=cnode.nextSibling) {
			if (cnode.nodeType==this.ELEMENT_NODE) {
				if (cnode.tagName!=undefined && (tagName==undefined || (tagName!=undefined && tagName==cnode.tagName))) {
					arr.push(new Swaf.XMLNode(cnode));
				}
			}
		}
		return arr;
  },
 	isNull:function() {
 		return (this.node==null);
 	},
  getValue:function() {
  	return this.toString();
  },
		/* API Interface */
  $:function(node,index) {
  		if (this.node) {
				var obj=this.node.getElementsByTagName(node)[index||0];
	  		if (obj) return new Swaf.XMLNode(obj);
  		}
  	return new Swaf.XMLNode(null);
  },
  $A:function(attribute) {	// Tag의 Attribute를 리턴
  	return this.node.getAttribute(attribute);
  },
  // 2006.8.25... 길이 반환
  $L:function(tagName) {
  	var arr=new Array();
		var cnode,len=0;
 		if (this.node) {
			for(cnode=this.node.firstChild;cnode;cnode=cnode.nextSibling) {
				if (cnode.nodeType==this.ELEMENT_NODE) {
					if (tagName) {
						if (cnode.tagName==tagName) len++;
					} else {
						len++;
					}
				}
			}
 		}
  	return len;
  }
});
Swaf.XMLNode.prototype.toString=function() {return (this.node&&this.node.firstChild)?this.node.firstChild.data:null;};		// 위에 넣으면 동작 안함

Swaf.Ajax={
	requestHeaders:[
		'X-Requested-With', 'SwafXMLHttpRequest',
    'X-Swaf-Version', Swaf.version+'.'+Swaf.build
	],
	// 2007.2.15.. regexp cache for Ajax Response
	regexp_local:/%%local%%/gm,
	regexp_load1:/%%load%%\s*=\s*\S+/gm,
	regexp_load2:/%%load%%\s*=\s*/,
	regexp_load3:/%%load%%\s*=\s*\S+/,
	//window:Swaf.globalStorage.window,
	msxmlProgId:["MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"],
	getgs:function() {
		//return Swaf.globalStorage.create("swaf:ajax:framework");
		if (!window.swaf_ajax_framework_gs) window.swaf_ajax_framework_gs={};
		return window.swaf_ajax_framework_gs;
	},
	getSequence:function() {
		gs=Swaf.Ajax.getgs();
		if (gs.sequence==undefined) gs.sequence=0;
		else gs.sequence=gs.sequence+1;
		if (gs.sequence>9999999) gs.sequence=0;
		return gs.sequence;
	},
	createXMLHTTPRequest:function() {
		var xhr = null;
		try
		{
			if (window.XMLHttpRequest) xhr = new XMLHttpRequest();
			else if (window.ActiveXObject)
			{
				for (var i = 0; !xhr && i < this.msxmlProgId.length; i++)
				{
					try { 
						xhr = new ActiveXObject(this.msxmlProgId[i]); 
					} catch (e) 
					{ 
						xhr = null; 
						this.msxmlProgId.splice(i, 1);	// 동작 안하는 object 제거 (나중 속도를 위해)
					}
				} // for
			} // else
		}
		catch (e) { 
			xhr = null;	
		}
		return xhr;
	},
	
	initAjax:function() {
		var gs=this.getgs();
		if (gs.initialized==true) {
			gs.refcount++;
			return;
		}
		gs.initialized=true;
		gs.refcount=1;
		// init pool
		var num=gs.poolnum=(Swaf.Util.Browser.isIE)?2:4;
		gs.queue_pool=new Array(num);
		for(var i=0;i<num;i++) {
			gs.queue_pool[i]=new Swaf.Ajax.RequestProcessor();
		}
		
		gs.queue_index=0;

		gs.ajaxobjnum=0;
		gs.ajaxobjcache={};
	},
	destroyAjax:function() {
		var gs=this.getgs();
		if (gs.initialized!=true) return;
		gs.refcount--;
		if (gs.refcount>0) {
			return;
		}
		for(var i=0;i<gs.poolnum;i++) {
			delete gs.queue_pool[i];
		}
		delete gs.queue_pool;
		gs.ajaxobjcache=null;
		gs.ajaxobjnum=0;
		gs.initialized=false;
	},
	// request
	// { url, parameter, method, userid, password, doctype, owner, callback, callbackParameter, headers}
	push_request:function(request) {
		var gs=this.getgs();
		gs.queue_index=(gs.queue_index+1)%gs.poolnum;
		return {queue:gs.queue_index,sequence:gs.queue_pool[gs.queue_index].push_request(request)};
	},
	abortRequest:function(req_seq) {
		var gs=this.getgs();
		gs.queue_pool[req_seq.queue].abortRequest(req_seq.sequence);
	},
	getResponseHeader:function(xhr,name) {
		return xhr.getResponseHeader(name);
	},
	
	// Synchronous ajax call
	ajaxSyncRequest:function(url,method,type,parameter,headers,userid,password) {
		var xhr=this.createXMLHTTPRequest();
		var rparameter=(parameter? ((typeof parameter=='string') ?parameter:$H(parameter).toQueryString()) : '');
		var rurl=url;
		var header=(headers)?this.requestHeaders.concat(headers):new Array();
		if (method=='get' && rparameter.length>0) {
			rurl+=(rurl.match(/\?/) ? '&' : '?') + rparameter;
		}
		xhr.open(method,rurl,false,userid,password);
		if (method=='post') {
			xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
		}
		if (xhr.overrideMimeType) header.push('Connection', 'close');		// Mozilla Bugzilla #246651 대응
		for(var i=0;i<header.length;i+=2) {
			xhr.setRequestHeader(header[i],header[i+1]);
		}
		xhr.send(method=='post'?rparameter:null);
		return new Swaf.Ajax.Response(xhr,type);
	},
	// Asynchronous ajax call
	ajaxRequest:function(url,callback,method,type,parameter,userid,password) {
		var request=new Swaf.Ajax.Request(method||'get',type||'XML',true,userid,password);
		request.setUrl(url);
		request.setCallbackHandler(callback);
		if (parameter) request.setParameter(parameter);
		request.request();
		return request;
	},
	// 11/9 ajax object
	ajaxobjnum:0,
	ajaxobjcache:{},
	getAjaxObject:function() {
		if (!this.ajaxobjcache[this.ajaxobjnum]) this.ajaxobjcache[this.ajaxobjnum]={_objectIndex:this.ajaxobjnum};
		var ret='ajaxScript'+this.ajaxobjnum;
		this[ret]=this.ajaxobjcache[this.ajaxobjnum];
		this.ajaxobjnum++;
		return ret;
	},
	removeAjaxObject:function(object) {
		if (object && object._objectIndex) {
			this['ajaxScript'+object._objectIndex]=null;
			this.ajaxobjcache[object._objectIndex]=null;
			object=null;
		}
	}
};

Swaf.Ajax.RequestQueue=Class.create();
Object.extend(Swaf.Ajax.RequestQueue.prototype, Swaf.Base.prototype);
Object.extend(Swaf.Ajax.RequestQueue.prototype, {
	queue:null,
	pool:{},
	garbage:null,
	init:function() {
		this.initRequestQueue();
	},
	initRequestQueue:function() {
		this.queue=new Array();
		this.garbage=new Array();
	},
	push:function(request) {
		var seq=Swaf.Ajax.getSequence();
		request.__sequence=seq;
		this.pool[seq]=request;
		this.queue.push(seq);
		return seq;
	},
	pop:function() {
		if (this.queue.length>0) {
			var seq=this.queue.shift();
			this.garbage.push(seq);
			return this.pool[seq];
		}
		return null;
	},
	remove:function(seq) {
		for(var i=0;i<this.queue;i++) {
			if (this.queue[i]==seq) {
				this.queue.splice(i,1);
				delete this.pool[seq];
				return true;
			}
		}
		return false;
	},
	clearGarbage:function() {
		for(var i=0;i<this.garbage.length;i++) {
			delete this.pool[this.garbage[i]];
		}
		this.garbage.length=0;
	}
});

Swaf.Ajax.RequestProcessor=Class.create();
Object.extend(Swaf.Ajax.RequestProcessor.prototype, Swaf.Base.prototype);
Object.extend(Swaf.Ajax.RequestProcessor.prototype, {
	queue:null,
	busy:false,
	curRequest:null,
	xhr:null,
	init:function() {
		this.initRequestProcessor();
	},
	initRequestProcessor:function() {
		this.queue=new Swaf.Ajax.RequestQueue();
	},
	onDestroy:function() {
		this.queue.clearGarbage();
		delete this.queue;
	},
	push_request:function(request) {
		// apply default
		var req={parameter:'', method:'get', doctype:'XML',headers:[]};
		Object.extend(req,request);
		var seq=this.queue.push(req);
		if (seq%10==0) this.queue.clearGarbage();
		window.setTimeout(this.do_request.bind(this),0); // for mozilla bug  https://bugzilla.mozilla.org/show_bug.cgi?id=317600
		return seq;
	},
	deleteXHR:function() {
		if (this.xhr) {
			this.xhr.onreadystatechange= Prototype.emptyFunction;
			delete this.xhr;
		}
		this.busy=false;
		this.curRequest=null;
	},
	abortRequest:function(req_seq) {
		if (this.curRequest) {
			if (this.curRequest.__sequence==req_seq) {
				if (this.xhr) this.xhr.abort();
				this.deleteXHR();
				window.setTimeout(this.do_request.bind(this),0); // for mozilla bug  https://bugzilla.mozilla.org/show_bug.cgi?id=317600
			}
		}
		this.queue.remove(req_seq);
	},
	do_request:function() {
		var request;
		if (this.busy==true) return;
		if (this.queue) {
			request=this.queue.pop();
			if (!request) return;
		} else return;
		this.deleteXHR();
		this.curRequest=request;
		this.busy=true;
		this.xhr=Swaf.Ajax.createXMLHTTPRequest();

		var requestHeaders=(request.headers)?Swaf.Ajax.requestHeaders.concat(request.headers):Swaf.Ajax.requestHeaders.copy();
		var parameter=(request.parameter? ((typeof request.parameter=='string') ?request.parameter:$H(request.parameter).toQueryString()) : '');
		var url=request.url;
		if (request.method=='get' && parameter.length>0) {
			url+=(url.match(/\?/) ? '&' : '?') + parameter;
		}
		if (url.indexOf('?')==-1) url+='?swaf_ajaxseq='+request.__sequence;
		else url+='&swaf_ajaxseq='+request.__sequence;

		this.xhr.open(request.method,url,true,request.userid,request.password);
		this.xhr.onreadystatechange=this.callbackAjax.bind(this);
		
		if (request.method=='post') {
			requestHeaders.push('Content-type','application/x-www-form-urlencoded');
		}
		if (this.xhr.overrideMimeType) requestHeaders.push('Connection', 'close');		// Mozilla Bugzilla #246651 대응
		for(var i=0;i<requestHeaders.length;i+=2) {
			this.xhr.setRequestHeader(requestHeaders[i],requestHeaders[i+1]);
		}
		this.xhr.send(request.method=='post'?parameter:'');
		request=null;
	},
	callbackAjax:function() {
		if (this.xhr.readyState==4) {	// ajax complete
			var response=new Swaf.Ajax.Response(this.xhr,this.curRequest.doctype,null,this.curRequest.owner);
			if (this.curRequest.callback) {
				try {
					if (this.curRequest.owner) this.curRequest.callback.call(this.curRequest.owner,response,this.curRequest.callbackParameter);
					else this.curRequest.callback(response,this.curRequest.callbackParameter);
				} catch(err) {
					Swaf.Util.outputDebugLn('Ajax Callback Handler Exception!<br>'+Swaf.Util.dumpObject(err,'<br>')+'<br>request url : '+this.curRequest.url+'<br>response status : '+response.getStatus()+' - '+response.getStatusText()+'<br>response data : <br>'+response.getText());
				}
			}
			response=null;
			this.deleteXHR();
			this.do_request();
		}
	}
});

Swaf.Ajax.Request = Class.create();
Object.extend(Swaf.Ajax.Request.prototype, Swaf.Base.prototype);
Object.extend(Swaf.Ajax.Request.prototype, {
	classname:'Swaf.Ajax.Request',
	url:null,
	method:'get',
	doctype:'XML',
	parameter:null,
	async:true,
	userid:null,
	password:null,
//	xhr:null,
	owner:null,
//	callbackMsg:null,
	callbackParameter:null,	// 2006.11.1
	request_sequence:null, // 2006.12.5
	init:function(method,doctype,async,userid,password) {
		this.initAjax(method,doctype,async,userid,password);
	},
	initAjax:function(method,doctype,async,userid,password) {
		// local variable
/*		this.option={
			applyScript:true,
			autoUpdate:false
		};*/
		this.onComplete=Prototype.emptyFunction;
		
//		this.xhr=Swaf.Ajax.createXMLHTTPRequest();
		this.method=method||'get';
		this.doctype=doctype||'XML';
		this.async=(async!=undefined)?async:true;		
		this.userid=userid;
		this.password=password;
	},
	setUrl:function(url) {
		this.url=url;
	},
	getUrl:function() { return this.url;},
	setOwner:function(owner) {
		this.owner=owner;
	},
	getOwner:function() {
		return this.owner;
	},
	setMethod:function(method) {
		this.method=method;
	},
	getMethod:function() {
		return this.method;
	},
	setDocType:function(doctype) {
		this.doctype=doctype;
	},
	getDocType:function() {
		return this.doctype;
	},
	setAsync:function(async) {
		this.async=async;
	},
	getAsync:function() {
		return this.async;
	},
	setUserId:function(id) {
		this.userid=id;
	},
	getUserId:function() {
		return this.userid;
	},
	setPassword:function(pw) {
		this.password=pw;
	},
	getPassword:function() {
		return this.password;
	},
	setParameter:function(parameter) {
		this.parameter=parameter;
	},
	getParameter:function() {
		return this.parameter;
	},
	setRequestHeader:function(arrHeaders) {
		if (!this.requestHeaders) this.requestHeaders=arrHeaders;
		else this.requestHeaders=this.requestHeaders.concat(arrHeaders);
	},
	getRequestHeader:function() {
		return this.requestHeaders;
	},
	setCallbackHandler:function(fn) {
		var exp=this.getExceptionProcessor();
		this.onComplete=(exp)?exp.getExceptionProxy(fn):fn;
	},
	getCallbackHandler:function() {
		return this.onComplete;
	},
	setCallbackParameter:function() {
		this.callbackParameter=$A(arguments);
	},
	request:function() {
	// { url, parameter, method, userid, password, doctype, owner, callback, callbackParameter, headers}
		var request={url:this.url, parameter:this.parameter,method:this.method,userid:this.userid,password:this.password,doctype:this.doctype,owner:this.owner,callback:this.onComplete,callbackParameter:this.callbackParameter,headers:this.requestHeaders};
		this.request_sequence=/*Swaf.globalStorage.window.*/Swaf.Ajax.push_request(request);
		request=null;
	},
	abort:function() {
		/*Swaf.globalStorage.window.*/Swaf.Ajax.abortRequest(this.request_sequence);
	}
});

Swaf.Ajax.MultiRequest = Class.create();
Object.extend(Swaf.Ajax.MultiRequest .prototype, Swaf.Base.prototype);
Object.extend(Swaf.Ajax.MultiRequest .prototype, {
	arrRequests:null,
	async:true,
	userid:null,
	password:null,
	url:null,
	arrRequestDocType:null,
	arrRequestCallback:null,
	arrRequestCallbackParameter:null,
	arrRequestCallbackOwner:null,
	ajaxRequest:null,
	completeCallback:null,
	init:function(arrRequests,async,userid,password) {
		this.initMultiRequest(arrRequests,async,userid,password);
	},
	initMultiRequest:function(arrRequests,async,userid,password) {
		this.arrRequests=arrRequests;
		this.async=async!=undefined?async:true;
		this.userid=userid;
		this.password=password;
	},
	setCompleteCallback:function(callback) {
		this.completeCallback=callback;
	},
	request:function(strProcessorUrl) {
		if (this.arrRequests) {
			var request_xml='<requests>';
			this.ajaxRequest=new Swaf.Ajax.Request('post','JSON',this.async,this.userid,this.password);
			this.ajaxRequest.setUrl(strProcessorUrl || '/js/swaf/processMultiAjax.php');
			this.ajaxRequest.setCallbackHandler(this.multiResponse.bind(this));
			this.arrRequestDocType=new Array();
			this.arrRequestCallback=new Array();
			this.arrRequestCallbackParameter=new Array();
			this.arrRequestCallbackOwner=new Array();
			for(var i=0;i<this.arrRequests.length;i++) {
				var subrequest=this.arrRequests[i];
				this.arrRequestDocType.push(subrequest.doctype);
				this.arrRequestCallback.push(subrequest.onComplete);
				this.arrRequestCallbackParameter.push(subrequest.callbackParameter);
				this.arrRequestCallbackOwner.push(subrequest.owner);
				var subxml='<request url="'+encodeURI(subrequest.url).escapeHTML()+'" method="'+subrequest.method+'">';
				if (subrequest.parameter) {
					for(selector in subrequest.parameter) {
						var pname=selector;
						var pvalue=subrequest.parameter[selector];
						if (pvalue && typeof pvalue=='string') pvalue=pvalue.replace(/"/,'\\"');
						subxml+='<parameter name="'+pname+'" value="'+encodeURI(pvalue).escapeHTML()+'"/>';
					}
				}
				request_xml+=subxml+'</request>';
				subrequest=null;
			}
			request_xml+='</requests>';
			this.ajaxRequest.setParameter({request:request_xml});
			this.ajaxRequest.request();
			this.arrRequests=null;
		}
	},
	multiResponse:function(oresponse) {
		if (oresponse.isSuccess()) {
			if (oresponse.value.success) {
				var result=oresponse.value.result;
				for(var i=0;i<result.length;i++) {
					var item=result[i];
					if (!item.success) continue;
					var response=new Swaf.Ajax.Response(oresponse.xhr,this.arrRequestDocType[i],null,this.arrRequestCallbackOwner[i],item.data);
					if (this.arrRequestCallback[i]) {
						try {
							if (this.arrRequestCallbackOwner[i]) this.arrRequestCallback[i].call(this.arrRequestCallbackOwner[i],response,this.arrRequestCallbackParameter[i]);
							else this.arrRequestCallback[i](response,this.arrRequestCallbackParameter[i]);
						} catch(err) {
							Swaf.Util.outputDebugLn('Ajax Multi Response Callback Handler Exception!<br>'+Swaf.Util.dumpObject(err,'<br>')+'<br>request URL : '+this.url+'<br>response status : '+response.getStatus()+' - '+response.getStatusText()+'<br>response data : <br>'+item.data);
						}
					}
					response=null;
					this.arrRequestDocType[i]=null;
					this.arrRequestCallback[i]=null;
					this.arrRequestCallbackOwner[i]=null;
					this.arrRequestCallbackParameter[i]=null;
				}
				if (this.completeCallback) {
					this.completeCallback();
				}
			} else {
				alert("서버 오류 : 잠시후 다시 시도하십시오.");
			}
		} else {
			alert("HTTP ERROR : "+response.getStatus());
		}
		this.arrRequestDocType=null;
		this.arrRequestCallback=null;
		this.arrRequestCallbackOwner=null;
		this.arrRequestCallbackParameter=null;
		this.ajaxRequest=null;
	}
});


Swaf.Ajax.Response = Class.create();
Object.extend(Swaf.Ajax.Response.prototype, Swaf.Base.prototype);
Object.extend(Swaf.Ajax.Response.prototype, {
	classname:'Swaf.Ajax.Response',
	xhr:null,
	doctype:null,
	option:null,
	value:null,
	owner:null,
	recvtext:null,				// 2007.1.9
	// 2007.1.9.. srctext 추가
	init:function(xhr,doctype,option,owner,srctext) {
		this.initResponse(xhr,doctype,option,owner,srctext);
	},
	initResponse:function(xhr,doctype,option,owner,srctext) {
		this.xhr=xhr;
		var readyState=xhr.readyState;
		var status=xhr.status;
		this.doctype=doctype;
		this.option=option;
		this.owner=owner;
		this.recvtext=srctext;
		if (!this.isSuccess() && !srctext) {
			// error
//			this.xhr=null;
/*			var err=new Error();
			err.name='Ajax Response Error';
			err.message=xhr.statusText;
			throw err;*/
			return;
		}
		switch(doctype) {
			case 'JSON' :
				this.value=this.evalResult();
				break;
			case 'XML' :
				this.value=this.getXML();
				break;
			case 'HTML' :
				this.value=this.getText();
				break;
			case 'JS' :
				this.value=this.applyScript();
				break;
			case 'TEXT' :
				this.value=this.getText().escapeHTML();
				break;
		}
/*		if (option.autoUpdate) {
			if (owner) owner.setContents(this.value);
		}*/
	},
	isSuccess:function() {
		return (this.xhr.status==undefined || this.xhr.status==0 || (this.xhr.status>=200 && this.xhr.status<300));
	},
	getHeader:function(name) {
		return this.xhr.getResponseHeader(name);
	},
	getDocType:function() {
		return this.doctype;
	},
	getOwner:function() {
		return this.owner;
	},
	getXML:function() {
		if (this.recvtext) {
			var ret=new Swaf.XMLDocument();
			ret.loadXML(this.recvtext);
			return ret;
		} else if (this.xhr) {
			return (new Swaf.XMLDocument(this.xhr.responseXML));
		}
	},
	getText:function() {
		if (this.recvtext) {
			return this.recvtext;
		} else if (this.xhr) {
			return (this.xhr.responseText);
		}
	},
	evalResult:function() {
		var ret;
		try {
			ret=eval('('+this.getText()+')');
		} catch(e) {
			Swaf.Util.outputDebugLn('Evaluation failed! '+Swaf.Util.dumpObject(e,'<br>')+'<br>Received data :<br>'+this.getText());
		}
		return ret;
	},
	applyScript:function() {
		return this.getText().evalScripts();
	},
	updateHTML:function(element,initFunction) {
		var i,tmparr,swafLoad;
		
		var objectnm=Swaf.Ajax.getAjaxObject();

		var html=this.getText().replace(Swaf.Ajax.regexp_local,'Swaf.Ajax.'+objectnm);;
		
		element.innerHTML=html;
		
		var script=html.extractScripts();
		if (script) {
			for(i=0;i<script.length;i++) {
				tmparr=script[i].match(Swaf.Ajax.regexp_load1);
				if (tmparr) {
					swafLoad=tmparr[0].replace(Swaf.Ajax.regexp_load2,'');
					swafLoad=swafLoad.replace(';','');
				}
				script[i]=script[i].replace(Swaf.Ajax.regexp_load3,'');
			} // for
		}
		/*if (this.option.applyScript)*/ script.map(eval);

		if (swafLoad) eval('Swaf.Ajax.'+objectnm+'.'+swafLoad+'()');
		
		if (initFunction) eval(initFunction+'()');	// 2006.11.6
	},
	updateIFrame:function(element) {
		if (Swaf.Dom) {
			Swaf.Dom.setIFrame(element,this.getText());
		}
	},
	getStatus:function() {
		return this.xhr.status;
	},
	getStatusText:function() {
		return this.xhr.statusText;
	}
});

Swaf.Ajax.Response.prototype.toString=function() { return this.getText();};

Swaf.Ajax.initAjax();
/*  if (window.addEventListener) {
    window.addEventListener('load', Swaf.Ajax.initAjax.bind(Swaf.Ajax), false);
  } else if (window.attachEvent) {
    window.attachEvent('load', Swaf.Ajax.initAjax.bind(Swaf.Ajax));
  }*/
  if (window.addEventListener) {
    window.addEventListener('unload', Swaf.Ajax.destroyAjax.bind(Swaf.Ajax), false);
  } else if (window.attachEvent) {
    window.attachEvent('unload', Swaf.Ajax.destroyAjax.bind(Swaf.Ajax));
  }

Swaf.Animation = Class.create();
Object.extend(Swaf.Animation.prototype, Swaf.Base.prototype);
Object.extend(Swaf.Animation.prototype, {
		classname:'Swaf.Animation',
		animation:'base',
		interval:10,
		step:15,
		elementId:null,
		bIng:false,
		cbParam:null,
		init:function(element,interval,step) {
			this.initAnimation(element,interval,step);
		},
		initAnimation:function(element,interval,step) {
			this.elementId=element.id;
			this.interval=interval || 2;
			this.step=step||15;
			element=null;
		},
		setInterval:function(interval) {
			this.interval=interval;
		},
		getInterval:function() {
			return this.interval;
		},
		setStep:function(step) {
			this.step=step;
		},
		getStep:function() {
			return this.step;
		},
		setElement:function(el) {
			this.elementId=el.id;
		},
		getElement:function() {
			return document.getElementById(this.elementId);
		},
		start:function() {
			this.stop();
			if (this.prepareAction) this.prepareAction();
			this.bIng=true;
			//this.animate_timer=window.setInterval(this.actionBase.bind(this),this.interval);
			this.animate_timer=window.setTimeout(this.actionBase.bind(this),this.interval);
		},
		stop:function() {
			if (this.bIng) {
				this.bIng=false;
				//if (this.animate_timer) window.clearInterval(this.animate_timer);
				this.animate_timer=null;
				if (this.endAction) this.endAction(this.cbParam);
			}
		},
		actionBase:function() {
			if (!this.getElement()) this.stop();
			if (this.bIng) {
				if (this.doAction) this.doAction();
				this.animate_timer=window.setTimeout(this.actionBase.bind(this),this.interval);
			}
		},
		setCallbackParameter:function(arrparam) {
			this.cbParam=arrparam;
		},
		setEndCallback:function(cbfn) {
			this.endAction=cbfn;
		}
});

Swaf.Animation.Size = Class.create();
Object.extend(Swaf.Animation.Size.prototype, Swaf.Animation.prototype);
Object.extend(Swaf.Animation.Size.prototype, {
	animation:'size',
	sw:0,
	sh:0,
	ew:-1,
	eh:-1,
	cw:0,
	ch:0,
	dw:0,
	dh:0,
	init:function(element,interval,step) {
		this.initSize(element,interval,step);
	},
	initSize:function(element,interval,step) {
		this.initAnimation(element,interval,step);
	},
	setTarget:function(w,h) {
		this.ew=w;
		this.eh=h;
	},
	setTargetWidth:function(w) {
		this.ew=w;
	},
	setTargetHeight:function(h) {
		this.eh=h;
	},
	prepareAction:function() {
		var size=Swaf.Dom.getSize(this.getElement());
		this.cw=this.sw=size.width;
		this.ch=this.sh=size.height;
		if (this.ew==0) this.ew=1;	// for IE
		if (this.eh==0) this.eh=1;  // for IE

		with(this) {
			var ddw=(ew>sw)?1:-1;
			var ddh=(eh>sh)?1:-1;
			if (ew==-1 && eh>=0) {
				dh=step*ddh;
				dw=0;
			} else if (eh==-1 && ew>=0) {
				dw=step*ddw;
				dh=0;
			} else if (eh>=0 && ew>=0) {
				var ssh=Math.abs(eh-sh);
				var ssw=Math.abs(ew-sw);
				if (ssh>ssw) {
					dh=step*ddh;
					dw=step*(ssw/ssh)*ddw;
				} else if (ssh<ssw) {
					dw=step*ddw;
					dh=step*(ssh/ssw)*ddh;
				} else {
					dw=step*ddw;
					dh=step*ddh;
				}
			} else {
				dw=0;
				dh=0;
			}
		} // with
	},
	doAction:function() {
		var wend=false,hend=false;
		if (this.ew>=0) {
			if (Math.abs(this.cw-this.ew)>this.step) {
				this.cw+=this.dw;
			} else {
				this.cw=this.ew;
				wend=true;
			}
		} else {
			wend=true;
		}
		if (this.eh>=0) {
			if (Math.abs(this.ch-this.eh)>this.step) {
				this.ch+=this.dh;
			} else {
				this.ch=this.eh;
				hend=true;
			}
		} else {
			hend=true;
		}
		
		Swaf.Dom.setSize(this.getElement(),this.cw,this.ch);
		
		if (wend && hend) this.stop();
	}
});

Swaf.Animation.Fade = Class.create();
Object.extend(Swaf.Animation.Fade.prototype, Swaf.Animation.prototype);
Object.extend(Swaf.Animation.Fade.prototype, {
	animation:'fade',
	cur:1,
	target:1,
	pos:null,
	increment:false,
	init:function(element,interval,step) {
		this.initFade(element,interval,step);
	},
	initFade:function(element,interval,step) {
		this.initAnimation(element,interval,step);
		this.step=this.step/100;
	},
	setTarget:function(opacity) {
		this.target=opacity/100;
	},
	setPosition:function(x,y) {
		this.pos={x:x,y:y};
	},
	prepareAction:function() {
		var el=this.getElement();
		var disp=el.style.display;
		if (disp=='none') {
			Swaf.Dom.setStyle(el,'opacity',0);
			Swaf.Dom.showElement(el);
		}
		if (this.pos) {
			Swaf.Dom.setPosition(el,this.pos.x,this.pos.y);
		}
		this.cur=parseFloat(Swaf.Dom.getStyle(el,'opacity'));
		if (this.cur<this.target) this.increment=true;
		else this.increment=false;
		el=null;
	},
	doAction:function() {
		if (this.increment) this.cur+=this.step;
		else {
			this.cur-=this.step;
		}

		if ((this.increment && this.cur>this.target)||(!this.increment && this.cur<this.target)) {
			this.cur=this.target;
		}
		if (this.cur==this.target) {
			if (this.target==0) {
				Swaf.Dom.hideElement(this.getElement());
			}
			var el=this.getElement();
			el.style.filter='alpha(opacity='+(this.target*100)+')';
			el.style.opacity=this.target;
			el.style['-moz-opacity']=this.target;
			el.style['-khtml-opacity']=this.target;
			el=null;
//			Swaf.Dom.setStyle(this.getElement(),'opacity',this.target);
			this.stop();
			return;
		}
			var el=this.getElement();
			el.style.filter='alpha(opacity='+(this.cur*100)+')';
			el.style.opacity=this.cur;
			el.style['-moz-opacity']=this.cur;
			el.style['-khtml-opacity']=this.cur;
			el=null;
//		Swaf.Dom.setStyle(this.getElement(),'opacity',this.cur);
	}
});

Swaf.Animation.fadeInElement=function(element,interval,step) {
	Swaf.Animation.stopFadeElement(element);
	var obj=new Swaf.Animation.Fade(element,interval||2,step||20);
	obj.setTarget(100);
	obj.setCallbackParameter([element]);
	obj.setEndCallback(Swaf.Animation.stopFadeElement);
	obj.start();
	element.swafFadeObject=obj;
};
Swaf.Animation.fadeInElementPos=function(element,x,y,interval,step) {
	Swaf.Animation.stopFadeElement(element);
	var obj=new Swaf.Animation.Fade(element,interval||2,step||20);
	obj.setTarget(100);
	obj.setCallbackParameter([element]);
	obj.setEndCallback(Swaf.Animation.stopFadeElement);
	obj.setPosition(x,y);
	obj.start();
	element.swafFadeObject=obj;
};
Swaf.Animation.fadeOutElement=function(element,interval,step) {
	Swaf.Animation.stopFadeElement(element);
	var obj=new Swaf.Animation.Fade(element,interval||2,step||20);
	obj.setTarget(0);
	obj.setCallbackParameter([element]);
	obj.setEndCallback(Swaf.Animation.stopFadeElement);
	obj.start();
	element.swafFadeObject=obj;
};
Swaf.Animation.stopFadeElement=function(arrElement) {
	var element=arrElement[0];
	if (arrElement instanceof Array) element=arrElement[0];
	else element=arrElement;
	if (element&&element.swafFadeObject) {
		element.swafFadeObject.stop();
		element.swafFadeObject=null;
	}
	element=null;
	arrElement=null;
}

/* 나중에 필요하면 구현
Swaf.Animation.Color = Class.create();
Object.extend(Swaf.Animation.Color.prototype, Swaf.Animation.prototype);
Object.extend(Swaf.Animation.Color.prototype, {
});*/

$ui={};

Swaf.UI={
	elementIndex:0,
	uidef:{},
	getStyle:function(el) {
		var normal=Swaf.UI.Util.getStrAttr(el,'swaf:style');
		var select=Swaf.UI.Util.getStrAttr(el,'swaf:style:select');
		var opened=Swaf.UI.Util.getStrAttr(el,'swaf:style:opened');
		var closed=Swaf.UI.Util.getStrAttr(el,'swaf:style:closed');
		var mouseover=Swaf.UI.Util.getStrAttr(el,'swaf:style:mouseover');
		var mousedown=Swaf.UI.Util.getStrAttr(el,'swaf:style:mousedown');
		var edit=Swaf.UI.Util.getStrAttr(el,'swaf:style:edit');
		var drag=Swaf.UI.Util.getStrAttr(el,'swaf:style:drag');
		var disabled=Swaf.UI.Util.getStrAttr(el,'swaf:style:disabled');
		var ret={};
		
		if (normal) ret['normal']=Swaf.UI.Util.strToStyleObj(normal);
		if (select) ret['select']=Swaf.UI.Util.strToStyleObj(select);
		if (opened) ret['opened']=Swaf.UI.Util.strToStyleObj(opened);
		if (closed) ret['closed']=Swaf.UI.Util.strToStyleObj(closed);
		if (mouseover) ret['mouseover']=Swaf.UI.Util.strToStyleObj(mouseover);
		if (mousedown) ret['mousedown']=Swaf.UI.Util.strToStyleObj(mousedown);
		if (edit) ret['edit']=Swaf.UI.Util.strToStyleObj(edit);
		if (drag) ret['drag']=Swaf.UI.Util.strToStyleObj(drag);
		if (disabled) ret['disabled']=Swaf.UI.Util.strToStyleObj(disabled);
		
		return ret;
	},
	setStyle:function(el,obj) {
		style=this.getStyle(el);

		if (style.normal) obj.setNormalStyle(style.normal);
		if (style.select) obj.setSelectStyle(style.select);
		if (style.opened) obj.setOpenedStyle(style.opened);
		if (style.closed) obj.setClosedStyle(style.closed);
		if (style.edit) obj.setEditStyle(style.edit);
		if (style.drag) obj.setDragStyle(style.drag);
		if (style.disabled) obj.setDisableStyle(style.disabled);
		if (style.mousedown) obj.setDownStyle(style.mousedown);
		if (style.mouseover) obj.setOverStyle(style.mouseover);
	},
	getElementIndex:function() {
		return this.elementIndex;
	},
	createElementId:function(uitype) {
		var ret='swaf_ui_'+uitype+'_'+this.elementIndex;
		this.elementIndex++;
		return ret;
	},
registUI:function(def) {
	def.type=def.base.prototype.type;
	def.form_ns='swaf:ui:'+def.type;				// swaf:ui:list=xxx
	def.attr_ns='swaf:'+def.type+':';						// swaf:list:xxx=xxx
	this.uidef[def.type]=def;
},
clearUIDef:function() {
	this.uidef=null;
},
createUI:function(el,processor) {
	var uitype=el.getAttribute('swaf:ui');
	var def,ret=null;
	def=this.uidef[uitype];
	if (uitype && def) {
		ret=this.createUIMain(el,def,processor);
	}
	el=null;
	return ret;
},
getAttribute:function(el,def,attrname,type,defaultValue) {
	var attr=def.attr_ns+attrname;
	var defvalue,tmp;
	switch(type) {
		case 'bool' :
			if (defaultValue!=undefined) defvalue=(defaultValue.toUpperCase()=='TRUE')?true:false;
			else defvalue=null;
			return Swaf.UI.Util.getBooleanAttr(el,attr,defvalue);
			break;
		case 'int' :
			if (defaultValue!=undefined) defvalue=parseInt(defaultValue,10);
			else defvalue=null;
			return Swaf.UI.Util.getIntAttr(el,attr,defvalue);
			break;
		case 'str' :
			tmp=Swaf.UI.Util.getStrAttr(el,attr);
			if (!tmp && defaultValue) tmp=defaultValue;
			return tmp;
			break;
	}
	return null;
},
processAttribute:function(el,def,attrdef,retst) {
	var split1=attrdef.split('=');		// split for default
	var defaultValue=null,type='str',name;
	if (split1.length>1) defaultValue=split1[1];
	var split2=split1[0].split('(');	// split for type
	if (split2.length>1) type=split2[1].substr(0,split2[1].length-1);
	name=split2[0];
	retst[name]=this.getAttribute(el,def,name,type,defaultValue);
},
createUIStructure:function(el,uitype,def,processor,forceId) {
	var i,j,childlist,retnodelist,retnode;
	var formdef=def.form[uitype];
	var attrdeflist;
	if (typeof formdef == 'string') {
		formdef=new Array(1);
		formdef[0]=def.form[uitype];
	}
	if (!el.id || el.id.length==0 || forceId==true) {
		el.id='swaf_ui_'+uitype+'_'+this.elementIndex;
		this.elementIndex++;
	}
	var ret={elementId:el.id};
	if (def.attribute[uitype]) {
		ret.attribute={};
		// read attribute
		attrdeflist=def.attribute[uitype];
		for(i=0;i<attrdeflist.length;i++) this.processAttribute(el,def,attrdeflist[i],ret.attribute);
	}
	if (formdef) {
		var childs=Swaf.UI.Util.getChildElement(el,def.form_ns,def.type,processor);
		for(i=0;i<formdef.length;i++) {
			if (childs[formdef[i]]) {
				childlist=childs[formdef[i]];
				retnodelist=new Array();
				for(j=0;j<childlist.length;j++) {
					retnode=this.createUIStructure(document.getElementById(childlist[j]),formdef[i],def,processor);
					retnodelist.push(retnode);
				} // for j
				ret[formdef[i]]=retnodelist;
			} // if
		} // for i
		childs=null;
	}
	el=null;
	return ret;
},
createUIMain:function(el,def,processor) {
	var enable=this.getAttribute(el,def,'enable','bool','true');
	var uistructure=this.createUIStructure(el,def.type,def,processor);
	var ret;
	
	ret=this.createUIObject(def.base,el,uistructure,enable,processor);
	uistructure=null;
	return ret;
},
createUIObject:function(base,el,uidef,enable,processor) {
	var object,style;
		
	object=new base(enable,processor,uidef);
		
	this.setStyle(el,object);
	object.setElementId(el.id);
	
	return object;
}

};

Swaf.UI.Util={
	getBooleanAttr:function(el,attrname,defvalue) {
		var tmp=el.getAttribute(attrname);
		var value;
		if (tmp) {
			value=tmp.toUpperCase();
			return (value=='TRUE');
		}
		return defvalue;
	},
	getIntAttr:function(el,attrname,defvalue) {
		var tmp=el.getAttribute(attrname);
		if (tmp) {
			return parseInt(tmp,10);
		}
		return defvalue;
	},
	getStrAttr:function(el,attrname) {
		return el.getAttribute(attrname);
	},
	strToStyleObj:function(strStyle) {
		var i;
		var styles=strStyle.split(';');
		var stylenode;
		var ret={};
		
		for( i=0; i< styles.length; i++ ) {
			stylenode=styles[i].split(':');
			if (stylenode.length<2) {
				if (styles.length==1) {
					return strStyle;
					break;
				}
				continue;
			}
			ret[stylenode[0].camelize()]=stylenode[1];
		}
		return ret;
	},
	getChildElement:function(el,attrname,uitype,processor) {
		var i,node,attr,index,nodelist,subret,uicategory;
		var ret={};
		var ELEMENT_NODE=1;

		for(node=el.firstChild;node;node=node.nextSibling) {
			if (node.nodeType==ELEMENT_NODE) {
				try {
					uicategory=node.getAttribute('swaf:ui');
				}
				catch (e){
					uicategory=null;
				}
				if (uicategory) {
					if (!node.id) {
						node.id='swaf_ui_'+uicategory+'_'+Swaf.UI.elementIndex;
						Swaf.UI.elementIndex++;
					}
					Swaf.UI.createUI(node,uicategory,processor);
					if (uicategory!=uitype) {
						subret=this.getChildElement(node,attrname,uitype,processor);
						Object.extend(ret,subret);
					}
				}
				try {
					attr=node.getAttribute(attrname);
				} // try
				catch (e){
					attr=null;
				}
				if (attr) {
					if (!ret[attr]) ret[attr]=new Array();
					if (!node.id) {
						node.id='swaf_ui_'+uitype+'_'+Swaf.UI.elementIndex;
						Swaf.UI.elementIndex++;
					}
					ret[attr].push(node.id);
				} else {
					// 2006.11.6 속성이 없을 때
					subret=this.getChildElement(node,attrname,uitype,processor);
					Object.extend(ret,subret);
				}
			} // if
		} // for
		return ret;
	},
	cleanChildElement:function(el) {
		var node;
		var ELEMENT_NODE=1;

		for(node=el.firstChild;node;node=node.nextSibling) {
			if (node.nodeType==ELEMENT_NODE) {
				node.id='';
				Swaf.unlinkInstance(node);
				node.removeAttribute('swaf_system:list:listid');
				node.removeAttribute('swaf_system:list:itemindex');
				
				this.cleanChildElement(node);
			} // if
		} // for
	},
	applyTemplate:function(templateId,data,assignId) {
		var result,newItem;
		var tmpEl=document.getElementById('_swaf_template_tmp');
		if (!tmpEl) {
			tmpEl=document.createElement('div');
			tmpEl.id='_swaf_template_tmp';
			Swaf.Dom.hideElement(tmpEl);
			document.body.appendChild(tmpEl);
		}
		result=document.getElementById(templateId).innerHTML;
		for(selector in data) {
			if (data[selector]==undefined) data[selector]='';
			var regexp=new RegExp('%%'+selector+'%%','gm');
			result=result.replace(regexp,data[selector]);
			regexp=null;
		}
		tmpEl.innerHTML=result;
		newItem=Swaf.Dom.getFirstChildNode(tmpEl).cloneNode(true);
		var expando_name=newItem.getAttribute('swaf:template:object_set');
		var new_id=newItem.getAttribute('swaf:template:id');
		if (new_id) {
			newItem.id=new_id;
		}
		else {
			newItem.id='';
			if (assignId==true) {
				newItem.id='swaf_ui_tpl_'+Swaf.UI.elementIndex;
				this.elementIndex++;
			}
		}
		
		tmpEl.innerHTML='';
		tmpEl=null;
		// apply json to expando attribute 2006.12.19
		if (expando_name) {
			var name_list=expando_name.split(',');
			newItem.swap_template={};
			for(var i=0;i<name_list.length;i++) {
				newItem.swap_template[name_list[i]]=data[name_list[i]];
			}
		}
		return newItem;
	}
};

Swaf.UI.Base=Class.create();
Object.extend(Swaf.UI.Base.prototype, Swaf.Base.prototype);
Object.extend(Swaf.UI.Base.prototype, {
	bEnable:true,
	normalStyle:null,
	selectStyle:null,
	openedStyle:null,
	closedStyle:null,
	overStyle:null,
	downStyle:null,
	editStyle:null,
	dragStyle:null,
	disableStyle:null,
	msgTarget:null,
	uiobject:null,
	
	getEnable:function() {
		return this.bEnable;
	},
	setNormalStyle:function(style) {
		this.normalStyle=style;
	},
	setDisableStyle:function(style) {
		this.disableStyle=style;
	},
	setSelectStyle:function(style) {
		this.selectStyle=style;
	},
	setOpenedStyle:function(style) {
		this.openedStyle=style;
	},
	setClosedStyle:function(style) {
		this.closedStyle=style;
	},
	setOverStyle:function(style) {
		this.overStyle=style;
	},
	setDownStyle:function(style) {
		this.downStyle=style;
	},
	setEditStyle:function(style) {
		this.editStyle=style;
	},
	setDragStyle:function(style) {
		this.dragStyle=style;
	},
	setMsgTarget:function(object) {
		this.msgTarget=object;
	},
	fireEvent:function(evttype,src,evt,value) {
		var fnName;
		if (this.msgTarget) {
				if (typeof this.msgTarget == 'function') return this.msgTarget(evttype,this.type,src,evt,value);
				else {
					var firstchar=evttype.substr(0,1);
					firstchar=firstchar.toUpperCase();
					fnName='on'+firstchar+evttype.substr(1,evttype.length-1);
				 	if (this.msgTarget[fnName]) return this.msgTarget[fnName].call(this.msgTarget,this.type,src,evt,value);
			  }
		}
	},
	init:function(enable,processor,uiobject) {
		this.initBase(enable,processor,uiobject);
	},
	initBase:function(enable,processor,uiobject) {
		this.bEnable=enable;
		if (processor) this.setMsgTarget(processor);
		this.uiobject=uiobject;
	},
	cbAfterSetElement:function() {
			this.initUI();
			this.setEnable(this.bEnable,true);
	},
	getAttribute:function(name,node) {
		if (!node) node=this.uiobject;
		return node.attribute[name];
	},
	setAttribute:function(name,value,node) {
		if (!node) node=this.uiobject;
		node.attribute[name]=value;
	},
	getChildNodeList:function(nodename) {
		return this.uiobject[nodename];
	},
	setEnable:function(enable,bForce) {
		if (bForce!=true && this.bEnable==enable) return;
		this.bEnable=enable;
		if (enable) {
			this.enableBaseAction();
			if (this.enableUI) this.enableUI();
			if (this.normalStyle) Swaf.Dom.setCSS(this.getElement(),this.normalStyle);
		} else {
			this.disableBaseAction();
			if (this.disableUI) this.disableUI();
			if (this.disableStyle) Swaf.Dom.setCSS(this.getElement(),this.disableStyle);
		}
	}
});

Swaf.UI.BaseAction= Class.create();
Object.extend(Swaf.UI.BaseAction.prototype, Swaf.UI.Base.prototype);
Object.extend(Swaf.UI.BaseAction.prototype, {
		// local member
		baseListener:null,
		
		enableBaseAction:function() {
			var arrListener=[];
			if (this.overStyle || this.overImg) {
				arrListener.push(
				{
					event:'mouseover',
					listener:this.onMouseOverBase.bind(this)
				},
				{
					event:'mouseout',
					listener:this.onMouseOutBase.bind(this)
				}
				);
			}
			if (this.downStyle || this.downImg) {
				arrListener.push(
				{
					event:'mousedown',
					listener:this.onMouseDownBase.bind(this)
				},
				{
					event:'mouseup',
					listener:this.onMouseUpBase.bind(this)
				}
				);
			}
			if (arrListener.length>0) {
				this.baseListener=new Swaf.Listener.Event(arrListener);
				this.baseListener.applyListener(this.getElement());
			}
		},
		disableBaseAction:function(enable) {
			if (this.baseListener) {
				this.baseListener.removeListener();
				delete this.baseListener;
				this.baseListener=null;
			}
		},
		// event listener
		onMouseOverBase:function(evt,src) {
			var cont=true;
			if (this.onMouseOver) cont=this.onMouseOver(evt,src);
			if (cont && this.overStyle) Swaf.Dom.setCSS(this.getElement(),this.overStyle);
		},
		onMouseOutBase:function(evt,src) {
			var cont=true;
			if (this.onMouseOut) cont=this.onMouseOut(evt,src);
			if (cont && this.normalStyle) Swaf.Dom.setCSS(this.getElement(),this.normalStyle);
		},
		onMouseDownBase:function(evt,src) {
			var cont=true;
			if (this.onMouseDown) cont=this.onMouseDown(evt,src);
			if (cont && this.downStyle) Swaf.Dom.setCSS(this.getElement(),this.downStyle);
		},
		onMouseUpBase:function(evt,src) {
			var cont=true;
			if (this.onMouseUp) cont=this.onMouseUp(evt,src);
			if (cont) {
				var rect=Swaf.Dom.getRect(this.getElement());
				if (evt && Swaf.Util.ptInRect(Event.pointerX(evt),Event.pointerY(evt),rect.x,rect.y,rect.width,rect.height)) {
//				rect.ptInRect(Event.pointerX(evt),Event.pointerY(evt))) {
					this.onMouseOverBase(evt,src);
				} else {
					this.onMouseOutBase(evt,src);
				}
			}
		}
});

Swaf.UI.Tree= Class.create();
Object.extend(Swaf.UI.Tree.prototype, Swaf.UI.BaseAction.prototype);
Object.extend(Swaf.UI.Tree.prototype, {
		type:'tree',
		indent:15,
		expanded:true,
		
		st_openimg:null,
		st_closeimg:null,
		st_opentxt:null,
		st_closetxt:null,
		st_normalimg:null,
		st_selectimg:null,
		st_normaltxt:null,
		st_selecttxt:null,
		
		openaction:'click',
		closeaction:'click',
		editaction:'dblclick',
		
		edit:false,
		editterm:null,
		editnonterm:null,
		editmaxlen:30,
		editroot:null,
		
		selectable:false,
		selectableterm:null,
		selectablenonterm:null,
		selectableroot:null,
//		selnode:null,
		selectedItem:null,
		
		dnd : false,
		dndopacity:50,
		dndterm:null,
		dndnonterm:null,
		dndroot:null,
		dndrange:'free',
		
		arrNodeList:null,
		origindex:-1,

		itemSelectListener:null,
		
		// 2006.11.27 ajax support
		ajax:false,
		ajax_template:null,
		ajax_read:null,
		ajax_update:null,
		ajax_param:null,
		ajax_busy:null,
//		ajax_key:null,
		ajaxRequestFlag:false,
		ajaxRequest:null,
		ajax_addParam:null,
		// 2006.11.28 foldable option
		foldable:null,
		foldableroot:null,
		// 2006.12.07
		dndmaxdepth:0,
		// 2006.12.14
		childclass:null,

		initUI:function() {
			this.indent=this.getAttribute('indent');
			this.expanded=this.getAttribute('expanded');
			this.st_openimg=this.getAttribute('status:openimg');
			this.st_closeimg=this.getAttribute('status:closeimg');
			this.st_opentxt=this.getAttribute('status:opentxt');
			this.st_closetxt=this.getAttribute('status:closetxt');
			this.st_normalimg=this.getAttribute('status:normalimg');
			this.st_selectimg=this.getAttribute('status:selectimg');
			this.st_normaltxt=this.getAttribute('status:normaltxt');
			this.st_selecttxt=this.getAttribute('status:selecttxt');
			this.openaction=this.getAttribute('active:open');
			this.closeaction=this.getAttribute('active:close');
			this.edit=this.getAttribute('edit');
			this.editterm=this.getAttribute('edit:term');
			this.editnonterm=this.getAttribute('edit:nonterm');
			this.editroot=this.getAttribute('edit:root');
			this.editmaxlen=this.getAttribute('edit:maxlen');
			this.editaction=this.getAttribute('active:edit');
			this.selectable=this.getAttribute('selectable');
			this.selectableterm=this.getAttribute('selectable:term');
			this.selectablenonterm=this.getAttribute('selectable:nonterm');
			this.selectableroot=this.getAttribute('selectable:root');
			this.dnd=this.getAttribute('dnd');
			this.dndterm=this.getAttribute('dnd:term');
			this.dndnonterm=this.getAttribute('dnd:nonterm');
			this.dndroot=this.getAttribute('dnd:root');
			this.dndopacity=this.getAttribute('dnd:opacity');
			this.dndrange=this.getAttribute('dnd:range');
			// 2006.11.27 ajax support
			this.ajax=this.getAttribute('ajax');
			this.ajax_template=this.getAttribute('ajax:template');
			this.ajax_read=this.getAttribute('ajax:read');
			this.ajax_update=this.getAttribute('ajax:update');
			var tmp=this.getAttribute('ajax:param');
			if (tmp) {
				var tparam,arrt=tmp.split(',');
				if (arrt) {
					this.ajaxParam={};
					for(var i=0;i<arrt.length;i++) {
						tparam=arrt[i].split(':');
						this.ajaxParam[tparam[0]]=tparam[1];
					}
				}
			}
			this.ajax_busy=this.getAttribute('ajax:busy');
//			this.ajax_key=this.getAttribute('ajax:key');
			// 2006.11.28 foldable option
			this.foldable=this.getAttribute('foldable');
			this.foldableroot=this.getAttribute('foldable:root');
			// 2006.12.07
			this.dndmaxdepth=this.getAttribute('dnd:maxdepth');
			// 2006.12.14
			this.childclass=this.getAttribute('child:class');
			
			this.itemSelectListener=[
				{
					event:this.getAttribute('active:select'),
					listener:this.selectItem.bind(this)
				}
			];
			this.buildNodeList(this.edit,this.selectable,this.dnd,this.foldable);

		},
		onDestroy:function() {
			this.deleteAll();
		},
		enableUI:function() {
/*			this.listener=new Swaf.Listener.Event(this.arrListener);
			this.listener.applyListener(this.handle);*/
		},
		disableUI:function() {
/*			if (this.listener) {
				this.listener.removeListener();
				delete this.listener;
				this.listener=null;
			}*/
		},
		buildNodeList:function(editable,selectable,dndenable,foldable) {
			var i,index,curnode;
			if (this.arrNodeList) {
				delete this.arrNodeList;
				this.arrNodeList=null;
			}
			this.arrNodeList=new Array();
			index=this.buildNodeListSub(this.uiobject,0,0,-1,editable,selectable,dndenable,foldable);
		},
		buildNodeListSub:function(curnode,index,depth,parent,editable,selectable,dndenable,foldable) {
			var i,curnode,dropdown,edit,dnd,nodeselectable,item,tmpnode,root,bTerminal;
	
				// root, childs가 모두 있을 때
				if (curnode.root && curnode.childs) {
					bTerminal=(curnode.childs[0].node)?false:true;
					dropdown=this.setDropdown(curnode,depth,(parent==-1 && this.foldableroot!=null)?this.foldableroot:foldable);
					document.getElementById(curnode.childs[0].elementId).style.marginLeft=this.indent+'px';
					// set root listener
					dnd=this.setDnD(curnode,depth,(parent==-1 && this.dndroot!=null)?this.dndroot:(bTerminal && this.dndterm!=null)?this.dndterm:((!bTerminal && this.dndnonterm!=null)?this.dndnonterm:dndenable));
					edit=this.setEdit(curnode.root[0],depth,(parent==-1 && this.editroot!=null)?this.editroot:(bTerminal && this.editterm!=null)?this.editterm:((!bTerminal && this.editnonterm!=null)?this.editnonterm:editable));
					nodeselectable=this.getAttribute('selectable',curnode.root[0]);
					item=	{
						elementId:curnode.elementId,
						itemId:curnode.root[0].elementId,
						childsId:curnode.childs[0].elementId,
						editId:(edit)?edit.getElementId():null,
						selectHandleId:(curnode.root[0].selecthandle)?curnode.root[0].selecthandle[0].elementId:curnode.root[0].elementId,
						index:index, 
						depth:depth,
						rect:Swaf.Dom.getRect(document.getElementById(curnode.root[0].elementId)), 
						terminal:bTerminal,
						childlen:0,
						expanded:dropdown.isOpened(),
						parent:parent,
						dropdown:dropdown,
						edit:edit,
						dnd:dnd,
						selectListener:null,
						nodeselectable:nodeselectable,
						selectstatusId:(curnode.root[0].selectstatus)?curnode.root[0].selectstatus[0].elementId:null,
						// 2006.11.29
						template_data:null
					};
					document.getElementById(item.elementId).setAttribute('swaf_system:tree:index',index);
					document.getElementById(item.itemId).setAttribute('swaf_system:tree:index',index);
					this.arrNodeList.push(item);
					
					this.enableSelectListener(item,(parent==-1 && this.selectableroot!=null)?this.selectableroot:(bTerminal && this.selectableterm!=null)?this.selectableterm:((!bTerminal && this.selectablenonterm!=null)?this.selectablenonterm:selectable));

					root=index;
					if (!bTerminal) {
						index=this.buildNodeListSub(curnode.childs[0],index+1,depth+1,index,editable,selectable,dndenable,foldable);
						this.arrNodeList[root].childlen=index-root-1;
					} else {
						index++;
						this.arrNodeList[root].childlen=0;
					}
				// node들이 주루룩 있을 때
				} else if (curnode.node) {
					for(i=0;i<curnode.node.length;i++) {
						index=this.buildNodeListSub(curnode.node[i],index,depth,parent,editable,selectable,dndenable,foldable);
					}
				// root, child 모두 없을 때
				} else {
					// 2006.11.27. dummy root&child 구조로 전환
					var el=document.getElementById(curnode.elementId);
					var orig_html=el.innerHTML;
					el.innerHTML='<div id="'+curnode.elementId+'_root" swaf:ui:tree="root">'+orig_html+'</div><div id="'+curnode.elementId+'_childs" swaf:ui:tree="childs" '+(this.childclass?'class="'+this.childclass+'" ':'')+'style="display:none;"></div>';
					el=null;
					curnode.root=[{elementId:curnode.elementId+'_root',attribute:{}}];
					curnode.childs=[{elementId:curnode.elementId+'_childs',attribute:{}}];
					curnode.root[0].selecthandle=curnode.selecthandle; curnode.selecthandle=null;
					curnode.root[0].dndhandle=curnode.dndhandle; curnode.dndhandle=null;
					curnode.root[0].openhandle=curnode.openhandle; curnode.openhandle=null;
					curnode.root[0].editarea=curnode.editarea; curnode.editarea=null;
					curnode.root[0].openstatus=curnode.openstatus; curnode.openstatus=null;
					curnode.root[0].selectstatus=curnode.selectstatus; curnode.selectstatus=null;
					index=this.buildNodeListSub(curnode,index,depth,parent,editable,selectable,dndenable,foldable);
				}
				item=null;

			return index;
		},
		refreshTree:function(index,parent,length,depth,closed) {
			var i,item;
			
			for(i=0;i<length;i++) {
				item=this.arrNodeList[index];
				if (closed!=undefined && closed==true) item.rect=null;
				else item.rect=Swaf.Dom.getRect(document.getElementById(item.itemId));
				item.index=index;
				item.parent=parent;
				item.depth=depth;
				document.getElementById(item.elementId).setAttribute('swaf_system:tree:index',index);
				document.getElementById(item.itemId).setAttribute('swaf_system:tree:index',index);
				index++;
				if (item.childlen>0) {
					index=this.refreshTree(index,item.index,item.childlen,depth+1,(closed==true)?true:(item.dropdown.isOpened()==false));
					i+=item.childlen;
					item.terminal=false;
				} else {
					// 2006.11.27 childln==0
					Swaf.Dom.hideElement(document.getElementById(item.childsId));
					item.terminal=true;
				}
				if (index==this.arrNodeList.length) break;
			}
			return index;
		},
		refreshItemListener:function() {
			var i,parent,bTerminal,item,len=this.arrNodeList.length;
			var dnd,edit,selectable,foldable;
			
			for(i=0;i<len;i++) {
				item=this.arrNodeList[i];
				bTerminal=item.terminal;
				parent=item.parent;
				if (item.node_dndenable!=false) dnd=item.node_dndenable?true:((parent==-1 && this.dndroot!=null)?this.dndroot:(bTerminal && this.dndterm)?this.dndterm:((!bTerminal && this.dndnonterm)?this.dndnonterm:this.dnd));
				else dnd=false;
				if (item.node_editable!=false) edit=item.node_editable==true?true:((parent==-1 && this.editableroot!=null)?this.editableroot:(bTerminal && this.editableterm)?this.editableterm:((!bTerminal && this.editablenonterm)?this.editablenonterm:this.editable));
				else edit=false;
				if (item.nodeselectable!=false) selectable=item.nodeselectable==true?true:((parent==-1 && this.selectableroot!=null)?this.selectableroot:(bTerminal && this.selectableterm)?this.selectableterm:((!bTerminal && this.selectablenonterm)?this.selectablenonterm:this.selectable));
				else selectable=false;
				if (item.node_foldable!=false) foldable=item.node_foldable==true?true:((parent==-1 && this.foldableroot!=null)?this.foldableroot:this.foldable);
				else foldable=false;
				
				if (item.dnd) item.dnd.setEnable(dnd);
				if (item.edit) item.edit.setEnable(edit);
				if (item.dropdown) item.dropdown.setEnable(foldable);
				this.enableSelectListener(item,selectable);
			}
		},
		// 2006.11.27 delete all item
		deleteAll:function() {
			var i,item;
			if (this.arrNodeList) {
				for(i=0;i<this.arrNodeList.length;i++) {
					item=this.arrNodeList[i];
					if (item.dropdown) { item.dropdown.setEnable(false); delete item.dropdown;}
					if (item.edit) { item.edit.setEnable(false); delete item.edit;}
					if (item.dnd) { item.dnd.setEnable(false); delete item.dnd;}
					if (item.selectListener) { item.selectListener.removeListener(); delete item.selectListener;}
				}
				delete this.arrNodeList;
				this.arrNodeList=null;
			}
			this.selectedItem=null;
			this.getElement().innerHTML='';
		},
		enableSelectListener:function(item,selectable) {
			if (item.selectListener) this.disableSelectListener(item);
			if (!item.nodeselectable==false) return;
			if (selectable==true) {
				item.selectListener=new Swaf.Listener.Event(this.itemSelectListener);
				item.selectListener.applyListener(document.getElementById(item.selectHandleId));
			}
		},
		disableSelectListener:function(item) {
			if (item.selectListener) {
				item.selectListener.removeListener();
				delete item.selectListener;
				item.selectListener=null;
			}
		},
		setDnD:function(node,depth,enable) {
			var dndhandle;
			var dndenable;
			var root;

			dndenable=this.getAttribute('dnd',(node.root)?node.root[0]:node);
			node.node_dndenable=dndenable;
			if (dndenable==false) return;

	/*		if (node.root) {
				root=node.root[0];
				enable=(this.dndnonterm!=null)?this.dndnonterm:enable;
			} else {
				enable=(this.dndterm!=null)?this.dndterm:enable;
			}*/
			
			if (dndenable==undefined || dndenable==null) dndenable=enable;
			

			if (root) {
				if (root.dndhandle) dndhandle=root.dndhandle[0];
				else dndhandle=root;
			} else {
				dndhandle=node;
			}
				
			var uidef={
				elementId:node.elementId,
				attribute: {proxy:true,top:true,opacity:this.dndopacity},
				handle:[{elementId:dndhandle.elementId,attribute:{}}]
			};
			if (this.dragStyle) document.getElementById(node.elementId).setAttribute('swaf:style:drag',this.getElement().getAttribute('swaf:style:drag'));
			return Swaf.UI.createUIObject(Swaf.UI.DnD,document.getElementById(node.elementId),uidef,dndenable,this);
		},
		setEdit:function(node,depth,enable) {
			var editarea;
			var editable;

			if (node.root && node.childs) return;
			
			editable=this.getAttribute('edit',(node.root)?node.root[0]:node);
			node.node_editable=editable;
			if (editable==false) return;

			if (editable==undefined || editable==null) editable=enable;

			if (node.editarea) editarea=node.editarea[0];
			else editarea=node;
				
			var uidef={
				elementId:editarea.elementId,
				attribute: {maxlen:this.editmaxlen,enableHTML:false,active:this.editaction}
			};
			if (this.editStyle) document.getElementById(editarea.elementId).setAttribute('swaf:style:edit',this.getElement().getAttribute('swaf:style:edit'));
			return Swaf.UI.createUIObject(Swaf.UI.Edit,document.getElementById(editarea.elementId),uidef,editable,this);
		},
		setDropdown:function(tree,depth,enable) {
			var uidef,handle,body,openstatus,foldable;
			
			foldable=this.getAttribute('foldable',(tree.root)?tree.root[0]:tree);
			tree.node_foldable=foldable;
			if (foldable==undefined || foldable==null) foldable=enable;
			
			if (tree.root && tree.childs) {
				handle=(tree.root[0].openhandle)?tree.root[0].openhandle[0]:tree.root[0];
				body=tree.childs[0];
				openstatus=(handle.openstatus)?handle.openstatus[0]:null;
				uidef={
					elementId:tree.elementId,
					attribute:{expanded:(tree.attribute.expanded!=undefined)?tree.attribute.expanded:this.expanded,step:20},
					handle:[{elementId:handle.elementId,attribute:{openaction:this.openaction,closeaction:this.closeaction}}],
					body:[{elementId:body.elementId,attribute:{minsize:0}}]
				};
				if (openstatus) uidef.status=[{elementId:openstatus.elementId,attribute:{'status:openimg':this.st_openimg,'status:opentxt':this.st_opentxt,'status:closeimg':this.st_closeimg,'status:closetxt':this.st_closetxt}}];
				return Swaf.UI.createUIObject(Swaf.UI.DropDown,document.getElementById(tree.elementId),uidef,foldable,this);
			}
			return null;
		},
		setSelectStatus:function(item,bSelect) {
			var el;
			if (item.selectstatusId) {
				el=document.getElementById(item.selectstatusId);
				if (el) {
					if (el.src!=undefined && this.st_selectimg && this.st_normalimg) {
						el.src=(bSelect)?this.st_selectimg:this.st_normalimg;
					} else if (this.st_selecttxt && this.st_normaltxt) {
						el.innerHTML=(bSelect)?this.st_selecttxt:this.st_normaltxt;
					}
				}
				el=null;
			}
		},
		setSel:function(item) {
			
			if (this.selectedItem==item) return;
			
			if (this.selectedItem) {
				if (this.normalStyle) Swaf.Dom.setCSS(document.getElementById(this.selectedItem.itemId),this.normalStyle);
				this.setSelectStatus(this.selectedItem,false);
			}
			
			this.selectedItem=null;
			
			if (item) {
				if (this.selectStyle) Swaf.Dom.setCSS(document.getElementById(item.itemId),this.selectStyle);
				this.setSelectStatus(item,true);
				this.selectedItem=item;
			}
			this.fireEvent('select',this);
		},
		setParentWhenIntoTree:function(srcindex,destindex) {
			var src=this.arrNodeList[srcindex];
			var dest=this.arrNodeList[destindex];
			var parent,curitem,num;
			num=src.childlen+1;

			for(curitem=src;curitem.parent>=0;curitem=this.arrNodeList[curitem.parent]) {
				this.arrNodeList[curitem.parent].childlen-=num;
			}
			for(curitem=dest;curitem.parent>=0;curitem=this.arrNodeList[curitem.parent]) {
				this.arrNodeList[curitem.parent].childlen+=num;
			}
		},
		moveNodeListBefore:function(srcindex,destindex) {
			var src=this.arrNodeList[srcindex];
			var dest=this.arrNodeList[destindex];
			var result;
			if (srcindex<destindex) {
				result=this.arrNodeList.slice(0,srcindex).concat(
				this.arrNodeList.slice(srcindex+src.childlen+1,destindex),
				this.arrNodeList.slice(srcindex,srcindex+src.childlen+1),
				this.arrNodeList.slice(destindex,this.arrNodeList.length));
			} else {
				result=this.arrNodeList.slice(0,destindex).concat(
				this.arrNodeList.slice(srcindex,srcindex+src.childlen+1),
				this.arrNodeList.slice(destindex,srcindex),
				this.arrNodeList.slice(srcindex+src.childlen+1,this.arrNodeList.length));
			}
			this.arrNodeList.length=0;
			this.arrNodeList=result;
		},
		// 2006.12.7 depth 체크
		isEnableMoveInDepth:function(srcindex,destdepth) {
			var src=this.arrNodeList[srcindex];
			var srcdepth=0;
			for(var i=srcindex;i<=srcindex+src.childlen;i++) {
				srcdepth=Math.max(srcdepth,this.arrNodeList[i].depth);
			}
			srcdepth-=src.depth;
			
			if (this.dndmaxdepth>0 && destdepth+srcdepth>this.dndmaxdepth) return false;
			return true;
		},
		// 2006.11.27 srcindex를 parent의 child로 넣는다.
		insertChild:function(srcindex,parent) {
			var src=this.arrNodeList[srcindex];
			var dest=this.arrNodeList[parent];
			var curitem,num;
			
			if (this.isEnableMoveInDepth(srcindex,dest.depth+1)==false) return;

			num=src.childlen+1;
			for(curitem=src;curitem.parent>=0;curitem=this.arrNodeList[curitem.parent]) {
				this.arrNodeList[curitem.parent].childlen-=num;
			}
			for(curitem=dest;;curitem=this.arrNodeList[curitem.parent]) {
				curitem.childlen+=num;
				if (curitem.parent<0) break;
			}

			if (parent==this.arrNodeList.length-1) {
				var moveArr=this.arrNodeList.splice(srcindex,src.childlen+1);
				this.arrNodeList=this.arrNodeList.concat(moveArr);
				moveArr=null;
			} else {
				this.moveNodeListBefore(srcindex,parent+1);
			}

			var childel=document.getElementById(dest.childsId);
			Swaf.Dom.showElement(childel);
			childel.appendChild(document.getElementById(src.elementId));
			childel=null;
			this.refreshTree(0,-1,this.arrNodeList.length,0);
/*				{
					var outmsg='insertChild('+srcindex+','+parent+')<BR>';
					//outmsg=index+' - '+item.index+' - ['+$(item.elementId).innerHTML.stripTags()+']<BR>';
					for(var i=0;i<this.arrNodeList.length;i++) {
						var eid=this.arrNodeList[i].itemId;
						outmsg+=i+'('+this.arrNodeList[i].index+') - '+eid+' - ['+$(eid).innerHTML.stripTags()+'] / '+this.arrNodeList[i].parent+' / '+this.arrNodeList[i].childlen+' / '+this.arrNodeList[i].rect+'<BR>';
					}
					$('debugmsg').innerHTML=outmsg;
				}*/
			return true;
		},
		moveBefore:function(srcindex,destindex) {
			var src=this.arrNodeList[srcindex];
			var dest=this.arrNodeList[destindex];
			if (srcindex+1==destindex && src.depth==dest.depth) return;

			if (srcindex<destindex && destindex<srcindex+src.childlen) return;
			if ((this.dndrange=='samelevel' || this.dndrange=='insiblings') && src.depth!=dest.depth) return;
			if (this.isEnableMoveInDepth(srcindex,dest.depth)==false) return;

			this.setParentWhenIntoTree(srcindex,destindex);
			
			this.moveNodeListBefore(srcindex,destindex);
			
			var destel=document.getElementById(dest.elementId);
			destel.parentNode.insertBefore(document.getElementById(src.elementId),destel);
			destel=null;
//			$('debugmsg2').innerHTML=$(src.elementId).innerHTML.stripTags()+'<BR>'+$(dest.elementId).parentNode.innerHTML.stripTags();

			this.refreshTree(0,-1,this.arrNodeList.length,0);
	/*			{
					var outmsg='moveBefore('+srcindex+','+destindex+')<BR>';
					//outmsg=index+' - '+item.index+' - ['+$(item.elementId).innerHTML.stripTags()+']<BR>';
					for(var i=0;i<this.arrNodeList.length;i++) {
						var eid=this.arrNodeList[i].itemId;
						outmsg+=i+'('+this.arrNodeList[i].index+') - '+eid+' - ['+$(eid).innerHTML.stripTags()+'] / '+this.arrNodeList[i].parent+' / '+this.arrNodeList[i].childlen+' / '+this.arrNodeList[i].rect+'<BR>';
					}
					$('debugmsg').innerHTML=outmsg;
				}*/

		},
		moveAfter:function(srcindex,destindex,bSibling) {
			//if (srcindex==destindex+1) return;
			var src=this.arrNodeList[srcindex];
			var dest=this.arrNodeList[destindex];
			var len=this.arrNodeList.length;
			var parent=this.arrNodeList[dest.parent];
			var destlevel,bAppendItem=false;

			if (srcindex<destindex && destindex<srcindex+src.childlen) return;
			if (this.isEnableMoveInDepth(srcindex,dest.depth)==false) {
				// 2007.1.26 depth 제한이 되어있을 때 가장 마지막에 추가시
				if (destindex==len-1) {
					for(;;) {
						if (dest.parent==-1) break;
						dest=this.arrNodeList[dest.parent];
					}
					destindex=dest.index;
					bSibling=true;
					bAppendItem=true;
				}
				else return;
			}

			destlevel=destindex;
			if (dest.terminal==false) {
				if (!dest.dropdown.isOpened()) {
						destindex=destindex+dest.childlen+1;
						if (destindex<len) {
							this.moveBefore(srcindex,destindex);
							return;
						} else {
							destindex=len-1;
							destlevel=dest.index;
						}
				}
			} else if (bSibling!=true) {
				// after terminal
				if (this.insertChild(srcindex,destindex)==true) return;
			}
			
			if ((this.dndrange=='samelevel' || this.dndrange=='insiblings') && src.depth!=this.arrNodeList[destlevel].depth) return;
			if (destindex==len-1 || bAppendItem==true) {
				this.setParentWhenIntoTree(srcindex,destlevel);
				var moveArr=this.arrNodeList.splice(srcindex,src.childlen+1);
				this.arrNodeList=this.arrNodeList.concat(moveArr);
				moveArr=null;

				document.getElementById(dest.elementId).parentNode.insertBefore(document.getElementById(src.elementId),null);
			} else if (dest.parent>=0 && src.parent>=0 && ((src.parent==dest.parent && destindex==parent.index+parent.childlen)||(src.parent!=dest.parent && destindex==parent.index+parent.childlen+1))) {

				this.setParentWhenIntoTree(srcindex,destlevel);
				
				this.moveNodeListBefore(srcindex,destindex+1);

				document.getElementById(dest.elementId).parentNode.insertBefore(document.getElementById(src.elementId),null);
			} else {
				this.moveBefore(srcindex,destindex+1);
			}
			this.refreshTree(0,-1,this.arrNodeList.length,0);
	/*			{
					var outmsg='moveAfter('+srcindex+','+destindex+')<BR>';
					//outmsg=index+' - '+item.index+' - ['+$(item.elementId).innerHTML.stripTags()+']<BR>';
					for(var i=0;i<this.arrNodeList.length;i++) {
						var eid=this.arrNodeList[i].itemId;
						outmsg+=i+'('+this.arrNodeList[i].index+') - '+eid+' - ['+$(eid).innerHTML.stripTags()+'] / '+this.arrNodeList[i].parent+' / '+this.arrNodeList[i].childlen+' / '+this.arrNodeList[i].rect+'<BR>';
					}
					$('debugmsg').innerHTML=outmsg;
				}*/

		},
		checkNodeOver:function(x,y,item) {
			var i,rect,checkHeight,ret,curitem,tmpitem,skip;
			var bImport=false;
			
			ret=false;
				for(i=0;i<this.arrNodeList.length;i++) {
					curitem=this.arrNodeList[i];
					if (curitem==item) continue;
					rect=curitem.rect;
					if (!rect) continue;
					if ((this.dndrange=='samelevel' || this.dndrange=='insiblings') && item.depth!=curitem.depth) continue;
					if (this.dndrange=='insubtree' && i==item.parent) continue;
					
					if (curitem.parent>=0) {
						skip=false;
						for(tmpitem=curitem;;tmpitem=this.arrNodeList[tmpitem.parent]) {
							if (tmpitem.index==item.index) { skip=true; break; }
							if (tmpitem.parent<0) break;
						}
						if (skip) continue;
					}
					
					checkHeight=rect.y+rect.height/2;
					if (Swaf.Util.ptInRect(x,y,rect.x,rect.y,rect.width,rect.height)) {
//						$('coordmsg').innerHTML=x+','+y+' / '+checkHeight+' ['+rect.x+','+rect.y+'-'+(rect.x+rect.width)+','+(rect.y+rect.height)+']';
						if (checkHeight<y) {
							// after
//							if (!bImport && i+1==item.index) break;
//							if (bImport) this.importAfter(itemlist,itemindex,i);
							/*else */this.moveAfter(item.index,i);
							ret=true;
						} else {
							// before
//							if (!bImport && i-1==item.index) break;
//							if (bImport) this.importBefore(itemlist,itemindex,i);
							/*else*/ this.moveBefore(item.index,i);
							ret=true;
						}
						break;
					} else if (i==this.arrNodeList.length-1) {
							if (checkHeight<y) {
								document.getElementById('coordmsg').innerHTML='append last '+x+','+y+' / '+checkHeight+' ['+rect.x+','+rect.y+'-'+(rect.x+rect.width)+','+(rect.y+rect.height)+']';
								// after
//								if (!bImport && i+1==item.index) break;
//								if (bImport) this.importAfter(itemlist,itemindex,i);
/*								else*/ this.moveAfter(item.index,i,true);
								ret=true;
						}
					}
				} // for
			if (ret) this.fireEvent('move',item,this);
			return ret;
		},
		// event listener
		onOpen:function(uitype,src) {
			if (uitype=='dropdown') {
				var index=parseInt(src.getAttribute('swaf_system:tree:index'),10);
				var edit=this.arrNodeList[index].edit;
				if (edit && edit.isEditing()) return true;
			}
		},
		onClose:function(uitype,src) {
			return this.onOpen(uitype,src);
		},
		onOpened:function(uitype) {
			if (uitype=='dropdown') this.refreshTree(0,-1,this.arrNodeList.length,0);
		},
		onClosed:function(uitype) {
			if (uitype=='dropdown') this.refreshTree(0,-1,this.arrNodeList.length,0);
		},
		selectItem:function(evt,src) {
			var index=parseInt(src.getAttribute('swaf_system:tree:index'),10);
			this.setSel(this.arrNodeList[index]);
		},
		// dnd processor
		onStartDrag:function(uitype,src,evt) {
			var tmprect;
			var index=parseInt(src.getAttribute('swaf_system:tree:index'),10);
			var item=this.arrNodeList[index];
			this.refreshTree(0,-1,this.arrNodeList.length,0);
			if (this.dndrange=='free' || this.dndrange=='samelevel') this.dndRangeRect=Swaf.Dom.getRect(this.getElement());
			else {
				if (item.parent==-1) this.dndRangeRect=Swaf.Dom.getRect(this.getElement());
				else {
					this.dndRangeRect=Swaf.Dom.getRect(document.getElementById(this.arrNodeList[item.parent].elementId));
					tmprect=this.arrNodeList[item.parent].rect;
					this.dndRangeRect.y+=tmprect.height;
					this.dndRangeRect.height-=tmprect.height;
				}
			}
			this.origindex=index;
			this.origdepth=item.depth;
			item=null;
	/*			{
					var outmsg='';
					//outmsg=index+' - '+item.index+' - ['+$(item.elementId).innerHTML.stripTags()+']<BR>';
					for(var i=0;i<this.arrNodeList.length;i++) {
						var eid=this.arrNodeList[i].itemId;
						outmsg+=i+'('+this.arrNodeList[i].index+') - '+eid+' - ['+$(eid).innerHTML.stripTags()+'] / '+this.arrNodeList[i].parent+' / '+this.arrNodeList[i].childlen+' / '+this.arrNodeList[i].rect+'<BR>';
					}
					$('debugmsg').innerHTML=outmsg;
				}*/
		},
		onDrag:function(uitype,src,evt) {
            var index=parseInt(src.getAttribute('swaf_system:tree:index'),10);
            var item=this.arrNodeList[index];
            var x=Event.pointerX(evt);
            var y=Event.pointerY(evt);
        
            var ret=false;
              
            if (Swaf.Util.ptInRect(x,y,this.dndRangeRect.x,this.dndRangeRect.y,this.dndRangeRect.width,this.dndRangeRect.height)) {
                ret=this.checkNodeOver(x,y,item);
            }
        
            /* if (!ret && this.group) {
                this.checkExport(x,y,item);
            }*/
		},
		onEndDrag:function(uitype,src,evt) {
			var index=parseInt(src.getAttribute('swaf_system:tree:index'),10);
			var item=this.arrNodeList[index];
			if (this.origindex!=index || this.origdepth!=item.depth) {
				this.fireEvent('moved',this.arrNodeList[index],this);
			}
			this.origindex=-1;
			this.depthindex=-1;
			this.refreshItemListener();
/*				{
					var outmsg='';
					//outmsg=index+' - '+item.index+' - ['+$(item.elementId).innerHTML.stripTags()+']<BR>';
					for(var i=0;i<this.arrNodeList.length;i++) {
						var eid=this.arrNodeList[i].itemId;
						outmsg+=i+'('+this.arrNodeList[i].index+','+$(this.arrNodeList[i].elementId).getAttribute('swaf_system:tree:index')+','+$(this.arrNodeList[i].itemId).getAttribute('swaf_system:tree:index')+') - '+eid+' - ['+$(eid).innerHTML.stripTags()+'] / '+this.arrNodeList[i].parent+' / '+this.arrNodeList[i].childlen+' / '+this.arrNodeList[i].rect+'<BR>';
					}
					$('debugmsg').innerHTML=outmsg;
				}*/
			return true;
		},
		onKeypress:function(uitype,src,editel) {
			this.fireEvent('keypress',editel,this);
		},
		onChanged:function(uitype,src,value) {
			this.fireEvent('edit',this.arrNodeList[parseInt(src.getAttribute('swaf_system:tree:index'),10)],this);
		},
		onPrepareDrag:function(uitype,src,evt) {
			var index=parseInt(src.getAttribute('swaf_system:tree:index'),10);
			var edit=this.arrNodeList[index].edit;
			if (edit && edit.isEditing()) {
				return true;
			}
		},
		// method
		insertBefore:function(template,data,destindex,parent) {
			var dest,depth,tmp;
			
			if (parent>=this.arrNodeList.length) return;
			
			var newItemElement=Swaf.UI.Util.applyTemplate(template,data,true);
			var parentNode=this.arrNodeList[parent];
			var orig_html=newItemElement.innerHTML;
			var id=newItemElement.id;
			newItemElement.innerHTML='<div id="'+id+'_root" swaf:ui:tree="root">'+orig_html+'</div><div id="'+id+'_childs" swaf:ui:tree="childs" '+(this.childclass?'class="'+this.childclass+'" ':'')+'style="display:none;"></div>';
			
			if (destindex>=0) {
				dest=this.arrNodeList[destindex];
				depth=dest.depth;
			} else {
				dest=null;
				if (parent>=0) {
					depth=this.arrNodeList[parent].depth+1;
				} else {
					depth=0;
				}
			}
			
			if (parent>=0 && parentNode.terminal) Swaf.Dom.showElement(document.getElementById(parentNode.childsId));

			if (destindex>=0) {
				parent=dest.parent;
				document.getElementById(dest.elementId).parentNode.insertBefore(newItemElement,dest);
			}
			else {
				if (parent>=0) {
					document.getElementById(parentNode.childsId).appendChild(newItemElement);
				} else {
					this.getElement().appendChild(newItemElement);
				}
			}
				
			var curnode=Swaf.UI.createUIStructure(newItemElement,'node',Swaf.UI.uidef['tree'],this);
			newItemElement=null;
			
			
			var dropdown=this.setDropdown(curnode,depth,(parent==-1 && this.foldableroot!=null)?this.foldableroot:this.foldable);
			document.getElementById(curnode.childs[0].elementId).style.marginLeft=this.indent+'px';
			// set root listener
			var dnd=this.setDnD(curnode,depth,(parent==-1 && this.dndroot!=null)?this.dndroot:(this.dndterm!=null?this.dndterm:this.dnd));
			var edit=this.setEdit(curnode.root[0],depth,(parent==-1 && this.editroot!=null)?this.editroot:(this.editterm!=null?this.editterm:this.edit));
			var nodeselectable=this.getAttribute('selectable',curnode.root[0]);
			var item=	{
				elementId:curnode.elementId,
				itemId:curnode.root[0].elementId,
				childsId:curnode.childs[0].elementId,
				editId:(edit)?edit.getElementId():null,
				selectHandleId:(curnode.root[0].selecthandle)?curnode.root[0].selecthandle[0].elementId:curnode.root[0].elementId,
				index:0, 
				depth:depth,
				rect:Swaf.Dom.getRect(document.getElementById(curnode.root[0].elementId)), 
				terminal:true,
				childlen:0,
				expanded:dropdown.isOpened(),
				parent:parent,
				dropdown:dropdown,
				edit:edit,
				dnd:dnd,
				selectListener:null,
				nodeselectable:nodeselectable,
				selectstatusId:(curnode.root[0].selectstatus)?curnode.root[0].selectstatus[0].elementId:null,
				template_data:data
			};
			
			this.enableSelectListener(item,(parent==-1 && this.selectableroot!=null)?this.selectableroot:(this.selectableterm!=null)?this.selectableterm:this.selectable);

			if (destindex>=0) {
				this.arrNodeList.splice(destindex,0,item);
			}
			else {
				if (parent>=0) {
					this.arrNodeList.splice(parentNode.index+parentNode.childlen+1,0,item);
				} else {
					this.arrNodeList.push(item);
				}
			}
			
			if (parent>=0) {
				for(tmp=parentNode;;tmp=this.arrNodeList[tmp.parent]) {
					tmp.childlen++;
					if (tmp.parent<0) break;
				}
			}
			parentNode=null;

			this.refreshTree(0,-1,this.arrNodeList.length,0);
			this.refreshItemListener();
/*				{
					var outmsg='insertBefore('+destindex+','+parent+')<BR>';
					//outmsg=index+' - '+item.index+' - ['+$(item.elementId).innerHTML.stripTags()+']<BR>';
					for(var i=0;i<this.arrNodeList.length;i++) {
						var eid=this.arrNodeList[i].itemId;
						outmsg+=i+'('+this.arrNodeList[i].index+'/'+this.arrNodeList[i].terminal+') - '+eid+' - ['+$(eid).innerHTML.stripTags()+'] / '+this.arrNodeList[i].parent+' / '+this.arrNodeList[i].childlen+' / '+this.arrNodeList[i].rect+'<BR>';
					}
					$('debugmsg').innerHTML=outmsg;
				}*/
			return id;
		},
		deleteItem:function(index) {
			var item;
			if (index<0 || index>=this.arrNodeList.length) return;
			var len=this.arrNodeList[index].childlen+1;
			
			var delel=document.getElementById(this.arrNodeList[index].elementId);
			delel.innerHTML='';
			Swaf.Dom.deleteElement(delel);
			delel=null;

			for(i=index;i<index+len;i++) {
				item=this.arrNodeList[i];
				if (item.dropdown) { item.dropdown.setEnable(false); delete item.dropdown;}
				if (item.edit) { item.edit.setEnable(false); delete item.edit;}
				if (item.dnd) { item.dnd.setEnable(false); delete item.dnd;}
				if (item.selectListener) { item.selectListener.removeListener(); delete item.selectListener;}
				item=null;
			}
			this.arrNodeList.splice(index,len);
			if (this.selectedItem&&this.selectedItem.index>=index && this.selectedItem.index<index+len) this.selectedItem=null;
			this.refreshTree(0,-1,this.arrNodeList.length,0);
			this.refreshItemListener();
	/*			{
					var outmsg='deleteItem('+index+')<BR>';
					//outmsg=index+' - '+item.index+' - ['+$(item.elementId).innerHTML.stripTags()+']<BR>';
					for(var i=0;i<this.arrNodeList.length;i++) {
						var eid=this.arrNodeList[i].itemId;
						outmsg+=i+'('+this.arrNodeList[i].index+'/'+this.arrNodeList[i].terminal+') - '+eid+' - ['+$(eid).innerHTML.stripTags()+'] / '+this.arrNodeList[i].parent+' / '+this.arrNodeList[i].childlen+' / '+this.arrNodeList[i].rect+'<BR>';
					}
					$('debugmsg').innerHTML=outmsg;
				}*/
		},
		deleteChildItem:function(index) {
			var item;
			if (index<0) {this.deleteAll();this.arrNodeList=new Array();return;}
			
			var len=this.arrNodeList[index].childlen;
			
			if (len==0) return;
			
			document.getElementById(this.arrNodeList[index].childsId).innerHTML='';

			for(i=index+1;i<=index+len;i++) {
				item=this.arrNodeList[i];
				if (item.dropdown) { item.dropdown.setEnable(false); delete item.dropdown;}
				if (item.edit) { item.edit.setEnable(false); delete item.edit;}
				if (item.dnd) { item.dnd.setEnable(false); delete item.dnd;}
				if (item.selectListener) { item.selectListener.removeListener(); delete item.selectListener;}
				item=null;
			}
			this.arrNodeList.splice(index+1,len);
			if (this.selectedItem&&this.selectedItem.index>index && this.selectedItem.index<=index+len) this.selectedItem=null;
			this.refreshTree(0,-1,this.arrNodeList.length,0);
			this.refreshItemListener();
	/*			{
					var outmsg='deleteItem('+index+')<BR>';
					//outmsg=index+' - '+item.index+' - ['+$(item.elementId).innerHTML.stripTags()+']<BR>';
					for(var i=0;i<this.arrNodeList.length;i++) {
						var eid=this.arrNodeList[i].itemId;
						outmsg+=i+'('+this.arrNodeList[i].index+'/'+this.arrNodeList[i].terminal+') - '+eid+' - ['+$(eid).innerHTML.stripTags()+'] / '+this.arrNodeList[i].parent+' / '+this.arrNodeList[i].childlen+' / '+this.arrNodeList[i].rect+'<BR>';
					}
					$('debugmsg').innerHTML=outmsg;
				}*/
		},
		setAjaxParameter:function(object) {
			this.ajax_addParam=object;
		},
		loadAjax:function(index) {
			var item=null;
			if (this.ajax && this.ajaxRequestFlag==false) {
				var param={};
				if (index>=0) {
					item=this.arrNodeList[index];
					param.system_key=item.elementId;
					if (item.template_data) Object.extend(param,item.template_data);
				} else {
					param.system_key='root';
				}
				if (this.ajaxParam) Object.extend(param,this.ajaxParam);
				if (this.ajax_addParam) Object.extend(param,this.ajax_addParam);
				{
					this.ajaxRequest=new Swaf.Ajax.Request('get','JSON');
					this.ajaxRequest.setUrl(this.ajax_read);
					this.ajaxRequest.setCallbackHandler(this.ajaxRecv.bind(this));
					this.ajaxRequest.setParameter(param);
					if (this.ajax_busy) {
						Swaf.Dom.showElement(document.getElementById(this.ajax_busy));
						Swaf.Dom.setPosition(document.getElementById(this.ajax_busy),0,0,this.getElement());
					}
					this.ajaxRequest.request();
				}
				this.ajaxRequestFlag=true;
			}
		},
		ajaxRecv:function(response) {
			var i,el,itemid,recvlen=0,index,key,keypool;
			this.ajaxRequestFlag=false;
			if (this.ajax_busy) Swaf.Dom.hideElement(document.getElementById(this.ajax_busy));
			if (!response.isSuccess()) {
				alert('네트워크 오류 ['+this.ajaxUrl+'] : '+response.getStatus()+' - '+response.getStatusText());
			} else {
				var result=response.value;
				if (result.success) {
					itemid=result.system_key;
					key=result.node_key;

					if (itemid=='root') index=-1;
					else {
						el=document.getElementById(itemid);
						if (el) index=this.getItemIndex(el);
						else {
							response=null;
							this.ajaxRequest=null;
							return;
						}
						el=null;
					}
					
					this.deleteChildItem(index);
					
					if (key) keypool={};
					
					for (i=0;i<result.node.length;i++) {
						var id=this.insertBefore(this.ajax_template,result.node[i],-1,index);
						if (keypool) keypool[(result.node[i])[key]]=id;
					}
					result.node=null;
					
					// 11.30 child load
					if (key && result.childs) {
						for(i=0;i<result.childs.length;i++) {
							var depthchild=result.childs[i];
							for(selector in depthchild) {
								var pid=keypool[selector];
								var childlist=depthchild[selector];
								index=this.getItemIndex(document.getElementById(pid));
								for(var j=0;j<childlist.length;j++) {
									var id=this.insertBefore(this.ajax_template,childlist[j],-1,index);
									keypool[(childlist[j])[key]]=id;
								} // for j
							} // for selector
						} // for i
					} // if
					
					result=null;
				} else {
					alert('데이터 읽기 실패. 잠시후 다시 시도해 주세요.');
				}
			}
			this.fireEvent('ajaxloaded',this);
			response=null;
			this.ajaxRequest=null;
		},
		getSelItem:function() {
			return this.selectedItem;
		},
		getItemIndex:function(element) {
			var ret=element.getAttribute('swaf_system:tree:index');
			element=null;
			return ret;
		}
});

Swaf.UI.ScrollList=Class.create();
Object.extend(Swaf.UI.ScrollList.prototype, Swaf.UI.BaseAction.prototype);
Object.extend(Swaf.UI.ScrollList.prototype, {
		type:'scroll_list',
		// property
		step:20,
		interval:2,
		direction:'vert',
		ajax:false,
		ajaxTemplate:null,
		ajaxUrl:null,
		InPage:0,
		pagelen:15,
		itemCount:1,
		
		itemlist:null,
		existlist:null,
		sizelist:null,
		swafobjlist:null,
		innerDIV:null,
		hiddenDIV:null,
		preSpace:null,
		postSpace:null,
		spaceWidth:0,
		
		ajaxRequest:null,
		initialItemNum:0,
		ajaxRequestFlag:false,
		ajaxRequestStart:-1,
		ajaxParam:null,
		ajaxBusy:null,
		scrollTarget:null,

		bufferedSt:-1,
		bufferedEd:-1,
		
		curViewSt:-1,
		curViewEd:-1,
		
		lastIndex:0,
		curItemPos:0,
		scrollPos:0,
		scrollMax:0,
		relbar:null,
		
		// 2006.11.30
		ajaxkeepall:false,
		// 2006.12.15
		totalnum:-1,
		// 2007.1.3
		animation_show:false,
		
		initUI:function() {
			var bh,margin,i,tmpsize,size,el=this.getElement();
			
			this.direction=this.getAttribute('direction');
			this.step=this.getAttribute('step');
			this.interval=this.getAttribute('interval');
			this.ajax=this.getAttribute('ajax');
			this.ajaxTemplate=this.getAttribute('ajax:template');
			this.ajaxUrl=this.getAttribute('ajax:url');
			this.InPage=this.getAttribute('inpage');
			this.pagelen=this.getAttribute('ajax:pagelen');
			this.ajaxBusy=this.getAttribute('ajax:busy');
			var tmp=this.getAttribute('ajax:param');
			if (tmp) {
				var tparam,arrt=tmp.split(',');
				if (arrt) {
					this.ajaxParam={};
					for(i=0;i<arrt.length;i++) {
						tparam=arrt[i].split(':');
						this.ajaxParam[tparam[0]]=tparam[1];
					}
				}
			}
			this.ajaxkeepall=this.getAttribute('ajax:keepall');	// 2006.11.30
			this.animation_show=this.getAttribute('animation:show'); // 2007.1.3
			
			Swaf.Dom.setStyle(el,'overflow','hidden');

			bh=(this.direction=='horz');
			this.scrollPos=(bh)?el.scrollLeft:el.scrollTop;

			var tmp=this.getChildNodeList('item');
			
			if (tmp) {
				this.itemlist=new Array(tmp.length);
				this.sizelist=new Array(tmp.length);
				this.existlist=new Array(tmp.length);
				this.swafobjlist=new Array(tmp.length);
				this.initialItemNum=tmp.length;
				for(i=0;i<tmp.length;i++) {
					this.itemlist[i]=tmp[i].elementId;
				}
				this.scrollMax=tmpsize;
			} else {
				this.itemlist=new Array();
				this.sizelist=new Array();
				this.existlist=new Array();
				this.swafobjlist=new Array();
				this.initialItemNum=0;
				this.scrollMax=0;
			}
			tmp=null;
			
			this.innerDIV=document.createElement('div');
			el.appendChild(this.innerDIV);
			
			this.hiddenDIV=document.createElement('div');
			Swaf.Dom.hideElement(this.hiddenDIV);
			document.body.appendChild(this.hiddenDIV);
			
			for(i=0;i<this.itemlist.length;i++) {
				this.hiddenDIV.appendChild(document.getElementById(this.itemlist[i]));
				this.existlist[i]=-2;
			}
			
			size=Swaf.Dom.getSize(el);
			this.preSpace=this.id+'_prespace';
			this.postSpace=this.id+'_postspace';
			this.innerDIV.innerHTML='<div id="'+this.preSpace+'" '+((bh)?'style="float:left;"':'')+'></div><div id="'+this.postSpace+'" '+((bh)?'style="float:left;"':'')+'></div>';
			
			this.scrollPos=0;
			this.curItemPos=0;
			
			this.curViewSt=0;
			this.curViewEd=Math.min(this.initialItemNum,this.InPage);
			this.bufferedSt=this.bufferedEd=0;

			el=null;
			this.setListItemElement(0,this.initialItemNum);
//			this.syncScrollPos();
		},
		onDestroy:function() {
			this.itemlist=null;
			this.sizelist=null;
			this.innerDIV=null;
			this.swafobjlist=null;
			this.existlist=null;
			this.getElement().innerHTML='';
			Swaf.Dom.deleteElement(this.hiddenDIV);
			this.postSpace=null;
			this.preSpace=null;
			this.hiddenDIV=null;
		},
		deleteAll:function() {
			var i,el;
			// delete Ajax item
			for(i=0;i<this.itemlist.length;i++) {
				if (this.existlist[i]==1 || this.existlist[i]==2) {
					el=document.getElementById(this.itemlist[i]);
					if (el) Swaf.Dom.deleteElement(el);
					el=null;
					this.itemlist[i]=null;
					this.existlist[i]=-1;
					this.swafobjlist[i]=null;
					this.sizelist[i]=null;
				}
			}
//			this.ajaxViewSt=-1;
//			this.ajaxViewEd=-1;
			this.curViewSt=0;
			this.curViewEd=Math.min(this.initialItemNum,this.InPage);
//			this.lastView=true;
			this.lastIndex=0;
			this.curItemPos=0;
			this.scrollPos=0;
			this.itemlist.length=0;
			this.sizelist.length=0;
			this.existlist.length=0;
			this.swafobjlist.length=0;
			this.syncScrollPos();
			
		},
		enableUI:function() {
			this.enableBaseAction();
		},
		disableUI:function() {
			this.disableBaseAction();
		},
		setScrollBar:function(bar) {
			this.relbar=bar;
		},
		loadAjax:function(start) {
			if (this.ajax && this.ajaxRequestFlag==false) {
				this.ajaxRequestFlag=true;
				this.ajaxRequestStart=Math.floor(start) || 0;
				if (this.ajaxRequestStart<0) this.ajaxRequestStart=0;
				var param={
					start:this.ajaxRequestStart,
					length: this.pagelen
				};
				if (this.ajaxParam) Object.extend(param,this.ajaxParam);
				{
					this.ajaxRequest=new Swaf.Ajax.Request('get','JSON');
					this.ajaxRequest.setUrl(this.ajaxUrl);
					this.ajaxRequest.setCallbackHandler(this.ajaxRecv.bind(this));
					this.ajaxRequest.setParameter(param);
					if (this.ajaxBusy) {
						var el=this.getElement();
						var size=Swaf.Dom.getSize(el);
						Swaf.Dom.showElement(document.getElementById(this.ajaxBusy));
//						Swaf.Dom.setPosition($(this.ajaxBusy),0,0,this.getElement());
						Swaf.Dom.setRect(document.getElementById(this.ajaxBusy),0,0,size.width,size.height,this.getElement());
					}
					
					this.ajaxRequest.request();
				}
			} else {
				this.setListItemElement(start,this.initialItemNum);
			}
		},
		cancelAjax:function() {
			if (this.ajaxRequest) {
				this.ajaxRequest.abort();
				this.ajaxRequestFlag=false;
				if (this.ajaxBusy) Swaf.Dom.hideElement(document.getElementById(this.ajaxBusy));
				this.ajaxRequest=null;
			}
		},
		ajaxRecv:function(response) {
			var i,recvlen=0;
			this.ajaxRequestFlag=false;
			if (this.ajaxBusy) Swaf.Dom.hideElement(document.getElementById(this.ajaxBusy));
			if (!response.isSuccess()) {
				alert('네트워크 오류 ['+this.ajaxUrl+'] : '+response.getStatus()+' - '+response.getStatusText());
			} else {
				var result=response.value;
				if (result.success) {
					recvlen=result.length;
					this.totalnum=result.total;
					for (i=0;i<recvlen;i++) {
						this.addItemByTemplate(result.item[i]);
					}
					this.lastIndex=result.total+this.initialItemNum;
					this.bufferedSt=(this.bufferedSt>=0)?Math.min(this.bufferedSt,this.ajaxRequestStart+this.initialItemNum):this.ajaxRequestStart+this.initialItemNum;
					this.bufferedEd=(this.bufferedEd>=0)?Math.max(this.bufferedEd,this.ajaxRequestStart+recvlen+this.initialItemNum):this.ajaxRequestStart+recvlen+this.initialItemNum;
					result.item=null;
					result=null;
					this.refreshList();
				} else {
					alert('데이터 읽기 오류. 잠시후 다시 시도해 주세요.');
				}
			}
			this.setListItemElement(this.ajaxRequestStart+this.initialItemNum,this.ajaxRequestStart+recvlen+this.initialItemNum);
			if (this.relbar) this.relbar.refreshUI();
			this.fireEvent('ajaxloaded',this);
			response=null;
			this.ajaxRequest=null;
	//		this.debugScrollWindow();
		},
		// 2006.12.8.. Ajax수신한것과 같은 데이터를 직접 삽입
		setListData:function(data) {
			var recvlen=data.length;
			for (var i=0;i<recvlen;i++) {
				this.addItemByTemplate(data[i]);
			}
			this.lastIndex=data.length;
			this.refreshList();
			this.setListItemElement(0,data.length);
			data=null;
			if (this.relbar) this.relbar.refreshUI();
		},
		addItemByTemplate:function(item) {
			var newItem,existvalue;
			var itemindex=item.index+this.initialItemNum;
			existvalue=this.existlist[itemindex];
			if (existvalue>=0 && existvalue<=2) return;	// return if item exist
			newItem=Swaf.UI.Util.applyTemplate(this.ajaxTemplate,item);
			if (this.itemlist[itemindex]) newItem.id=this.itemlist[itemindex];
			else {
				if (!newItem.id) newItem.id='swaf_ui_'+this.type+'_'+Swaf.UI.elementIndex;
				Swaf.UI.elementIndex++;
			}
			// add list
			this.itemlist[itemindex]=newItem.id;
			this.existlist[itemindex]=2;
			this.hiddenDIV.appendChild(newItem);

			var uicategory=newItem.getAttribute('swaf:ui');
			if (uicategory) {
				this.swafobjlist[itemindex]=Swaf.UI.createUI(newItem,uicategory,this.msgTarget);
			}

			newItem=null;
			tplel=null;
		},
		refreshList:function() {
			var i,tmpsize,size,innerW,innerH;
			var bh=(this.direction=='horz');
			tmpsize=0;
			var elsize=Swaf.Dom.getSize(this.getElement());
			Swaf.Dom.setSize(document.getElementById(this.preSpace),elsize.width,elsize.height);
			Swaf.Dom.setSize(document.getElementById(this.postSpace),elsize.width,elsize.height);
			for(i=0;i<this.itemlist.length;i++) {
				if (this.existlist[i]==0 || this.existlist[i]==1) {
					var itemel=document.getElementById(this.itemlist[i]);
					size=Swaf.Dom.getSize(itemel);
					margin=Swaf.Dom.getMargin(itemel);
					this.sizelist[i]=(bh)?(size.width+margin.left+margin.right):(size.height+margin.top+margin.bottom);
					tmpsize+=this.sizelist[i];
					itemel=null;
				}
			}
			this.scrollMax=tmpsize;
			if (bh) {
				innerW=Math.max(this.scrollMax,elsize.width)+elsize.width*2;
				innerH=elsize.height;
				this.spaceWidth=elsize.width;
			} else {
				innerW=elsize.width;
				innerH=Math.max(this.scrollMax,elsize.height)+elsize.height*2;
				this.spaceWidth=elsize.height;
			}
			Swaf.Dom.setSize(this.innerDIV,innerW,innerH);
		},
		deleteItem:function(nIndex,len) {
			var i;

			for(i=nIndex;i<nIndex+len;i++) {
				if (this.existlist[i]==0) {
					this.hiddenDIV.appendChild(document.getElementById(this.itemlist[i]));
					this.existlist[i]=-2;
				} else if (this.existlist[i]==1) {
					Swaf.Dom.deleteElement(document.getElementById(this.itemlist[i]));
					this.existlist[i]=-1;
					if (this.swafobjlist[i]) delete this.swafobjlist[i];
				}
			}
		},
		setListItemElement:function(st,ed) {
			var i,existValue,itemid,lastitem=null,itemel;
			if (this.itemlist) {
				for(i=st;i<this.itemlist.length;i++) {
					if ((this.existlist[i]==0 || this.existlist[i]==1)) {lastitem=document.getElementById(this.itemlist[i]); break;}
				}
			}
			if (lastitem==null) {
				lastitem=document.getElementById(this.postSpace);
			}
			for(i=st;i<ed;i++) {
				existValue=this.existlist[i];
				itemid=this.itemlist[i];
				itemel=document.getElementById(itemid);
				switch(existValue) {
					case -2 : // in hidden div (permanent item)
						Swaf.Dom.hideElement(itemel);
						this.innerDIV.insertBefore(itemel,lastitem);
						this.existlist[i]=0;
						if (this.animation_show==true) Swaf.Animation.fadeInElement(itemel);
						else Swaf.Dom.showElement(itemel);
						break;
					case 2 : // in hidden div (ajax item)
						Swaf.Dom.hideElement(itemel);
						this.innerDIV.insertBefore(itemel,lastitem);
						this.existlist[i]=1;
						if (this.animation_show==true) Swaf.Animation.fadeInElement(itemel);
						else Swaf.Dom.showElement(itemel);
						break;
					case 0 : // in list (permanent item)
					case 1 : // in list (ajax item)
					case -1 : // deleted item (ajax item)
						continue;
				} // switch
				itemel=null;
			}
			lastitem=null;
			this.refreshList();
			this.setScrollPos(this.curViewSt);
			//this.debugScrollWindow();
		},
		loadAjaxPrev:function() {
			var st;
			if (this.curViewSt==0 || this.curViewSt>this.bufferedSt) return;
			if (this.ajaxkeepall==false) {
				this.deleteItem(this.curViewEd,this.bufferedEd-this.curViewEd);
				this.bufferedEd=this.curViewEd;
				this.setScrollPos(this.curViewSt);
			}
			st=this.bufferedSt-this.pagelen;
			if (st<this.initialItemNum) st=this.initialItemNum;
			this.loadAjax(st-this.initialItemNum);
		},
		loadAjaxNext:function() {
			var st;
			if (this.curViewEd==this.lastIndex || this.curViewEd<this.bufferedEd) return;
			if (this.ajaxkeepall==false) {
				this.deleteItem(this.bufferedSt,this.curViewSt-this.bufferedSt);
				this.bufferedSt=this.curViewSt;
				this.setScrollPos(this.curViewSt);
			}
			st=this.bufferedEd;
			this.loadAjax(st-this.initialItemNum);
		},
		setScrollPos:function(nIndex) {
			var i,pos=0;
			if (nIndex==-1) {
				this.curViewSt=this.curViewEd=0;
				pos=-this.spaceWidth;
				
			} else {
				this.curViewSt=nIndex;
				this.curViewEd=Math.min(this.lastIndex,nIndex+this.InPage);
				for(i=this.bufferedSt;i<nIndex;i++) {
					pos+=this.sizelist[i];
				}			
			}
			this.scrollPos=pos;
			this.syncScrollPos();
		},
		syncScrollPos:function() {
			if (this.direction=='horz') {
				this.getElement().scrollLeft=this.scrollPos+this.spaceWidth;				
			} else {
				this.getElement().scrollTop=this.scrollPos+this.spaceWidth;
			}
		},
		renewScroll:function(scrollPos) {
			var st;
			if (this.ajaxkeepall==false) {
				this.deleteItem(0,this.itemlist.length);	// delete all
				this.bufferedSt=this.bufferedEd=-1;
			}
			this.curViewSt=scrollPos;
			this.curViewEd=scrollPos+this.InPage;
			if (scrollPos+this.pagelen>this.lastIndex) st=this.lastIndex-this.pagelen;
			else st=scrollPos;
			if (this.ajax) {
				if (this.totalnum>this.bufferedEd-this.bufferedSt) this.loadAjax(st-this.initialItemNum);
			}
		},
		setScrollDrag:function(scrollPos) {
			if (scrollPos<this.bufferedSt || scrollPos>this.bufferedEd) {
				this.setScrollPos(-1);
			} else {
				this.setScrollPos(scrollPos);
			}
		},
		// itemCount 추가   
		scrollItem:function(bNext,step,interval,itemCount) {
			var i;
			//alert('view : '+this.curViewSt+'-'+this.curViewEd+' ajax : '+this.ajaxViewSt+'-'+this.ajaxViewEd+' / '+this.itemlist.length);

			if (!itemCount) itemCount = this.itemCount;   
			if (bNext==true) {
				if (this.lastIndex!=-1 && this.curViewEd==this.lastIndex) return;
				this.loadAjaxNext();
				this.scrollTarget=this.curViewSt+itemCount; 
			}
			if (bNext==false) {
				if (this.curViewSt==0) return;
				this.loadAjaxPrev();
				this.scrollTarget=this.curViewSt-itemCount;
			}
			this.ani_step=step || this.step;
			this.ani_interval=interval || this.interval;
			this.ani_next=bNext;
			if (bNext) {
					this.curItemPos=0;
			} else {
					this.curItemPos=this.sizelist[this.curViewSt-1];
			}
//			alert(this.curViewSt+':'+this.sizelist[this.curViewSt]);
			this.rollOneRow();
		},
		
		rollOneRow:function() {
			if (this.animate_timer) window.clearInterval(this.animate_timer);
			this.animate_timer=window.setInterval(this.animateOneScrollTimer.bind(this),this.ani_interval);
		},
		animateOneScrollTimer:function() {
			var bh=(this.direction=='horz');
			if (this.ani_next) {
				this.scrollPos+=this.ani_step;
				this.curItemPos+=this.ani_step;
			
				if (this.curItemPos>=this.sizelist[this.curViewSt]) {
					this.curViewSt++;
					this.curViewEd++;
					this.stopOneRow();
					this.fireEvent('itemstop',this.curViewSt,this);
				}
			} else {
				this.scrollPos-=this.ani_step;
				this.curItemPos-=this.ani_step;
			
				if (this.curItemPos<=0) {
					this.curViewSt--;
					this.curViewEd--;
					this.stopOneRow();
					this.fireEvent('itemstop',this.curViewSt,this);
				}
			}

			this.syncScrollPos();
		},
		stopOneRow:function() {
			this.setScrollPos(this.scrollTarget);
			if (this.animate_timer) window.clearInterval(this.animate_timer);
			this.animate_timer=null;
			//this.debugScrollWindow();
		},
		getItemId:function(nIndex) {
			return this.itemlist[nIndex];
		},
		getItemLength:function() {
			return this.itemlist.length;
		},
		getItemSwaf:function(nIndex) {
			return this.swafobjlist[nIndex];
		},
		getTotalItem:function() {
			return this.lastIndex;
		},
		getHeadIndex:function() {	// 2006.12.28
			return this.curViewSt;
		},
		getInPageNum:function() {
			return this.InPage;
		},
		getAjaxUrl:function() {
			return this.ajaxUrl;
		},
		setAjaxUrl:function(url) {
			this.ajaxUrl=url;
		},
		setItemAttribute:function(attrname,value) {
			var i,el;
			for(i=0;i<this.itemlist.length;i++) {
				el=document.getElementById(this.itemlist[i]);
				if (el) el.setAttribute(attrname,value);
				el=null;
			}
		},
		setAjaxTemplate:function(tplid) {
			this.ajaxTemplate=tplid;
		},
		setAjaxParameter:function(paraobj) {
			this.ajaxParam=paraobj;
		},
		setInPage:function(inPage) {
			this.InPage=inPage;
		},
		reloadAjax:function() {
			var start=this.curViewSt;
			this.deleteItem(this.bufferedSt,this.bufferedEd-this.bufferedSt);
			this.setScrollPos(this.curViewSt);
			this.bufferedSt=this.bufferedEd=-1;
			this.loadAjax(start-this.initialItemNum);
		},
		debugScrollWindow:function() {
			{
				var el=document.getElementById('windowdebug');
				if (!el) {
					el=document.createElement('div');
					el.id='windowdebug';
					el.style.position='absolute';
					el.style.left='0px';
					el.style.top='0px';
					el.style.background='white';
					el.style.border='1px solid blue';
					el.style.zIndex=9999;
					document.body.appendChild(el);
				}
				var html='<TABLE><TR>';
				for(var i=0;i<this.itemlist.length;i++) {
					html+='<td style="width:30px;height:10px;background:'+((this.existlist[i]==1 || this.existlist[i]==0)?'red':'gray')+'">'+i+'</td>';
				}
				html+='</tr><tr>';
				for(var i=0;i<this.itemlist.length;i++) {
					html+='<td style="width:30px;height:10px;background:'+((document.getElementById(this.itemlist[i]))?'blue':'gray')+'">'+i+'</td>';
				}
				html+='</tr><tr>';
				for(var i=0;i<this.itemlist.length;i++) {
					if (i>=this.bufferedSt && i<this.bufferedEd && (this.existlist[i]==1 || this.existlist[i]==0)) {
						html+='<td style="width:30px;height:10px;background:yellow">'+i+'</td>';
					} else {
						html+='<td style="width:30px;height:10px;">'+i+'</td>';
					}
				}
				html+='</tr><tr>';
				for(var i=0;i<this.itemlist.length;i++) {
					if (i>=this.curViewSt && i<this.curViewEd && (this.existlist[i]==1|| this.existlist[i]==0)) {
						html+='<td style="width:30px;height:10px;background:lightblue">'+i+'</td>';
					} else {
						html+='<td style="width:30px;height:10px;">'+i+'</td>';
					}
				}
				html+='</tr></table>'
				el.innerHTML=html;
			}
		}
});

Swaf.UI.ScrollBar=Class.create();
Object.extend(Swaf.UI.ScrollBar.prototype, Swaf.UI.BaseAction.prototype);
Object.extend(Swaf.UI.ScrollBar.prototype, {
		type:'scroll_bar',
		list:null,
		step:10,
		direction:null,
		prevbtn:null,
		nextbtn:null,
		thumbbtn:null,
		thumbarea:null,
		thumb_dndobject:null,
		prev_btnobject:null,
		next_btnobject:null,
		totalItem:null,
		listInPage:null,
		curPos:0,
		thumbSize:0,
		viewtip:true,
		tipDiv:null,
		// 2006.11.30
		enabledrag:true,
		// 2006.12.12
		enableThumbDrag:true,
		initUI:function() {
			var tmp,uidef,listobj;
			this.list=this.getAttribute('list');
			this.step=this.getAttribute('step');
			this.direction=this.getAttribute('direction');
			this.viewtip=this.getAttribute('viewtip');
			this.enabledrag=this.getAttribute('enabledrag');
			
			tmp=this.getChildNodeList('prevbtn');
			if (tmp) this.prevbtn=tmp[0].elementId;
			tmp=this.getChildNodeList('nextbtn');
			if (tmp) this.nextbtn=tmp[0].elementId;
			tmp=this.getChildNodeList('thumbarea');
			if (tmp) this.thumbarea=tmp[0].elementId;
			tmp=tmp[0].thumbbtn;
			if (tmp) this.thumbbtn=tmp[0].elementId;
			
			listobj=this.getListObject();
			if (listobj) {
				listobj.setScrollBar(this);
			}

			// thumb
			if (this.thumbbtn && this.thumbarea) {
				var thumbbtnel=document.getElementById(this.thumbbtn);
				thumbbtnel.style.position='relative';
				thumbbtnel.style.overflow='hidden';
				if (this.enabledrag) {
					uidef={
						elementId:this.thumbbtn,
						attribute: {proxy:false,top:true,opacity:100,areaconstrict:true},
						handle:[{elementId:this.thumbbtn,attribute:{}}]
					};
					if (this.dragStyle) thumbbtnel.setAttribute('swaf:style:drag',this.getElement().getAttribute('swaf:style:drag'));
					this.thumb_dndobject=Swaf.UI.createUIObject(Swaf.UI.DnD,thumbbtnel,uidef,false,this);
				}
				thumbbtnel=null;
			}
			// prev
			if (this.prevbtn) {
				uidef={
					elementId:this.prevbtn,
					attribute: {}
				};
				this.prev_btnobject=Swaf.UI.createUIObject(Swaf.UI.Button,document.getElementById(this.prevbtn),uidef,false,this);
			}
			// next
			if (this.nextbtn) {
				uidef={
					elementId:this.nextbtn,
					attribute: {}
				};
				this.next_btnobject=Swaf.UI.createUIObject(Swaf.UI.Button,document.getElementById(this.nextbtn),uidef,false,this);
			}
			
			if (this.viewtip) {
				this.tipDiv=document.createElement('div');
				document.body.appendChild(this.tipDiv);
				this.tipDiv.style.border="1px solid #a0a0a0";
				this.tipDiv.style.background="white";
				this.tipDiv.style.position='absolute';
				Swaf.Dom.hideElement(this.tipDiv);
			}

			this.refreshUI();
		},
		onDestroy:function() {
			if (this.thumb_dndobject) this.thumb_dndobject=null;
			if (this.prev_btnobject) this.prev_btnobject=null;
			if (this.next_btnobject) this.next_btnobject=null;
			if (this.tipDiv) Swaf.Dom.deleteElement(this.tipDiv);
			this.tipDiv=null;
		},
		enableUI:function() {
			this.enableBaseAction();
			if (this.thumb_dndobject && this.enableThumbDrag==true) this.thumb_dndobject.enableUI();
			if (this.prev_btnobject) this.prev_btnobject.enableUI();
			if (this.next_btnobject) this.next_btnobject.enableUI();
		},
		disableUI:function() {
			this.disableBaseAction();
			if (this.thumb_dndobject) this.thumb_dndobject.disableUI();
			if (this.prev_btnobject) this.prev_btnobject.disableUI();
			if (this.next_btnobject) this.next_btnobject.disableUI();
		},
		refreshUI:function() {
			listobj=this.getListObject();
			if (listobj) {
				this.totalItem=listobj.getTotalItem();
				this.listInPage=listobj.InPage;
				this.curPos=listobj.curViewSt;
				if (this.totalItem<=this.listInPage) { this.enableThumbDrag=false; this.curPos=0;}
				else this.enableThumbDrag=true;
				if (this.thumb_dndobject) this.thumb_dndobject.setEnable(this.enableThumbDrag);
			}
			this.setThumbSize();
			this.setCurPos(this.curPos);
		},
		setThumbSize:function() {
			var thumbsize;
			var areasize,size;
			if (this.thumbbtn && this.thumbarea) {
				size=Swaf.Dom.getSize(document.getElementById(this.thumbarea));
				this.areasize=(this.direction=='vert')?size.height:size.width;
				if (this.totalItem>this.listInPage) {
					thumbsize=(this.listInPage*this.areasize)/this.totalItem;
				} else {
					thumbsize=this.areasize;
				}
				if (Swaf.Util.Browser.isIE) {
					var thmbel=document.getElementById(this.thumbbtn);
					var border=Swaf.Dom.getBorderWidth(thmbel);
					if (this.direction=='vert') thumbsize-=border.top+border.bottom;
					else thumbsize-=border.left+border.right;
					thmbel=null;
				}
				if (thumbsize<3) thumbsize=2;
				if (this.direction=='vert') Swaf.Dom.setHeight(document.getElementById(this.thumbbtn),thumbsize);
				else Swaf.Dom.setWidth(document.getElementById(this.thumbbtn),thumbsize);
				this.thumbSize=thumbsize;
			}
		},
		setThumbPos:function() {
			var thumbpos;
			if (this.thumbbtn && this.thumbarea) { 
				if (this.totalItem>this.listInPage) {
					thumbpos=(this.curPos*(this.areasize-this.thumbSize))/(this.totalItem-this.listInPage);
					if (this.direction=='vert') {
						Swaf.Dom.setPosition(document.getElementById(this.thumbbtn),0,thumbpos,document.getElementById(this.thumbarea));
					} else {
						Swaf.Dom.setPosition(document.getElementById(this.thumbbtn),thumbpos,0,document.getElementById(this.thumbarea));
					}
				} else {
					if (this.direction=='vert') {
						Swaf.Dom.setPosition(document.getElementById(this.thumbbtn),0,0,document.getElementById(this.thumbarea));
					} else {
						Swaf.Dom.setPosition(document.getElementById(this.thumbbtn),0,0,document.getElementById(this.thumbarea));
					}
				}
			}
		},
		setCurPos:function(nPos) {
			this.curPos=nPos;
			if (this.totalItem>this.listInPage) {
				if (this.curPos>this.totalItem-this.listInPage) this.curPos=this.totalItem-this.listInPage;
				if (this.curPos<0) this.curPos=0;
			} else {this.curPos=0;}
			this.setThumbPos();
		},
		getListObject:function() {
			var i,arrobj,listobj=null;
			if (!this.list) return null;
			arrobj=Swaf.getInstance(document.getElementById(this.list));
			if (arrobj && arrobj instanceof Array) {
				for(i=0;i<arrobj.length;i++) {
					if (arrobj[i].type=='scroll_list') { listobj=arrobj[i]; break;}
				}
				arrobj.length=0;
			} else listobj=arrobj;
			return listobj;
		},
		// btn click
		onClick:function(uitype,src,evt) {
			var listobj;
			var cat=src.getAttribute('swaf:ui:scroll_bar');
			listobj=this.getListObject();
			if (!listobj || !cat) return;
			switch(cat) {
				case 'prevbtn' :
					listobj.scrollItem(false,this.step);
					this.setCurPos(this.curPos-1);
					break;
				case 'nextbtn' :
					listobj.scrollItem(true,this.step);
					this.setCurPos(this.curPos+1);
					break;
			} // switch
		},
		// thumb drag
		onDrag:function(uitype,src,evt) {
			var pos=Swaf.Dom.getPosition(document.getElementById(this.thumbbtn),document.getElementById(this.thumbarea));
			var thumbpos=(this.direction=='vert')?pos.y:pos.x;
			this.curPos=Math.floor((thumbpos*(this.totalItem-this.listInPage+1))/(this.areasize-this.thumbSize));
			listobj=this.getListObject();
			if (listobj) listobj.setScrollDrag(this.curPos);
			if (this.viewtip) {
				var rect=Swaf.Dom.getRect(src);
				this.tipDiv.innerHTML='&nbsp;'+(this.curPos+1)+'&nbsp;';
				Swaf.Dom.setPosition(this.tipDiv,rect.x+rect.width,rect.y);
				Swaf.Dom.showElement(this.tipDiv);
			}
		},
		onEndDrag:function(uitype,src,evt) {
			listobj=this.getListObject();
			if (listobj) listobj.renewScroll(this.curPos);
			if (this.viewtip) Swaf.Dom.hideElement(this.tipDiv);
		}
});

Swaf.UI.Marquee=Class.create();
Object.extend(Swaf.UI.Marquee.prototype, Swaf.UI.BaseAction.prototype);
Object.extend(Swaf.UI.Marquee.prototype, {
		type:'marquee',
		// property
		direction:'up',
		step:10,
		interval:2,
		autostart:false,
		rowsleep:500,
		
		itemlist:null,
		sizelist:null,
		dummylist:null,
		innerDIV:null,
		bInfiniteRolling:false,

		curTopIndex:null,
		curItemPos:0,
		scrollPos:0,
		scrollMax:0,
		initUI:function() {
			var bh,margin,i,tmpsize,size,elsize,el=this.getElement();
			
			this.direction=this.getAttribute('direction');
			this.step=this.getAttribute('step');
			this.interval=this.getAttribute('interval');
			this.autostart=this.getAttribute('autostart');
			this.rowsleep=this.getAttribute('itemsleep');
			
			Swaf.Dom.setStyle(el,'overflow','hidden');

			bh=(this.direction=='left' || this.direction=='right');
			this.scrollPos=(bh)?el.scrollLeft:el.scrollTop;

			var tmp=this.getChildNodeList('item');
			
			if (tmp) {
				this.itemlist=new Array(tmp.length);
				this.sizelist=new Array(tmp.length);
				this.dummylist=new Array(tmp.length);
				
				tmpsize=0;
				for(i=0;i<tmp.length;i++) {
					var itemel=document.getElementById(tmp[i].elementId);
					this.itemlist[i]=tmp[i].elementId;
					size=Swaf.Dom.getSize(itemel);
					margin=Swaf.Dom.getMargin(itemel);
					this.sizelist[i]=(bh)?(size.width+margin.left+margin.right):(size.height+margin.top+margin.bottom);
					tmpsize+=this.sizelist[i];
					itemel=null;
				}
				this.scrollMax=tmpsize;
			}
			tmp=null;
			
			// create dummy
			for(i=0;i<this.itemlist.length;i++) {
				this.dummylist[i]=document.getElementById(this.itemlist[i]).cloneNode(true);
				this.dummylist[i].id='';
			}

			elsize=Swaf.Dom.getSize(el);
			this.innerDIV=document.createElement('div');
			this.innerDIV.style.width=(bh)?this.scrollMax*2:elsize.width;
			this.innerDIV.style.height=(bh)?elsize.height:this.scrollMax*2;
			el.appendChild(this.innerDIV);
			
			if (this.direction=='up' || this.direction=='left') {
				for(i=0;i<this.itemlist.length;i++) {
					this.innerDIV.appendChild(document.getElementById(this.itemlist[i]));
				}
				for(i=0;i<this.dummylist.length;i++) {
					this.innerDIV.appendChild(this.dummylist[i]);
				}
				this.curTopIndex=0;
				this.scrollPos=0;
				this.curItemPos=0;
			} else {
				for(i=0;i<this.dummylist.length;i++) {
					this.innerDIV.appendChild(this.dummylist[i]);
				}
				for(i=0;i<this.itemlist.length;i++) {
					this.innerDIV.appendChild(document.getElementById(this.itemlist[i]));
				}
				this.curTopIndex=this.itemlist.length-1;
				this.scrollPos=(this.scrollMax*2)-((bh)?elsize.width:elsize.height);
				this.curItemPos=this.sizelist[this.itemlist.length-1];
			}
			el=null;
			this.syncScrollPos();
			
			if (this.autostart) this.start();
		},
		onDestroy:function() {
			this.stop();
			this.itemlist=null;
			this.sizelist=null;
			for(var i=0;i<this.dummylist.length;i++) {this.dummylist[i]=null;}
			this.dummylist=null;
			this.innerDIV=null;
			var el=this.getElement();
			if (el) this.getElement().innerHTML='';
			el=null;
		},
		enableUI:function() {
			this.enableBaseAction();
		},
		disableUI:function() {
			this.disableBaseAction();
		},
		syncScrollPos:function() {
			if (!this.getElement()) {
				this.stop();
				return;
			}
			if (this.direction=='left' || this.direction=='right') {
				this.getElement().scrollLeft=this.scrollPos;
			} else {
				this.getElement().scrollTop=this.scrollPos;
			}
		},
		start:function(rowsleep,step,interval) {
			if (this.fireEvent('start',this)==true) return;
			this.ani_rowsleep=rowsleep||this.rowsleep;
			this.ani_step=step || this.step;
			this.ani_interval=interval || this.interval;
			this.bInfiniteRolling=true;
			this.startRolling();
			if (this.fireEvent('started',this)==true) return;
		},
		startOneRow:function(step,interval) {
			this.ani_step=step || this.step;
			this.ani_interval=interval || this.interval;
			this.bInfiniteRolling=false;
			this.rollOneRow();
		},
		startRolling:function() {
			if (this.rolling_timer) window.clearTimeout(this.rolling_timer);
			this.rolling_timer=null;
			if (this.ani_rowsleep>0) this.rolling_timer=window.setTimeout(this.rollOneRow.bind(this),this.ani_rowsleep);
			else this.rollOneRow();
		},
		rollOneRow:function() {
			if (this.animate_timer) window.clearInterval(this.animate_timer);
			this.animate_timer=window.setInterval(this.animateOneRollingTimer.bind(this),this.ani_interval);
		},
		animateOneRollingTimer:function() {
			var bh=(this.direction=='left' || this.direction=='right');
			var dnext=(this.direction=='left' || this.direction=='up');
			if (dnext) {
				this.scrollPos+=this.ani_step;
				this.curItemPos+=this.ani_step;
			
				if (this.curItemPos>=this.sizelist[this.curTopIndex]) {
					this.scrollPos-=this.curItemPos-this.sizelist[this.curTopIndex];
					this.curItemPos=0;
					if (!document.getElementById(this.itemlist[this.curTopIndex])) { this.stop(); return;}
					Swaf.Dom.swapNode(document.getElementById(this.itemlist[this.curTopIndex]),this.dummylist[this.curTopIndex]);
					this.curTopIndex++;
					if (this.curTopIndex==this.itemlist.length) {
						this.curTopIndex=0;
					}
					this.fireEvent('itemstop',this.curTopIndex,this);
					this.stopOneRow();
				}
				if (this.scrollPos>this.scrollMax) {
					this.scrollPos-=this.scrollMax;
					for(var i=0;i<this.itemlist.length;i++) {
						Swaf.Dom.swapNode(document.getElementById(this.itemlist[i]),this.dummylist[i]);
					}
				}
			} else {
				this.scrollPos-=this.ani_step;
				this.curItemPos-=this.ani_step;
			
				if (this.curItemPos<=0) {
					this.scrollPos-=this.curItemPos;
					if (!document.getElementById(this.itemlist[this.curTopIndex])) {this.stop();return;}
					Swaf.Dom.swapNode(document.getElementById(this.itemlist[this.curTopIndex]),this.dummylist[this.curTopIndex]);
					this.curTopIndex--;
					if (this.curTopIndex==-1) {
						this.curTopIndex=this.itemlist.length-1;
					}
					this.curItemPos=this.sizelist[this.curTopIndex];
					this.stopOneRow();
					this.fireEvent('itemstop',this.curTopIndex,this);
				}
				if (this.scrollPos<0) {
					this.scrollPos+=this.scrollMax;
					for(var i=0;i<this.itemlist.length;i++) {
					Swaf.Dom.swapNode(document.getElementById(this.itemlist[i]),this.dummylist[i]);
					}
				}
			}
			

			this.syncScrollPos();
		},
		stopOneRow:function(bStop) {
			if (bStop!=true) this.syncScrollPos();
			window.clearInterval(this.animate_timer);
			this.animate_timer=null;
			if (this.bInfiniteRolling) {
				this.startRolling();
			}
		},
		stop:function() {
			if (this.fireEvent('stop',this)==true) return;
			this.bInfiniteRolling=false;
			if (this.rolling_timer) window.clearTimeout(this.rolling_timer);
			this.stopOneRow(true);
			this.rolling_timer=null;
			if (this.fireEvent('stopped',this)==true) return;
		},
		getItemId:function(nIndex) {
			return this.itemlist[nIndex];
		}
});

Swaf.UI.Scroll=Class.create();
Object.extend(Swaf.UI.Scroll.prototype, Swaf.UI.BaseAction.prototype);
Object.extend(Swaf.UI.Scroll.prototype, {
		type:'scrollview',
		scrollPosX:0,
		scrollPosY:0,
		scrollMaxX:0,
		scrollMaxY:0,
		initUI:function() {
			var el=this.getElement();
			Swaf.Dom.setStyle(el,'overflow','hidden');
			
			var size=Swaf.Dom.getSize(el);
			this.scrollPosX=el.scrollLeft;
			this.scrollPosY=el.scrollTop;
			this.scrollMaxX=el.scrollWidth-size.width;
			this.scrollMaxY=el.scrollHeight-size.height;
			el=null;
		},
		onDestroy:function() {
		},
		enableUI:function() {
			this.enableBaseAction();
		},
		disableUI:function() {
			this.disableBaseAction();
		},
		syncScrollPos:function() {
			if (this.scrollPosY<0) this.scrollPosY=0;
			if (this.scrollPosX<0) this.scrollPosX=0;
			if (this.scrollPosY>this.scrollMaxY) this.scrollPosY=this.scrollMaxY;
			if (this.scrollPosX>this.scrollMaxX) this.scrollPosX=this.scrollMaxX;
			this.getElement().scrollLeft=this.scrollPosX;
			this.getElement().scrollTop=this.scrollPosY;
		},
		scrollX:function(cx) {
			this.scrollPosX=cx;
			this.syncScrollPos();
		},
		scrollY:function(cy) {
			this.scrollPosY=cy;
			this.syncScrollPos();
		},
		scroll:function(cx,cy) {
			this.scrollPosX=cx;
			this.scrollPosY=cy;
			this.syncScrollPos();
		},
		scrollBy:function(dx,dy) {
			this.scrollPosX+=dx;
			this.scrollPosY+=dy;
			this.syncScrollPos();
		},
		scrollByX:function(dx) {
			this.scrollPosX+=dx;
			this.syncScrollPos();
		},
		scrollByY:function(dy) {
			this.scrollPosY+=dy;
			this.syncScrollPos();
		},
		animateScroll:function(cx,cy,interval,step) {
			var st=step || 15;
			var dx,dy;

			if (cy<0) cy=0;
			if (cx<0) cx=0;
			if (cy>this.scrollMaxY) cy=this.scrollMaxY;
			if (cx>this.scrollMaxX) cx=this.scrollMaxX;

			this.animate_targetX=cx;
			this.animate_targetY=cy;
			
			if (this.animate_timer) window.clearInterval(this.animate_timer);

			dx=Math.abs(this.animate_targetX-this.scrollPosX);
			dy=Math.abs(this.animate_targetY-this.scrollPosY);
			
			this.animate_stepX=st;
			this.animate_stepY=st;

			if (dx!=0 && dy!=0) {
				if (dx<dy) {
					this.animate_stepY=(dy*st)/dx;
				} else if (dy<dx) {
					this.animate_stepX=(dx*st)/dy;
				}
			}

			this.animate_interval=interval || 2;
			this.animate_finishX=false;
			this.animate_finishY=false;
			this.animate_timer=window.setInterval(this.animateScrollTimer.bind(this),this.animate_interval);
		},
		animateScrollTimer:function() {
			if (this.animate_finishX==false) {
				if (Math.abs(this.scrollPosX-this.animate_targetX)<this.animate_stepX) {
					this.scrollPosX=this.animate_targetX;
				} else {
					if (this.scrollPosX>this.animate_targetX) this.scrollPosX-=this.animate_stepX;
					else if (this.scrollPosX<this.animate_targetX) this.scrollPosX+=this.animate_stepX;
				}
				if (this.scrollPosX==this.animate_targetX) this.animate_finishX=true;
			}
			if (this.animate_finishY==false) {
				if (Math.abs(this.scrollPosY-this.animate_targetY)<this.animate_stepY) {
					this.scrollPosY=this.animate_targetY;
				} else {
					if (this.scrollPosY>this.animate_targetY) this.scrollPosY-=this.animate_stepY;
					else if (this.scrollPosY<this.animate_targetY) this.scrollPosY+=this.animate_stepY;
				}
				if (this.scrollPosY==this.animate_targetY) this.animate_finishY=true;
			}
			this.syncScrollPos();
			if (this.animate_finishX && this.animate_finishY) {
				window.clearInterval(this.animate_timer);
				this.animate_timer=null;
			}
		}
});

Swaf.UI.List= Class.create();
Object.extend(Swaf.UI.List.prototype, Swaf.UI.BaseAction.prototype);
Object.extend(Swaf.UI.List.prototype, {
		// share member
		sharedList:{},
		// property
		type:'list',
		group : null,
		selectable:true,
		multiselect:false,
		dnd : false,
		edit : false,
//		space:null,
		itemlist:null,
		dnd_opacity : 50,
		edit_maxlen:30,
		origindex:-1,
		origdepth:-1,
//		origlist:null,
		
		itemSelectListener:null,
		selitems:null,
		
		// old
		st_selectimg:null,
		st_normalimg:null,
		st_selecttxt:null,
		st_normaltxt:null,
		active_select:'click',
		active_edit:'dblclick',
		
		
		initUI:function() {
			this.group=this.getAttribute('group');
			this.selectable=this.getAttribute('selectable');
			this.multiselect=this.getAttribute('multiselect');
			this.dnd=this.getAttribute('dnd');
			this.edit=this.getAttribute('edit');
			this.dnd_opacity=this.getAttribute('dnd:opacity');
			this.edit_maxlen=this.getAttribute('edit:maxlen');
			this.st_selectimg=this.getAttribute('status:selectimg');
			this.st_normalimg=this.getAttribute('status:normalimg');
			this.st_selecttxt=this.getAttribute('status:selecttxt');
			this.st_normaltxt=this.getAttribute('status:normaltxt');
			
			this.itemlist=this.getChildNodeList('item');
			if (!this.itemlist) this.itemlist=[];
			
			// 2007.1.20
/*			var tmpspace=this.getChildNodeList('space');
			if (tmpspace) {
				this.space=tmpspace[0].elementId;
				var spaceel=document.getElementById(this.space);
				if (this.itemlist.length>0) Swaf.Dom.hideElement(spaceel);
				else Swaf.Dom.showElement(spaceel);
			}*/
			
			if (this.group) {
				if (!this.sharedList[this.group]) this.sharedList[this.group]=new Array();
				this.sharedList[this.group].push(this);
			}
			
			this.itemSelectListener=[
				{
					event:this.getAttribute('active:select'),
					listener:this.selectItem.bind(this)
				}
			];
			if (this.multiselect && this.getAttribute('active:select')!='mousedown') {
				this.itemSelectListener.push({
					event:'selectstart',
					listener:this.stopBrowserSelect.bind(this)
				});
			}
			
			this.makeList();
		},
		disableSelectListener:function(item) {
			if (item.selectListener) {
				item.selectListener.removeListener();
				delete item.selectListener;
				item.selectListener=null;
			}
		},
		enableSelectListener:function(item) {
			if (item.selectListener) return;
			selectable=this.getAttribute('selectable',item);
			if ((selectable==null && this.selectable==true) || selectable==true) {
				item.selectListener=new Swaf.Listener.Event(this.itemSelectListener);
				item.selectListener.applyListener(document.getElementById(item.selecthandle));
//				this.setAttribute('selectable',true,item);
			} else {
//				this.setAttribute('selectable',false,item);
			}
		},
		enableUI:function() {
			var i,item;
			for(i=0;i<this.itemlist.length;i++) {
				item=this.itemlist[i];
				this.enableSelectListener(item);
				if (item.dndobject) item.dndobject.setEnable(true);
				if (item.editobject) item.editobject.setEnable(true);
			}
		},
		disableUI:function() {
			var i,item;
			for(i=0;i<this.itemlist.length;i++) {
				item=this.itemlist[i];
				this.disableSelectListener(item);
				if (item.dndobject) item.dndobject.setEnable(false);
				if (item.editobject) item.editobject.setEnable(false);
			}
		},
		makeList:function() {
			var i,item,rect,tmp,itemel,tmpel;
			if (!this.itemlist) return;
			if (this.rectlist) delete this.rectlist;
			this.rectlist=new Array(this.itemlist.length);
			for(i=0;i<this.itemlist.length;i++) {
				item=this.itemlist[i];
				
//				if (!item.element.id) item.element.id='list_'+this.getElementId()+'_'+'item'+i;
				
				if (item.dndhandle) {
					tmp=item.dndhandle[0].elementId;
					tmpel=document.getElementById(tmp);
					delete item.dndhandle;
					item.dndhandle=tmp;
					this.setItemIndex(tmpel,i);
					this.setListId(tmpel);
					tmpel=null;
				} else {
					item.dndhandle=item.elementId;
				}
				if (item.editarea) {
					tmp=item.editarea[0].elementId;
					tmpel=document.getElementById(tmp);
					delete item.editarea;
					item.editarea=tmp;
					this.setItemIndex(tmpel,i);
					this.setListId(tmpel);
					tmpel=null;
				} else {
					item.editarea=item.elementId;
				}
				if (item.selecthandle) {
					tmp=item.selecthandle[0].elementId;
					tmpel=document.getElementById(tmp);
					delete item.selecthandle;
					item.selecthandle=tmp;
					this.setItemIndex(tmpel,i);
					this.setListId(tmpel);
					tmpel=null;
				} else {
					item.selecthandle=item.elementId;
				}
				if (item.status) {
					tmp=item.status[0].elementId;
					delete item.status;
					item.status=tmp;
				} else {
					item.status=null;
				}
				itemel=document.getElementById(item.elementId);
				
				item.itemrect=Swaf.Dom.getRect(itemel);
				this.setItemIndex(itemel,i);
				this.setListId(itemel);
				
				this.enableSelectListener(item);
				this.setItemListener(item);
				
				itemel=null;
			} // for
			
		},
		setDndListener:function(item,processor) {
			var dnd,uidef;
			var itemel=document.getElementById(item.elementId);
			dnd=this.getAttribute('dnd',item);
			if ((dnd==null && this.dnd==true) || dnd==true) {
				uidef={
					elementId:item.elementId,
					attribute: {proxy:true,top:true,opacity:this.dnd_opacity},
					handle:[{elementId:item.dndhandle,attribute:{}}]
				};
				if (this.dragStyle) itemel.setAttribute('swaf:style:drag',this.getElement().getAttribute('swaf:style:drag'));
				item.dndobject=Swaf.UI.createUIObject(Swaf.UI.DnD,itemel,uidef,true,processor);
//				this.setAttribute('dnd',true,item);
			}/* else {
				this.setAttribute('dnd',false,item);
			}*/
			itemel=null;
		},
		setEditListener:function(item,processor) {
			var edit,uidef;
			var itemel=document.getElementById(item.elementId);
			edit=this.getAttribute('edit',item);
			if ((edit==null && this.edit==true) || edit==true) {
				uidef={
					elementId:item.editarea,
					attribute: {maxlen:this.edit_maxlen,enableHTML:false,active:this.getAttribute('active:edit')}
				};
				if (this.editStyle) itemel.setAttribute('swaf:style:edit',this.getElement().getAttribute('swaf:style:edit'));
				item.editobject=Swaf.UI.createUIObject(Swaf.UI.Edit,document.getElementById(item.editarea),uidef,true,processor);
//				this.setAttribute('edit',true,item);
			}/* else {
				this.setAttribute('edit',false,item);
			}*/
			itemel=null;
		},
		setItemListener:function(item) {
			this.setDndListener(item,this);
			this.setEditListener(item,this);
		},
		changeProcessorItemListener:function(item,processor) {
			var dnd=this.getAttribute('dnd',item);
			if ((dnd==null && this.dnd==true) || dnd==true) {
				if (item.dndobject) item.dndobject.setMsgTarget(processor);
				else this.setDndListener(item,processor);
			} else {
				if (item.dndobject) item.dndobject.setEnable(false);
			}
			var edit=this.getAttribute('edit',item);
			if ((edit==null && this.edit==true) || edit==true) {
				if (item.editobject) item.editobject.setMsgTarget(processor);
				else this.setEditListener(item,processor);
			} else {
				if (item.editobject) item.editobject.setEnable(false);
			}
		},
		setStatus:function(item,bSelect) {
			var el=document.getElementById(item.status);
			if (el) {
				if (el.src!=undefined && this.st_selectimg && this.st_normalimg) {
					el.src=(bSelect)?this.st_selectimg:this.st_normalimg;
				} else if (this.st_selecttxt && this.st_normaltxt) {
					el.innerHTML=(bSelect)?this.st_selecttxt:this.st_normaltxt;
				}
			}
			el=null;
		},
		// interface
		setSel:function(nIndex) {
			var i;
			var item=this.itemlist[nIndex];
			var itemel;

//			if (item && item.element.getAttribute('swaf_system:list:selected')=='selected') return;
			
			if (this.selitems) {
				for(i=0;i<this.selitems.length;i++) {
					if (this.selitems[i]>=0 && this.selitems[i]<this.itemlist.length) {
						itemel=document.getElementById(this.itemlist[this.selitems[i]].elementId);
						if (this.normalStyle) Swaf.Dom.setCSS(itemel,this.normalStyle);
						itemel.setAttribute('swaf_system:list:selected','deleted');
						this.setStatus(this.itemlist[this.selitems[i]],false);
					}
				}
			}
			
			if (this.selitems) { delete this.selitems;this.selitems=null;}
			
			if (nIndex>=0) {
				if (this.getAttribute('selectable',item)==false) return;
				itemel=null;
				itemel=document.getElementById(item.elementId);
			
				if (nIndex>=0 && nIndex<this.itemlist.length) {
					if (this.selectStyle) Swaf.Dom.setCSS(itemel,this.selectStyle);
					itemel.setAttribute('swaf_system:list:selected','selected');
					this.setStatus(item,true);
				} else nIndex=-1;
			
				this.selitems=[nIndex];
			}
			itemel=null;

		},
		addSel:function(nIndex) {
			var item=this.itemlist[nIndex];
			var itemel=document.getElementById(item.elementId);
			var selected=itemel.getAttribute('swaf_system:list:selected');
			
			if (this.getAttribute('selectable',item)==false) return;
			if (selected=='selected') return;
			else {
				if (nIndex>=0 && nIndex<this.itemlist.length) {
					if (this.selectStyle) Swaf.Dom.setCSS(itemel,this.selectStyle);
					if (!this.selitems) this.selitems=[nIndex];
					else {
						for(var i=0;i<this.selitems.length;i++) {
							if (this.selitems[i]==nIndex) return;
						}
						this.selitems.push(nIndex);
					}
					itemel.setAttribute('swaf_system:list:selected','selected');
					this.setStatus(item,true);
				} else nIndex=-1;
			}
			itemel=null;
		},
		deleteSel:function(nIndex) {
			var item=this.itemlist[nIndex];
			var itemel=document.getElementById(item.elementId);
			var selected=itemel.getAttribute('swaf_system:list:selected');
			var delindex;
			if (selected==null || selected=='deleted') return;
			if (nIndex>=0 && nIndex<this.itemlist.length) {
				if (this.normalStyle) Swaf.Dom.setCSS(itemel,this.normalStyle);
				itemel.setAttribute('swaf_system:list:selected','deleted');
				this.setStatus(item,false);
				delindex=this.selitems.indexOf(nIndex);
				if (delindex>=0) {
					this.selitems.splice(delindex,1);
				}
			}
			itemel=null;
		},
		toggleSel:function(nIndex) {
			var selected=document.getElementById(this.itemlist[nIndex].elementId).getAttribute('swaf_system:list:selected');
			if (selected=='selected') {
				this.deleteSel(nIndex);
			} else {
				this.addSel(nIndex);
			}
		},
		
		// event listener
		selectItem:function(evt,src) {
			var i;
			var itemindex=this.getItemIndex(src);
			if (this.multiselect) {
				if (evt.ctrlKey || evt.ctrlLeft) {
					Event.stop(evt);
					this.toggleSel(itemindex);
					this.fireEvent('select',this);
					return;
				} else if (evt.shiftKey || evt.shiftLeft) {
					Event.stop(evt);
					var tmp=this.selitems[this.selitems.length-1];
					for(i=Math.min(tmp,itemindex);i<=Math.max(tmp,itemindex);i++) {
						this.addSel(i);
					}
					this.fireEvent('select',this);
					return;
				}
			}
			this.setSel(itemindex);
			this.fireEvent('select',this);
		},
		stopBrowserSelect:function(evt,src) {
//				if (evt.ctrlKey || evt.ctrlLeft || evt.shiftKey || evt.shiftLeft) {
					Event.stop(evt);
//				}
		},
		// dnd processor
		onPrepareDrag:function(uitype,src,evt) {
			var itemindex=this.getItemIndex(src);
			var item=this.itemlist[itemindex];
			var edit=item.editobject;
			if (edit && edit.isEditing()) {
				return true;
			}
		},
		onStartDrag:function(uitype,src,evt) {
			var itemindex=this.getItemIndex(src);
			src.setAttribute('swaf_system:list:startindex',this.getListId(src)+':'+itemindex);
			
			this.refreshList();
			if (this.getAttribute('selectable',this.itemlist[itemindex])) {
				this.setSel(itemindex);
			}
			src=null;
		},
		onDrag:function(uitype,src,evt) {
			var ret=false;
			
			var itemindex=this.getItemIndex(src);
			var item=this.itemlist[itemindex];
			var x=Event.pointerX(evt);
			var y=Event.pointerY(evt);
			var thisrect=Swaf.Dom.getRect(this.getElement());
			if (Swaf.Util.ptInRect(x,y,thisrect.x,thisrect.y,thisrect.width,thisrect.height)) {
				ret=this.checkListOver(x,y,item);
			}
			thisrect=null;
			if (!ret && this.group) {
				this.checkExport(x,y,item);
			}
		},
		onEndDrag:function(uitype,src,evt) {
			var itemindex=this.getItemIndex(src);
			var listid=this.getListId(src);
			var oldindex=src.getAttribute('swaf_system:list:startindex');
			var newindex=listid+':'+itemindex;
			if (oldindex!=newindex) {
				this.fireEvent('moved',this,this.origindex,itemindex);
			}
			src.setAttribute('swaf_system:list:startindex',null);

			return true;
		},
		onChanged:function(uitype,src,value) {
			this.fireEvent('edit',this.itemlist[this.getItemIndex(src)],this);
		},
		onKeypress:function(uitype,src,editel) {
			this.fireEvent('keypress',editel,this);
		},
		
		// internal use method
		checkExport:function(x,y,item) {
			var i,list,listRect;
			var shareGroup=this.group;
			var groupList=this.sharedList[shareGroup];
			for(i=0;i<groupList.length;i++) {
				list=groupList[i];
				if (list==this) continue;
				listRect=Swaf.Dom.getRect(list.getElement());
				if (Swaf.Util.ptInRect(x,y,listRect.x,listRect.y,listRect.width,listRect.height)) {
					// check
					if (list.checkListOver(x,y,item)==true) {
						this.fireEvent('delete',item,this);
						listRect=null;
						return true;
					}
				}
				listRect=null;
			} // for
			return false;
		},
		importBefore:function(listId,srcindex,destindex) {
			var srclist=Swaf.getInstance(document.getElementById(listId));
			var src=srclist.itemlist[srcindex];
			var dest=this.itemlist[destindex];
			var srcel=document.getElementById(src.elementId);
			
			//this.refreshItemListener(src);
			this.changeProcessorItemListener(src,this);
			this.disableSelectListener(src);

			srclist.itemlist.splice(srcindex,1);
			if (destindex==0) {
				this.itemlist.unshift(src);
			}
			else {
				this.itemlist.splice(destindex,0,src);
			}
			this.getElement().insertBefore(srcel,document.getElementById(dest.elementId));
			this.refreshList();
			srclist.refreshList();
///			src.element.setAttribute('swaf_system:list:selected','deleted');
				if (srcel.getAttribute('swaf_system:list:selected')=='selected') {
				srcel.setAttribute('swaf_system:list:selected','deleted');
//				if (this.normalStyle) Swaf.Dom.setCSS($(src.elementId),this.normalStyle);
				if (this.selitems) {
					for(var i=0;i<this.selitems.length;i++) {
						if (this.selitems[i]>=destindex) this.selitems[i]++;
					}
				}
				this.addSel(destindex+1);
			}
			if (srclist.selitems && srclist.selitems[0]==srcindex) srclist.setSel(-1);
//			this.setSel(this.getItemIndex($(src.elementId)));
			srcel=null;
			this.enableSelectListener(src);
		},
		importAfter:function(listId,srcindex,destindex) {
			var srclist=Swaf.getInstance(document.getElementById(listId));
			var src=srclist.itemlist[srcindex];
			var dest=this.itemlist[destindex+1];
			var srcel=document.getElementById(src.elementId);

			var len=this.itemlist.length;

//			this.refreshItemListener(src);
			this.changeProcessorItemListener(src,this);
			this.disableSelectListener(src);

			srclist.itemlist.splice(srcindex,1);
			if (destindex==len-1) {
				this.itemlist.push(src);
				this.getElement().insertBefore(srcel,null);
			} else {
				this.itemlist.splice(destindex+1,0,src);
				this.getElement().insertBefore(srcel,document.getElementById(dest.elementId));
			}

			this.refreshList();
			srclist.refreshList();
//			src.element.setAttribute('swaf_system:list:selected','deleted');
			if (srcel.getAttribute('swaf_system:list:selected')=='selected') {
				srcel.setAttribute('swaf_system:list:selected','deleted');
//				if (this.normalStyle) Swaf.Dom.setCSS($(src.elementId),this.normalStyle);
				if (this.selitems) {
					for(var i=0;i<this.selitems.length;i++) {
						if (this.selitems[i]>destindex) this.selitems[i]++;
					}
				}
				this.addSel(destindex+1);
			}
			if (srclist.selitems && srclist.selitems[0]==srcindex) srclist.setSel(-1);
//			this.setSel(this.getItemIndex($(src.elementId)));
			srcel=null;
			this.enableSelectListener(src);
		},
		importAppend:function(listId,srcindex) {
			var srclist=Swaf.getInstance(document.getElementById(listId));
			var src=srclist.itemlist[srcindex];
			var srcel=document.getElementById(src.elementId);

			srclist.itemlist.splice(srcindex,1);
			
			this.appendItem(src,true);
			
			srclist.refreshList();

			if (srcel.getAttribute('swaf_system:list:selected')=='selected') {
				srcel.setAttribute('swaf_system:list:selected','deleted');
				this.addSel(this.itemlist.length-1);
			}
			srcel=null;
			if (srclist.selitems && srclist.selitems[0]==srcindex) srclist.setSel(-1);
		},
		moveBefore:function(srcindex,destindex) {
			if (srcindex+1==destindex) return;
			var src=this.itemlist[srcindex];
			var dest=this.itemlist[destindex];
			var resultindex=(srcindex<destindex)?destindex-1:destindex;
			this.itemlist.splice(srcindex,1);

			if (destindex==0) {
				this.itemlist.unshift(src);
			}
			else {
				this.itemlist.splice(resultindex,0,src);
			}
			this.getElement().insertBefore(document.getElementById(src.elementId),document.getElementById(dest.elementId));
			this.refreshList();
			if (this.selitems) {
				var selindex;
				for(var i=0;i<this.selitems.length;i++) {
					selindex=this.selitems[i];
					if (selindex>=destindex) this.selitems[i]++;
					if (selindex>srcindex) this.selitems[i]--;
					else if (selindex==srcindex) this.selitems[i]=resultindex;
				}
			}
//				 && this.selitems[0]==srcindex) this.selitems[0]=resultindex;
		},
		moveAfter:function(srcindex,destindex) {
			if (srcindex==destindex+1) return;
			var src=this.itemlist[srcindex];
			var dest=this.itemlist[destindex+1];
			var len=this.itemlist.length;
			var resultindex=(srcindex<destindex)?destindex:destindex+1;
			this.itemlist.splice(srcindex,1);
			if (destindex==len-1) {
				this.itemlist.push(src);
				this.getElement().insertBefore(document.getElementById(src.elementId),null);
			} else {
				this.itemlist.splice(resultindex,0,src);
				this.getElement().insertBefore(document.getElementById(src.elementId),document.getElementById(dest.elementId));
			}
			this.refreshList();
//			if (this.selitems && this.selitems[0]==srcindex) this.selitems[0]=resultindex;
			if (this.selitems) {
				var selindex;
				for(var i=0;i<this.selitems.length;i++) {
					selindex=this.selitems[i];
					if (selindex>destindex) this.selitems[i]++;
					if (selindex>srcindex) this.selitems[i]--;
					else if (selindex==srcindex) this.selitems[i]=resultindex;
				}
			}
		},
		appendItem:function(item,notSelect) {
			this.changeProcessorItemListener(item,this);
			this.disableSelectListener(item);
			var itemel=document.getElementById(item.elementId);

			this.itemlist.push(item);
			this.getElement().insertBefore(itemel,null);

			this.refreshList();
			if (notSelect!=true) this.setSel(this.getItemIndex(itemel));
			this.enableSelectListener(item);
			itemel=null;
		},
		checkListOver:function(x,y,item) {
			var i,rect,checkHeight,buddy,ret,curitem,y2;
			var itemlen=this.itemlist.length;
			var itemel=document.getElementById(item.elementId);
			var itemindex=this.getItemIndex(itemel);
			var itemlist=this.getListId(itemel);
			var thisid=this.getElementId();
			var bImport=(thisid!=itemlist);
			ret=false;
			itemel=null;
			if (bImport && itemlen==0) {
				this.importAppend(itemlist,itemindex);
			} else {
				for(i=0;i<itemlen;i++) {
					if (!bImport && i==itemindex) continue;
					curitem=this.itemlist[i];
					rect=curitem.itemrect;
					checkHeight=rect.height/2;
					y2=rect.y+rect.height;
					if (Swaf.Util.ptInRect(x,y,rect.x,rect.y,rect.width,rect.height)) {
						if (y2-checkHeight<y) {
							// after
							if (!bImport && i+1==itemindex) break;
							if (bImport) this.importAfter(itemlist,itemindex,i);
							else this.moveAfter(itemindex,i);
							ret=true;
						} else {
							// before
							if (!bImport && i-1==itemindex) break;
							if (bImport) this.importBefore(itemlist,itemindex,i);
							else this.moveBefore(itemindex,i);
							ret=true;
						}
						break;
					} else if (i==itemlen-1) {
							if (y2-checkHeight<y) {
								// after
								if (!bImport && i+1==itemindex) break;
								if (bImport) this.importAfter(itemlist,itemindex,i);
								else this.moveAfter(itemindex,i);
								ret=true;
						}
					}
				} // for
			} // else
			if (ret) { if (bImport) this.fireEvent('insert',item,this); else this.fireEvent('move',item,this); }
			return ret;
		},
		refreshList:function() {
			var i,item,itemel;
			for(i=0;i<this.itemlist.length;i++) {
				item=this.itemlist[i];
				itemel=document.getElementById(item.elementId);
				item.itemrect=Swaf.Dom.getRect(itemel);
				this.setItemIndex(itemel,i);
				this.setListId(itemel);
				if (item.dndhandle!=item.elementId) {
					var tmpel=document.getElementById(item.dndhandle);
					this.setItemIndex(tmpel,i);
					this.setListId(tmpel);
					tmpel=null;
				}
				if (item.editarea!=item.elementId) {
					var tmpel=document.getElementById(item.editarea);
					this.setItemIndex(tmpel,i);
					this.setListId(tmpel);
					tmpel=null;
				}
				if (item.selecthandle!=item.elementId) {
					var tmpel=document.getElementById(item.selecthandle);
					this.setItemIndex(tmpel,i);
					this.setListId(tmpel);
					tmpel=null;
				}
				itemel=null;
			}
/*			if (this.space) {
				var spaceel=document.getElementById(this.space);
				if (this.itemlist.length>0) Swaf.Dom.hideElement(spaceel);
				else Swaf.Dom.showElement(spaceel);
				spaceel=null;
			}*/
		},
		setItemIndex:function(el,index) {
			el.setAttribute('swaf_system:list:itemindex',index);
		},
		getItemIndex:function(el) {
			return parseInt(el.getAttribute('swaf_system:list:itemindex'),10);
		},
		setListId:function(el) {
			el.setAttribute('swaf_system:list:listid',this.getElementId());
		},
		getListId:function(el) {
			return el.getAttribute('swaf_system:list:listid');
		},
		getItemValue:function(nIndex) {
			var item=this.itemlist[nIndex];
			if (item.editarea) {
				var v=document.getElementById(item.editarea).getAttribute('swaf:edit:value');
				if (v) return v;
				return document.getElementById(item.elementId).innerHTML;
			}
			return null;
		},



		getSelectedList:function() {
			var ret=this.selitems.copy();
			ret.sort(function(a,b) {return a-b;});
			return ret;
		},
		getItem:function(nIndex) {
			return this.itemlist[nIndex];
		},
		getLength:function() {
			return this.itemlist.length;
		},
		toNext:function(index) {
			if (index>=0 && index<this.itemlist.length-1) {
				this.moveAfter(index,index+1);
			}
		},
		toPrev:function(index) {
			if (index>0 && index<this.itemlist.length) {
				this.moveBefore(index,index-1);
			}
		},
		toLast:function(index) {
			if (index>=0 && index<this.itemlist.length-1) {
				this.moveAfter(index,this.itemlist.length-1);
			}
		},
		toFirst:function(index) {
			if (index>0 && index<this.itemlist.length) {
				this.moveBefore(index,0);
			}
		},
		// 11.8
		importBeforeCopy:function(listid,srcindex,destindex) {
			var el,selectable=false;
			var srclist=Swaf.getInstance(document.getElementById(listid));
			var src=srclist.itemlist[srcindex];

			var srcel=document.getElementById(src.elementId);
			if (!srcel) return;

			if (src.dndobject) src.dndobject.setEnable(false);
			if (src.editobject) src.editobject.setEnable(false);
			if (src.selectListener) { selectable=true; this.disableSelectListener(src); }

			el=srcel.cloneNode(true);
			el.id='';
			Swaf.unlinkInstance(el);
			el.removeAttribute('swaf_system:list:itemindex');
			el.removeAttribute('swaf_system:list:listid');
			
			Swaf.UI.Util.cleanChildElement(el);
			
			this.insertItem(el,destindex);
			
			if (src.dndobject) src.dndobject.setEnable(true);
			if (src.editobject) src.editobject.setEnable(true);
			if (selectable) {this.enableSelectListener(src); }

			el=null;
			srcel=null;
			srclist=null;
		},
		// 11.13
		insertItem:function(itemel,destIndex) {
	    var objs,dummyList = document.getElementById('swaf_dummyList');
    	if (!dummyList) {
        dummyList = document.createElement('DIV');
        dummyList.id = 'swaf_dummyList';
        dummyList.style.display = 'none';
        dummyList.setAttribute('swaf:ui','list');
        dummyList.setAttribute('swaf:list:dnd','false');
        dummyList.setAttribute('swaf:list:edit','false');
        dummyList.setAttribute('swaf:list:selectable','false');
        document.body.appendChild(dummyList);
    	}
    	dummyList.innerHTML='';
    	dummyList.appendChild(itemel);
			objs=$swafUI({'swaf_dummyList':null});
			
			if (destIndex!=undefined && destIndex!=null && destIndex<this.itemlist.length-1) this.importBefore('swaf_dummyList',0,destIndex);
			else this.importAppend('swaf_dummyList',0);
			
			Swaf.unlinkInstance(document.getElementById('swaf_dummyList'));
			delete objs[0];
			objs.length=0;
			objs=null;
			
    	dummyList.innerHTML='';
			dummyList=null;
			itemel=null;
		},
		deleteItem:function(nIndex) {
			if (nIndex<0 || nIndex>=this.itemlist.length) return;
			var src=this.itemlist[nIndex];
			this.itemlist.splice(nIndex,1);
			
			if (src.dndobject) {
				src.dndobject.setEnable(false);
				delete src.dndobject;
			}
			if (src.editobject) {
				src.editobject.setEnable(false);
				delete src.editobject;
			}
			if (src.selectListener) {
				src.selectListener.removeListener();
				delete src.selectListener;
			}

			Swaf.Dom.deleteElement(document.getElementById(src.elementId));
			
			delete src;
			
			this.refreshList();
			
			if (this.selitems) {
				var selindex;
				for(var i=0;i<this.selitems.length;i++) {
					selindex=this.selitems[i];
					if (selindex==nIndex) { this.selitems.splice(i,1); i--;}
					else if (selindex>nIndex) this.selitems[i]--;
				}
			}
		}
});

Swaf.UI.DropDown = Class.create();
Object.extend(Swaf.UI.DropDown.prototype, Swaf.UI.BaseAction.prototype);
Object.extend(Swaf.UI.DropDown.prototype, {
		type:'dropdown',
		handle:null,		// arr
		body:null,			// 1
		status:null,		// 1
		minsize:0,
		st_openimg:null,
		st_closeimg:null,
		st_opentxt:null,
		st_closetxt:null,
		
		arrListener:null,
		listener:null,

		opened:false,
		
		// method
		isOpened:function() {
			return this.opened;
		},

		initUI:function() {
			var childlist;
			var body;
			var openaction='click';
			var closeaction='click';
			
			childlist=this.getChildNodeList('handle');
			if (childlist) {
				this.handle=childlist[0].elementId;
				openaction=this.getAttribute('openaction',childlist[0]);
				closeaction=this.getAttribute('closeaction',childlist[0]);
			} else {
				this.handle=this.getElementId();
			}
			childlist=this.getChildNodeList('body');
			if (childlist) {
				this.body=childlist[0].elementId;
				this.minsize=this.getAttribute('minsize',childlist[0]);
			} else {
				this.body=this.getElementId();
			}
			body=document.getElementById(this.body);
			body.style.overflow='hidden';
			
			childlist=this.getChildNodeList('status');
			if (childlist) {
				this.status=childlist[0].elementId;
				this.st_openimg=this.getAttribute('status:openimg',childlist[0]);
				this.st_closeimg=this.getAttribute('status:closeimg',childlist[0]);
				this.st_opentxt=this.getAttribute('status:opentxt',childlist[0]);
				this.st_closetxt=this.getAttribute('status:closetxt',childlist[0]);
			}

			this.arrListener=new Array();
			if (openaction==closeaction) {
				this.arrListener.push({
					event:openaction,
					listener:this.toggleAction.bind(this)
				});
			} else {
				this.arrListener.push({
					event:openaction,
					listener:this.openAction.bind(this)
				},
				{
					event:closeaction,
					listener:this.closeAction.bind(this)
				}
				);
			}
			this.opened=this.getAttribute('expanded');
			if (!this.opened) {
				Swaf.Dom.setHeight(body,this.minsize);
				if (this.minsize<=1) Swaf.Dom.hideElement(body);
				if (body.innerHTML) {
					if (this.status) {
						var statusel=document.getElementById(this.status);
						if (this.st_closeimg && statusel.src!=undefined) statusel.src=this.st_closeimg;
						else if (this.st_closetxt && statusel.innerHTML!=undefined) statusel.innerHTML=this.st_closetxt;
						statusel=null;
					}
				} else {
					if (this.status) {
						var statusel=document.getElementById(this.status);
						if (this.st_openimg && statusel.src!=undefined) statusel.src=this.st_openimg;
						else if (this.st_opentxt && statusel.innerHTML!=undefined) statusel.innerHTML=this.st_opentxt;
						statusel=null;
					}
				}
			} else {
				if (this.status) {
					var statusel=document.getElementById(this.status);
					if (this.st_openimg && statusel.src!=undefined) statusel.src=this.st_openimg;
					else if (this.st_opentxt && statusel.innerHTML!=undefined) statusel.innerHTML=this.st_opentxt;
					statusel=null;
				}
			}
			body=null;
		},
		enableUI:function() {
			this.listener=new Swaf.Listener.Event(this.arrListener);
			this.listener.applyListener(document.getElementById(this.handle));
		},
		disableUI:function() {
			if (this.listener) {
				this.listener.removeListener();
				delete this.listener;
				this.listener=null;
			}
		},
		
		cbOpened:function() {
			this.opened=true;
			Swaf.Dom.setStyle(document.getElementById(this.body),'height','auto');
			if (this.status) {
				var el=document.getElementById(this.status);
				if (el) {
					if (this.st_openimg && el.src!=undefined) el.src=this.st_openimg;
					else if (this.st_opentxt && el.innerHTML!=undefined) el.innerHTML=this.st_opentxt;
					el=null;
				}
			}
			this.fireEvent('opened',this.getElement());
		},
		cbClosed:function() {
			this.opened=false;
			if (this.minsize<=1) Swaf.Dom.hideElement(document.getElementById(this.body));
			if (this.status) {
				var el=document.getElementById(this.status);
				if (el) {
					if (this.st_closeimg && el.src!=undefined) el.src=this.st_closeimg;
					else if (this.st_closetxt && el.innerHTML!=undefined) el.innerHTML=this.st_closetxt;
					el=null;
				}
			}
			this.fireEvent('closed',this.getElement());
		},
		open:function() {
			var body=document.getElementById(this.body);
			Swaf.Dom.showElement(body);
			var target=Swaf.Dom.getContentsHeight(body);
			if (target==0 && this.minsize==0) {
				Swaf.Dom.hideElement(body);
				body=null;
				return;
			}
			var anim=new Swaf.Animation.Size(body,2,this.getAttribute('step'));
			anim.setEndCallback(this.cbOpened.bind(this));
			Swaf.Dom.showElement(body);
			anim.setTargetHeight(target);
			anim.start();
			body=null;
		},
		close:function() {
			var body=document.getElementById(this.body);
			var target=Swaf.Dom.getContentsHeight(body);
			if (target==0) {body=null;return;}
			var anim=new Swaf.Animation.Size(body,2,this.getAttribute('step'));
			anim.setEndCallback(this.cbClosed.bind(this));
			anim.setTargetHeight(this.minsize);
			anim.start();
			body=null;
		},
		toggle:function(evt) {
			var ret;
			if (this.opened) {
				ret=this.fireEvent('close',this.getElement(),evt);
				if (ret!=undefined && ret==true) return;
				this.close();
			}
			else {
				ret=this.fireEvent('open',this.getElement(),evt);
				if (ret!=undefined && ret==true) return;
				this.open();
			}
		},
		toggleAction:function(evt) {
//			Event.stop(evt);
			this.toggle(evt);
		},
		openAction:function(evt) {
			ret=this.fireEvent('open',this.getElement(),evt);
			if (ret!=undefined && ret==true) return;
//			Event.stop(evt);
			this.open();
		},
		closeAction:function(evt) {
			ret=this.fireEvent('close',this.getElement(),evt);
			if (ret!=undefined && ret==true) return;
//			Event.stop(evt);
			this.close();
		}
});

Swaf.UI.DnD= Class.create();
Object.extend(Swaf.UI.DnD.prototype, Swaf.UI.BaseAction.prototype);
Object.extend(Swaf.UI.DnD.prototype, {
		type:'dnd',
		handle:null,
		useProxy:false,
		opacity:0.5,

		moveArea:null,		// Swaf.Util.Rect
		
		listener:null,
		arrListener:null,
		docListener:null,
		dragging:false,
		proxy:null,
		lbtndown:false,
		
		sx:0,
		sy:0,
		bodysx:0,
		bodysy:0,

		curX:0,
		curY:0,
		
		// method
		setMoveArea:function(rect) {
			this.moveArea=rect;
			this.moveArea.x2=rect.x+rect.width;
			this.moveArea.y2=rect.y+rect.height;
		},
		getMoveArea:function() {
			return this.moveArea;
		},
		isDragging:function() {
			return this.dragging;
		},
		getCurPoint:function() {
			return {x:this.curX,y:this.curY};
		},
		setCurPoint:function(x,y) {
			this.curX=x;
			this.curY=y;
		},
		
		initUI:function() {
			this.arrListener=
			[
				{	// start Drag
					event:"mousedown",
					listener:this.startDragImpl.bind(this)
				}
			];
			this.documentListener=
			[
				{	// dragging
					event:"mousemove",
					listener:this.onDragImpl.bind(this)
				},
				{	// end drag
					event:'mouseup',
					listener:this.endDragImpl.bind(this)
				}
			];
			this.handle=this.getChildNodeList('handle');
			if (!this.handle) {
				this.handle=new Array(1);
				this.handle[0]={elementId:this.getElementId()};
			}
			this.useProxy=this.getAttribute('proxy');
			this.opacity=this.getAttribute('opacity')/100;
		},
		enableUI:function() {
			this.listener=new Array(this.handle.length);
			for(i=0;i<this.listener.length;i++) {
				this.listener[i]=new Swaf.Listener.Event(this.arrListener);
				this.listener[i].applyListener(document.getElementById(this.handle[i].elementId));
			}
		},
		disableUI:function() {
			if (this.listener) {
				for(i=0;i<this.listener.length;i++) {
					this.listener[i].removeListener();
					delete this.listener[i];
					this.listener[i]=null;
				}
				delete this.listener;
				this.listener=null;
			}
		},
		createProxy:function() {
			var body=this.getElement();
			var pos=Swaf.Dom.getPosition(body);
			var size=Swaf.Dom.getSize(body);
			var position=body.style.position;
//			this.proxy=body.cloneNode(true);
			this.proxy=Swaf.Dom.cloneNode(body);
			this.proxy.id=body.id+'_proxy';
			document.body.appendChild(this.proxy);
			if (position=='relative' || position=='absolute') Swaf.Dom.setStyle(this.proxy,'position',position);
			else Swaf.Dom.setStyle(this.proxy,'position','absolute');
			if (this.dragStyle) {Swaf.Dom.setCSS(this.proxy,this.dragStyle);}
			Swaf.Dom.hideSelect(this.proxy);
			Swaf.Dom.hideObject(this.proxy);
			Swaf.Dom.setPosition(this.proxy,pos.x,pos.y);
			Swaf.Dom.setSize(this.proxy,size.width,size.height);
			body=null;
		},
		deleteProxy:function() {
			if (this.proxy) {
				//Swaf.Dom.hideElement(this.proxy);
				Swaf.Dom.deleteElement(this.proxy);
				//Element.remove(this.proxy);
				this.proxy=null;
			}
		},
		startDragImpl:function(evt,src) {
			if (this.fireEvent('prepareDrag',this.getElement(),evt)==true) return;
			if (!Event.isLeftClick(evt)) return;
			this.lbtndown=true;
			this.sx=Event.pointerX(evt);
			this.sy=Event.pointerY(evt);
			var bodypos=Swaf.Dom.getPosition(this.getElement());
			this.bodysx=bodypos.x;
			this.bodysy=bodypos.y;
			
			if (this.getAttribute('areaconstrict')) {
				var pn=this.getElement().parentNode;
				if (pn) {
					this.setMoveArea(Swaf.Dom.getRect(pn));
				}
			}
			if (this.docListener) {
				this.docListener.removeListener();
				delete this.docListener;
			}
			this.docListener=new Swaf.Listener.Event(this.documentListener);
			this.docListener.applyListener(document);
			Event.stop(evt);
//			if (this.fireEvent('stopDragEvent','prepareDrag',src)==true) Event.stop(evt);
		},
		onDragImpl:function(evt,src) {
			if (!Event.isLeftClick(evt)) {
				this.endDragImpl(evt,src);
				return;
			}
            try {
			var body=this.getElement();
			var ret;
			if (this.lbtndown) {
				if (!this.dragging) {
					ret=this.fireEvent('startDrag',body,evt,{handleId:this.handle[0].elementId,x:this.curX,y:this.curY});
					if (ret!=undefined && ret==true) {body=null;return;}
					this.dragging=true;
					if (this.useProxy) {
						this.createProxy();
						body=this.proxy;
	 					Swaf.Dom.setPosition(body,this.bodysx,this.bodysy);
					}
					if (this.getAttribute('top')) {
						this.bodyZIndex=Swaf.Dom.getStyle(body,'zIndex');
						Swaf.Dom.setStyle(body,'zIndex',99999);
					}
					if (this.opacity<1) {
						Swaf.Dom.setStyle(body,'opacity',this.opacity);
					}
//					if (this.fireEvent('stopDragEvent','startDrag',src)==true) Event.stop(evt);
				} else {
					var cx=Event.pointerX(evt);
					var cy=Event.pointerY(evt);
					var dx=cx-this.sx;
					var dy=cy-this.sy;
					
					this.curX=this.bodysx+dx;
					this.curY=this.bodysy+dy;
					
					if (this.moveArea) {
						var rect=Swaf.Dom.getRect(body);
						if (this.curX+rect.width>this.moveArea.x2) this.curX=this.moveArea.x2-rect.width;
						if (this.curX<this.moveArea.x) this.curX=this.moveArea.x;
						if (this.curY+rect.height>this.moveArea.y2) this.curY=this.moveArea.y2-rect.height;
						if (this.curY<this.moveArea.y) this.curY=this.moveArea.y;
						rect=null;
					}

					ret=this.fireEvent('drag',body,evt,{handleId:this.handle[0].elementId,x:this.curX,y:this.curY});
					if (ret!=undefined && ret==true) {body=null;return;}

 					Swaf.Dom.setPosition((this.useProxy)?this.proxy:body,this.curX,this.curY);
//					if (this.fireEvent('stopDragEvent','onDrag',src)==true) Event.stop(evt);
				}
			}
			Event.stop(evt);
			body=null;
			evt=null;
            } catch (e) { }
		},
	endDragImpl:function(evt,src) {
			var body=this.getElement();
			var ret;
			this.lbtndown=false;
			if (this.dragging) {
				this.dragging=false;
				
				ret=this.fireEvent('endDrag',body,evt,{handleId:this.handle[0].elementId,x:this.curX,y:this.curY});
				if (this.useProxy) {
					var proxypos=Swaf.Dom.getPosition(this.proxy);
					this.deleteProxy();
					if (ret==undefined || ret!=true) Swaf.Dom.setPosition(body,proxypos.x,proxypos.y);
				} else {
					if (this.getAttribute('top')) {
							Swaf.Dom.setStyle(body,'zIndex',this.bodyZIndex);
					}
					if (this.opacity<1) {
							Swaf.Dom.setStyle(body,'opacity',1);
					}
				}
//				if (this.msgTarget && this.msgTarget.onEndDrag) this.msgTarget.onEndDrag.call(this.msgTarget,evt,body);
			}
			if (this.docListener) {
				this.docListener.removeListener();
				this.docListener=null;
			}
			Event.stop(evt);
			body=null;
//			if (this.fireEvent('stopDragEvent','endDrag',src)==true) Event.stop(evt);
		}
});

Swaf.UI.Memo=Class.create();
Object.extend(Swaf.UI.Memo.prototype, Swaf.UI.BaseAction.prototype);
Object.extend(Swaf.UI.Memo.prototype, {
		type:'memo',
		
		editId:null,
		minH:0,
		lineHeight:0,

		listener:null,
		editcontents:null,
		// method
		enableUI:function() {
			if (this.editid) document.getElementById(this.editid).disabled=false;
		},
		disableUI:function() {
			if (this.editid) document.getElementById(this.editid).disabled=true;
		},
		initUI:function() {
			var editel,contents;
			this.editId=this.getElementId()+'_memo';
			this.editcontents=this.getElement().innerHTML;
			
			var el=this.getElement();
			var size=Swaf.Dom.getSize(el);
			this.minH=size.height;
			var memo='<textarea id="'+this.editId+'" style="word-wrap:break-word;word-break:break-all;overflow:'+((this.getAttribute('autoexpand'))?'hidden':'auto')+';"></textarea>';
			el.innerHTML=memo;

			editel=document.getElementById(this.editId);
			contents=this.toMemo(this.editcontents);
			
			if (!this.editStyle) {
				editel.style.border=el.style.border;
				el.style.border='none';
				editel.style.background=el.style.background;
				el.style.background='none';
			};
			if (this.editStyle) {
				Swaf.Dom.setCSS(editel,this.editStyle);
			}

			// check font height
			editel.rows=1;
			var h1=Swaf.Dom.getHeight(editel);
			editel.rows=2;
			var h2=Swaf.Dom.getHeight(editel);
			this.lineHeight=h2-h1;
			
			editel.value=contents;

			editel.style.width=size.width+'px';
			editel.style.height=size.height+'px';
			
			var arrListener=
			[
				{	// lose focus
					event:"blur",
					listener:this.onEditLoseFocus.bind(this)
				},
				{	// key down
					event:"keypress",
					listener:this.onEditKeyPress.bind(this)
				},
				{	// key down
					event:["keydown","keyup"],
					listener:this.onEditKeyUp.bind(this)
				}
			]; 
			
			var listener=new Swaf.Listener.Event(arrListener);
			listener.applyListener(editel);

		},
		toMemo:function(contents) {
			contents=contents.replace(/&nbsp;/gm,' ');
			contents=contents.replace(/\n/gm,'');
			contents=contents.replace(/ {2,100}/gm,'');
			contents=contents.replace(/<BR>/gmi,'[$%BR%$]');
			contents=contents.stripTags();
			contents=contents.unescapeHTML();
			contents=contents.replace(/\[\$%BR%\$\]/gm,'\n');
			return contents;
		},
		toHTML:function(contents) {
			contents=contents.replace(/\n/gm,'[$%BR%$]');
			contents=contents.escapeHTML();
			contents=contents.replace(/\[\$%BR%\$\]/gm,'<BR>');
			contents=contents.replace(/ /gm,'&nbsp;');
			return contents;
		},
		refreshContents:function() {
			var contents;
			contents=document.getElementById(this.editId).value;
			this.editcontents=this.toHTML(contents);
			this.getElement().setAttribute('swaf:edit:value',contents);
		},
		getValue:function() {
			var contents;
			contents=document.getElementById(this.editId).value;
			this.editcontents=this.toHTML(contents);
			return this.editcontents;
		},
		// edit event
		onEditLoseFocus:function(evt,src) {
			this.refreshContents();
			this.fireEvent('memo',this.getElement(),evt,src.value);
		},
		onEditKeyUp:function(evt,src) {
			var tmph;
			var editel=document.getElementById(this.editId);
			var sh=Swaf.Dom.getContentsHeight(editel);
			if (this.getAttribute('autoexpand') && sh>this.minH) {
				Swaf.Dom.setHeight(this.getElement(),sh+2);
				Swaf.Dom.setHeight(editel,sh+2);
			} else {
				Swaf.Dom.setHeight(this.getElement(),this.minH);
				Swaf.Dom.setHeight(editel,this.minH);
			}
		},
		onEditKeyPress:function(evt,src) {
			var code=evt.keyCode;
			var editel=document.getElementById(this.editId);
			var sh=Swaf.Dom.getContentsHeight(editel);
			if (sh/this.lineHeight>this.getAttribute('maxrows')) {
				if (code==13) Event.stop(evt);
			} else {
				this.fireEvent('keypress',this.getElement(),evt,src.value);
			}
		}
});

Swaf.UI.Edit=Class.create();
Object.extend(Swaf.UI.Edit.prototype, Swaf.UI.BaseAction.prototype);
Object.extend(Swaf.UI.Edit.prototype, {
//		editCSSClass:null,
		type:'edit',
		
		bEditing:false,
		editId:null,

		listener:null,
		docListener:null,
		editListener:null,
		subedit:false,
		precontents:null,
		postcontents:null,
		editcontents:null,
		// method
		initUI:function() {
			var tmp,i;
			this.editId=this.getElementId()+'_edit';
			var contents=this.getElement().innerHTML;
			contents=contents.replace(/\n/gm,'');
			contents=contents.replace(/\t/gm,' ');
			contents=contents.replace(/ {2,100}/gm,'');
			tmp=contents.split('@@');
			if (tmp.length>2) {
				this.subedit=true;
				this.precontents=tmp[0];
				this.postcontents=tmp[tmp.length-1];
				this.editcontents='';
				for(i=1;i<tmp.length-1;i++) {
					this.editcontents+=tmp[i];
				}
				this.precontents=this.precontents.replace(/\\@/gm,'@');
				this.postcontents=this.postcontents.replace(/\\@/gm,'@');
				this.editcontents=this.editcontents.replace(/\\@/gm,'@');
				
				this.getElement().innerHTML=this.precontents+this.editcontents+this.postcontents;
			} else {
				this.editcontents=contents;
			}
			this.getElement().setAttribute('swaf:edit:value',this.editcontents);
		},
		onDestroy:function() {
			this.editListener=null;
			this.docListener=null;
				this.listener=null;
		},
		enableUI:function() {
			this.listener=$listener(this.getElement(),this.getAttribute('active'),this.onStartEdit.bind(this));
		},
		disableUI:function() {
			if (this.listener) {
				this.listener.removeListener();
				delete this.listener;
				this.listener=null;
			}
		},
		isEditing:function() {
			return this.bEditing;
		},
		setInnerContents:function() {
			var el=this.getElement();
			var contents=this.editcontents;
			if (this.subedit) {
				el.innerHTML=this.precontents+contents+this.postcontents;
				this.edend=this.edstart+contents.length;
			} else {
				el.innerHTML=contents;
			}
			el=null;
		},
		showEdit:function() {
			var i,editel,contents,editobj;
			if (Swaf.globalEditingId) {
				var inst=Swaf.getInstance(document.getElementById(Swaf.globalEditingId));
				if (inst instanceof Array) {
					for(i=0;i<inst.length;i++) {
						if (inst[i].type=='edit') { editobj=inst[i]; break;}
					}
				} else if (inst.type && inst.type=='edit') editobj=inst;
				if (editobj) editobj.completeEdit();
				editobj=null;
				inst=null;
			}
			this.bEditing=true;
			var el=this.getElement();
			var size=Swaf.Dom.getSize(el);
			var edit='<input id="'+this.editId+'" type="text" maxLength="'+this.getAttribute('maxlen')+'">';
			
			el.innerHTML=edit;
			editel=document.getElementById(this.editId);
			contents=this.editcontents;
			if (!this.getAttribute('enableHTML')) {
//				contents=contents.replace(/&nbsp;/gm,' ');
				contents=contents.stripTags();
				contents=contents.unescapeHTML();
			}
			editel.value=contents;
			if (!this.editStyle) {
				editel.style.border='1px solid gray';
				editel.style.width='90%';
			};
			editel.style.width=size.width+'px';
			editel.style.height=size.height+'px';
			
			if (this.editStyle) {
				Swaf.Dom.setCSS(editel,this.editStyle);
			}
			
			Swaf.globalEditingId=this.getElementId();
			
			var arrListener=
			[
				{	// lose focus
					event:"blur",
					listener:this.onEditLoseFocus.bind(this)
				},
				{	// key down
					event:"keypress",
					listener:this.onEditKeyPress.bind(this)
				}
			]; 
			var arrDocListener=[
				{	// mousedown
					event:"mousedown",
					listener:this.onMouseDown.bind(this)
				}
			];
			
			this.editListener=new Swaf.Listener.Event(arrListener);
			this.editListener.applyListener(editel);
			this.docListener=new Swaf.Listener.Event(arrDocListener);
			this.docListener.applyListener(document);

			editel.focus();		// FireFox Bug
			
		},
		completeEdit:function(evt) {
			var contents,editel;
			if (this.bEditing==false) return;
			this.bEditing=false;
			editel=document.getElementById(this.editId);
			if (!editel) return;
			
			this.editListener.removeListener();
			delete this.editListener;
			this.editListener=null;
			
			contents=editel.value;
			if (!this.getAttribute('enableHTML')) {
				contents=contents.escapeHTML();
				contents=contents.replace(/ /gm,'&nbsp;');
			}
//			Swaf.Dom.deleteElement(editel);
			editel=null;
//			this.getElement().innerHTML='';
			this.editcontents=contents;
			this.getElement().setAttribute('swaf:edit:value',contents);
			this.fireEvent('changed',this.getElement(),null,contents);
			this.setInnerContents();
			
			Swaf.globalEditingId=null;

			this.docListener.removeListener();
			delete this.docListener;
			this.docListener=null;
		},
		onStartEdit:function(evt,src) {
			if (this.bEditing) return;
			if (this.fireEvent('startEdit',this.getElement())==true) return;
			this.showEdit();
//			Event.stop(evt);
		},
		// edit event
		onEditLoseFocus:function(evt,src) {
			this.completeEdit(evt);
		},
		onEditKeyPress:function(evt,src) {
			var code=evt.keyCode;
			var char=String.fromCharCode(code);
			switch (code) {
				case 27 : 	// ESC
				case 13 : 	// ENTER
					this.completeEdit(evt);	
					Event.stop(evt);
					break;
				default :
					this.fireEvent('keypress',this.getElement(),evt,src);
					break;
			}
		},
		onMouseDown:function(evt,src) {
			var x=Event.pointerX(evt);
			var y=Event.pointerY(evt);
			var rect=Swaf.Dom.getRect(this.getElement());
			if (!Swaf.Util.ptInRect(x,y,rect.x,rect.y,rect.width,rect.height)) {
				this.completeEdit(evt);
			}
		}
});

Swaf.UI.Button= Class.create();
Object.extend(Swaf.UI.Button.prototype, Swaf.UI.BaseAction.prototype);
Object.extend(Swaf.UI.Button.prototype, {
		type:'button',
		// static member
		radiogroup:{},
		// local member
		listener:null,
		arrListener:null,
		checked:false,
		bRadio:false,
		groupname:null,
		enable3state:false,
		
		// image
		normalImg:null,
		overImg:null,
		downImg:null,
		bImg:false,
		
		downBtn:null,
		
		uncheckable:true,
		
		initUI:function() {
			var group=this.getAttribute('group');
			this.normalImg=this.getAttribute('src');
			this.overImg=this.getAttribute('src:over');
			this.downImg=this.getAttribute('src:down');
			this.uncheckable=this.getAttribute('uncheckable');

			if (group) {
				if (!this.radiogroup[group]) this.radiogroup[group]=new Array();
				this.radiogroup[group].push(this);
				this.bRadio=true;
				this.groupname=group;
				this.setAttribute('_3state',true);
			}
			
			this.arrListener=[];
			this.enable3state=this.getAttribute('_3state');
			if (!this.enable3state) this.arrListener.push(
				{
					event:'click',
					listener:this.onMouseClick.bind(this)
				}
			);
			if (this.getElement().src!=undefined && this.normalImg) {
				this.bImg=true;
				this.getElement().src=this.normalImg;
			}
			
			if (this.getAttribute('checked')==true) {
				this.setCheck(true);
			}
			
		},
		// method
		enableUI:function() {
			if (this.arrListener.length>0) {
				this.listener=new Swaf.Listener.Event(this.arrListener);
				this.listener.applyListener(this.getElement());
			}
		},
		disableUI:function() {
			if (this.listener) {
				this.listener.removeListener();
				delete this.listener;
				this.listener=null;
			}
		},
		setCheck:function(bCheck) {
			this.checked=bCheck;
			if (bCheck) {
				if (this.downStyle) Swaf.Dom.setCSS(this.getElement(),this.downStyle);
				if (this.bImg==true && this.downImg) this.getElement().src=this.downImg;
			} else {
				if (this.normalStyle) Swaf.Dom.setCSS(this.getElement(),this.normalStyle);
				if (this.bImg==true && this.normalImg) this.getElement().src=this.normalImg;
			}
		},
		getCheck:function() {
			return this.checked;
		},
		getCheckedRadio:function() {
			var arr=this.radiogroup[this.groupname];
			if (arr) {
				for(i=0;i<arr.length;i++) {
					if (arr[i].checked) return arr[i].getElementId();
				}
			}
			return null;
		},
		checkRadio:function() {
			var i;
			var arr=this.radiogroup[this.groupname];
			if (arr) {
				for(i=0;i<arr.length;i++) {
					if (arr[i]==this) continue;
					arr[i].setCheck(false);
				}
			}
		},
		// event listener
		onMouseOver:function(evt,src) {
			if (!this.enable3state  || (this.enable3state && this.checked==false)) {
				if (this.overStyle) Swaf.Dom.setCSS(this.getElement(),this.overStyle);
				else if (this.normalStyle) Swaf.Dom.setCSS(this.getElement(),this.normalStyle);
				if (this.bImg==true) {
				    if (this.overImg) this.getElement().src=this.overImg;
				    else if (this.normalImg) this.getElement().src=this.normalImg;
				}
			}
			return false;
		},
		onMouseOut:function(evt,src) {
			if (!this.enable3state  || (this.enable3state && this.checked==false)) {
				if (this.normalStyle) Swaf.Dom.setCSS(this.getElement(),this.normalStyle);
				if (this.bImg==true && this.normalImg) this.getElement().src=this.normalImg;
			}
			return false;
		},
		onMouseDown:function(evt,src) {
			this.downBtn=src.id;
			if (this.enable3state) {
				if (this.uncheckable==false && this.checked==true) return true;
				this.checked=!this.checked;
				if (this.checked) {
					if (this.bRadio) this.checkRadio();
					this.onMouseClick(evt,src);
				}
			}
			return true;
		},
		onMouseUp:function(evt,src) {
			if (this.downBtn && this.downBtn==src.id) {
				if (this.checked) {
					if (this.downStyle) Swaf.Dom.setCSS(this.getElement(),this.downStyle);
					if (this.bImg==true && this.downImg) this.getElement().src=this.downImg;
				} else {
					var rect=Swaf.Dom.getRect(this.getElement());
					if (evt && Swaf.Util.ptInRect(Event.pointerX(evt),Event.pointerY(evt),rect.x,rect.y,rect.width,rect.height)) {
						this.onMouseOver(evt,src);
					} else {
						this.onMouseOut(evt,src);
					}
					if (this.enable3state) this.onMouseClick(evt,src);
				}
				this.downBtn=null;
			}
			return false;
		},
		onMouseClick:function(evt,src) {
			this.fireEvent('click',src,evt);
		}
});

Swaf.UI.Popup= {
		getPopupStorage:function(group) {
			var gs=Swaf.globalStorage.create('swaf_system:popup');
			if (group) {
				if (!gs[group]) gs[group]={};
				return gs[group];			
			} else {
				if (!gs.common) gs.common={};
				return gs.common;
			}
		},
		deletePopupStorage:function(group) {
			var gs=Swaf.globalStorage.create('swaf_system:popup');
			if (group) {
				delete gs[group];
			} else {
				delete gs.common;
			}
		},
		// open window
		// option
		// { method: iframe | ajax | direct | from element [direct]
		//   dim:true|false  [true]
		//   autosize:true|false  [true]
		//   width:number   [300]
		//   height:number  [300]
		//   hcenter:true/false   [true]
		//   vcenter:true/false   [true]
		//   x:number    [0]
		//   y:number    [0]
		//   animation:true/false [true]
		//	 initCallback: function name [null]
		//   callbackOwner : object 11.13
		//	 openCallback: function 11.13
		//   openCallbackArg : array 11.13
		//   closeCallback: function 11.13
		//   closeCallbackArg : array 11.13
		//   backIframe: true/false 11.18
		//   ajaxMethod: get|post 11.18
		//   ajaxParameter : str 11.18
		//   group : str 11.30
		//   loadingHTML : str 11.30
		//   dimOpacity : number 12.14	ljbear@nate.com
		//   keepOnUnload : false // 2007.1.29
		// }
		open:function(src,option) {
			var group=(option&&option.group)?option.group:'common';
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			gs.opener=window;
			var doc=Swaf.globalStorage.window.document;
			var gSwaf=Swaf.globalStorage.window.Swaf;
			if (gs.existPopup==true && gs.option) {
				// close exist popup
				var tmpani=gs.option.animation;
				gs.option.animation=false;
				this.close(group);	// force close
				gs.option.animation=tmpani;
			}
			
			{
				var ggs=Swaf.UI.Popup.getPopupStorage();
				if (typeof ggs.zindex!='number') ggs.zindex=91000;
				else ggs.zindex+=10;
				if (typeof ggs.openedpopup!='number') ggs.openedpopup=1;
				else ggs.openedpopup++;
			}
			
			gs.iframe_loaded=false;
			gs.ajax_loaded=false;
			gs.callback_called=false;

			gs.option={
				animation:false,
				autosize:true,
				hcenter:true,
				vcenter:true,
				x:0,
				y:0,
				width:300,
				height:300,
				backIframe:true,
				loadingHTML:'',
				dimOpacity:0.5,
				keepOnUnload:false
				};
			gs.option.backIframe=(Swaf.Util.Browser.isIE && Swaf.Util.Browser.getVersion()<7);
			if (option) Object.extend(gs.option,option);
			// insert background iframe
			if (gs.option.backIframe) this.createBackIframe(group);

			if (!gs.element) {
				gs.element=doc.createElement('div');
				gs.element.id=group+'_swaf_popup_div';
				gs.element.style.position='absolute';
				gs.element.style.left='0px';
				gs.element.style.top='0px';
				gs.element.style.background='none';
				gs.element.style.border='none';
				doc.body.appendChild(gs.element);
				//gs.element.style.display='hidden';
			} else {
				Swaf.Dom.showElement(gs.element);
			}
			Swaf.Dom.setStyle(gs.element,'zIndex',0);
//			Swaf.Dom.setStyle(gs.element,'opacity',0);

			// 2007.1.19.. close event
			if (gs.onunload!=true && gs.option.keepOnUnload!=true) {
			  window.__popup_group=group;
			  if (window.onunload) {
			  	var tmpfn=window.onunload;
			  	window.onunload=function() { tmpfn();Swaf.UI.Popup.onWindowUnload();}
			  } else 
			  	window.onunload=Swaf.UI.Popup.onWindowUnload;
			  gs.onunload=true;
			}
			
			// dim
			if (gs.option.dim!=false) Swaf.UI.Popup.Dim.showDim(gs.option.animation,gs.option.dimOpacity);
			//contents
			if (!gs.option.method) gs.option.method='direct';
			switch(gs.option.method) {
				case 'iframe' :
					setTimeout('Swaf.UI.Popup.loadIFrame("'+group+'","'+src+'")',0); // 207.9.28 prevent abort of iframe-request
					//gs.element.innerHTML='<iframe id="'+group+'_swaf_popup_div_iframe" src="'+src+'" allowTransparency="true" frameborder="0" scrolling="no" style="border:none;background:none;" onload="Swaf.UI.Popup.loadedIFrame(\''+group+'\')"/>';
					break;
				case 'ajax' :
					{
						gs.element.innerHTML=gs.option.loadingHTML;
						gSwaf.UI.Popup.showGSElement(group);
						if (gs.ajax) {gs.ajax.abort();gs.ajax=null;}
						gs.ajax=new gSwaf.Ajax.Request(gs.option.ajaxMethod || 'get','HTML');
						gs.ajax.setUrl(src);
						gs.ajax.setOwner(this);
						if (gs.option.ajaxParameter) {
							gs.ajax.setParameter(gs.option.ajaxParameter);
						}
						gs.ajax.setCallbackParameter(group);
						gs.ajax.setCallbackHandler(this.loadedAjax);
						gs.ajax.request();
					}
					break;
				case 'direct' :
					this.directInsert(src,group);
					break;
				case 'element' :
					this.elementInsert(src,group);
					break;
			} // switch
		},
		loadIFrame:function(group,src) {
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			gs.element.innerHTML='<iframe id="'+group+'_swaf_popup_div_iframe" src="'+src+'" allowTransparency="true" frameborder="0" scrolling="no" style="border:none;background:none;" onload="Swaf.UI.Popup.loadedIFrame(\''+group+'\')"/>';
		},
		onWindowUnload:function() {
			var group=window.__popup_group?window.__popup_group:'common';
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			if (gs.option) gs.option.animation=false;
			Swaf.UI.Popup.close(group);
			Swaf.UI.Popup.deletePopupStorage(group);
		},
		elementInsert:function(elid,group) {
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			var gSwaf=Swaf.globalStorage.window.Swaf;
			gs.elementContents=gSwaf.globalStorage.$(elid).innerHTML;
			gs.elementContentsEl=gSwaf.globalStorage.$(elid);
			gSwaf.globalStorage.$(elid).innerHTML='';
			gs.element.innerHTML=gs.elementContents;
			if (gs.option.autosize) {
				gs.element.style.width='auto';
				gs.element.style.height='auto';
			} else {
				gSwaf.Dom.showElement(gs.element);
				gSwaf.Dom.setSize(gs.element,gs.option.width,gs.option.height);
				gSwaf.Dom.setStyle(gs.element,'overflow','auto');
			}
			if (gs.option.initCallback) {eval(gs.option.initCallback+'()');}
			this.showGSElement(group);
		},
		directInsert:function(html,group) {
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			var gSwaf=Swaf.globalStorage.window.Swaf;
			gs.element.innerHTML=html;
			if (gs.option.autosize) {
				gs.element.style.width='auto';
				gs.element.style.height='auto';
			} else {
				gSwaf.Dom.showElement(gs.element);
				gSwaf.Dom.setSize(gs.element,gs.option.width,gs.option.height);
				gSwaf.Dom.setStyle(gs.element,'overflow','auto');
			}
			if (gs.option.initCallback) {eval(gs.option.initCallback+'()');}
			this.showGSElement(group);
		},
		loadedAjax:function(response,arrGroup) {
			var group=arrGroup[0];
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			var gSwaf=Swaf.globalStorage.window.Swaf;
			if (!response.isSuccess()) {
				gs.ajax=null;
				alert('네트워크 오류 : '+response.getStatus());
				return;
			}
			response.updateHTML(gs.element,gs.option.initCallback);

			if (gs.option.autosize) {
				gs.element.style.width='auto';
				gs.element.style.height='auto';
			} else {
				gSwaf.Dom.showElement(gs.element);
				gSwaf.Dom.setSize(gs.element,gs.option.width,gs.option.height);
				gSwaf.Dom.setStyle(gs.element,'overflow','auto');
			}
			gs.ajax=null;
			this.setCenter(group);
			gs.ajax_loaded=true;
			if (gs.callback_called!=true) {
 					gs.callback_called=true;
 					if (gs.option.openCallback) gs.option.openCallback.apply(gs.option.callbackOwner||document,gs.option.openCallbackArg||[]);
			}
		},
		loadedIFrame:function(group) {
//			alert('loaded');
			group=(group)?group:'common';
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			if (!gs.element) return;
			var gSwaf=Swaf.globalStorage.window.Swaf;
			try {
				//if (!gSwaf.Dom.getIFrameDoc(gSwaf.globalStorage.$(group+'_swaf_popup_div_iframe'))) return;
//				alert(gSwaf.Dom.getIFrameDoc(gSwaf.globalStorage.$(group+'_swaf_popup_div_iframe')).body.innerHTML);
				if (gs.option.autosize && gSwaf.Dom.getIFrameDoc(gSwaf.globalStorage.$(group+'_swaf_popup_div_iframe'))) {
/*					var body=gSwaf.Dom.getIFrameDoc(gSwaf.globalStorage.$(group+'_swaf_popup_div_iframe')).body;
					body.scroll='no';
					body=null;*/
					var ifel=gSwaf.globalStorage.$(group+'_swaf_popup_div_iframe');
					gSwaf.Dom.autoResizeIFrame(ifel);
					//gSwaf.Dom.setStyle($('_swaf_popup_div_iframe'),'border','2px solid red');
					var size=gSwaf.Dom.getSize(ifel);
					gSwaf.Dom.setSize(ifel,size.width+20,size.height+20);
					ifel=null;
				} else {
					gSwaf.Dom.setSize(gSwaf.globalStorage.$(group+'_swaf_popup_div_iframe'),gs.option.width,gs.option.height);
				}
			} catch(e) {
					//gSwaf.Dom.setSize(gSwaf.globalStorage.$(group+'_swaf_popup_div_iframe'),800,600);
					gSwaf.Util.outputDebugLn('Iframe load Exception!<br>'+Swaf.Util.dumpObject(e,'<br>'));
					gSwaf.UI.Popup.close(group);
			}
			this.setCenter(group);
			gs.iframe_loaded=true;
			if (gs.callback_called!=true) {
 					gs.callback_called=true;
 					if (gs.option.openCallback) gs.option.openCallback.apply(gs.option.callbackOwner||document,gs.option.openCallbackArg||[]);
			}
			gSwaf.UI.Popup.showGSElement(group);
		},
		showGSElement:function(group) {
			var x=0,y=0;
			// popup show
			var gs=Swaf.UI.Popup.getPopupStorage(group);
  		var ggs=Swaf.UI.Popup.getPopupStorage();
			var doc=Swaf.globalStorage.window.document;
			var gSwaf=Swaf.globalStorage.window.Swaf;
			
			gSwaf.Dom.setStyle(gs.element,'zIndex',ggs.zindex);
			
			if (gs.option.animation) {
				if (gs.openani) gs.openani.stop();
				gs.openani=null;
 				gs.existPopup=true;
				gs.openani=new Swaf.globalStorage.window.Swaf.Animation.Fade(gs.element,10,35);
				gs.openani.setTarget(100);
				gs.openani.setCallbackParameter(group);
				gs.openani.setEndCallback(gSwaf.UI.Popup.openEnd);
 				Swaf.Dom.showElement(gs.element);
 				this.setCenter(group);
				Swaf.Dom.setStyle(gs.element,'opacity',0);
				gs.openani.start();
			} else {
//				Swaf.Dom.setStyle(gs.element,'opacity',1);
 				Swaf.Dom.showElement(gs.element);
 				this.setCenter(group);
 				gs.existPopup=true;
 				if (gs.option.method=='iframe' || gs.option.method=='ajax') {
	 				if (gs.callback_called!=true && (gs.iframe_loaded==true || gs.ajax_loaded==true)) {
	 					gs.callback_called=true;
	 					if (gs.option.openCallback) gs.option.openCallback.apply(gs.option.callbackOwner||document,gs.option.openCallbackArg||[]);
	 				}
 				} else {
 					if (gs.option.openCallback) gs.option.openCallback.apply(gs.option.callbackOwner||document,gs.option.openCallbackArg||[]);
 				}
			}
		},
		setCenter:function(group) {
			var x,y;
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			var gSwaf=Swaf.globalStorage.window.Swaf;
			var winrect=gSwaf.Util.Browser.getClientRect();
			var elrect=gSwaf.Dom.getRect(gs.element);
			// 프레임 내의 팝업을 위해 좌표 보정
			var local_scroll=Swaf.Util.Browser.getScrollPosition();
			var curwinpos=Swaf.Util.Browser.getWindowPosition();
			var gwinpos=gSwaf.Util.Browser.getWindowPosition();
			var ldx=curwinpos.x-gwinpos.x-local_scroll.x;
			var ldy=curwinpos.y-gwinpos.y-local_scroll.y;
			if (window==Swaf.globalStorage.window) {
				ldx=ldy=0;
			}
			// set position
			var scrpos=gSwaf.Util.Browser.getScrollPosition();
			if (gs.option.hcenter) {
				x=Math.ceil((winrect.width-elrect.width)/2)+scrpos.x;
				if (x<0) x=0;
			} else x=gs.option.x+ldx;
			if (gs.option.vcenter) {
				y=Math.ceil((winrect.height-elrect.height)/2)+scrpos.y;
				if (y<0) y=0;
			} else y=gs.option.y+ldy;
			gSwaf.Dom.setPosition(gs.element,x,y);
			this.adjustBackIFrame(group);
		},
		close:function(group) {
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			var gSwaf=Swaf.globalStorage.window.Swaf;
			var doc=Swaf.globalStorage.window.document;
			if (gs.existPopup==false) return;
			// hide popup
			if (gs.element){
				if (gs.option&&gs.option.animation) {
					if (gs.openani) gs.openani.stop();
					gs.openani=null;
					gs.openani=new gSwaf.Animation.Fade(gs.element,10,35);
					gs.openani.setTarget(0);
					gs.openani.setCallbackParameter(group);
					gs.openani.setEndCallback(gSwaf.UI.Popup.closeEnd);
					gs.openani.start();
				} else {
					gSwaf.Dom.hideElement(gs.element);
					if (gs.option.closeCallback) gs.option.closeCallback.apply(gs.option.callbackOwner||document,gs.option.closeCallbackArg||[]);
					this.removeBackIFrame(group);
					if (gs.option.method=='iframe') {
						gSwaf.globalStorage.$('_swaf_popup_div_iframe').src='about:blank';
						gSwaf.Dom.deleteElement(gs.element);
					} else {
						gSwaf.Dom.deleteElement(gs.element);
					}
					gs.element=null;
//						gs.element.innerHTML='';
					gs.existPopup=false;
				}
			}
			// hide dim
			if (gs.option) {
				if (gs.option.dim!=false) gSwaf.UI.Popup.Dim.closeDim(gs.option.animation);
				// element restore
				if (gs.option.method=='element' && gs.elementContents) {
					gs.elementContentsEl.innerHTML=gs.elementContents;
					gs.elementContents=null;
					gs.elementContentsEl=null;
				}
			}

			{
				var ggs=gSwaf.UI.Popup.getPopupStorage();
				if (typeof ggs.openedpopup=='number') {
					ggs.openedpopup--;
					if (ggs.openedpopup==0) ggs.zindex=90000;
				}
			}

		},
		openEnd:function(group) {
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			delete gs.openani;
			if (gs.option) {
				if (gs.option.method=='iframe' || gs.option.method=='ajax') {
	 				if (gs.callback_called!=true && (gs.iframe_loaded==true || gs.ajax_loaded==true)) {
	 					gs.callback_called=true;
	 					if (gs.option.openCallback) gs.option.openCallback.apply(gs.option.callbackOwner||document,gs.option.openCallbackArg||[]);
	 				}
				} else {
					if (gs.option.openCallback) gs.option.openCallback.apply(gs.option.callbackOwner||document,gs.option.openCallbackArg||[]);
				}
			}

		},
		closeEnd:function(group) {
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			var gSwaf=Swaf.globalStorage.window.Swaf;
			delete gs.openani;
			gs.existPopup=false;
			if (gs.option&&gs.option.openCallback) gs.option.openCallback.apply(gs.option.callbackOwner||document,gs.option.openCallbackArg||[]);
			gSwaf.UI.Popup.removeBackIFrame(group);
		},
		// 11.13
		getPopupLayer:function(group) {
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			return gs.element;
		},
		isOpenedPopup:function(group) {
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			return (gs.existPopup!=undefined)?gs.existPopup:false;
		},
		// 11.30
		getTotalPopupCount:function() {
			var ggs=Swaf.UI.Popup.getPopupStorage();
			return ggs.openedpopup;
		},
		// 11.18
		adjustBackIFrame:function(group) {
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			var gSwaf=Swaf.globalStorage.window.Swaf;
			var rect=gSwaf.Dom.getRect(gs.element);
			//var rect2=gSwaf.Dom.getRect(gs.backgroundIFrame);
			//var rect=gSwaf.Util.getUnion(rect1,rect2);
			if (gs.backgroundIFrame) gSwaf.Dom.setRect(gs.backgroundIFrame,rect.x,rect.y,rect.width,rect.height);
			gs=null;
			//gs2=null;
		},
		createBackIframe:function(group) {
			var gs=Swaf.UI.Popup.getPopupStorage(group);
  		var ggs=Swaf.UI.Popup.getPopupStorage();
			var doc=Swaf.globalStorage.window.document;
			var gSwaf=Swaf.globalStorage.window.Swaf;
			if (!gs.backgroundIFrame) {
				gs.backgroundIFrame=doc.createElement('iframe');
				gs.backgroundIFrame.style.position="absolute";
				gs.backgroundIFrame.style.width='0px';
				gs.backgroundIFrame.style.height='0px';
				gSwaf.Dom.setStyle(gs.backgroundIFrame,'opacity',0);
				gSwaf.Dom.setStyle(gs.backgroundIFrame,'zIndex',ggs.zindex-1);
				doc.body.appendChild(gs.backgroundIFrame);
				gs.backgroundIFrameRef=1;
			} else {
				gs.backgroundIFrameRef++;
			}
			gSwaf.Dom.showElement(gs.backgroundIFrame);
		},
		removeBackIFrame:function(group) {
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			var gSwaf=Swaf.globalStorage.window.Swaf;
			if (gs.backgroundIFrame) {
				gs.backgroundIFrameRef--;
				if (gs.backgroundIFrameRef>0) {
					return;
					//gSwaf.Dom.hideElement(gs.backgroundIFrame);
				} else {
					gSwaf.Dom.deleteElement(gs.backgroundIFrame);
					gs.backgroundIFrame=null;
					gs.backgroundIFrameRef=0;
				}
			} else {
				gs.backgroundIFrameRef=0;
			}
		},
		// 11.23
		$:function() {
			Swaf.globalStorage.$.apply(Swaf.globalStorage.window,arguments);
		},
		// 12.13
		getPopupFrame:function(group) {
			group=(group)?group:'common';
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			var gSwaf=Swaf.globalStorage.window.Swaf;
			return gSwaf.globalStorage.$(group+'_swaf_popup_div_iframe');
		},
		getOpener:function(group) {
			group=(group)?group:'common';
			var gs=Swaf.UI.Popup.getPopupStorage(group);
			return gs.opener;
		}
/*		,
		$$:function() {
			Swaf.globalStorage.$$.apply(Swaf.globalStorage.window,arguments);
		},
		$search:function() {
			Swaf.globalStorage.$search.apply(Swaf.globalStorage.window,arguments);
		}*/
};
Swaf.UI.Popup.Dim={
		bDim:false,
		isDim:function() {
			return this.bDim;
		},
		showDim:function(bAnimation,nOpacity) {
			var gs=Swaf.globalStorage.create('swaf_system:popup:dim');
//			var gs=Swaf.UI.Popup.getPopupStorage();
			var doc=Swaf.globalStorage.window.document;
			var gSwaf=Swaf.globalStorage.window.Swaf;

			var rect=gSwaf.Util.Browser.getDocumentRect();
			var winrect=gSwaf.Util.Browser.getClientRect();
			
			if (!gs.dimel) {
			// dim
				gs.dimel=doc.createElement('div');
				gs.dimel.id='_swaf_popup_dim_div';
				gs.dimel.style.position='absolute';
				gs.dimel.style.left='0px';
				gs.dimel.style.top='0px';
				gs.dimel.style.background='#505050';
				gs.dimel.style.zIndex=9000;
				gSwaf.Dom.hideElement(gs.dimel);
				doc.body.appendChild(gs.dimel);
				gs.dimel.style.width='100%';
				gs.dimel.style.height='100%';
			}
			if (gs.refcnt==undefined) gs.refcnt=0;
			if (gs.refcnt==0) {
				// 처음일 때
				if (Swaf.Util.Browser.isIE) gSwaf.Dom.hideAllSelect();
				gSwaf.Dom.setSize(gs.dimel,Math.max(rect.width,winrect.width),Math.max(rect.height,winrect.height));
				
				gSwaf.Dom.showElement(gs.dimel);
				this.bDim=true;
				if (bAnimation) {
					gSwaf.Dom.setStyle(gs.dimel,'opacity',0);
					if (gs.dimani) gs.dimani.stop();
					gs.dimani=null;
					gs.dimani=new gSwaf.Animation.Fade(gs.dimel,10,35);
					gs.dimani.setTarget(nOpacity*100);
					gs.dimani.setEndCallback(this.dimEnd);
					gs.dimani.start();
				} else {
					gSwaf.Dom.setStyle(gs.dimel,'opacity',nOpacity);
				}
			}
			gs.refcnt++;

		},
		dimEnd:function() {
			var gs=Swaf.globalStorage.create('swaf_system:popup:dim');
			delete gs.dimani;
			gs.dimani=null;
		},
		closeDim:function(bAnimation) {
			var gs=Swaf.globalStorage.create('swaf_system:popup:dim');
			var gSwaf=Swaf.globalStorage.window.Swaf;
			if (!gs || gs.refcnt==undefined || gs.refcnt<1) {
				//gSwaf.Util.outputDebugLn('Warning : Swaf.UI.Popup.Dim.closeDim consistency breaked!!');
				return;
			}
			gs.refcnt--;
			if (gs.refcnt>0) return;
			// hide dim
			if (gs.dimel) {
				if (bAnimation) {
					if (gs.dimani) gs.dimani.stop();
					gs.dimani=null;
					gs.dimani=new gSwaf.Animation.Fade(gs.dimel,10,35);
					gs.dimani.setTarget(0);
					gs.dimani.setEndCallback(this.dimClose.bind(this));
					gs.dimani.start();
				} else {
					gSwaf.Dom.hideElement(gs.dimel);
					if (Swaf.Util.Browser.isIE) gSwaf.Dom.showAllSelect();
					this.bDim=false;
				}
			}
		},
		dimClose:function() {
			var gs=Swaf.globalStorage.create('swaf_system:popup:dim');
			var gSwaf=Swaf.globalStorage.window.Swaf;
			delete gs.dimani;
			gs.dimani=null;
			if (Swaf.Util.Browser.isIE) gSwaf.Dom.showAllSelect();
			this.bDim=false;
		}
};


var _c2_alert_template=[
'<div class="layer_tpl"><table class="layer_layout"><tr><td><div class="layer_wrap"><div class="layer_header"><strong>%%TITLE%%</strong><a href="#" onclick="_c2_alert_close()"><img src="http://c2img.cyworld.co.kr/img/common/popup/btn_layer_close.gif" alt="레이어 닫기" /></a></div><div class="layer_content">%%MESSAGE%%</div><div class="layer_button">',
'</div></div></td><td class="shadow" width="2"></td></tr><tr><td class="shadow" colspan="2" height="3"></td></tr></table></div>'
];
var _c2_alert_btn_template=[
'<a href="#" onclick="_c2_alert_ok()"><img src="%%IMGBASE%%button/btn_yes.gif" alt="예" /></a> ',
'<a href="#" onclick="_c2_alert_cancel()"><img src="%%IMGBASE%%button/btn_no.gif" alt="아니요" /></a>',
'<a href="#" onclick="_c2_alert_ok()"><img src="%%IMGBASE%%button/btn_confirm.gif" border="0" alt="확인" /></a> ',
'<a href="#" onclick="_c2_alert_cancel()"><img src="%%IMGBASE%%button/btn_cancel.gif" border="0" alt="취소" /></a>'
];

var _c2_cancel_callback=null;
var _c2_ok_callback=null;
var _c2_alert_close=function(key) {
	var gs=Swaf.globalStorage.create('_c2_alert_option');
	Swaf.UI.Popup.close('_c2_alert');
	var cbfn=gs._c2_close_callback;
	var callerWin=gs.caller_window;
	Swaf.globalStorage.remove('_c2_alert_option');
	gs=null;
	if (cbfn) cbfn.call(callerWin);
	cbfn=callerWin=null;
};
var _c2_alert_cancel=function(key) {
	var gs=Swaf.globalStorage.create('_c2_alert_option');
	Swaf.UI.Popup.close('_c2_alert');
	var cbfn=gs._c2_cancel_callback;
	var callerWin=gs.caller_window;
	Swaf.globalStorage.remove('_c2_alert_option');
	gs=null;
	if (cbfn) cbfn.call(callerWin);
	cbfn=callerWin=null;
};
var _c2_alert_ok=function(key) {
	var gs=Swaf.globalStorage.create('_c2_alert_option');
	Swaf.UI.Popup.close('_c2_alert');
	var cbfn=gs._c2_ok_callback;
	var callerWin=gs.caller_window;
	Swaf.globalStorage.remove('_c2_alert_option');
	gs=null;
	if (cbfn) cbfn.call(callerWin);
	cbfn=callerWin=null;
};
var c2_confirm=function(msg,title,mode,option) {
	var gs=Swaf.globalStorage.create('_c2_alert_option');
	var html=_c2_alert_template[0];
	var imgbase= (option && option.imgbase)?option.imgbase:'http://c2img.cyworld.co.kr/img/ko/';
	gs.caller_window=window;
	var html_ok=_c2_alert_btn_template[(option&&option.yesno==true)?0:2];
	var html_cancel=_c2_alert_btn_template[(option&&option.yesno==true)?1:3];
	var contents_cls='default';
	if (!option || option&&option.view_ok!=false) html+=html_ok;
	if (!option || option&&option.view_cancel!=false) html+=html_cancel;
	if (option) {
		if (option.cancel) gs._c2_cancel_callback=option.cancel;
		if (option.ok) gs._c2_ok_callback=option.ok;
		if (option.close) gs._c2_close_callback=option.close;
		else if (option.cancel) gs._c2_close_callback=option.cancel;
		if (option.className&&option.className.length>0) contents_cls=option.className;
	}
	msg='<div class="'+contents_cls+'">'+msg+'</div>';
	html+=_c2_alert_template[1];
	html=html.replace(/%%MESSAGE%%/gmi,msg);
	html=html.replace(/%%TITLE%%/gmi,title||'');
	html=html.replace(/%%IMGBASE%%/gmi,imgbase);
	Swaf.UI.Popup.open(html,{dim:true,animation:false,method:'direct',group:'_c2_alert',dimOpacity:0.01});
};
var c2_alert=function(msg,title,mode,option) {
	if (option) {
		if (option.view_ok==undefined) option.view_ok=true;
		if (option.view_cancel==undefined) option.view_cancel=false;
	} else {
		option={view_cancel:false};
	}
	c2_confirm(msg,title,mode,option);
};

$swafUI=function(def) {
	var processor;
	var elid,el,uicategory;
	var ret=[];
	for(selector in def) {
		elid=selector;
		processor=def[selector];
		el=document.getElementById(elid);
		if (!el) {
			Swaf.Util.outputDebugLn('element <'+elid+'> is not exist!!!');
			continue;
		}
		ret.push(Swaf.UI.createUI(el,processor));
	}
	return ret;
};

$initUI=function() {
var uidef=[
{
	base : Swaf.UI.Button,
	form : { button : null},
	attribute : {
		button : [ 'group(str)', '_3state(bool)=false', 'src:over(str)', 'src:down(str)', 'src(str)', 'uncheckable(bool)=true', 'checked(bool)=false']
	}
},
{
	base : Swaf.UI.Edit,
	form : { edit : null},
	attribute : {
		edit : [ 'maxlen(int)=30', 'enableHTML(bool)=false', 'active(str)=click']
	}
},
{
	base : Swaf.UI.Memo,
	form : { memo : null},
	attribute : {
		memo : [ 'maxrows(int)=5', 'autoexpand(bool)=false']
	}
},
{
	base : Swaf.UI.DnD,
	form : { dnd : 'handle'},
	attribute : {
		dnd : [ 'proxy(bool)=false', 'top(bool)=true', 'opacity(int)=50', 'areaconstrict(bool)=false']
	}
},
{
	base : Swaf.UI.DropDown,
	form : { dropdown : ['handle','body','status']},
	attribute : {
		dropdown : [ 'expanded(bool)=false', 'step(int)=20'],
		status:[ 'status:openimg(str)','status:closeimg(str)','status:opentxt(str)','status:closetxt(str)'],
		handle:[ 'openaction(str)=click', 'closeaction(str)=click'],
		body:[ 'minsize(int)=0']
	}
},
{
	base : Swaf.UI.List,
	form : { list : 'item',
					 item : [ 'dndhandle','editarea','selecthandle','status']
				 },
	attribute : {
		list:['group(str)',
					'dnd(bool)=false',
					'dnd:opacity(int)=50',
					'edit(bool)=false',
					'edit:maxlen(int)=30',
					'selectable(bool)=true',
					'multiselect(bool)=false',
					'status:selectimg(str)',
					'status:normalimg(str)',
					'status:selecttxt(str)',
					'status:normaltxt(str)',
					'active:select(str)=click',
					'active:edit(str)=dblclick'
				],
		item:['dnd(bool)',
					'edit(bool)',
					'selectable(bool)'
				]
	}
},
{
	base : Swaf.UI.Tree,
	form : { tree : [ 'root','childs', 'node' ],
					 childs : [ 'node' ],
					 root : [ 'dndhandle','selecthandle','editarea','selectstatus','openstatus' ],
					 node : [ 'root','childs','dndhandle','selecthandle','editarea','selectstatus','openhandle','openstatus' ]
				 },
	attribute : {
		tree:['group(str)',
					'expanded(bool)=true',
					'dnd(bool)=false',
					'dnd:opacity(int)=50',
					'dnd:term(bool)',
					'dnd:nonterm(bool)',
					'dnd:root(bool)',
					'dnd:range(str)=free',
					'edit(bool)=false',
					'edit:term(bool)',
					'edit:nonterm(bool)',
					'edit:root(bool)',
					'edit:maxlen(int)=30',
					'selectable(bool)=false',
					'selectable:term(bool)',
					'selectable:nonterm(bool)',
					'selectable:root(bool)',
					'indent(int)=15',
					'status:selectimg(str)',
					'status:normalimg(str)',
					'status:selecttxt(str)',
					'status:normaltxt(str)',
					'status:openimg(str)',
					'status:closeimg(str)',
					'status:opentxt(str)',
					'status:closetxt(str)',
					'active:select(str)=click',
					'active:edit(str)=dblclick',
					'active:open(str)=click',
					'active:close(str)=click',
					//2006.11.27 ajax support
					'ajax(bool)=false',
					'ajax:template(str)',
					'ajax:read(str)',
					'ajax:update(str)',
					'ajax:param(str)',
					'ajax:busy(str)',
					//2006.11.28 foldable option
					'foldable(bool)=true',
					'foldable:root(bool)',
					//2006.12.07
					'dnd:maxdepth(int)=2',
					//2006.12.13
					'child:class(str)'
				],
		childs:['dnd(bool)','dnd:range(str)','edit(bool)','selectable(bool)','indent(int)'],
		root:['dnd(bool)','edit(bool)','selectable(bool)','foldable(bool)'],
		node:['dnd(bool)','edit(bool)','selectable(bool)','expanded(bool)','foldable(bool)']
	}
},
{
	base : Swaf.UI.Scroll,
	form : { scroll : 'item'},
	attribute : {
		scroll : [ 'step(int)=2', 'interval(int)=2' ]
	}
},
{
	base : Swaf.UI.Marquee,
	form : { marquee : 'item'},
	attribute : {
		marquee : ['direction(str)=down', 'step(int)=2', 'interval(int)=2', 'autostart(bool)=false', 'itemsleep(int)=500']
	}
},
{
	base : Swaf.UI.ScrollList,
	form : { scroll_list : 'item'},
	attribute : {
		scroll_list : ['direction(str)=vert', 'step(int)=15', 'interval(int)=2', 'ajax(bool)=false', 'ajax:template(str)', 'ajax:url(str)', 'inpage(int)=1', 'ajax:pagelen(int)=15', 'ajax:param(str)', 'ajax:busy(str)','ajax:keepall(bool)=false','animation:show(bool)=false']
	}
},
{
	base : Swaf.UI.ScrollBar,
	form : { scroll_bar : ['prevbtn','nextbtn','thumbarea'], thumbarea:'thumbbtn'},
	attribute : {
		scroll_bar : ['direction(str)=vert', 'list(str)', 'step(int)=15', 'viewtip(bool)=true','enabledrag(bool)=true']
	}
}

];
		for (var i=0;i<uidef.length;i++) Swaf.UI.registUI(uidef[i]);
};

function clearSwafUI() {
	Swaf.UI.clearUIDef();
}

$listener(window,'unload',clearSwafUI);

