/*
========================================================================
	Author : puheol
	Comment : myLshop 프레임웍에서 사용하는 기본 데이터 형
		- Hashtable
		- Vector
		- DataObject
========================================================================
*/
/*
------------------------------------------------------------------------
	1. Hashtable 시작
------------------------------------------------------------------------	
		Java의 Hashtable과 같은 기능을 하는 Object
		사용방법) var hash = new Hashtable();
				  var obj = hash.get( "key" );
				  hash.put( "key", obj );
				  var obj = hash.remove( "key" );
				  var array = hash.keys();
				  var array = hash.elements();
				  var str = hash.toString();
*/
var Hashtable = function() {
	this.type = "hashtable";
	this.pair = new Array();
//	this.key = new Array();
//	this.data = new Array();
//	this.dataType = new Array();
//	this.attributeName = new Array();
//	this.attributeValue = new Array();
}
Hashtable.prototype = {
	
	put: function(_key, _value) {
		var ret = null;
		try {
			var pair = this.pair.detect(function(value, index) {
				if ( value.key == _key ) {
					ret = value.value;
					if (typeof _value.type == "undefined" || _value.type == null || _value.type == "") {
						value.value = _value+"";
						value.dataType = "string";
					} else {
						value.value = _value;
						value.dataType = _value.type;
					}
					return true;
				}
				return false;
			});
			if (typeof pair == 'undefined' || pair == null) {
				if (typeof _value.type == "undefined" || _value.type == null || _value.type == "") {
					pair = [ _key, _value+"", "string" ];
					pair.key = _key;
					pair.value = _value+"";
					pair.dataType = "string";
				} else {
					pair = [ _key, _value, _value.type ];
					pair.key = _key;
					pair.value = _value;
					pair.dataType = _value.type;
				}
				this.pair.push(pair);
			}		
		} catch( e ) {
			printStackTrace( e );
		}
		return ret;
	},
	
	get: function( _key ) {
		var pair = null;
		try {
			pair = this.pair.detect(function(value, index) {
				if (value.key == _key) return true;
				return false;
			});
			
		} catch( e ) {
			printStackTrace( e );
		}
		if (pair == null) {
			return null;
		} else if (pair.dataType == "string") {
			return XMLDecoder(pair.value);
		} else {
			return pair.value;
		}	
	},
	
	remove: function( _key ) {
		var ret = null;
		try {
			var couple = this.pair.partition(function(value, index) {
				if (value.key == _key) return true;
				return false;
			});
			if (!couple[0]) {
				this.pair = couple[1];
				ret = couple[0][0].value;
			}
		} catch( e ) {
			printStackTrace( e );
		}
		return ret;
	},
	
	containsKey: function( _key ) {
		var exist = false;
		try {
			var pair = this.pair.detect(function(value, index) {
				if (value.key == _key) return true;
				return false;
			});
			if (pair != null) exist = true;
		} catch( e ) {
			printStackTrace( e );
		}
		return exist;
	},
	keys: function() {
		return this.pair.pluck('key');
	},
	
	values: function() {
		return this.pair.pluck('value');
	},
	
	types: function() {
		return this.pair.pluck('dataType');
	},
		
	elements: function() {
		return keys();
	},
	
	toString: function() {
		var hashArray = new Array();
		hashArray.push( "\n" );
		this.pair.each(function(value, index) {
			if ($A(["hashtable", "vector", "dataobject"]).include(value.dataType) ) {
				hashArray.push("\n");
				hashArray.push(value.value.toString());
				hashArray.push("\n");
			} else {
				hashArray.push( "\n" );
			}		
		});
		hashArray.push( "\n" );
		return  hashArray.join("");
	}
}
/*
------------------------------------------------------------------------
	2. Vector 시작
------------------------------------------------------------------------
		Java의 Vector과 같은 기능을 하는 Object로 Vector을 xml형태로 변환도 가능하다.
		구현된 method는 addElement, elementAt, insertElementAt, remove, size, toString, toDocument이다.
		사용방법) var vector = new Vector();
				  vector.addElement( obj );
				  var obj = vector.elementAt( idx );
				  vector.insertElementAt( obj, idx );
				  var obj = vector.remove( idx );
				  var len = vector.size();
				  var str = vector.toString();
				  var dom = vector.toDocument();
					Object set( index, Object element)
 */
var Vector = function() {
	this.type = "vector";
	this.length = 0;
	this.pair = new Array();
//	this.data = new Array();
//	this.dataType = new Array();
//	this.attributeName = new Array();
//	this.attributeValue = new Array();
}
Vector.prototype = {
	
	addElement: function(_value) {
		try {
			var pair = null;
			if (typeof _value.type == "undefined" || _value.type == null || _value.type == "") {
				pair = [ _value+"", "string" ];
				pair.value = _value+"";
				pair.dataType = "string";
			} else {
				pair = [ _value, _value.type ];
				pair.value = _value;
				pair.dataType = _value.type;
			}
			this.pair.push(pair);
			this.length++;
			
		} catch( e ) {
			printStackTrace( e );
		}
	},
	elementAt: function(_index) {
		var ret = null;
		try {
			if ( _index >= 0 && _index < this.length ) {
				ret = this.pair[_index].value;
			}
		} catch( e ) {
			printStackTrace( e );
		}
		return ret;
	},
	insertElementAt: function(_value, _index) {
		try {
			if( _index == this.length ) {
				this.addElement( _value );
				return;
			}
			if ( _index >= 0 && _index < this.length ) {
				for( var i = this.length ; i > _index ; i-- ) {
					this.pair[i] = this.pair[i-1];
				}
				if (typeof _value.type == "undefined" || _value.type == null || _value.type == "") {
					this.pair[_index].value = _value+"";
					this.pair[_index].dataType = "string";
				} else {
					this.pair[_index].value = _value;
					this.pair[_index].dataType = _value.type;
				}
				this.length++;
			}
		} catch( e ) {
			printStackTrace( e );
		}
	},
	remove: function(_index) {
		var ret = null;
		try {
			if ( _index >= 0 && _index < this.length ) {
				ret = this.pair[_index].value;
	
				if( _index < this.length - 1 ) {
					for( var i = _index ; i < this.length - 1 ; i++ ) {
						this.pair[i] = this.pair[i+1];
					}
				}
				this.pair.pop();
				this.length--;
			}
		} catch( e ) {
			printStackTrace( e );
		}
		return ret;
	},
	size: function() {
		return this.length;
	},
	values: function() {
		return this.pair.pluck('value');
	},
	
	types: function() {
		return this.pair.pluck('dataType');
	},
	
	toString: function() {
		var vecArray = new Array();
		vecArray.push( "\n" );
		this.pair.each(function(value, index) {
			if ($A(["hashtable", "vector", "dataobject"]).include(value.dataType) ) {
				vecArray.push("\n");
				vecArray.push(value.value.toString());
				vecArray.push("\n");
			} else {
				vecArray.push( "\n" );
			}		
		});			
		vecArray.push( "\n" );
		return vecArray.join("");
	}
}
/*
2.11. XMLEncoder
*/
function XMLEncoder( s ) {
	var str = null;
	if ( s == null ) {
		str = "";
	} else if ( typeof s == 'string' ) {
		str = s;
	} else if ( typeof s == 'number' ){
		return s;
	} else {
		return s;
	}
	var re1 = /&/g;	//Initialize pattern.
	var re2 = //g;	//Initialize pattern.
	var re4 = /'/g;	//Initialize pattern.
	var re5 = /"/g;	//Initialize pattern.
	var re6 = /\n\r/g;	//Initialize pattern.
	var re7 = /\r\n/g;	//Initialize pattern.
	var re8 = /\n/g;	//Initialize pattern.
	var re9 = /\r/g;	//Initialize pattern.
	return str.replace( re1 ,"&").replace( re2 ,"<").replace( re3 ,">").replace( re4 ,"'").replace( re5 ,""").replace( re6 ,"
").replace( re7 ,"
").replace( re8 ,"
").replace( re9 ,"
");
}
/*
2.12. XMLDecoder
*/
function XMLDecoder( s ) {
	var re1 = /</g;	//Initialize pattern.
	var re2 = />/g;	//Initialize pattern.
	var re3 = /'/g;	//Initialize pattern.
	var re4 = /"/g;	//Initialize pattern.
	var re5 = /&/g;	//Initialize pattern.
	var re6 = /
/g;	//Initialize pattern.
	return s.replace( re1 ,"<").replace( re2 ,">").replace( re3 ,"'").replace( re4 ,"\"").replace( re5 ,"&").replace( re6 ,"\n");
}
function printStackTrace( e ) {
	var str = "";
	var isCaller = false;
	for( var idx in e ) {
		var tmp = idx + "               ";
		tmp = tmp.substring( 0, 15 );
		if ( idx == "number" ) {
			str += tmp + ":" + ( e[idx] & 0xFFFF ) + "\n";   // Prints the error code.
		} else {
			str += tmp + ":" + e[idx] + "\n";
		}
		if( idx == "caller" ) {
			isCaller = true;
		}
	}
}
function trim(strings)	{
	var re1 = /^\s+/;	//Initialize pattern.
	var re2 = /\s+$/;	//Initialize pattern.
	var ret =  strings.replace( re1 ,"");
	ret = ret.replace( re2 ,"");
	return ret;
}
//==========================================================
//	문자열 처리 함수들
//	1. ltrim, rtrim, trim
//	2. nullTo : 빈 문자값을 다른 값으로 치환한다.
//	3. replaceFileName : 원본파일명+접미사+확장자로 치환
//		fileName : 원본파일명
//		suffix : 접미사
//	4. Date.format : 날짜형식 정규화 
//		default: yyyy.MM.dd hh:mm:ss
//		param dd : 날짜 형식 (ex: "yyyy-MM-dd hh:mm:ss")
//  5. replaceAll : 문자열치환
//  6. replaceQuote : 스크립트 인자로 들어갈 "와 '를 특수문자코드로 변환한다. 
//  7. replaceHtml : 화면표시시에 문제가 될 수 있는(