/****************************************************************************************************
제목 : 공통 함수
----------------------------------------------------------------------------------------------------
목적 : 공통으로 사용되는 함수를 별도 관리하기 위한 객체 처리
----------------------------------------------------------------------------------------------------
주의 :
----------------------------------------------------------------------------------------------------
POST
----------------------------------------------------------------------------------------------------
GET
----------------------------------------------------------------------------------------------------
REQUEST
----------------------------------------------------------------------------------------------------
작성자 : 고광진 (akanaka)
작성일 : 2007년 10월 03일
수정일 : 2009년 07월 01일
연락처 : akanaka@hanmail.net
****************************************************************************************************/


var UTIL = new Object () ;


/**************************************************
실행 : 기본형
--------------------------------------------------
**************************************************/
UTIL.run = function ()
{
	UTIL.set.variable () ;
	window.onerror = UTIL.error ;
}


/**************************************************
에러
--------------------------------------------------
description	: 에러 내용
url			: 에러 발생 URL
line		: 에러 발생 Line
count		: 에러 발생 횟수					// UTIL.echo.error 함수에 의해서만 전달 됨.
same		: 동일 에러 발생 횟수 ( 연속성 )	// UTIL.echo.error 함수에 의해서만 전달 됨.
**************************************************/
UTIL.error = function ( description , url , line , count , same )
{
//	url = encodeURIComponent ( ( url ) ? url : window.location.href ) ;
//	UTIL.ajax.send ( "/module/errorJavaScript.php?count=" + count + "&same=" + same + "&line=" + line + "&url=" + url + "&description=" + description , "GET" , "TEXT" ) ;
}


UTIL.set = new Object () ;


/**************************************************
변수 선언
--------------------------------------------------
**************************************************/
UTIL.set.variable = function ()
{
	try
	{
		UTIL.v						= new Object () ;
		UTIL.v.date					= new Object () ;
		UTIL.v.error				= new Object () ;
		UTIL.v.error.echo			= true ;			// 에러 출력 여부
		UTIL.v.error.detail			= true ;			// 에러 내용 상세 출력 여부
		UTIL.v.error.limit			= 1 ;				// 에러 발생 제한 값 ( 에러 발생 제한 값 이상으로 에러가 발생 시, 브라우저를 종료한다. )
		UTIL.v.error.count			= 0 ;				// 에러 발생 수
		UTIL.v.error.same			= 0 ;				// 동일 에러 발생 수
		UTIL.v.error.number			= false				// 에러 번호
		UTIL.v.ajax					= new Object () ;
		UTIL.v.ajax.request			= new Array () ;	// AJAX Request 객체 배열
		UTIL.v.ajax.error			= new Object () ;
		UTIL.v.ajax.error.limit		= 10 ;				// AJAX 이용 시, 지정 횟수 이상 네트워크 오류 발생 시, 오류 발생 누적 수 초기화 후, 에러 출력.
		UTIL.v.ajax.error.second	= 1000 ;			// AJAX 이용 시, 에러로 인한 재 반복 시 대기 시간.
		UTIL.v.ajax.error.count		= 0 ;				// AJAX 이용 시, 네트워크 오류 발생 누적 수.
		UTIL.v.ajax.count = 0 ;
	}
	catch ( errorCode )
	{
		UTIL.echo.error ( errorCode , "UTIL 객체 초기화에 실패하였습니다.\n\n관리자에게 문의하여 주십시오." ) ;
	}
}


UTIL.toggle = new Object () ;


/**************************************************
변수 값 토글 처리
--------------------------------------------------
string	: 현재 문자열
yes		: 변경 대상 1
no		: 변경 대상 2
--------------------------------------------------
입력된 string 값이 yes 와 동일하면, no 를 반환하고, string 값이 no 와 같다면 yes 를 반한환다.
**************************************************/
UTIL.toggle.string = function ( string , yes , no )
{
	return ( string == yes ) ? no : ( string == no ) ? yes : string ;
}


/**************************************************
변수의 사이 값 구하기
--------------------------------------------------
number	: 현재 값
min		: 최소 값
max		: 최대 값
--------------------------------------------------
입력된 number 값을 min 보다 크게, max 보다는 작은 값으로 리턴한다.
**************************************************/
UTIL.toggle.between = function ( number , min , max )
{
	number	= parseInt ( number	, 10 ) ;
	min		= parseInt ( min	, 10 ) ;
	max		= parseInt ( max	, 10 ) ;
	return ( number < min ) ? min : ( ( number > max ) ? max : number ) ;
}


UTIL.get = new Object () ;


/**************************************************
날자 및 시간
--------------------------------------------------
**************************************************/
UTIL.get.date = function ()
{
	var date = new Date () ;
	UTIL.v.date.year		= date.getYear () ;
	UTIL.v.date.month		= date.getMonth () + 1 ;
	UTIL.v.date.day			= date.getDate () ;
	UTIL.v.date.hour		= date.getHours () ;
	UTIL.v.date.minute		= date.getMinutes () ;
	UTIL.v.date.second		= date.getSeconds () ;
	UTIL.v.date.date		= UTIL.v.date.year + '-' + UTIL.v.date.month + '-' + UTIL.v.date.day ;
	UTIL.v.date.time		= UTIL.v.date.hour + ':' + UTIL.v.date.minute + ':' + UTIL.v.date.second ;
	UTIL.v.date.dateTime	= UTIL.v.date.date + ' ' + UTIL.v.date.time ;
}


/**************************************************
랜덤
--------------------------------------------------
start	: 시작 값
end		: 끝 값
--------------------------------------------------
음수 및 실수 사용 불가
**************************************************/
UTIL.get.random = function ( start , end )
{
	if ( start < 0 || end < 0 || start > end ) return false ;
	var result = Math.round ( Math.random () * ( end - start ) ) ;
	return result + start ;
}


/**************************************************
배열 롤링 : 앞 -> 뒤
--------------------------------------------------
array	: 배열 객체
random	: 랜덤 여부 ( Y : index 0 부터 index 를 기준으로 랜덤하게 가져옴. , N : Key 0 에서 가져 옴 , Key 값 : 해당 Key 에서 가져 옴 )
		  랜덤 여부의 값은 true , false 만 존재하는 형식이 아닌, Y 값이 존재하므로 주의해야 한다.
roll	: 결과을 배열에 넣을지 여부 ( true : 배열의 맨 뒤에 넣음 , false : 넣지 않음 )
untie	: 배열 풀기 여부 ( true : 풀기 , false : 결과 그대로 사용 ) // 2차 배열을 처리하는 경우에는 splice 결과가 배열로 쌓여서 나온다.
--------------------------------------------------
본 함수를 실행하고 나면 해당 배열 객체 ( array ) 에 index Attribute 가 추가 되며, 배열의 길이와는 무관 함.
**************************************************/
UTIL.get.first = function ( array , random , roll , untie )
{
	if ( array.length > 0 )
	{
		random		= ( UTIL.get.type ( random ) == 'string' ) ? random.toUpperCase () : random ;
		array.index = ( UTIL.get.type ( array.index ) != 'number' ) ? array.length - 1 : array.index ;
		array.loop	= ( UTIL.get.type ( array.loop ) != 'number' ) ? 0 : array.loop ;
		var index	= ( array.index == array.length - 1 ) ? array.index - 1 : array.index ;
		var slice	= ( random == 'Y' ) ? UTIL.get.random ( 0 , index ) : ( random == 'N' ) ? 0 : random ;
		var value	= array.splice ( slice , 1 ) ;
		array.index -- ;
		if ( array.index < 0 )
		{
			array.loop ++ ;
			array.index	= array.length - 1 ;
		}
		if ( roll == true )
		{
			array.push ( ( untie == true ) ? value[0] : value ) ;
		}
		return ( untie == true ) ? value[0] : value ;
	}
	return false ;
}


/**************************************************
배열 롤링 : 뒤 -> 앞
--------------------------------------------------
array	: 배열 객체
random	: 랜덤 여부 ( Y : index 0 부터 index 를 기준으로 랜덤하게 가져옴. , N : 마지막 Key 에서 가져 옴 , Key 값 : 해당 Key 에서 가져 옴 )
		  랜덤 여부의 값은 true , false 만 존재하는 형식이 아닌, Y 값이 존재하므로 주의해야 한다.
roll	: 결과을 배열에 넣을지 여부 ( true : 배열의 맨 앞에 넣음 , false : 넣지 않음 )
untie	: 배열 풀기 여부 ( true : 풀기 , false : 결과 그대로 사용 ) // 2차 배열을 처리하는 경우에는 splice 결과가 배열로 쌓여서 나온다.
--------------------------------------------------
본 함수를 실행하고 나면 해당 배열 객체 ( array ) 에 index Attribute 가 추가 되며, 배열의 길이와는 무관 함.
**************************************************/
UTIL.get.last = function ( array , random , roll , untie )
{
	if ( array.length > 0 )
	{
		random		= random.toUpperCase () ;
		array.index = ( UTIL.get.type ( array.index ) != 'number' ) ? array.length - 1 : array.index ;
		array.loop	= ( UTIL.get.type ( array.loop ) != 'number' ) ? 0 : array.loop ;
		var index	= ( array.index == array.length - 1 ) ? 1 : array.index + 1 ;
		var slice	= ( random == 'Y' ) ? UTIL.get.random ( index , array.length - 1 ) : ( random == 'N' ) ? array.length - 1 : random ;
		var value	= array.splice ( slice , 1 ) ;
		array.index ++ ;
		if ( array.index > array.length - 1 )
		{
			array.loop -- ;
			array.index	= 0 ;
		}
		if ( roll == true )
		{
			array.unshift ( ( untie == true ) ? value[0] : value ) ;
		}
		return ( untie == true ) ? value[0] : value ;
	}
	return false ;
}


/**************************************************
문자열의 Bytes 수 반환
--------------------------------------------------
string	: 문자열
--------------------------------------------------
한/영 구분 없이 문자열의 수에 따라 Bytes 값을 구할 수 있음.
**************************************************/
UTIL.get.bytes = function ( string )
{
	var bytes = 0 ;
	for ( i = 0 ; i < string.length ; i ++ )
	{
		var character = string.charAt ( i ) ;
		bytes += ( character.charCodeAt() > 128 ) ? 2 : 1 ;
	}
	return bytes ;
}


/**************************************************
객체 타입 가져오기
--------------------------------------------------
obj	: 객체
**************************************************/
UTIL.get.type = function ( obj )
{
	try
	{
		obj = typeof ( obj ) ;
		return obj.toLowerCase () ;
	}
	catch ( errorCode )
	{
		return 'undefined' ;
	}
}


/**************************************************
객체 가져오기
--------------------------------------------------
objName		: 객체의 ID 값
windowName	: 창 이름 ( 프레임으로 나눈 경우 )
**************************************************/
UTIL.get.obj = function ( objName , windowName )
{
	try
	{
		return eval ( ( windowName ) ? windowName : 'window' ).document.getElementById ( objName ) ;
	}
	catch ( errorCode )
	{
		UTIL.echo.error ( errorCode , objName + ' 객체가 존재하지 않습니다.' ) ;
	}
}


/**************************************************
객체 속성 가져오기
--------------------------------------------------
obj			: 객체
attribute	: 속성 이름
**************************************************/
UTIL.get.attribute = function ( obj , attribute )
{
	var result	= obj.getAttribute ( attribute ) ;
	if ( result == 'true' || result == 'TRUE' )
		return true ;
	if ( ! result || result == 'false' || result == 'NULL' || result == 'null' )
		return false ;
	return result ;
}


UTIL.node = new Object () ;


/**************************************************
Node , Attribute 속성 반환
--------------------------------------------------
resource	: XML Node 객체
type		: 객체 배열 방식 ( default : 번호 , name : nodeName ) ;
**************************************************/
UTIL.node.obj = function ( resource , type )
{
	var obj = new Array () ;
	if ( type == 'name' )
	{
		for ( k = 0 ; k < resource.childNodes.length ; k ++ )
		{
			obj[resource.childNodes[k].nodeName] = UTIL.node.attribute ( resource.childNodes[k] ) ;
		}
	}
	else
	{
		for ( k = 0 ; k < resource.childNodes.length ; k ++ )
		{
			obj.push ( UTIL.node.attribute ( resource.childNodes[k] ) ) ;
		}
	}
	return obj ;
}


/**************************************************
Attribute 속성 반환
--------------------------------------------------
obj		: XML Node 객체
**************************************************/
UTIL.node.attribute = function ( obj )
{
	var result = new Array () ;
	for ( var i = 0 ; i < obj.attributes.length ; i ++ )
	{
		result[obj.attributes[i].name] = decodeURIComponent ( obj.attributes[i].value ) ;
	}
	return result ;
}


UTIL.ajax = new Object () ;


/**************************************************
AJAX 객체 생성
--------------------------------------------------
AJAX 객체는 함수 내에 생성되는 Local 인스턴스 변수라도,
메모리를 차지하게 되므로, 별도의 배열을 이용하여 DB 풀링 하듯이 관리하도록 한다.
**************************************************/
UTIL.ajax.set = function ()
{
	var i , count = 0 ;
	for ( i = 0 ; i < UTIL.v.ajax.request.length ; i++ )
	{
		if ( UTIL.v.ajax.request[i].readyState && UTIL.v.ajax.request[i].readyState == 4 )
		{
			count ++ ;
		}
	}
	if ( count > 1 && count == UTIL.v.ajax.request.length )
	{
		UTIL.v.ajax.request.splice ( 1 , UTIL.v.ajax.request.length - 1 ) ;
		return 0 ;
	}
	try
	{
		UTIL.v.ajax.request.push ( new XMLHttpRequest () ) ;								// Mozilla, FireFox, Opera, Safari, Konqueror3
	}
	catch ( errorCode )
	{
		try
		{
			UTIL.v.ajax.request.push ( new ActiveXObject ( 'Msxml2.XMLHTTP' ) ) ;			// IE6
		}
		catch ( errorCode )
		{
			try
			{
				UTIL.v.ajax.request.push ( new ActiveXObject ( 'Microsoft.XMLHTTP' ) ) ;	// IE6
			}
			catch ( errorCode )
			{
				UTIL.echo.error ( 'AJAX' , "Request 를 생성 할 수 없습니다.\n\n관리자에게 문의하여 주십시오." ) ;
				return -1 ;
			}
		}
	}
	return UTIL.v.ajax.request.length - 1 ;
}


/**************************************************
AJAX 실행 ( 전달 )
--------------------------------------------------
url						: 스크립트 파일 경로
sendType				: 전달 방식 ( GET , POST )
receiveType				: returnFunction 에 전달 할 방식 ( XML : XML DOM 객체 형 , TEXT : Plain Text )
async					: 동기화 처리 여부 ( true : 동기 , false : 비 동기 )
userFunction			: 스크립트 실행 결과를 전달 할 함수 객체
userFunctionParameter	: userFunction 에 함께 전달 될 Paramater 값으로 Ajax 실행 결과 값 뒤에 함께 전달 된다.
timeout					: 처리 제한 시간
**************************************************/
UTIL.ajax.send = function ( url , sendType , receiveType , async , userFunction , userFunctionParameter , timeout )
{
	timeout	= ( timeout ) ? parseInt ( timeout , 10 ) : 0 ;
	var sequence = UTIL.ajax.set () ;
	if ( sequence >= 0 )
	{
//		UTIL.v.ajax.request[sequence].setRequestHeader ( 'Ajax: , 'true' ) ;
//		UTIL.v.ajax.request[sequence].setCharacterEncoding ( 'utf-8' ) ;
//		UTIL.v.ajax.request[sequence].setRequestHeader ( 'Content-Type' , 'text/xml; charset=EUC-KR' ) ;
		if ( sendType == 'POST' )
		{
			var temp	= url.split ( '?' ) ;
			parameter	= temp[1] ;
			UTIL.v.ajax.request[sequence].open ( sendType , temp[0] , async ) ;	// GET/POST , URL , 동기/비동기 , 사용자 이름 , 사용자 암호
			UTIL.v.ajax.request[sequence].setRequestHeader ( 'Content-Type' , 'application/x-www-form-urlencoded; charset=UTF-8' ) ;
			UTIL.v.ajax.request[sequence].setRequestHeader ( 'Content-length' , parameter.length ) ;
			UTIL.v.ajax.request[sequence].setRequestHeader ( 'Connection' , 'close' ) ;
		}
		else
		{
			UTIL.v.ajax.request[sequence].open ( sendType , url , async ) ;	// GET/POST , URL , 동기/비동기 , 사용자 이름 , 사용자 암호
			UTIL.v.ajax.request[sequence].setRequestHeader ( 'Content-Type' , 'text/xml; charset=UTF-8' ) ;
			parameter	= null ;
		}
		UTIL.v.ajax.request[sequence].onreadystatechange = function ()
		{
			if( UTIL.v.ajax.request[sequence].readyState == 4 ) // 페이지 상태
			{
				switch ( UTIL.v.ajax.request[sequence].status )
				{
					case 200 :		// 전송 성공 정상
					case 0 :		// status 값이 0 인 경우는 local 실행인 경우 임.
						var receiveData = ( receiveType == 'XML' ) ? UTIL.v.ajax.request[sequence].responseXML : UTIL.v.ajax.request[sequence].responseText ;
						if ( userFunction )
						{
							userFunction ( receiveData , userFunctionParameter ) ;							
						}
						break ;
					case 404 :		// 파일 없음
						UTIL.echo.error ( 'AJAX' , "실행 파일이 존재하지 않습니다.\n\n관리자에게 문의하여 주십시오." ) ;
						break ;
					case 403 :		// 접근 권한 부족
						UTIL.echo.error ( 'AJAX' , "실행 파일에 대한 접근권한이 없습니다.\n\n관리자에게 문의하여 주십시오." ) ;
						break ;
					case 12029 :	// The attempt to connect to the server failed.
					case 12007 :	// The server name could not be resolved.
					case 12002 :	// The request has timed out.
					case 12031 :	// The connection with the server has been reset.
					case 12030 :	// The connection with the server has been terminated.
					case 12017 :	// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed.
					case 12152 :	// The server response could not be parsed.
						if ( UTIL.v.ajax.error.count >= UTIL.v.ajax.error.limit )
						{
							UTIL.v.ajax.error.count = 0 ;
							UTIL.echo.error ( 'AJAX' , "네트워크 연결이 해제되었습니다.\n\n컴퓨터의 인터넷 회선 및 네트워크 환경을 확인하여 주십시오." , false , true ) ;
						}
						else
						{
							UTIL.v.ajax.error.count ++ ;
							setTimeout ( 'UTIL.ajax.send ( "' + url + '" , "' + sendType + '" , "' + receiveType + '" , ' + async + ' , ' + userFunction + ' , "' + userFunctionParameter + '" , "' + timeout + '" )' , UTIL.v.ajax.error.second ) ;
						}
						break ;
					default :		// 그외 기타 에러
						var errorMsg = UTIL.v.ajax.request[sequence].getResponseHeader ( 'Status' ) ;
						UTIL.echo.error ( 'AJAX' , ( ( errorMsg.length == null || errorMsg.length <= 0 ) ? 'Error : status code is ' + UTIL.v.ajax.request[sequence].status : errorMsg ) ) ;
						break ;
				}
			}
			else					// 전송 중
			{
				// none : 전송 중인 그래프 처리를 하고 싶은 경우에 처리
			}
		}
		UTIL.v.ajax.request[sequence].send ( parameter ) ;
		if ( async == false )
			return ( receiveType == 'XML' ) ? UTIL.v.ajax.request[sequence].responseXML : UTIL.v.ajax.request[sequence].responseText ;
	}
	else
	{
		UTIL.echo.error ( 'AJAX' , "Request 를 호출 할 수 없습니다.\n\n관리자에게 문의하여 주십시오." ) ;
	}
}


UTIL.convert = new Object () ;


/**************************************************
문자열의 첫 글자를 대문자로 변경한다.
--------------------------------------------------
string : 문자열
**************************************************/
UTIL.convert.cap = function ( string )
{
	return string.substr ( 0 , 1 ).toUpperCase () + string.substring ( 1 , string.length ) ;
}


/**************************************************
문자열 자릿수 변환
--------------------------------------------------
cipher	: 자리 수
string	: 문자열
just	: 문자열이 지정 자리 수 보다 큰 경우, 처리 여부 ( true , 맞춤 , false : 맞추지 않음 , 기본값 : false )
--------------------------------------------------
문자열의 앞에 자리수 만큼 0 을 채운다.
**************************************************/
UTIL.convert.sprintf = function ( cipher , string , just )
{
	string				= string.toString () ;
	cipher				= parseInt ( cipher , 10 ) ;
	var stringLength	= parseInt ( string.length , 10 ) ;
	if ( cipher > stringLength )
	{
		var modLength = cipher - stringLength ;
		for ( i = 0 ; i < modLength ; i++ )
		{
			string = '0' + string ;
		}
		return string ;
	}
	else if ( cipher < stringLength )
	{
		var modLength = stringLength - cipher ;
		return ( just == true ) ? string.substring ( stringLength , modLength ) : string ;
	}
	else
	{
		return string ;
	}
}


/**************************************************
통화 (￦) 자리 수 변환
--------------------------------------------------
string	: 변환 대상 값 ( 숫자 )
--------------------------------------------------
소수 점을 가지고 있는 값도 처리가 가능 하다.
**************************************************/
UTIL.convert.numberFormat = function ( string )
{
	var number		= string.toString ().split ( '.' ) ;
	var pattern		= new Array () ;
	pattern["not"]	= /[^0-9\+\-\.]/g ;
	pattern["won"]	= /([0-9]+)([0-9]{3})/ ;
	number[0]		= number[0].replace ( pattern['not'] , '' ) ;
	while ( pattern["won"].test ( number[0] ) )
	{
		number[0] = number[0].replace ( pattern["won"] , "$1,$2" ) ;
	}
	return number.join ( '.' ) ;
}


/**************************************************
파일 용량 정보 단위 변경
--------------------------------------------------
size	: 파일 용량
--------------------------------------------------
이 후, GB 단위를 처리하게 되는 경우 배열과 for 문을 이용하는 것이 바람직 함.
**************************************************/
UTIL.convert.fileSize = function ( size )
{
	size				= parseInt ( size , 10 ) ;
	var arraySize		= new Array () ;
	arraySize["Byte"]	= 1024 ;
	arraySize["KB"]		= 1024 * 1024 ;
	if ( size < arraySize["Byte"] )
	{
		var result = UTIL.convert.numberFormat ( size ) + ' Byte' ;
	}
	else if ( size >= arraySize["Byte"] && size <= arraySize["KB"] )
	{
		var result = UTIL.convert.numberFormat ( parseInt ( Math.round ( size / arraySize["Byte"] ) , 10 ) ) + ' KB' ;
	}
	else
	{
		var result = UTIL.convert.numberFormat ( parseInt ( Math.round ( size / arraySize["KB"] ) , 10 ) ) + ' MB' ;
	}
	return result ;
}


/**************************************************
Trim ( 문자열 좌, 우의 공백을 제거한다. )
--------------------------------------------------
string	: 문자열
**************************************************/
UTIL.convert.trim = function ( string )
{
	return string.replace ( /^\s+/g , "" ).replace ( /\s+$/g , "" ) ;
}


/**************************************************
시간 변환 : 초 -> 시간
--------------------------------------------------
second	: 초
--------------------------------------------------
주의 : 배열 내의 Key 값의 대 , 소문자를 구분하여 처리 함.
**************************************************/
UTIL.convert.secondToTime = function ( second )
{
	second = parseInt ( second , 10 ) ;
	var time = new Array () ;
	time["h"]	= Math.floor ( second / 3600 ) ;
	time["m"]	= Math.floor ( ( second - 3600 * time["h"] ) / 60 ) ;
	time["s"]	= second % 60 ;
	for ( var i in time )
	{
		time[UTIL.convert.cap ( i )] = UTIL.convert.sprintf ( 2 , time[i] ) ;
	}
	time["HMS"]	= time["H"] + ":" + time["M"] + ":" + time["S"] ;
	return time ;
}


/**************************************************
시간 변환 : 시간 -> 초
--------------------------------------------------
time		: 시:분:초
division	: 구분자 ( 기본값 : )
**************************************************/
UTIL.convert.timeToSecond = function ( time , division )
{
	var multiply ;
	division	= ( division ) ? division : ':' ;
	timeSplit	= time.split ( division ) ;
	if ( timeSplit.length <= 1 ) return time ;
	for ( var i in timeSplit )
	{
		timeSplit[i] = parseInt ( timeSplit[i] , 10 ) ;
	}
	return timeSplit[2] + ( timeSplit[1] * 60 ) + ( timeSplit[0] * 3600 ) ;
}


/**************************************************
날짜 변환 : 20070707 -> 2007년 07월 07일
--------------------------------------------------
string		: 날짜
type		: 형태 ( 0 : nnnn년 nn월 nn일 , 1 : nnnn-nn-nn , 2 : nnnn/nn/nn , 3 : nnnn.nn.nn , 4 : nnnn nn nn )
division	: 구분자
**************************************************/
UTIL.convert.date = function ( string , type , division )
{
	var date			= new Array () ;
	var pattern			= /^[0-9]{8}$/ ;
	var arrayDivision	= new Array ( null , '-' , '/' , '.' , ' ' ) ;
	if ( pattern.test ( string ) )
	{
		date[0]	= string.substr ( 0 , 4 ) ;
		date[1]	= string.substr ( 4 , 2 ) ;
		date[2]	= string.substr ( 6 , 2 ) ;
	}
	else if ( division )
	{
		date = date.split ( division ) ;
	}
	else
	{
		for ( var i = 1 ; i < arrayDivision.length; i ++ )
		{
			if ( string.indexOf ( arrayDivision[i] ) > 0 )
			{
				date.split ( arrayDivision[i] ) ;
				break ;
			}
		}
	}
	if ( date.length == 3 )
	{
		switch ( type )
		{
			case 4 :
			case 3 :
			case 2 :
			case 1 :
				return date.join ( arrayDivision[type] ) ;
				break ;
			case 0 :
			default :
				return date[0] + '년 ' + date[1] + '월 ' + date[2] + '일' ;
				break ;
		}
	}
}


/**************************************************
배열 내 원소 문자열 치환
--------------------------------------------------
array		: 배열 객체
search		: 검색 문자열
replace		: 치환 문자열 ( 기본 값 : 0 Space )
division	: 구분자 ( String.replace 매소드를 이용하므로, 문자열로 변환을 위해 Array.join 시 사용 될 문자열 , 기본 값 : ∥ )
--------------------------------------------------
1차 배열 이상의 2차 , 3차 배열은 지원하지 못 함.
**************************************************/
UTIL.convert.replace = function ( array , search , replace , division )
{
	replace			= ( ! replace ) ? '' : replace ;
	division		= ( ! division ) ? '∥' : division ;
	var arrayString	= array.join ( '∥' ) ;
	var pattern		= new RegExp ( search , 'g' ) ;
	if ( arrayString.search ( pattern ) >= 0 )
	{
		arrayString = arrayString.replace ( pattern , replace ) ;
		arrayString = arrayString.replace ( /(^∥)|(∥$)/gi , '' ) ;
		arrayString = arrayString.replace ( /(∥∥)/gi , '∥' ) ;
		array		= arrayString.split ( '∥' ) ;
		return array ;
	}
	return false ;
}


UTIL.create = new Object () ;


/**************************************************
태그 생성
--------------------------------------------------
name		: 태그 명칭 ( 종류 )
attributes	: 속성 ( 구분자 : | )
styles		: 스타일 ( 구분자 : ; )
inner		: innerHTML 값
body		: body Tag 출력 여부 ( 출력 : true , 리턴 : false , 기본 값 : undefined )
**************************************************/
UTIL.create.tag = function ( name , attributes , styles , inner , body )
{
	try
	{
		var valueSplit ;
		var tag				= document.createElement ( name.toLowerCase () ) ;
		var attributesSplit = ( UTIL.get.type ( attributes ) == 'string' ) ? attributes.split ( '|' ) : attributes ;
		var stylesSplit		= ( UTIL.get.type ( styles ) == 'string' ) ? styles.split ( ';' ) : styles ;
		for ( var i in attributesSplit )
		{			
			attributesSplit[i] = UTIL.convert.trim ( attributesSplit[i] ) ;
			if ( attributesSplit[i] )
			{
				valueSplit = attributesSplit[i].split ( '=' ) ;
				tag.setAttribute ( valueSplit[0].toLowerCase () , valueSplit[1] ) ;
			}
		}
		for ( var i in stylesSplit )
		{			
			stylesSplit[i] = UTIL.convert.trim ( stylesSplit[i] ) ;
			if ( stylesSplit[i] )
			{
				valueSplit		= stylesSplit[i].split ( ':' ) ;
				var styleName	= valueSplit[0].split ( '-' ) ;
				valueSplit[0]	= ( styleName.length > 1 ) ? styleName[0] + UTIL.convert.cap ( styleName[1] ) : valueSplit[0] ;
				tag.style[UTIL.convert.trim ( valueSplit[0] )] = valueSplit[1] ;
			}
		}
		if ( inner )
			tag.innerHTML	= inner ;
		if ( body ) UTIL.echo.tag ( tag ) ;
		return tag ;
	}
	catch ( errorCode )
	{
		UTIL.echo.error ( errorCode , 'Tag ( ' + name + ' ) 를 생성하지 못하였습니다.\n\n관리자에게 문의하여 주십시오.' ) ;
	}
}


/**************************************************
ActiveX 생성
--------------------------------------------------
absolute		: ActiveX 설치 요청 문구 Alert 출력 주기 ( 0 : 출력하지 않음 , 1 : 안내메세지만 출력 , n : n초 주기로 문구 출력 )
id				: Object Tag ID
classid			: 컨트롤 ID
codebase		: 컨트롤 파일 ( *.cab ) 경로
version			: 컨트롤 버전
userFunction	: 설치 후, 실행 함수
**************************************************/
UTIL.create.activeX = function ( absolute , id , classid , codebase , version , userFunction )
{
	var obj , curtain ;
	if ( obj = UTIL.get.obj ( id ) )
	{
		curtain	= UTIL.get.obj ( id + 'Curtain' ) ;
		if ( obj.object == null )
		{
			if ( ! curtain && absolute > 0 )
			{
				var message	= '<p align="center" style="position:relative;top:45%;line-height:200%; font-size:15px;color:white;">ActiveX 를 설치하여 주십시오.<br>정상적인 서비스 진행을 위해서는 ActiveX 설치가 필요합니다.</p>' ;
				UTIL.create.tag ( 'div' , 'id=' + id + 'Curtain' , "position:absolute;top:0px;left:0px;width:100%;height:100%;filter:alpha(opacity=75);background:black" , message , true ) ;
			}
			if ( absolute > 1 && obj.retryCount % absolute == 0 )
			{
				alert ( 'ActiveX 를 설치하여 주십시오.\n\n정상적인 서비스 진행을 위해서는 ActiveX 설치가 필요합니다.' ) ;
			}
			obj.retryCount ++ ;
			setTimeout ( 'UTIL.create.activeX ( ' + absolute + ' , "' + id + '" )' , 1000 ) ;
		}
		else if ( obj.userFunction )
		{
			if ( curtain && absolute > 0 )
			{
				curtain.removeNode ( true ) ;
			}
			obj.userFunction ( id ) ;
		}
	}
	else
	{
		UTIL.echo.tag
		(
			'<object id="' + id + '" classid="clsid:' + classid + '" codebase="' + codebase + '#version=' + version + '" width="0" height="0"></object>'
		) ;
		obj					= UTIL.get.obj ( id ) ;
		obj.userFunction	= userFunction ;
		obj.retryCount		= 1 ;
//		setTimeout ( 'UTIL.create.activeX ( ' + absolute + ' , "' + id + '" )' , 1000 ) ;
		UTIL.create.activeX ( absolute , id ) ;
	}
}


UTIL.cookie	= new Object ;


/**************************************************
쿠키 생성
--------------------------------------------------
name	: 쿠키 이름
value	: 쿠키 값
second	: 만료 시간 ( 단위 : 초 )
path	: 적용 경로
**************************************************/
UTIL.cookie.set = function ( name , value , second , path )
{
	var date , expires ;
	if ( ! second )
		second	= 0 ;
	if ( ! path )
		path = '/' ;
	date			= new Date();
	date.setTime ( date.getTime() + ( second * 1000 ) ) ;
	expires			= '; expires=' + date.toGMTString () ;	
	document.cookie = name + '=' + value + expires + '; path=' + path ;
}


/**************************************************
쿠키 값 반환
--------------------------------------------------
name	: 쿠키 이름
**************************************************/
UTIL.cookie.get = function ( name )
{
	var i , cookies , c ;
	name	= name + '=' ;
	cookies	= document.cookie.split ( ';' ) ; 
	for ( i = 0 ; i < cookies.length ; i ++ )
	{
		while ( cookies[i].charAt ( 0 ) == ' ' )
			cookies[i] = cookies[i].substring ( 1 , cookies[i].length ) ;
		if ( cookies[i].indexOf ( name ) == 0 )
			return cookies[i].substring ( name.length , cookies[i].length ) ;
	} 
	return null;
}


/**************************************************
쿠키 삭제
--------------------------------------------------
name	: 쿠키 이름
**************************************************/
UTIL.cookie.remove = function ( name )
{
	UTIL.cookie.setCookie ( name , '' , -1 ) ;
}


UTIL.echo	= new Object ;


/**************************************************
태그 출력
--------------------------------------------------
tag	: 출력을 원하는 Tag 의 객체 혹은 문자열
--------------------------------------------------
BODY Tag 가 출력되지 않은 상황에서 출력해야 하는 Tag 가 Object 인 경우에는,
setTimeout 함수를 이용하여 1초 후 다시 실행하도록 하였으나, 오류가 발생하고 있음.
이후, 점진적인 테스트를 통해 오류 원인을 밝혀 둘 필요가 있음.
**************************************************/
UTIL.echo.tag = function ( tag )
{
	var body ;
	( body = document.getElementsByTagName ( 'body' )[0] )
		? ( UTIL.get.type ( tag ) == 'object' ) ? body.appendChild ( tag ) : body.innerHTML += tag
		: ( UTIL.get.type ( tag ) == 'object' ) ? setTimeout ( 'UTIL.echo.tag ( ' + tag + ' )' , 1000 ) : document.write ( tag ) ;
}


/**************************************************
에러 출력
--------------------------------------------------
code	: 에러 발생 시 try catch 값 혹은 분류코드
message	: 에러 안내 문구
limit	: 동일 에러 제한 값 ( 숫자 : 해당 숫자 만큼 에러가 발생하면 윈도우 창을 닫는다 , true : 기본 제한에 따라 창을 닫는다 , false : 창을 닫지 않는다. )
hidden	: 출력 여부 ( true : 비 출력 , false : 출력 )
**************************************************/
UTIL.echo.error = function ( code , message , limit , hidden )
{
	var errorDetail ;
	var nowLimit = ( UTIL.get.type ( limit ) == 'number' ) ? limit : UTIL.v.error.limit ;
	if ( UTIL.v.error.same < nowLimit )
	{
		UTIL.v.error.count ++ ;
		if ( UTIL.v.error.detail == true )
		{
			UTIL.get.date () ;
			if ( UTIL.get.type ( code ) != 'object' )
			{
				var temp		= code ;
				code			= new Object () ;
				code.name		= temp ;
				code.number		= temp ;
				code.message	= 'JavaScript Program Source Error!' ;
			}
			else
			{
				code.number		= ( code.number >> 16 & 0x1FFF ) + '-' + ( code.number & 0xFFFF )
			}
			if ( code.number == UTIL.v.error.number )
			{
				UTIL.v.error.same ++ ;
			}
			else
			{
				UTIL.v.error.same	= 1 ;
				UTIL.v.error.number = code.number ;
			}
			errorDetail = '[' + UTIL.v.date.dateTime + ' / ' + code.name + ' : ' + code.number + '] ' + code.message + "\n\n" + 'Error Total Count : ' + UTIL.v.error.count + '회, Error Same Count : ' + UTIL.v.error.same + '회' + "\n\n" ;
		}
		if ( UTIL.v.error.echo == true && hidden != true )
		{
			alert ( errorDetail + message ) ;
		}
		UTIL.error ( code.message + "\n\n" + message , window.location.href , code.number , UTIL.v.error.count , UTIL.v.error.same ) ;
		return true ;
	}
	else if ( limit )
	{
		UTIL.v.error.same = 0 ;
		alert ( '동일한 종류의 에러가 ' + nowLimit + '회 이상 발생하여, 시스템 안정을 위해 윈도우 창을 닫습니다.\n\n웹 사이트 이용에 불편을 드려 죄송합니다.' ) ;
		parent.close () ;
		return false ;
	}
}


UTIL.curtain = new Object () ;


/**************************************************
커튼 생성
--------------------------------------------------
**************************************************/
UTIL.curtain.on = function ( message )
{
	try
	{
		if ( ! message )
			message	= '고객님의 소중한 정보를 전송 중 입니다.<br>잠시만 기다려 주십시오.<br>감사합니다.' ;
		if ( UTIL.get.obj ( 'oneUtilCurtain' ) )
		{				
			document.getElementById ( 'oneUtilCurtain' ).style.display = '' ;
			return true ;
		}		
		var border	= 0 ;
		var body	= document.getElementsByTagName ( 'body' )[0] ;
		var obj		= UTIL.create.tag
		(
			'div'
			, 'id=oneUtilCurtain'
			, 'position:absolute;top:0px;left:0px;z-index:9999;'
				+ 'text-align:center;font-size:12px;line-height:160%;color:#444444;'
				+ 'padding:' + Math.floor ( ( body.offsetHeight / 2 ) , 10 ) + 'px 0px 0px 0px;'
				+ 'border:' + border + 'px dashed silver;background-color:black;'
				+ 'filter:alpha(opacity=80);opacity:0.8;-moz-opacity:0.8;'
			, '<div style="width:' + ( body.offsetWidth - ( border * 2 ) ) + 'px;height:' + ( ( body.offsetHeight / 2 ) - ( border * 2 ) ) + 'px">'
				+ message
				+ '</div>'
			, true
		) ;
	}
	catch ( errorCode )
	{
		UTIL.echo.error ( errorCode , '커튼 출력에 실패하였습니다.\n\n관리자에게 문의하여 주십시오.' ) ;
	}
}


/**************************************************
커튼 제거
--------------------------------------------------
**************************************************/
UTIL.curtain.off = function ()
{
	if ( UTIL.get.obj ( 'oneUtilCurtain' ) )
		document.getElementById ( 'oneUtilCurtain' ).style.display = 'none' ;
}


UTIL.image = new Object () ;


/**************************************************
이미지 크기 재 조정
--------------------------------------------------
obj			: 객체 id ( this )
limitWidth	: 가로 최대 크기
limitHeight	: 세로 최대 크기
base		: 기준 값 ( width : 가로 기준 , height : 세로 기준 , fit : 맞춤 , original : 변경 이전으로 되돌림 , restore : 바로 이전으로 되돌림 )
--------------------------------------------------
this.reSizeHistory 사용
**************************************************/
UTIL.image.reSize = function ( obj , base , limitWidth , limitHeight )
{
	var mod				= 0 ;
	var objSize			= new Array () ;
	objSize["width"]	= obj.offsetWidth ;
	objSize["height"]	= obj.offsetHeight ;
	limitWidth			= parseInt ( limitWidth		, 10 ) ;
	limitHeight			= parseInt ( limitHeight	, 10 ) ;
	if ( ! obj.reSizeHistory )
	{
		obj.reSizeHistory = new Array () ;
		obj.reSizeHistory.push ( objSize ) ;
	}
	else if ( base != 'restore' )
	{
		obj.reSizeHistory.push ( objSize ) ;
	}
	switch ( base )
	{
		case 'width' :
			obj.style.width		= limitWidth ;
			mod					= limitWidth / objSize["width"] ;
			obj.style.height	= Math.round ( objSize["height"] * mod ) ;
			break ;
		case 'height' :
			obj.style.height	= limitHeight ;
			mod					= limitHeight / objSize["height"] ;
			obj.style.width		= Math.round ( objSize["width"] * mod ) ;
			break ;
		case 'auto' :
			if ( objSize["width"] > limitWidth && limitWidth != 0 )
			{
				mod					= limitWidth / objSize["width"] ;
				obj.style.width		= limitWidth ;
				obj.style.height	= Math.round ( objSize["height"] * mod ) ;
			}
			if ( objSize["height"] > limitHeight && limitHeight != 0 )
			{
				mod					= limitHeight / objSize["height"] ;
				obj.style.height	= limitHeight ;
				obj.style.width		= Math.round ( objSize["width"] * mod ) ;
			}
			break ;
		case 'restore' :
			if ( ! obj.reSizeHistory == "" || obj.reSizeHistory.length == 0 )
			{
				UTIL.echo.error ( 'IMAGE' , '되돌릴 값이 없습니다.' ) ;
			}
			else
			{
				var restoreSize = obj.reSizeHistory.pop () ;
				obj.style.width		= restoreSize["width"] ;
				obj.style.height	= restoreSize["height"] ;
			}
			break ;
		case 'original' :
			var restoreSize = obj.reSizeHistory[0] ;
			obj.style.width		= restoreSize["width"] ;
			obj.style.height	= restoreSize["height"] ;
			break ;
		default :
		case 'fit' :
			obj.style.width = limitWidth ;
			obj.style.height = limitHeight ;
			break ;
	}
}


UTIL.window = new Object () ;


/**************************************************
팝업
--------------------------------------------------
url			: 팝업 웹 페이지 경로
winWidth	: 팝업 창 가로 크기 ( 단위 : px )
winHeight	: 팝업 창 세로 크기 ( 단위 : px )
scrollBar	: 스크롤 바 출력 여부 ( true : 출력 , false : 비 출력 )
windowName	: 팝업 창 이름
topPoint	: 팝업 창 세로 위치
leftPoint	: 팝업 창 가로 위치
**************************************************/
UTIL.window.popup = function ( url , winWidth , winHeight , scrollBar , windowName , topPoint , leftPoint )
{
	var scrollBarWidth , scrollBarHeight ;
	scrollBar			= ( scrollBar == '1' || scrollBar == 'Y' || scrollBar == true ) ? '1' : '' ;
	windowName			= ( windowName ) ? windowName : 'winPopup' + Math.round ( Math.random() * 100000 ) ;
	winWidth			= parseInt ( winWidth , 10 ) ;
	winHeight			= parseInt ( winHeight , 10 ) ;
	var scrollSize		= parseInt ( 16 , 10 ) ;							// XP 및 Vista 의 경우, 16 픽셀이 아닐 수 있다.
	var monitorWidth	= window.screen.width ;
	var monitorHeight	= window.screen.height ;
	monitorWidth		-= parseInt ( monitorWidth * 0.025 , 10 ) ;			// 우측 스크롤바 공간을 제외. ( 비율 : 0.025 ) 절대치 아님.
	monitorHeight		-= parseInt ( monitorHeight * 0.065 , 10 ) ;		// 하단 시작메뉴 공간을 제외. ( 비율 : 0.065 ) 절대치 아님.
	var modWidth		= parseInt ( monitorWidth - winWidth , 10 ) ;
	var modHeight		= parseInt ( monitorHeight - winHeight , 10 ) ;
	if ( ! topPoint )
	{
		if ( modHeight <= 0 )
		{
			var scrollBarHeight	= 1 ;
			winHeight			= monitorHeight ;
			topPoint			= 0 ;
		}
		else
		{
			topPoint = parseInt ( modHeight / 2 , 10 ) ;
		}
	}
	if ( ! leftPoint )
	{
		if ( modWidth <= 0 ) // 이미지가 모니터의 해상도보다 크다면... 스크롤바를 생성하고 좌표를 0으로 한다.
		{
			var scrollBarWidth	= 1 ;
			winWidth			= monitorWidth ;
			leftPoint			= 0 ;
		}
		else
		{
			leftPoint = parseInt ( modWidth / 2 , 10 ) ;
		}
	}
	if ( scrollBarWidth && scrollBarHeight )
	{
		scrollBar = 1;
	}
	else if ( scrollBarWidth )
	{
		winHeight = parseInt ( winHeight + scrollSize , 10 ) ;
		scrollBar = 1 ;
	}
	else if ( scrollBarHeight )
	{
		winWidth = parseInt ( winWidth + scrollSize , 10 ) ;
		scrollBar = 1 ;
	}
	return window.open ( url , windowName , 'toolbar=0 , location=0 , directories=0 , status=0 , menubar=0 , scrollbars=' + scrollBar + ' , resizable=0 , width=' + winWidth + ' , height=' + winHeight + ' , top=' + topPoint + ' , left=' + leftPoint ) ;
}


/**************************************************
현재 경로를 재 호출한다.
--------------------------------------------------
FireFox 의 경우 reload () Method 를 호출하면,
FORM 전송이 다시 발생하는 문제가 있으므로, 본 함수를 사용한다.
**************************************************/
UTIL.window.reload = function ()
{
	location.href = location.pathname + location.search + location.hash ; 
}


UTIL.browser = new Object () ;


/**************************************************
즐겨찾기 추가
--------------------------------------------------
url		: 즐겨찾기 경로
title	: 즐겨찾기 명칭
**************************************************/
UTIL.browser.favorites = function ( url , title )
{
	if ( ! $.browser.msie || ! confirm ( title + ' ( ' + url + ' ) 을 즐겨찾기에 추가하시겠습니까?' ) ) return false ;
	return window.external.AddFavorite ( url , title ) ;
}


/**************************************************
브라우저 시작 페이지 설정
--------------------------------------------------
url	: URL
**************************************************/
UTIL.browser.startWebPage = function ( url )
{
	if ( ! browser.msie ) return false ;
	document.body.style.behavior	= 'url(#default#homepage)' ;
	document.body.setHomePage ( url ) ;
}


UTIL.run () ;