//
// calldb.js -- Copyright 2011 One More Story, Inc.
//
// Provides AJAX support for html pages to query the OMS database.  This library requires
// that jQuery is loaded.
//
// callDB -- calls the database via jQuery
// callDBNew -- calls the database via jQuery.  This version does not create an array in returnObj.
// createArray -- creates a Javascript associative array from an incoming JSON
// dumpArray -- dumps a Javascript associative array to an incoming HTML div.  Prepends a
// addToCSVStr -- adds a value to a csv string
// addToJSONStr -- adds a key/value pair to a json string
// uploadFile -- this method takes in a file upload form and a dbCall command, and sets the form
// aim -- This object handles file uploads via a hidden iframe and ajax calls.
// getTimeStamp -- returns a timestamp formatted as
// JSONify -- takes in a string and prepends control characters and quotes with forward slashes
//

var debug	= false;

if ( debug ) {
	alert( "Loading calldb.js" );
}

var returnObj	= new Object;			// This object contains the returned key/value pairs


//
// callDB -- calls the database via jQuery
//
function callDB( command, params, handler, verbose ) {
	var debug	= false;

	if ( debug ) {
		alert( "In callDB:\n" +
				"command = [" + command + "]\n" +
				"params = [" + params + "]\n" +
				"handler = [" + handler + "]\n" +
				"verbose = [" + verbose + "]\n" +
				"" );
	}

		// Get the parameters into JSON notation
		// Add the command parameter

	var fullParams	= '"command" : "' + command + '"';

		// Add any additional parameters

	if (( params != "" )
			&& ( params != undefined )
			&& ( params != null		 )) {

			// We must check if params' last character is either a comma or a comma then a space
			// This is because IE will crash the page if you submit a json string ending in a comma

		params = $.trim( params );		// trim whitespace or line breaks from beginning or end of string

			// check to see if the final character is a comma, if it is: remove it

		paramsLength  			= params.length;
		paramsLengthMinusOne 	= paramsLength - 1;
		paramsLastChar 			= params.charAt( paramsLengthMinusOne );

		if ( paramsLastChar == ',') {
			if ( debug ) {
				alert( "final character is a comma, now removing" );
			}

				// remove the last char

			params = params.slice( 0, paramsLengthMinusOne );

			if ( debug ) {
				alert( "final comma was removed, params is now [" + params + "]" );
			}
		}

		fullParams	+= ", " + params;
	}

		// Append the verbose parameter

	if ( verbose != null ) {
		fullParams += ', "verbose" : "true"';
	}

		// Add curly brackets

	fullParams = "{" + fullParams + "}";
	if ( debug ) {
		alert( "fullParams = [" + fullParams + "]" );
	}

		// Convert to object

	try {
		var postObj = $.parseJSON( fullParams );
	} catch ( ex ) {
		if ( debug ) {
			alert( "Exception trying to parseJSON: ex.description = [" + ex.description + "]" );
		}
	}

		// Call the dbCall page and parse the results

	if ( debug ) {
		alert( "Calling dbCall.aspx" );
	}
	$.post( API_URL, postObj, function( data ) {

		if ( debug ) {
			alert( "In callback function" );
		}

			// Always build a JSON response object

		//returnObj	= createArray( returnObj, data );		//! don't need this because the array is created locally

			// Call any passed in function

		if ( handler ) {
			if ( debug ) {
				alert( "Calling handler" );
			}
			handler( data );
		}

	});

}


//
// callDBNew -- calls the database via jQuery.  This version does not create an array in returnObj.
//
function callDBNew( command, params, handler, verbose ) {
	var debug	= false;

	if ( debug ) {
		alert( "In callDBNew:\n" +
				"command = [" + command + "]\n" +
				"params = [" + params + "]\n" +
				"handler = [" + handler + "]\n" +
				"verbose = [" + verbose + "]\n" +
				"" );
	}

		// Get the parameters into JSON notation
		// Add the command parameter

	var fullParams	= '"command" : "' + command + '"';

		// Add any additional parameters

	if (( params != "" )
			&& ( params != undefined )
			&& ( params != null )) {

			// We must check if params' last character is either a comma or a comma then a space
			// This is because IE will crash the page if you submit a json string ending in a comma

		params = $.trim( params );		// trim whitespace or line breaks from beginning or end of string

			// check to see if the final character is a comma, if it is: remove it

		paramsLastChar 			= params.charAt( params.length - 1 );
		if ( paramsLastChar == ',') {
			if ( debug ) {
				alert( "final character is a comma, now removing" );
			}

				// remove the last char

			params = params.slice( 0, params.length - 1 );

			if ( debug ) {
				alert( "final comma was removed, params is now [" + params + "]" );
			}
		}

		fullParams	+= ", " + params;
	}

		// Append the verbose parameter

	if ( verbose != null ) {
		fullParams += ', "verbose" : "true"';
	}

		// Add curly brackets

	fullParams = "{" + fullParams + "}";
	if ( debug ) {
		alert( "fullParams = [" + fullParams + "]" );
	}



		// Convert to object

	var postObj = $.parseJSON( fullParams );

		// Call the dbCall page and parse the results

	if ( debug ) {
		alert( "Calling dbCall.aspx" );
	}
	$.post( API_URL, postObj, function( data ) {

		if ( debug ) {
			alert( "In callback function" );
		}

			// Call any passed in function

		if ( handler ) {
			if ( debug ) {
				alert( "Calling handler" );
			}
			handler( data );
		}

	});

}


//
// createArray -- creates a Javascript associative array from an incoming JSON
// string
//
function createArray( arrayObj, data ) {
	var debug	= false;
	if ( debug ) {
		alert( "In createArray:\n" +
				"arrayObj = [" + arrayObj + "]\n" +
				"data = [" + data + "]\n" +
				"" );
		$.each( arrayObj, function( key, value ) {
			alert( "arrayObj[ \"" + key + "\" ] = [" + arrayObj[ key ] + "]" );
		});
	}

		//
		// Convert the result into a Javascript object
		//

	var JSONStr	= $.trim( data );

	JSONStr = "{" + JSONStr + "}";
	if ( debug ) {
		alert( "JSONStr = [" + JSONStr + "]" );
	}

	try {
		arrayObj = $.parseJSON( JSONStr );
		if ( debug ) {
		 	$.each( arrayObj, function( key, value ) {
				alert( "arrayObj[ \"" + key + "\" ] = [" + arrayObj[ key ] + "]" );
			});
		}
	} catch( e ) {
		if ( debug ) {
			alert( "Error: " + e );
		}
		arrayObj	= { "results" : "error",
						"error" : "Invalid JSON in create array in calldb.js",
						"exception" : e,
						"json" : data };
	}

	if ( debug ) {
		alert( "Done createArray" );
	}

	return arrayObj;
}


//
// dumpArray -- dumps a Javascript associative array to an incoming HTML div.  Prepends a
// timestamp.
//
function dumpArray( arrayObj, divid ) {
	var debug	= false;

	if ( debug ) {
		alert( "In dumpArray:\n" +
				"arrayObj = [" + arrayObj + "]\n" +
				"divid = [" + divid + "]" );
		$.each( arrayObj, function( key, value ) {
			alert( "arrayObj[ \"" + key + "\" ] = [" + arrayObj[ key ] + "]" );
		});
	}

		// Dump the array to the trace field

	var todayStr	= getTimeStamp();
	var arrayText = "Returned at " + todayStr + ":<br>\n";
	$.each( arrayObj, function( key, value ) {
		if ( debug ) {
			alert( "key = [" + key + "]\n" +
					"value = [" + value + "]" );
		}

		if ( typeof arrayObj[ key ] == "object" ) {

			arrayText 	+= "&nbsp;&nbsp;arrayObj[ \"" + key + "\" ] = [<br>\n";

			var valObj	= arrayObj[ key ];
			$.each( valObj, function( key, value ) {
				arrayText 	+= "&nbsp;&nbsp;&nbsp;&nbsp;valObj[ \"" + key + "\" ] = [" +
								valObj[ key ] + "]<br>\n";

			});
			arrayText	+= "&nbsp;&nbsp;]<br>\n";

		} else {
			arrayText	+= "&nbsp;&nbsp;arrayObj[ \"" + key + "\" ] = [" + arrayObj[ key ] + "]<br>\n";
		}
	});

	if ( debug ) {
		alert( "arrayText = [" + arrayText + "]" );
	}

	$( "#" + divid ).html( arrayText );

	if ( debug ) {
		alert( "Done dumpArray" );
	}

}


//
// addToCSVStr -- adds a value to a csv string, prepending a comma before the new value if
// necessary
//
function addToCSVStr( csvString, newVal ) {
	var debug	= false;
	if ( debug ) {
		alert( "In addToCSVStr:\n" +
				"csvString = ["+ csvString + "]\n"+
				"newVal = ["+ newVal + "]\n" +
				"" );
	}

	if ( csvString == undefined ) {
		csvString	= "";
	}

	if ( csvString.length > 0 ) {
		csvString	+= ", ";
	}
	csvString	+= newVal;

	if ( debug ) {
		alert( "Done addToCSVStr, csvString = [" + csvString + "]" );
	}
	return csvString;
}


//
// addToJSONStr -- adds a key/value pair to a json string.  Note that this does not add curly brackets.
// If the incoming value is another JSON string, it should already have the curly brackets added.
//
function addToJSONStr( jsonString, key, value ) {
	var debug	= false;
	if ( debug ) {
		alert( "In addToJSONStr:\n" +
				"jsonString = [" + jsonString + "]\n" +
				"key = [" + key + "]\n" +
				"value = [" + value + "]\n" +
				"" );
	}

	var retVal	= "";

	if ( jsonString == undefined ) {
		jsonString = "" ;
	}

	if ( value == undefined ) {
		value = "" ;
	}
	var valTrimmed	= $.trim( value );


		// Check if adding a simple value or if nesting another JSON string

	if (( valTrimmed.substr( 0, 1 ) == "{" )
			&& ( valTrimmed.substr( valTrimmed.length - 1 ) == "}" )) {
		if ( debug ) {
			alert( "value is a JSON string" );
		}

			// value is a JSON object

		retVal	= addToCSVStr( jsonString, "\"" + key + "\" : " + value + "" );
	} else {
		if ( debug ) {
			alert( "value is a normal string" );
		}

			// value is a string

		value = JSONify( value );

		retVal	= addToCSVStr( jsonString, "\"" + key + "\" : \"" + value + "\"" );
	}

	if ( debug ) {
		alert( "Done addToJSONStr, retVal = [" + retVal + "]" );
	}
	return retVal;
}


//
// uploadFile -- this method takes in a file upload form and a dbCall command, and sets the form
// to upload via upload.php in the Logic subdirectory.  Upload.php will then call dbCall to process
// the file based on the incoming dbCall command.
//
function uploadFile( command, formID, handler, verbose ) {
	var debug	= false;

	if ( debug ) {
		alert( "In uploadFile:\n" +
				"command = [" + command + "]\n" +
				"formID = [" + formID + "]\n" +
				"handler = [" + handler + "]\n" +
				"verbose = [" + verbose + "]\n" +
				"" );
	}

		// Get the incoming form

	var formObj	= document.getElementById( formID );
	if ( debug ) {
		alert( "formObj = [" + formObj + "]" );
	}

		// Add the command as a hidden input field

	var iField		= document.createElement("input");
	iField.type		= "hidden";
	iField.name		= "command";
	iField.value	= command;
	formObj.appendChild( iField );

		// Add the action as /Logic/upload.php

	formObj.action	= UPLOAD_URL;

		// Call aim to handle the submit

	aim.submit( formObj, { 'onStart' : null, 'onComplete' : handler });

	if ( debug ) {
		alert( "Done uploadFile" );
	}

	return false;

}


//
// aim -- This object handles file uploads via a hidden iframe and ajax calls.
//
// Developed from AJAX IFRAME METHOD ( AIM ) at http://www.webtoolkit.info/
//
aim	= {

 	//
 	// frame -- creates a hidden iFrame and adds the onComplete method to it
 	//
	frame : function( uplForm ) {
		var debug	= false;
		if ( debug ) {
			alert( "In aim.frame, uplForm = [" + uplForm + "]" );
		}

			// Generate random name

		var iFrameName	= 'f' + Math.floor( Math.random() * 99999 );
		if ( debug ) {
			alert( "iFrameName = [" + iFrameName + "]" );
		}

			// Add a hidden iframe to the document

		var newDiv			= document.createElement( 'DIV' );
		newDiv.innerHTML	= '<iframe style = "display:none" ' +
								'src = "about:blank" ' +
								'id = "' + iFrameName + '" ' +
								'name = "' + iFrameName + '" ' +
								'onload = "aim.loaded( \'' + iFrameName + '\' );">' +
								'</iframe>';
		if ( debug ) {
			alert( "newDiv.innerHTML = [" + newDiv.innerHTML + "]" );
		}

		document.body.appendChild( newDiv );

			// Get a handle to the iframe

		var iFrame	= document.getElementById( iFrameName );

			// If the form object exists and has a function named onComplete
			// Copy the onComplete method from the form to the mystery element

		if ( uplForm && typeof( uplForm.onComplete ) == 'function' ) {
			if ( debug ) {
				alert( "Copying onComplete method to new iframe" );
			}
			iFrame.onComplete	= uplForm.onComplete;
		}

		if ( debug ) {
			alert( "Done aim.frame" );
		}
		return iFrameName;
	},


 	//
 	// form -- sets the incoming form's target to the hidden iframe
 	//
	form : function( formObj, iFrameName ) {
		formObj.setAttribute( 'target', iFrameName );
	},


 	//
 	// submit -- calls frame to create the hidden iframe and hook in the callback methods.
 	// Calls form to set the target to the name of the form to the new hidden iframe.
 	// Calls the onStart method if it exists and returns its value, or true.
 	//
	submit : function( formObj, callbackObj ) {
		var debug	= false;
		if ( debug ) {
			alert( "In aim.submit" );
		}

		aim.form( formObj, aim.frame( callbackObj ));

		if ( callbackObj && typeof( callbackObj.onStart ) == 'function' ) {
			return callbackObj.onStart();
		} else {
			return true;
		}

		if ( debug ) {
			alert( "Done aim.submit" );
		}

	},


 	//
 	// loaded
 	//
	loaded : function( iFrameID ) {
		var debug	= false;
		if ( debug ) {
			alert( "In loaded, iFrameID = [" + iFrameID + "]" );
		}

			// Get a handle to the incoming frame

		var iFrame	= document.getElementById( iFrameID );

			// Get the inner document in the frame

		if ( iFrame.contentDocument ) {
			var innerDoc	= iFrame.contentDocument;
		} else if ( iFrame.contentWindow ) {
			var innerDoc	= iFrame.contentWindow.document;
		} else {
			var innerDoc	= window.frames[ iFrameID ].document;		// Is this cross browser?
		}

		if ( debug ) {
			alert( "innerDoc = [" + innerDoc + "]" );
		}

			// If the frame is empty, stop

		if ( innerDoc.location.href == "about:blank" ) {
			if ( debug ) {
				alert( "about:blank found in iFrame, exiting" );
			}
			return;
		} else {

				// Always build a JSON response object

			returnObj	= createArray( returnObj, innerDoc.body.innerHTML );

				// If the frame contains an onComplete function, call it

			if ( typeof( iFrame.onComplete ) == 'function' ) {
				if ( debug ) {
					alert( "Calling iFrame.onComplete" );
				}
				iFrame.onComplete( innerDoc.body.innerHTML );
			}
		}

		if ( debug ) {
			alert( "Done loaded" );
		}
	}

}


//
// getTimeStamp -- returns a timestamp formatted as
//
function getTimeStamp() {

	var today		= new Date();
	var todayStr	= "";

	todayStr	+= today.getHours() + ":";
	todayStr	+= ( today.getMinutes().toString().length == 1 ) ? "0" + today.getMinutes() : today.getMinutes()
	todayStr	+= ":";
	todayStr	+= ( today.getSeconds().toString().length == 1 ) ? "0" + today.getSeconds() : today.getSeconds();
	todayStr	+= " ";
	todayStr		+= ( today.getMonth() + 1 ) + "/" +
						today.getDate() + "/" +
						today.getFullYear();

	if ( debug ) {
		alert( "todayStr = [" + todayStr + "]" );
	}

	return todayStr;
}

//
// JSONify -- takes in a string and prepends control characters and quotes with forward slashes
// this code replaces back slashes, quotes and line breaks
//
// This should handle control characters and other characters as per json.org
//
function JSONify( string ) {
	var debug = false;

	if ( debug ) {
		alert( "now in JSONify\n\n" +
		"string is [" + string  + "]" );
	}

	string 	= string + ""; 						// make sure its a string

	string  = string.replace( /[\x00-\x08\x0B-\x0C\x0E-\x1f\x7F]/g, '' );	// Strip most control chars
	string 	= string.replace( /\t/g, "\\t" );								// Escape tab
	string 	= string.replace( /\n/g, "\\n" );								// Escape new line
	string 	= string.replace( /\r/g, "\\r" );								// Escape carriage return
	string 	= string.replace( /\\/g, "\\\\" );								// Escape Backslash
	string 	= string.replace( /\"/g, "\\\"" );								// Escape double quote

	if ( debug ) {
		alert( "string is now [" + string + "]" );
	}

	return string;

	if ( debug ) {
		alert( "done in JSONify" );
	}


}


if ( debug ) {
	alert( "Done loading calldb.js" );
}



