
var xhr = new xhrWrapper( true ); // ... MAKES THE xhr OBJECT UNIQUE AND SHARED.

/** -------------------------------------------------------------------------------------------------------------------------------------------
  * PARSE, ANALYZE AND COMPUTE INCOMING JSON DATA ( WITHOUT THIRD-PARTY JSON FRAMEWORK ).
  * void evalprime( mixed arg [, boolean callback] )
  * 
  * QUICK NOTES:
  * 
  * THE ARGUMENT arg SHOULD CONTAIN SOME DATA - USUALLY ALL WRAPPED IN AN ARRAY - WHILE THE callback ARGUMENT SHOULD IDENTIFY A RETURN FROM AN
  * ASYNCHRONOUS CALL TO THE 'XML HTTP REQUEST' OBJECT.
  * 
  * FURTHER EXPLANATIONS:
  * 
  * FIRST, IT MUST BE KNOWN THAT 'JSON' IS THE ACRONYM FOR 'JAVASCRIPT OBJECT NOTATION'. SO THAT IT IS TOTALLY PART OF THE JAVASCRIPT LANGUAGE
  * AND THUS CAN BE USED LIKE EVERY OTHER JAVASCRIPT OBJECT ( ONCE PARSED ).
  * 
  * NOWADAYS, THERE IS MAINLY THREE WAYS TO PARSE JSON DATA:
  * 
  *    1. VIA THE NATIVE eval FUNCTION.
  *    2. VIA A THIRD-PARTY JAVASCRIPT FRAMEWORK ( AVAILABLE AT THE JSON'S WEBSITE: http://www.json.org ).
  *    3. THROUGH THE WEB BROWSER NATIVE JSON SUPPORT.
  * 
  * THOUGH THE THIRD OPTION WOULD SURELY BE THE BEST, IT IS ONLY IMPLEMENTED ON BROWSERS RELEASED PAST JUNE 2009.
  * 
  * IT IS USUALLY SAID THAT THE FIRST OPTION IS THE SIMPLEST AND THE FASTEST BUT ALSO THE LESS SECURED WHILE THE SECOND ONE, THE INVERSE. THE
  * POINTED OUT SECURITY ISSUE IS THAT THE eval FUNCTION CAN COMPILE AND EXECUTE ANY JAVASCRIPT PROGRAM. THEREFORE, ITS USE SHOULD BE LIMITED
  * TO CASES WHERE THE SOURCE PROVIDING THE eval ARGUMENT CAN BE FULLY TRUSTED AND IS KNOWN TO BE 'COMPETENT'.
  * 
  * IN WEB APPLICATIONS - USING THE 'XML HTTP REQUEST' OBJECT -, COMMUNICATIONS ARE ONLY PERMITTED TO THE SAME ORIGIN THAT INITIALLY PROVIDED
  * THE PAGE IMPLEMENTING THAT PARTICULAR OBJECT. SO THAT THE SOURCE CAN BE TRUSTED. 'COMPETENT' REFERS TO THE SERVER'S RIGOROUSNESS OF ITS
  * JSON DATA ENCODING. AS THAT ENCODING WILL STRICTLY BE REALISED BY THE SERVER AND ONLY BE USING DATA COMING FROM THE SERVER ALGORITHMS AND
  * DATABASES, IT CAN BE ASSUMED THAT THE SOURCE IS ALSO COMPETENT.
  * 
  * THE arg ARGUMENT SHOULD BE AN TWO-INDEXED ARRAY:
  * 
  *    0. SERVER STATUS VALUE ( E.G. 200, 404, 500 ).
  *    1. SERVER RESPONSE ( JSON DATA ).
  * -------------------------------------------------------------------------------------------------------------------------------------------
  */
function evalprime( arg, callback )
{
	if ( callback != true )
	{
		xhr.send( 'GET', 'primes.engine', null, evalprime );
	}
	else
	{
		switch ( arg[0] )
		{
			case 200:
				
				var abort = "<img src='./images/stop.jpg' onmousedown=\"javascript:evalprime( [ 800, 'OK' ], true )\" alt='Stop!!!' />";
				
				document.getElementById( 'image' ).innerHTML = abort; // ... LOAD THE ABORT BUTTON.
				
			//  -------------------------------------------------------------------------------------------------------------------------------
				
				var json = eval('(' + arg[1] + ')'); // ... THE eval ARG MUST BE WRAPPED IN PARENTHESIS TO AVOID JAVASCRIPT SYNTAX AMBIGUITY.
				
			/*
			 * ALGORITHM'S NOTES:
			 * 
			 * THE CLIENT WEB BROWSER SHOULD RECEIVE AT LEAST ONE NUMBER TO BE EVALUATED - TO CHECK IF IT IS A PRIME OR NOT - AND AT LEAST ONE
			 * PRIME. USUALLY, THERE SHOULD BE A LIST OF NUMBERS TO EVALUATE ( json.number[] ) AND SEVERAL PRIMES ( json.prime[] ).
			 * 
			 * EACH NUMBER REQUIRED TO BE CHECKED WILL BE DIVIDED BY EACH KNOWN PRIMES, FOLLOWING THE EUCLID'S PROOF:
			 * EACH TIME A NUMBER WILL GET A REST EQUALS TO 'ZERO', THE NUMBER WILL BE IMMEDIATELY DISCARDED! ( AS THERE IS NO NEED TO CHECK
			 * THAT NUMBER WITH THE OTHER PRIMES AS IT IS NOW KNOWN TO BE A MULTIPLE OF THE CURRENT ONE, SO THAT IT DEFINITELY CANNOT BE A
			 * PRIME. )
			 * IN CASE THE LAST KNOWN PRIME IS REACHED WITHOUT A SINGLE DISCARD, THEN IT WILL BE ASSUMED THAT THE EVALUATED NUMBER MAY BE A 
			 * PRIME, AND AS SUCH STORED IN MEMORY.
			 */
				for ( var i = 0; i < json.number.length; i++ )
				{
					for ( var j = 0; j < json.prime.length; j++ )
					{
						if ( ( json.number[i] % json.prime[j] ) != 0 )
						{
							if ( j == ( json.prime.length - 1 ) ) json.modulo.push( json.number[i] );
						}
						else
						{
							break;
						}
					}
				}
				
			//  -------------------------------------------------------------------------------------------------------------------------------
				
				var jsonlog  = '[1] numbers evaluated: ' + json.number.join( ) + '.<br />';
					jsonlog += '[2] prime numbers: ' + json.prime.join( ) + '.<br />&nbsp;<br />';
					jsonlog += '[3] computation results: ' + json.modulo.join( ) + '.';
				
				document.getElementById( 'jsonlog' ).innerHTML = jsonlog; // ... LET USERS KNOW WHAT THEIR WEB BROWSER IS DOING.
				
			//  -------------------------------------------------------------------------------------------------------------------------------
				
				xhr.send( 'GET', 'primes.engine', [ [ 'serialize', serialize( json.modulo ) ] ], evalprime ); // ... SEND BACK SERIALIZED DATA!
				
				break;
			
			case 800:
				
				xhr.send( 'GET', 'primes.engine', [ [ 'sigterm', 'kill' ] ], null );
				
			//  -------------------------------------------------------------------------------------------------------------------------------
				
				document.getElementById( 'jsonlog' ).innerHTML = 'Calica\'s 2.0 engine status: aborted.';
				
				var abort = "<img src='./images/run.jpg' onmousedown=\"javascript:evalprime( )\" alt='Restart!' />";
				
				document.getElementById( 'image' ).innerHTML = abort; // ... LOAD THE RUN BUTTON.
				
				break;
			
			default:
				document.getElementById( 'jsonlog' ).innerHTML = arg[1];
				break;
		}
	}
}

/** -------------------------------------------------------------------------------------------------------------------------------------------
  * CALICA 2.0 SUPPORT EVAL ENGINE.
  * void eval20( mixed arg [, boolean callback] )
  * 
  * THE ARGUMENT arg SHOULD CONTAIN SOME DATA - USUALLY ALL WRAPPED IN AN ARRAY - WHILE THE callback ARGUMENT SHOULD IDENTIFY A RETURN FROM AN
  * ASYNCHRONOUS CALL TO THE 'XML HTTP REQUEST' OBJECT.
  * -------------------------------------------------------------------------------------------------------------------------------------------
  */
function eval20( arg, callback )
{
	if ( callback != true )
	{
		xhr.send( 'GET', 'eval20.engine', [ [ 'domId', arg ] ], eval20 );
	}
	else
	{
		switch ( arg[0] )
		{
			case 200:
				
				var json = eval('(' + arg[1] + ')'); // ... THE eval ARG MUST BE WRAPPED IN PARENTHESIS TO AVOID JAVASCRIPT SYNTAX AMBIGUITY.
				
				document.getElementById( json.domId ).innerHTML = json.domCn;
				
				break;
			
			default:
				alert( arg[1] );
				break;
		}
	}
}

/** -------------------------------------------------------------------------------------------------------------------------------------------
  * LOGGING ENGINE.
  * void logusr( mixed arg [, boolean callback] )
  * 
  * THE ARGUMENT arg SHOULD CONTAIN SOME DATA - USUALLY ALL WRAPPED IN AN ARRAY - WHILE THE callback ARGUMENT SHOULD IDENTIFY A RETURN FROM AN
  * ASYNCHRONOUS CALL TO THE 'XML HTTP REQUEST' OBJECT.
  * -------------------------------------------------------------------------------------------------------------------------------------------
  */
function logusr( arg, callback )
{
	if ( callback != true )
	{
		xhr.send( 'POST', 'authentication', arg, logusr );
	}
	else
	{
		switch ( arg[0] )
		{
			case 200:
				
				var regex = new RegExp( 'Welcome', 'gi' );
				
				if ( arg[1].match( regex ) )
				{
					var color = '#005000';
					
					document.getElementById( 'log' ).elements[0].style.backgroundColor = color;
					document.getElementById( 'log' ).elements[1].style.backgroundColor = color;
					document.getElementById( 'log' ).elements[2].style.backgroundColor = color;
					
					    color = '#505050';
					
					document.getElementById( 'reg' ).elements[0].style.backgroundColor = color;
					document.getElementById( 'reg' ).elements[1].style.backgroundColor = color;
					document.getElementById( 'reg' ).elements[2].style.backgroundColor = color;
				
					setTimeout( 'window.location.href=\'?lib=usrpanel\';', 3000 );
				}
				
				document.getElementById( 'logmsg' ).innerHTML = arg[1];
				
				break;
			
			default:
				document.getElementById( 'logmsg' ).innerHTML = arg[1];
				break;
		}
	}
}

/** -------------------------------------------------------------------------------------------------------------------------------------------
  * REGISTRATION ENGINE.
  * void regusr( mixed arg [, boolean callback] )
  * 
  * THE ARGUMENT arg SHOULD CONTAIN SOME DATA - USUALLY ALL WRAPPED IN AN ARRAY - WHILE THE callback ARGUMENT SHOULD IDENTIFY A RETURN FROM AN
  * ASYNCHRONOUS CALL TO THE 'XML HTTP REQUEST' OBJECT.
  * -------------------------------------------------------------------------------------------------------------------------------------------
  */
function regusr( arg, callback )
{
	if ( callback != true )
	{
		xhr.send( 'POST', 'registration', arg, regusr );
	}
	else
	{
		switch ( arg[0] )
		{
			case 200:
				
				var regex = new RegExp( 'Congratulations', 'gi' );
				
				if ( arg[1].match( regex ) )
				{
					var color = '#005000';
					
					document.getElementById( 'reg' ).elements[0].style.backgroundColor = color;
					document.getElementById( 'reg' ).elements[1].style.backgroundColor = color;
					document.getElementById( 'reg' ).elements[2].style.backgroundColor = color;
				}
				
				document.getElementById( 'regmsg' ).innerHTML = arg[1];
				
				break;
			
			default:
				document.getElementById( 'regmsg' ).innerHTML = arg[1];
				break;
		}
	}
}

/** -------------------------------------------------------------------------------------------------------------------------------------------
  * RETURN A PHP FORMAT SERIALIZED STRING.
  * string serialize( mixed arg )
  * 
  * THE ARGUMENT arg SHOULD BE BOOLEANS, INTEGERS, FLOATS, STRINGS OR ARRAYS - RECURSIVE OR NOT - BUT SHOULD NOT BE OBJECTS.
  * 
  * ADDITIONAL NOTES: IN JAVASCRIPT, AN OBJECT AND AN ARRAY SHARES THE SAME 'object' TYPE.
  * -------------------------------------------------------------------------------------------------------------------------------------------
  */
function serialize( arg )
{
	switch( typeof( arg ) )
	{
		case 'boolean':
			return 'b:' + ( ( arg ) ? '1' : '0' ) + ';';
			break;
			
		case 'string':
			return 's:' + arg.length + ':\"' + arg + '\";';
			break;
			
		case 'number':
			return ( Math.round( arg ) == arg ? 'i:' : 'd:' ) + arg + ';'; // ... MAKES THE DISTINCTION BETWEEN AN 'INTEGER' AND A 'FLOAT'.
			break;
			
		case 'object':
			if ( arg == null ) // ... BECAUSE IN JAVASCRIPT, null IS ALSO AN OBJECT!
			{
				return 'N;';
			}
			else if ( 'length' in arg ) // ... IF THE length PROPERTY IS AVAILABLE, THEN THIS IS IN FACT AN 'ARRAY'.
			{
				var i = 0, loopval = '';
				
				for ( var k in arg )
				{
					if ( !isNaN( k ) ) k = Number( k );
					
					loopval += serialize( k ) + serialize( arg[k] );
					i++;
				}
				
				return 'a:' + i + ':{' + loopval + '}';
			}
			else
			{
				return 'N;'; // ... PURE 'OBJECTS' ARE NOT HANDLED ( NEVER NEEDED FOR RUNNING THE WEB APP: CODING WILL BE WASTE OF TIME ).
			}
			break;
			
		default:
			return 'N;';
			break;
	}
}

/** -------------------------------------------------------------------------------------------------------------------------------------------
  * CLEAR AN INPUT FIELD.
  * void clearField( string name )
  * 
  * CLEAR THE name FIELD IDENTIFIED BY ITS 'name' PROPERTY WITHIN A FORM. THE FUNCTION CAN BE CALLED THROUGH JAVASCRIPT EVENTS SUCH 'onclick'.
  * -------------------------------------------------------------------------------------------------------------------------------------------
  */
function clearField( name )
{
	 name.value = '';
}

