﻿/**
 * Dynamic Script Including
 *
 * @author hooriza@nhncorp.com
 * @version 0.95
 *
 * @created Nov.1.2007.
 */
var Include = function() {
	
	var self = this;
	
	this._uniqID = new Date().getTime();
	this._requests = {};
	
	if (!Include._instance) Include._instance = {};
	Include._instance[this._uniqID] = this;
	
	this._gcTimer = setInterval(function() { self._gc(); }, this._gcInterval);
	
};

Include.prototype = {
	
	_uniqID : null,
	_requests : null,
	
	_trID : null,
	_callback : null,

	_gcTimer : null,
	_gcInterval : 30000, // 30초마다 gc 실행
	
	request : function(sUrl, pCallback) {
		
		var nTrID = (new Date().getTime() % 31536000000) * 100 + parseInt(Math.random() * 100);
		
		var sMethod = 'Include._response(' + this._uniqID + ', ' + nTrID + ')';
		
		if (sUrl.indexOf('?') == -1) sUrl += '?';
		sUrl += '&callback=' + encodeURIComponent(sMethod);
		
		this._trID = nTrID;
		this._callback = pCallback;
		
		this._createScript(nTrID, sUrl);
		
	},
	
	abort : function() {
		this._trID = null;
	},
	
	_createScript : function(nTrID, sUrl) {
		
		var oScript = document.createElement('script');
		var nTime = new Date().getTime();

		with (oScript) {
			src = sUrl;
			id = nTime; // 생성시간
			language = 'javascript';
			type = 'text/javascript';
		};
		
		this._requests[nTrID] = oScript;
		document.body.appendChild(oScript);
		
	},
	
	_destroyScript : function(nTrID, nExpires, nNow) {
		
		var oScript = this._requests[nTrID];
		
		// 생성된지 지정된 시간이 지난 것만 삭제
		if (nExpires) {

			nNow = nNow || new Date().getTime();
			
			if (parseInt(oScript.id) > nNow - nExpires)
				return;

		}
		
		oScript.parentNode.removeChild(oScript);
		delete this._requests[nTrID];
		
	},
	
	_gc : function() {
		
		var nNow = new Date().getTime();
		
		for (var nTrID in this._requests)
			this._destroyScript(nTrID, this._gcInterval, nNow);

	}
	
};

Include._response = function(nUniqID, nTrID) {
	
	var pIgnore = function() { };
	
	var oInst = this._instance[nUniqID];
	if (!oInst) return pIgnore;

	oInst._destroyScript(nTrID);
	if (oInst._trID != nTrID) return pIgnore;
	
	var pCallback = oInst._callback;

	return function(oData) { return pCallback(oData); };
	
};
