/**
 * Handles TypeWriter Event to text related containers.
 * Note: Container should not contains any other element but texts. 
 * Or these will be removed on typewriter event.
 */
function JSGC_TYPEWRITER(WRITE_ELEMENT, WRITE_MESSAGE, WRITE_SPEED, CALLBACK_METHOD)
{
	// Parameter Validation
	// ----------------------------------------------------------
	JSVC_AV.VAR_VALIDATE_NULL(WRITE_ELEMENT, "WRITE_ELEMENT");
	JSVC_AV.VAR_VALIDATE_NULL(WRITE_MESSAGE, "WRITE_MESSAGE");
	JSVC_AV.VAR_VALIDATE_ARGUMENT_TYPE(WRITE_MESSAGE, 'WRITE_MESSAGE', 'STRING');
	if(JSVC_VAR.VAR_ISSET(CALLBACK_METHOD))
	{
		JSVC_AV.VAR_VALIDATE_ARGUMENT_TYPE(WRITE_SPEED, 'WRITE_SPEED', 'STRING');
		WRITE_SPEED = JSVC_STR.VAR_UCASE(WRITE_SPEED);
		if(WRITE_SPEED != "FAST" && WRITE_SPEED != "NORMAL" && WRITE_SPEED != "SLOW")
		{
			throw "Invalid speed mode : " + WRITE_SPEED;
		}
	}
	else
	{
		WRITE_SPEED = "NORMAL";
	}
	if(JSVC_VAR.VAR_ISSET(CALLBACK_METHOD))
	{
		JSVC_AV.VAR_VALIDATE_ARGUMENT_TYPE(CALLBACK_METHOD, 'CALLBACK_METHOD', 'FUNCTION');
	}
	// ----------------------------------------------------------
	
	
	// Initialize
	// _______________________________________________________________________
	var CACHE_WRITE_ELEMENT = JSOC_ELEMENT.VAR_GET(WRITE_ELEMENT);
	var CACHE_WRITE_MESSAGE = WRITE_MESSAGE;
	var CACHE_WRITE_MESSAGE_ON_PROCESS = WRITE_MESSAGE;
	var CACHE_WRITE_SPEED = WRITE_SPEED;
	var CACHE_CALLBACK_METHOD = CALLBACK_METHOD;
	var CACHE_PROCESSING_TIMER = null;
	
	// Clear text container
	// _______________________________________________________________________
	JSOC_ELEMENT.VAR_INNER_HTML(CACHE_WRITE_ELEMENT, "");
	
	// Prepare Class
	// _______________________________________________________________________
	var THIS_CLASS = function TYPEWRITER(){};

	
	/**
	 * =================================================================================
	 * Private: Handles timer recurring events, write typewriting
	 * =================================================================================
	 */
	THIS_CLASS.VAR_SET_TIMER = function()
	{
		if(CACHE_WRITE_SPEED == "FAST")
		{
			CACHE_PROCESSING_TIMER = setTimeout(THIS_CLASS.VAR_PROCESS_WRITE, 15);
		}
		
		else if(CACHE_WRITE_SPEED == "NORMAL")
		{
			CACHE_PROCESSING_TIMER = setTimeout(THIS_CLASS.VAR_PROCESS_WRITE, 50);
		}
		
		else if(CACHE_WRITE_SPEED == "SLOW")
		{
			CACHE_PROCESSING_TIMER = setTimeout(THIS_CLASS.VAR_PROCESS_WRITE, 100);
		}
		
		else
		{
			alert('Timer error. Please contact the developer.');
		}
	};
	
	
	/**
	 * =================================================================================
	 * Private: Handle `Write` action on type writer.
	 * =================================================================================
	 */
	THIS_CLASS.VAR_PROCESS_WRITE = function()
	{				
		// Clear Timer
		// ...........................................
		CACHE_PROCESSING_TIMER = null;
	
		// Initialize
		// ...........................................
		var WRITE_CHAR = JSVC_STR.VAR_LEFT(CACHE_WRITE_MESSAGE_ON_PROCESS, 1);
		CACHE_WRITE_MESSAGE_ON_PROCESS = JSVC_STR.VAR_DLEFT(CACHE_WRITE_MESSAGE_ON_PROCESS, 1);
		
		// Write Text
		// ...........................................
		JSOC_ELEMENT.VAR_TEXT(CACHE_WRITE_ELEMENT, WRITE_CHAR, true);
		
		// Continue or Complete
		// ...........................................
		if(JSVC_STR.VAR_LEN(CACHE_WRITE_MESSAGE_ON_PROCESS) > 0)
		{
			THIS_CLASS.VAR_SET_TIMER();
		}
		else
		{
			THIS_CLASS.VAR_DISPOSE();
		}
	};
	
	/**
	 * =================================================================================
	 * Force Completing the TypeWriting event, then clears the cache data.
	 * =================================================================================
	 */
	THIS_CLASS.VAR_DISPOSE = function()
	{
		// Initialize
		// ...........................................
		var ONCOMPLETE_CALLBACK_METHOD = CACHE_CALLBACK_METHOD;
	
		// Write All Texts
		// ...........................................
		JSOC_ELEMENT.VAR_TEXT(CACHE_WRITE_ELEMENT, CACHE_WRITE_MESSAGE);
		
		// Clear Timer
		// ...........................................
		if(JSVC_VAR.VAR_ISSET(CACHE_PROCESSING_TIMER))
		{
			clearTimeout(CACHE_PROCESSING_TIMER);
		}
		
		// Clear Cache
		// ...........................................
		CACHE_WRITE_ELEMENT = null;
		CACHE_WRITE_MESSAGE = null;
		CACHE_WRITE_MESSAGE_ON_PROCESS = null;
		CACHE_WRITE_SPEED = null;
		CACHE_CALLBACK_METHOD = null;
		CACHE_PROCESSING_TIMER = null;
		
		// Callback (if not null)
		// ...........................................
		if(JSVC_VAR.VAR_ISSET(ONCOMPLETE_CALLBACK_METHOD))
		{
			ONCOMPLETE_CALLBACK_METHOD();
		}			
	};
	
	// Starts a TypeWriter Event
	// _______________________________________________________________________
	THIS_CLASS.VAR_SET_TIMER();
	
	// Returns generated class
	// _______________________________________________________________________
	return THIS_CLASS;
	
};