/* ******************** BEGIN TextArea Object ******************** */

/* ======================================================================
OBJECT:		com_netobjects_TextArea

PLATFORMS:	Netscape Navigator 4.01 or higher, 
				Microsoft Internet Explorer 4.02 or higher

DESC:			This object allows developers to create TextArea fields with common built
				in behaviors such as onClick events and field validation.

NOTES:		The onKeyPress, onKeyDown and onKeyUp events are disabled for Navigator 4.0 only
				due to a bug in Netscape Navigator 4.0.
====================================================================== */
function com_netobjects_TextArea(params) {
 	// Public Properties	
	this.name 				= (params.name != null) ? params.name : "";
	this.textAreaName		= (params.textAreaName != null) ? params.textAreaName : "";
	this.formName			= (params.formName != null) ? params.formName : "";
	this.defaultValue		= (params.defaultValue != null) ? params.defaultValue : "";
	this.cols				= (params.cols != null) ? params.cols : "";
	this.rows				= (params.rows != null) ? params.rows : "";
	this.wrap				= (params.wrap != null) ? params.wrap : "";

	this.validate 			= (params.validate != null && params.validate == true) ? params.validate : false;
	this.isRequired		= (params.isRequired != null && params.isRequired == true) ? params.isRequired : false;
	this.maxChars			= (params.maxChars != null) ? params.maxChars : 0;  // 0 indicates no maximum limit
	this.state 				= (params.state != null) ? params.state : "";

	this.testMode			= (params.testMode != null) ? params.testMode : "off";
	
	// Private Properties
	this.isValid 			= true;
	this.errType 			= null;
	this.textAreaIndex 	= null

	// Public Methods
	this.render 			= _textarea_render;
	this.validateValue 	= _textarea_validateValue;

	this.getValue			= _textarea_getValue;
	this.setValue			= _textarea_setValue;

	// Private Methods
	this.validateProperties = _textarea_validateProperties;
	this.gethdlElement		= _textarea_gethdlElement;	// gets the handle to the form element object on the page

	// Public Events
	this.onBlur     	= _textarea_onBlur;
	this.onChange 		= _textarea_onChange;
	this.onFocus   	= _textarea_onFocus;
	this.onKeyDown		= _textarea_onKeyDown;
	this.onKeyPress	= _textarea_onKeyPress;
	this.onKeyUp		= _textarea_onKeyUp;
	this.onSelect 		= _textarea_onSelect;

	this.onValidate  	= _textarea_onValidate;
	this.onInvalid   	= _textarea_onInvalid;
	this.onValid   	= _textarea_onValid;
	this.onRender     = _textarea_onRender;

	// Private Events (internal event driven functionality)
	this.eOnChange    = _textarea_eOnChange;

	// Validate object properties
	this.validateProperties();

	// Public Methods ----------------------------------------

	/* ======================================================================
	
   METHOD: _textarea_render.  Renders the element in HTML.
	
	====================================================================== */
	function _textarea_render() {
		// Initialize Variables
		var stextAreaName = "";
		var svalue = "";
		var srows = "";
		var scols = "";
		var swrap = "";
		var sonKeyDown = "";
		var sonKeyPress = "";
		var sonKeyUp = "";

		var sonBlur  	= "";
		var sonChange  = "";
		var sonFocus   = "";
		var sonSelect  = "";
	
		// Set Variables
		stextAreaName = ' NAME="' + this.textAreaName + '"';
		if (this.rows != "")
			srows = ' ROWS="' + this.rows + '"';
		if (this.cols != "")	
			scols = ' COLS="' + this.cols + '"';
		if (this.wrap != "")
			swrap = ' WRAP="' + this.wrap + '"';

		svalue = this.defaultValue;

		// Build Nav & IE shared link events
		sonBlur  	= ' onBlur="' + this.name + '.onBlur();"';
		sonChange   = ' onChange="' + this.name + '.eOnChange();"';
		sonFocus    = ' onFocus="' + this.name + '.onFocus();"';

		// Workaround for a Nav 4.0 bug - these events don't work well with onChange.  
		// So this component will provide onChange for Nav 4.0, but not the following three events:
		if (DetermineCurrentBrowser() != "Netscape 4.0") {
			sonKeyDown 	= ' onKeyDown="' + this.name + '.onKeyDown();"';
			sonKeyPress	= ' onKeyPress="' + this.name + '.onKeyPress();"';
			sonKeyUp  	= ' onKeyUp="' + this.name + '.onKeyUp();"';
		}
		sonSelect  	= ' onSelect="' + this.name + '.onSelect();"';
		eEvents  	= sonBlur + sonChange + sonFocus + sonKeyDown + sonKeyPress + sonKeyUp + sonSelect;

		// Write HTML
		if (this.state == "hidden") {
		   document.write( "<Input Type=hidden" + stextAreaName + ' value="' + svalue + '"' + eEvents + ">\n");
		} else if (this.state == "read-only") {
		   document.write( this.defaultValue + "\n");
		} else {
		   document.write("<TEXTAREA " + 
							stextAreaName + 
							srows + 
							scols + 
							swrap +
							eEvents + ">");
			document.write(svalue);
			document.writeln("</TEXTAREA>");
		}

		if (this.state != "read-only") { 
			// Set control index:
			// The control index is used by the object to identify its respective form element
			// in the event that there are more than one form element with the same name.
			this.textAreaIndex = eval("window.document." + this.formName + "." + this.textAreaName + ".length")-1
			if (isNaN(this.textAreaIndex)) {this.textAreaIndex=0}
		}

		// Write HTML
		
		// Fire public events
		this.onRender(); 
	} // END _textarea_render


	/* ======================================================================
	
   METHOD: _textarea_validateValue.  Validates the current value of the 
	textarea field.  Checks isRequired (not blank) and length vs. maxChars.
	
	====================================================================== */
	function _textarea_validateValue() {
		var value = (this.gethdlElement() != null) ? (this.gethdlElement()).value : this.defaultValue;
		this.isValid = true;
		this.errType = "";

		// Check for required value
		if ((this.isRequired) && ((value == null) || (value == ""))) {
			this.errType = "NoValue";
			this.isValid = false;
		}
		if (value != null && this.maxChars > 0 && value.length > this.maxChars) {
			this.errType = "OverMaxChars";
			this.isValid = false;
		}

		// Fire public events
		if (this.isValid) 
			this.onValid();
		else 
			this.onInvalid();
		this.onValidate();

		return this.isValid;
	} // END _textarea_validateValue


	/* ======================================================================
	
   METHOD: _textarea_getValue.  Gets the value of the form element on the page.
	
	====================================================================== */
	function _textarea_getValue() {
		var value = "";
		
		if (this.gethdlElement() != null)
			value = (this.gethdlElement()).value
		else
			value = this.defaultValue;

		return value;
	} // END _textarea_getValue


	/* ======================================================================
	
   METHOD: _textarea_setValue.  Sets the value of the form element on the page.
	
	====================================================================== */
	function _textarea_setValue(value) {
		var success = false;
		
		if (this.gethdlElement() != null && value != null) {
			(this.gethdlElement()).value = value;
			success = true;
		}

		return success;
	} // END _textarea_setValue


	// Private Methods ----------------------------------------

	//
	// Validate current properties
	//
	function _textarea_validateProperties() {
		if ((this.testMode.toLowerCase() == "text") || (this.testMode.toLowerCase() == "alerts")) {
			var errors = new Array()
	      iIndex = 0;  
         
			// Check for errors
			if (this.name == "") 
				errors[iIndex++] = "Name is a required property.";  
			if (this.textAreaName == "") 
				errors[iIndex++] = "Text area name is a required property.";  
			if (this.textAreaName == this.name) 
				errors[iIndex++] = "Text area name and object name may not be the same.";  
			if (this.formName == "") 
				errors[iIndex++] = "Form name is a required property.";  
			if ((this.defaultValue == "") && (this.isRequired) && (this.validate))
				errors[iIndex++] = "WARNING: A value is required but no default is given.  Invalid values are only automatically trapped upon change from their original value.";  

			// Display errors
			for (var i=0; i<errors.length; i++)  {
				if (this.testMode.toLowerCase()	== "text") 
					document.write( "<BR><HR><B><FONT COLOR=RED>TEST MODE, com_netobjects_Button, '" + this.name + "' : </FONT> " + errors[i] + "</B><HR>\n");
				else
  					alert("TEST MODE, com_netobjects_TextBox, '" + this.name + "' : " + errors[i]);
 
			}			
		} 
	} // END _textarea_validateProperties



	/* ======================================================================
	
   METHOD: _textarea_gethdlElement.  Gets handle of associated element. 
	
	====================================================================== */
	function _textarea_gethdlElement() {
		var result = null
		if (this.textAreaIndex != null) { // if null hasn't rendered a hidden or default element
			var index = "";
			
				if (!isNaN(eval("window.document." + this.formName + "." + this.textAreaName + ".length"))) {
				index = "[" + this.textAreaIndex + "]"
			}
			result = eval("window.document." + this.formName + "." + this.textAreaName + index )
		}
		return result
	} // END _textarea_gethdlElement


	// Private Event Handlers ----------------------------------------

	/* ======================================================================
	
   EVENT: _textarea_eOnChange.  Internal event handler that validates the
	value when the value of the textarea field is changed.
	
	====================================================================== */
	function _textarea_eOnChange() {
		// Validate the newly changed value
		if (this.validate) 
			this.validateValue();

		// Fire public events
		this.onChange();

		return this.isValid;
	} // END _textarea_eOnChange
	
	// Public Event Handlers ----------------------------------------

	// Default handlers for each event, overridden in calling page.
	function _textarea_onBlur() {
	}
	function _textarea_onChange() {
	}
	function _textarea_onFocus() {
	}
	function _textarea_onKeyDown() {
	}
	function _textarea_onKeyPress() {
	}
	function _textarea_onKeyUp() {
	}
	function _textarea_onSelect() {
	}
	function _textarea_onValidate() {
	}
	function _textarea_onInvalid() {
		if (this.errType == "NoValue") 
			alert("An entry in this field is REQUIRED.")	;
		else if (this.errType == "OverMaxChars") 
			alert("You have exceeded " + this.maxChars + " characters, the maximum allowed.");
	} // END _textarea_onInvalid
	function _textarea_onValid() {
	}
	function _textarea_onRender() {
	}
} // END CONSTRUCTOR com_netobjects_TextArea 


// Shared functions ----------------------------------------

/* ======================================================================
FUNCTION:  	IsNum
 
INPUT:  		numstr (string/number) - the string that will be tested to ensure 
      										 that the value is a number (int or float)

RETURN:  	true, if all characters represent a valid integer or float
     			false, otherwise.

PLATFORMS:	Netscape Navigator 3.01 and higher,
			  	Microsoft Internet Explorer 3.02 and higher,
			  	Netscape Enterprise Server 3.0,
			  	Microsoft IIS/ASP 3.0.
====================================================================== */
function IsNum( numstr ) {
	// Return immediately if an invalid value was passed in
	if (numstr+"" == "undefined" || numstr+"" == "null" || numstr+"" == "")	
		return false;

	var isValid = true;
	var decCount = 0;		// number of decimal points in the string

	// convert to a string for performing string comparisons.
	numstr += "";	

	// Loop through string and test each character. If any
	// character is not a number, return a false result.
 	// Include special cases for negative numbers (first char == '-')
	// and a single decimal point (any one char in string == '.').   
	for (i = 0; i < numstr.length; i++) {
		// track number of decimal points
		if (numstr.charAt(i) == ".")
			decCount++;

    	if (!((numstr.charAt(i) >= "0") && (numstr.charAt(i) <= "9") || 
				(numstr.charAt(i) == "-") || (numstr.charAt(i) == "."))) {
       	isValid = false;
       	break;
		} else if ((numstr.charAt(i) == "-" && i != 0) ||
				(numstr.charAt(i) == "." && numstr.length == 1) ||
			  (numstr.charAt(i) == "." && decCount > 1)) {
       	isValid = false;
       	break;
      }         	         	       
   } // END for   
   
   	return isValid;
}  // end IsNum


/* ======================================================================
FUNCTION:	IsAlphaNumOrUnderscore

INPUT:		str (string) - the string to be tested

RETURN:  	true, if the string contains only alphanumeric characters or underscores.
				false, otherwise.

PLATFORMS:	Netscape Navigator 3.01 and higher,
			  	Microsoft Internet Explorer 3.02 and higher,
			  	Netscape Enterprise Server 3.0,
			  	Microsoft IIS/ASP 3.0.
====================================================================== */
function IsAlphaNumOrUnderscore( str ) {
	// Return immediately if an invalid value was passed in
	if (str+"" == "undefined" || str+"" == "null" || str+"" == "")	
		return false;

	var isValid = true;

	str += "";	// convert to a string for performing string comparisons.
	// Loop through string one character at a time. If non-alpha numeric
	// is found then, break out of loop and return a false result

	for (i = 0; i < str.length; i++)
   	{
		// Alphanumeric must be between "0"-"9", "A"-"Z", or "a"-"z"
      		if ( !( ((str.charAt(i) >= "0") && (str.charAt(i) <= "9")) || 
      			((str.charAt(i) >= "a") && (str.charAt(i) <= "z")) ||
      			((str.charAt(i) >= "A") && (str.charAt(i) <= "Z")) ||
      			(str.charAt(i) == "_") ) )
      		{
   				isValid = false;
         		break;
      		}

	} // END for   
   
	return isValid;
}  // end IsAlphaNumOrUnderscore


/* ======================================================================
FUNCTION:	DetermineCurrentBrowser 
 
INPUT: 		none.

RETURN:		a string indicating the current browser

DESC:			This function is used with client-side JavaScript to detect
				the brand and version of the user's browser.  Detects only
				Netscape and Microsoft browsers.  Returns "Other" if a different
				brand is detected.

PLATFORMS:	Netscape Navigator 3.01 and higher,
			  	Microsoft Internet Explorer 3.02 and higher,
====================================================================== */
function DetermineCurrentBrowser() {
	var current_browser = ""; 
	var bwr = navigator.appName; 
	var ver = parseInt(navigator.appVersion, 10); 
	
	if ( bwr == "Netscape" && ver == 4 ) current_browser = "Netscape 4.0"; 
	else if ( bwr == "Netscape" && ver == 3 ) current_browser = "Netscape 3.0";  
	else if ( bwr == "Netscape" && ver == 2 ) current_browser = "Netscape 2.0"; 
	else if ( bwr == "Microsoft Internet Explorer" && ver == 3 ) current_browser = "MSIE 3.0"; 
	else if ( bwr == "Microsoft Internet Explorer" && ver == 4 ) current_browser = "MSIE 4.0"; 
	else current_browser = "Other";
	
	return current_browser;
} // end DetermineCurrentBrowser


/* ******************** END TextArea Object ******************** */

