/* Copyright 2005, 2008 Arda Group, LC 
   version and change history at end. (the above blank lines for alignment with server version)
*/
/* NOTES:
	Replaces commonNavigation.js and siteNavigation.js, contains common methods and data required only in the client environment.
    These include:
    	Exception handling
    	Mail functionality
        Various diagnostic methods
    These do NOT include any client-side methods or data required by only a single page.
*/

/***********************************************
Methods reference (TODO: need to completely rebuild this)


***********************************************/

/***********************************************
	DATA - client-side
***********************************************/

var debug 			= false;		// during testing (any)
var debugInit		= false;		// during testing (client-side initialization)
var debugProcess	= false;		// during testing (client-side form Processing)
var debugOnce		= true;			// during testing (anywhere; set to false after use)

var nullValue		= "[NULL]";

/*********************************************** 
	METHODS - COMMON - presumed to be required or useful - delete if not used.
***********************************************/

/*  Function: setDebug(type,val)
		Usage:		utility function called by various methods to enable/disable client-side debugging
		Arguments:
        	type:	the debug type to set
            val:	true or false
		Processing:
			- (original server version) returns "NULL", "true" or "false"
*/
function setDebug(type,val) {
	if (val == null || (val != true && val != false)) { alert("In siteNavigation.setDebug(): val must be true or false."); return; }
    var typ = new String(type).toLowerCase();
    if (typ == "debug" 			|| typ == "all" || typ == "any") { debug		= val; return; }
    if (typ == "debuginit"  	|| typ == "init")                { debugInit	= val; return; }
    if (typ == "debugprocess"	|| typ == "process")             { debugProcess	= val; return; }
}

/*  Function: chkDebug(type)
		Usage:		utility function called by various methods to check if client-side debugging is enabled
		Arguments:
        	type:	the debug type to set
            val:	true or false
		Processing:
			- (original server version) returns "NULL", "true" or "false"
*/
function chkDebug(type) {
    var typ = new String(type).toLowerCase();
    if (typ == "debug" 			|| typ == "all" || typ == "any") { return (debug);					}
    if (typ == "debuginit"  	|| typ == "init")                { return (debug || debugInit); 	}
    if (typ == "debugprocess"	|| typ == "process")             { return (debug || debugProcess);	}
}

/*  Function: booleanToText(val)
		Usage:		utility function called by various methods
		Arguments:
		Processing:
			- (original server version) returns "NULL", "true" or "false"
*/
function booleanToText(val) {
  if (val == null)  { return nullValue };
  if (val == true)  { return "true" };
  if (val == false) { return "false" };
  return "unknown";
}

/*  Function: booleanToString(boolValue)
		Usage:		utility function to return string equivalent for messages
		Arguments:	boolean 
		Processing:
			- (original client version) display the cookie values
*/
function booleanToString(boolValue){
 	return booleanToText(boolValue);
}

/* ************************************************** */
/* Exception handling.                                */
/* This retains all client-side behavior from the     */
/* common code. all server-side code has been removed */
/* and only JSrrors are handled (no ASP or ADO). The  */
/* error page action does not used errorPage.asp.     */
/* Note: unlike the server-side, on the client, some  */
/*       script errors (like missing methods) cannot  */ 
/*       be trapped via a try-catch in all browsers.  */
/* ************************************************** */

/***********************************************
	Exception handling data
***********************************************/

// values used by saveException(), reportExceptions()
var currentException  		= new Array("","");   	// used during catch
var systemExceptions  		= new Array();   

var exIdxException 			= 0;					// index to exception type
var exIdxMessage	 		= 1;					// index to message

// values used by handleException()
var exActionIgnore 			= 0;					// ignore (no alert)
var exActionAlert			= 1;					// generate alert only
var exActionAlertOnly		= 1;					// generate alert only
var exActionAlertEnd 		= 2;					// (on client, same as AlertOnly)
var exActionErrorPage		= 3;					// display error page (clein error specific
var exActionMin				= exActionIgnore;
var exActionMax				= exActionErrorPage;
var exActionDflt			= exActionAlert;		// default

var	clientErrorPage			= "errorPage.asp";		// use standard error page

/***********************************************
	Exception handling methods
***********************************************/

/*  Object: customException(name, message, number, description)
		Usage:		defines a custom exception template object.  Thios models the standard JSerror type.
		Arguments:
			name:			the excepton name
			message:		the message to be displayed
			number:			the message number
			description:	the error description
		Processing:
			- save arguments to object parameters
*/
function customException(name, message, number, description) {
	this.name			= name;
	this.message		= message;
	this.number			= number;
	this.description	= description;
}

/*  Function: handleException(ex,msg,act)
		Usage:		called to handle an exception.  
		Arguments:
			ex:			the exception object
			msg:		the message to be displayed
			act:		the action to be performed (on client side, alert or invoke errorPage)
		Processing:
			- invoke the error page, passing the clientErrorMessage parameter
*/
function handleException(ex,msg,act) {
	var doAlert       	= false;
	var doErrorPage   	= false;
    var epMsg			= "";	// for error page
	var bp				= "";	// if HTML, begin paragraph
	var ep				= "";	// if HTML, end paragraph
	var br				= "";	// if HTML, break
	var nb				= "";	// if HTML, non-blocking space
	var tb				= "";	// if HTML, tab
	var haveJSerror		= false;
	var JSerror			= null;
	var i,j;

//alert("In handleException: " 	+ "\n" +
//"ex='"+ex+"', "					+ "\n" +	      
//"msg='"+msg+"', "				+ "\n" +	      
//"act='"+act+"', "				+ "\n" +
//"(done)");	      
//return;

	if ((act == null) || (act < exActionMin) || (act > exActionMax))  { act=exActionDflt; }
	
	// if ignore, just return
	if (act == exActionIgnore) { return; }
	
	// see what to do
	doAlert     = ((act == exActionAlertOnly) || (act == exActionAlertEnd));
	doErrorPage = (act == exActionErrorPage);
	
	// see what kind of object we have
	haveJSerror   = (ex.name != null && ex.name != "");

	if (haveJSerror)  { JSerror  = ex; }
    
    // set formatting characters
	if (doAlert) {				// regular client-side alert()
		bp = "";					// no begin paragraph
		ep = "\n";					// no end paragraph; use newline
		br = "\n";					// no break; use newline
		nb = " ";					// no non-blanking space; use blank
		tb = "\t";					// tab
	} else if (doErrorPage) {	// error page (displays in textarea)
		bp = "";					// no begin paragraph
		ep = "";					// no end paragraph; use newline
		br = "\n";					// no break; use newline
		nb = " ";					// no non-blanking space; use blank
		tb = "  ";					// tab; use 2 blanks
	}
	
	// see if we need to build a message
	if ((doAlert) || (doErrorPage)) {
	
		if ((msg == null) || (msg == "")) { msg = "An exception has occurred."; } // if caller provided no message
		
		//    <p>  msg &nbsp; <br><br>   ErrorInformation:     <br>
		msg = bp + msg + nb + br + br + "Error Information: " + br;
		
		if (haveJSerror) {
			if (doAlert) {
				msg += br + "Contents of JavaScript Error object:";
				msg += br + tb + "name           = '" + JSerror.name           + "', ";
				msg += br + tb + "message        = '" + JSerror.message        + "', ";
				msg += br + tb + "number         = '" + JSerror.number         + "', ";
				msg += br + tb + "description    = '" + JSerror.description    + "' " + br;
			}
			if (doErrorPage) { 
				epMsg += "Contents of JavaScript Error object:";
				epMsg += br + tb + "name           = '" + JSerror.name           + "', ";
				epMsg += br + tb + "message        = '" + JSerror.message        + "', ";
				epMsg += br + tb + "number         = '" + JSerror.number         + "', ";
				epMsg += br + tb + "description    = '" + JSerror.description    + "'";
            }
		}
		
		msg += ep;
	}    
	
	// final disposition
	if (doAlert)     { alert(msg); }    
	if (doErrorPage) { displayErrorPage(epMsg); }    
	
	return true;
}

/*  Function: displayErrorPage(msg)
		Usage:		called to display a client-side error message in the standard error page.  
		Arguments:
			msg:		the message to be displayed
		Processing:
			- invoke the error page, passing the clientErrorMessage parameter
*/
function displayErrorPage(msg) {
   	window.location = clientErrorPage + "?clientErrorMsg=" + escape(msg) + ""; 
}

/* ************************************************** */
/* Mail handling.                                     */
/* This retains all client-side behavior from the     */
/* common code.                                       */
/* ************************************************** */

/***********************************************
	Mail handling data
***********************************************/

// v1.2.0a: changed e-mail due to Exchange problem on test server

// site defaults
var mailTestMode	= true;										// if TRUE, BCC's webmaster
var mailTestId 		= "ardagroup@myrapidsys.com";				// account used for testing
var mailServer 		= "localhost";								// mail server
var mailFromId 		= mailTestId;								// account used to send all mail

var mailToWebmaster = "Webmaster@Rule144Solution.com";			// account for mail to webmaster
var mailToQuestions = "Questions@Rule144Solution.com";			// account for mail for Question and NoControl Forms
// v1.2.0h: CustomerService mail account renamed "ClientServices" to eliminate spam
var mailToCustServ	= "ClientServices@Rule144Solution.com";		// account for mail for Customer Service
var mailToFeedback	= "Feedback@Rule144Solution.com";			// account for mail for Feedback Form
var mailFormatText	= "text";									// send mail in Text format
var mailFormatHtml	= "html";									// send mail in HTML format (v1.5.0d: N/A for this version)
var mailFormatDflt	= mailFormatText;							// default format
var mailFormat		= mailFormatDflt;							// initial format (default)

/***********************************************
	Mail handling methods
***********************************************/

/*  Function: handleClientEmail (emailType)
    - extract passed message field values
    - construct the fromId, toId, subject and message Body.
    - redirect user to the formatted mailto URL in new window 
*/

function handleClientEmail (emailType) {
	if (emailType == null || emailType == "") { emailType = "feedback"; }

	// process the form
	var mailToURL = formatMailToURL(emailType);
	
	// Open mail URL in new window
	window.open(mailToURL);
}

/*  Function: formatMailToURL (emailType, page, opinion, token)
		Usage:		called to format an e-mail message Body.  
		Arguments:
			emailType:	the type of e-mail, e.g, feedback, question, etc.
            page:		page from which the request was issued (or null)
            opinion:	opinion type, if applicable (or null)
            token:		generated token, if applicable (or null)
		Processing:
			- extract values from variables
      - format the mailto URL. All values must be escaped.
*/
function formatMailToURL (emailType) {
	var i,j;
	var fromId			= mailFromId;
	var toId			= "";
	var ccId			= "";
	var bccId			= "";
	var subject			= "";
	var format			= mailFormatText;
	var formatHTML		= false;			// not supported yet.
	var msgBody			= "";
	var mailToURL		= "mailTo:"

    var pag				= "";
	var sel				= "";
	var tok				= "";

    var nl				= "\n";
    
	// check optional values; referring page must define these variables if needed
    try { pag = currentPage; 		} catch (ex) { pag = "not specified"; }
    try { sel = selectedOpinion; 	} catch (ex) { sel = "not specified"; }
    try { tok = currentToken; 		} catch (ex) { tok = "not specified"; }

	// see if webmaster to be BCC'd
	if (mailTestMode) {
		bccId = mailToWebmaster;
	}
	
	emailType = emailType.toLowerCase();
	
	if (emailType == "feedback") {
	
		// process the Feedback form
		toId			= mailToFeedback;		// recipient
		subject			= "Rule144Solution.com  - Website problems or questions";
		if (formatHTML) {
			// TBD
		} else {
			msgBody  = "Selected Opinion (if any): " + sel + ", " 							+ nl;
			msgBody += "Opinion Purchase Confirmation Number (if any): " + tok + ", "		+ nl;
			msgBody += "Referring Page: " + pag 											+ nl + nl;
			msgBody += "Please enter your question or comment below. ";
			msgBody += "If you experienced a problem with the site, please include as much detail as possible ";
			msgBody += "about your environment (at minimum, your web browser and version):"	+ nl + nl;
		}
		
	} else if (emailType == "question") {
		
		// process the Question form
		toId			= mailToQuestions;	// recipient
		subject			= "Rule144Solution.com - Question on page '"+pag+"'";
		if (formatHTML) {
			// TBD
		} else {
			msgBody  = "Selected Opinion: " + sel + ", "									+ nl;
			msgBody += "Opinion Purchase Confirmation Number: " + tok + ", "				+ nl;
			msgBody += "Question on Page: " + pag										 	+ nl + nl;
			msgBody += "Please enter your question below. ";
			// v1.0.1l: removed relationship question, reworded phone question.
			// 	  	msgBody += "Also, please describe your relationship to the issuing company ";
			// 	  	msgBody += "in as much detail as possible.\n\n";
			msgBody += "Optionally, provide a phone number where you can be reached during normal business hours ";
			msgBody += "in the event we need to contact you for more information."			+ nl + nl;
		}
		
	} else if (emailType == "custserv") {
	
		// process the Customer Service form
		// v1.1.0h: changed "Customer Service" to "Client Sevices"; custserv handles requests from the contact page
		toId			= mailToCustServ;		// recipient
		subject			= "Rule144Solution.com  - Client Services Inquiry";
		if (formatHTML) {
			// TBD
		} else {
			// v1.1.0h: changes text to reflect usage "Customer Service" to "Client Sevices"
			msgBody += "Please enter your question or comment below.\n\n";
		}
		
	} else if (emailType == "custserv2") {
		
		// v1.1.0h: added "Client Sevices" request from FAQ page as custserv2.
		toId			= mailToCustServ;		// recipient
		subject			= "Rule144Solution.com  - Client Services FAQ Inquiry";
		if (formatHTML) {
			// TBD
		} else {
			// v1.1.0h: changed text to reflect usage "Customer Service" to "Client Sevices"; changed wording for FAQ inquiries
			msgBody += "My question is not answered on the FAQ page."										+ nl + nl +
				"Please enter your question below; if it relates to an FAQ question or answer, please copy and paste that into the email. "+
				"Optionally, provide a phone number where you can be reached "+
				"during normal business hours in the event we need to contact you for more information."	+ nl + nl;
		}
		
	} else if (emailType == "nocontrol") {
	
		// process the noControl Form
		toId			= mailToQuestions;	// recipient
		subject			= "Rule144Solution.com - Question on page '"+pag+"', potential affiliates lacking actual control relationship";
		if (formatHTML) {
			// TBD
		} else {
			msgBody  = "Selected Opinion: " + sel + ", "									+ nl;
			msgBody += "Opinion Purchase Confirmation Number: " + tok + ", "				+ nl;
			msgBody += "Question on Page: " + pag 											+ nl + nl;
			// v1.0.1k: changed wording per JM
			msgBody	+= "Please describe the facts and reasons why you believe you are not in an actual control ";
			msgBody += "relationship (an \"affiliate\") of the issuing company. ";
			msgBody += "Please provide a phone number where you can be reached during normal business hours."	+ nl + nl;
		}
		
	} else if (emailType == "cancel") {
	
		// process the Cancel form
		toId			= mailToQuestions;	// recipient
		subject			= "Rule144Solution.com - Cancellation request.";
		if (formatHTML) {
			// TBD
		} else {
			msgBody  = "Selected Opinion: " + sel + ", "									+ nl;
			msgBody += "Opinion Purchase Confirmation Number: " + tok 						+ nl + nl;	// 1.0.1e: removed page ref
			// v1.0.1e: new text from JM, edited to reduce length
			msgBody += "Although your cancellation will not be affected if you decline to provide an explanation, ";
			msgBody += "Rule144Solution.com would like to know the reason for your cancellation request, ";
			msgBody += "especially any suggestions you might have on improving our services. ";	// v1.0.1h: added text
			msgBody += "Rule144Solution.com will cancel your opinion purchase and provide a credit against your credit card. ";
			msgBody += "You may also provide a phone number where you can be reached during normal business hours in the ";
			msgBody += "event we need to contact you for more information." 				+ nl + nl;
			msgBody += "Please return to Rule144Solution.com whenever you need an opinion for restricted securities or ";
			msgBody += "Reg. S securities. " 												+ nl + nl;
			msgBody += "Note: you must Send ths e-mail to initiate a refund. " 				+ nl + nl;	// v1.0.1k
		}
		
	} else if (emailType == "pdfrequest") {
    
		// v1.2.0a: new e-mail type - handles PDF files not available for download
		toId			= mailToCustServ;	// recipient
		subject			= "Rule144Solution.com Form Set request: confirmation number '" + tok + "' for Form Set '" + formSetName + "'.";
		if (formatHTML) {
			// TBD
		} else {
			msgBody  = "Selected Opinion: " 	+ sel			+ "\t\t";
			msgBody += "Confirmation Number: " 	+ tok 			+ "\t\t";
			msgBody += "Form Set Name: "	 	+ formSetName 	+ nl + nl;	

			msgBody += "The form set I purchased, '"+formSetName+"', Is not available for download. ";
			msgBody += "Please deliver the form set to me via e-mail reply." 	+ nl + nl;
		}
		
	} else {
	
		// unrecognized e-mail type
		toId			= mailToFeedback;		// recipient
		subject			= "Rule144Solution.com  - Internal error unrecognized e-mail type '"+emailType+"'";
		if (formatHTML) {
			// TBD
		} else {
			msgBody  = "Selected Opinion (if any): " + sel + ", "							+ nl;
			msgBody += "Opinion Purchase Confirmation Number (if any): " + tok + ", "		+ nl;
			msgBody += "Referring Page: " + pag 											+ nl + nl;
			msgBody += "The e-mail handler received an unrecognized e-mail type '"+emailType+". ";
			msgBody += "To help us identify and resolve this problem, please include as much detail as possible ";
			msgBody += "about your environment (at minimum, your web browser and version):"	+ nl + nl;
		}
	}

	// common closing
	msgBody += 	nl + nl + nl+ nl + nl + "-----------------------------------------------------------------------"	+ nl + nl;
	msgBody += "Rule144Solution.com typically responds to questions within 1-2 business days."	+ nl + nl;
	
	
	// construct the mailTo URL
	mailToURL += toId
	mailToURL += "?" + "subject=" + escape(subject);
	if (ccId  != "") { mailToURL += "&" + "cc="  + ccId; }
	if (bccId != "") { mailToURL += "&" + "bcc=" + bccId; }
	mailToURL += "&"+ "body=" + escape(msgBody);			// convert newlines
	
	//var mailLen = new String(mailToURL).length;
	//alert("In formatMailToURL, emailType='"+emailType+"' - built the following URL (length="+mailLen+"):\n\n"+mailToURL);
	
	return mailToURL;
}

/*  Function: initPageData ()
		Usage:		default client-side page initialization method (called by BODY onLoad event).  
                    Pages requiring additional fields should define the initPageSpecificData() method.
		Arguments:
            none.
		Processing:
			- option 1: method is empty, performing no initialization
	      	- option 2: overriden in specific page
*/
function initPageData () {
//alert("commonClientScripts.initPageData(): common client-side page initialization method called.");

	// get common data for all pages
    try { sessionId		= pageDataForm.sessionId.value; 	} catch (ex) { /* ignore errors */ }
    try { currentPage	= pageDataForm.currentPage.value; 	} catch (ex) { /* ignore errors */ }
    try { PreviousPage	= pageDataForm.previousPage.value;	} catch (ex) { /* ignore errors */ }
    try { currentToken	= pageDataForm.currentToken.value;	} catch (ex) { /* ignore errors */ }
        
	// now try to get page-specific data
   	initPageSpecificData(); 
    // NOTE: the default method below must be defined; if the current page has no method, a try-catch
    //       here would not trap the missing method error on the client side as it does on the server side.

}

/*  Function: initPageSpecificData ()
		Usage:		default page-specific client-side page initialization method (called by initPageData()).  
                    Pages requiring additional fields should define their own initPageSpecificData() method. 
                    Because the page's method is encountered after commonNavigation has been INCLUDEd,
                    the page's copy of the method will be used instead of the default implementation below.
		Arguments:
            none.
		Processing:
			- option 1: method is empty, performing no initialization
	      	- option 2: overriden in specific page
*/
function initPageSpecificData () {
//alert("commonClientScripts.initPageSpecificData(): common-defined page-specific client-side page initialization method called.");
}

/*  Function: getFileExtension(fileName)
		Usage:		returns the file extension from a filename.
		Arguments:
		Processing:
			- locate and return extension
*/
function getFileExtension(fileName) {
	var extn = "";
    if (fileName.lastIndexOf(".") >= 0) {
    	extn = fileName.slice(fileName.lastIndexOf(".")+1).toLowerCase();
    }
    return extn;
}

// v1.2.0a: new method
/*  Function: isPDF (fileName)
		Usage:			returns true if the fileName is a PDF file.  
		Arguments:
			fileName:	the filename to check
		Processing:
*/
function isPDF (pdfFile) {
	return (getFileExtension(fileName) == "pdf");
}

/* Copyright 2005, 2008 Arda Group, LC 
  version:	1.2.0h
  change history:
  2008-11-18 (djh): v1.2.0h - CustomerService mail account renamed "ClientServices" to eliminate spam
  2008-03-21 (djh): v1.2.0a - initial version. Created from commonNavigation.js and siteNavigation.js 
                              to contain methods still required on the client side.
*/
