//Container for global javascript functions and variables

// AppGlobals.js
// A collection of javascript utility functions to support the core framework
//
// (c) 2008 by Craig A. Cassidy
// Created by: Craig A. Cassidy June 24, 2008
//
// Modification History:


//Global variables
var slider_position = 241;
var navbar_height = 31;
var slider_offset = 4;
var mouse_offset = 0;
var isIE = document.all;
var mouseX = 0;
var mouseY = 0;


//Needed to automate a div reveal animation
var reveal_mRect = null;
var reveal_sRect = null;
var reveal_mObj = null;
var reveal_sObj = null;
var delay_speed = 1;
var pixelsPerTic = 8;


//Default menu
var mainMenuAr = new Array();
 mainMenuAr[0] = new menuItem('Import Feedlist', '', '');
 mainMenuAr[1] = new menuItem('Export Feedlist', '', '');
 mainMenuAr[2] = new menuItem('-', '', '');
 mainMenuAr[3] = new menuItem('Refresh All Feeds', '', '');
 mainMenuAr[4] = new menuItem('New Folder', '', '');
 mainMenuAr[5] = new menuItem('-', '', '');
 mainMenuAr[6] = new menuItem('Preferences', '', '');
 mainMenuAr[7] = new menuItem('-', '', '');
 mainMenuAr[8] = new menuItem('About Photon Feedreader', '', '');
 mainMenuAr[9] = new menuItem('Help', '', '');


if (isIE)
{
  var ff_horiz_buffer = 0;
  var ff_vertl_buffer = 0;
}
else  
{
  var ff_horiz_buffer = 2;
  var ff_vertl_buffer = 4;
}


//event.clientX etc not working in safari & ff3
function getMouseXY(e)
{ 
  if (!e) e = window.event;
  if (e)
  { 
    mouseX = isIE ? (e.clientX + document.body.scrollLeft) : e.pageX;
    mouseY = isIE ? (e.clientY + document.body.scrollTop) : e.pageY;
  }
}
document.onmousemove = getMouseXY;

//called when the page first loads
function js_init()
{
  if (!isIE ) 
     document.getElementById('slider').style.cursor = 'move';
     
  resize_mainwindow()
}

function resize_mainwindow()
{
  document.getElementById('navtree_outer').style.height = document.body.clientHeight - (navbar_height + ff_vertl_buffer); 
  document.getElementById('navtree_inner').style.height = document.body.clientHeight - (navbar_height + 5 + ff_vertl_buffer);
  
  document.getElementById('slider').style.height = document.body.clientHeight - (navbar_height + 4 + ff_vertl_buffer); 
  document.getElementById('main_content').style.height = document.body.clientHeight - (navbar_height + 2 + ff_vertl_buffer);
  document.getElementById('main_content').style.width = document.body.clientWidth - (slider_position + 6 + ff_horiz_buffer);
  
  document.getElementById('address').style.width = document.body.clientWidth - 450;
  document.getElementById('addressbar_div').style.width = document.body.clientWidth - 300;
  
  //Firefox & Safari place the slider too far to the left
  document.getElementById('slider').style.left = slider_position + ff_horiz_buffer; 
}

function address_help_focus(inbound)
{
  if (inbound)
    if (document.getElementById('address').value=='<<enter feed url here>>')
    {
      document.getElementById('address').value= '';
      document.getElementById('address').className = 'address_text';
    }
    else 
    { }
  else
    if (document.getElementById('address').value=='')
    {
      document.getElementById('address').value= '<<enter feed url here>>';
      document.getElementById('address').className = 'address_text_disabled';
    }
}

function menuItem(itemText, itemAction, itemIcon)
{
	this.itemText = itemText;
	this.itemAction = itemAction;
	this.itemIcon = itemIcon;
}

function buildPopupMenu(mArray, revealPosition, revealDirection)
{
   s = '';
   mHeight = 0;
   
   while(document.getElementById("menuContent").firstChild) 
     document.getElementById("menuContent").removeChild(document.getElementById("menuContent").firstChild); 
   
   for (var i=0; i<mArray.length; i++) 
   {
	  if (mArray[i].itemText=='-') 
	  {
		 var newdiv = document.createElement("div")
		 newdiv.className = 'mi_spacer';
		
		 document.getElementById("menuContent").appendChild(newdiv);
		 mHeight = mHeight + 7;   
	  }
	  else
	  {
		 var newdiv = document.createElement("div")
		 newdiv.className = 'mi_off';
		 newdiv.onmouseover = dx.onmouseover;
		 newdiv.onmouseout = dx.onmouseout;
		
		 var newtext = document.createTextNode(mArray[i].itemText);
		 newdiv.appendChild(newtext); 
		 document.getElementById("menuContent").appendChild(newdiv);
 		 mHeight = mHeight + 17;   
	  }
   }
		
   document.getElementById("menuContent").style.pixelHeight = mHeight;
   dropdown_rel('menubtn', 'popup_menu_div', revealPosition, revealDirection)
}


//reveals a dev and (optionally) a drop shadow div)
//assumes they have already been positioned & hidden
//shadowDiv=null to skip the shadow
function reveal_divs(mainDiv, shadowDiv, revealDirection)
{
  reveal_mObj = mainDiv;
  reveal_mRect = getElementRec(mainDiv);
  
  if (shadowDiv)
  {
    reveal_sObj = shadowDiv;
    reveal_sRect = getElementRec(shadowDiv);
  }

  if (revealDirection=='left' || revealDirection=='right')
    setTimeout("reveal_divs_tic("+ (reveal_mRect.width) +", '"+revealDirection+"')",  delay_speed);
  else  
    setTimeout("reveal_divs_tic("+ (reveal_mRect.height) +", '"+revealDirection+"')",  delay_speed);
}

function reveal_divs_tic(tic, revealDirection)
{
  switch(revealDirection) 
  {
    case 'up':
  	 reveal_mObj.style.clip = "rect(0px, auto, "+ (reveal_mRect.height - tic) +"px, 0px)";
  	 reveal_mObj.style.top = (reveal_mRect.top + tic);
  	 
     if (reveal_sObj)
     {
    	reveal_sObj.style.clip = "rect(0px, auto, "+ (reveal_sRect.height - tic) +"px, 0px)";
    	reveal_sObj.style.top = (reveal_sRect.top + tic);
    	reveal_sObj.style.visibility = "visible";
  	 }
     break;
  
    case 'down':
  	 reveal_mObj.style.clip = "rect("+ tic +"px, auto, auto, 0px)";
  	 reveal_mObj.style.top = (reveal_mRect.top - tic);
  	 
     if (reveal_sObj)
     {
    	reveal_sObj.style.clip = "rect("+ tic +"px, auto, auto, 0px)";
    	reveal_sObj.style.top = (reveal_sRect.top - tic);
    	reveal_sObj.style.visibility = "visible";
  	 }
     break;
  
    case 'left':
  	 reveal_mObj.style.clip = "rect(0px, "+(reveal_mRect.width - tic)+", auto, 0px)";
  	 reveal_mObj.style.left = (reveal_mRect.left + tic);
  	 
     if (reveal_sObj)
     {
    	reveal_sObj.style.clip = "rect(0px,"+(reveal_mRect.width - tic)+", auto, 0px)";
    	reveal_sObj.style.left = (reveal_sRect.left + tic);
    	reveal_sObj.style.visibility = "visible";
  	 }
     break;
     
    case 'right':
  	 reveal_mObj.style.clip = "rect(0px, auto, auto, "+tic+")";
  	 reveal_mObj.style.left = (reveal_mRect.left - tic);
  	 
     if (reveal_sObj)
     {
    	reveal_sObj.style.clip = "rect(0px, auto, auto, "+tic+")";
    	reveal_sObj.style.left = (reveal_sRect.left - tic);
    	reveal_sObj.style.visibility = "visible";
  	 }
     break;

    case 'se':
  	 reveal_mObj.style.clip = "rect("+ tic +"px, auto, auto, "+tic+")";
  	 reveal_mObj.style.top = (reveal_mRect.top - tic);
  	 reveal_mObj.style.left = (reveal_mRect.left - tic);
  	 
     if (reveal_sObj)
     {
    	reveal_sObj.style.clip = "rect("+ tic +"px, auto, auto, "+tic+")";
    	reveal_sObj.style.top = (reveal_sRect.top - tic);
    	reveal_sObj.style.left = (reveal_sRect.left - tic);
    	reveal_sObj.style.visibility = "visible";
  	 }
     break;
     
    case 'sw':
  	 reveal_mObj.style.clip = "rect("+ tic +"px, auto, auto, "+tic+"px)";
  	 reveal_mObj.style.top = (reveal_mRect.top - tic);
  	 
     if (reveal_sObj)
     {
    	reveal_sObj.style.clip = "rect("+ tic +"px, auto, auto, "+tic+")";
    	reveal_sObj.style.top = (reveal_sRect.top - tic);
    	reveal_sObj.style.visibility = "visible";
  	 }
     break;
     
    case 'ne':
  	 reveal_mObj.style.clip = "rect(0px, auto, "+(reveal_mRect.height - tic)+", "+tic+")";
  	 reveal_mObj.style.top = (reveal_mRect.top + tic);
  	 reveal_mObj.style.left = (reveal_mRect.left - tic);
  	 
     if (reveal_sObj)
     {
    	reveal_sObj.style.clip = "rect(0px, auto, "+(reveal_sRect.height - tic)+", "+tic+")";

    	reveal_sObj.style.top = (reveal_sRect.top + tic);
    	reveal_sObj.style.left = (reveal_sRect.left - tic);
    	reveal_sObj.style.visibility = "visible";
  	 }
     break;
     
    case 'nw':
  	 reveal_mObj.style.clip = "rect(0px, auto, "+(reveal_mRect.height - tic)+", "+tic+")";
  	 reveal_mObj.style.top = (reveal_mRect.top + tic);
  	 
     if (reveal_sObj)
     {
    	reveal_sObj.style.clip = "rect(0px, auto, "+(reveal_sRect.height - tic)+", "+tic+")";
    	reveal_sObj.style.top = (reveal_sRect.top + tic);
    	reveal_sObj.style.visibility = "visible";
  	 }
     break;
     
     
  }
  reveal_mObj.style.visibility = "visible";
  
  if (tic > 0)
    setTimeout("reveal_divs_tic("+ (tic-pixelsPerTic) +", '"+revealDirection+"')",  delay_speed);
  else  
  {
    if (revealDirection=='left' || revealDirection=='right')
      reveal_mObj.style.left = reveal_mRect.left;
    else  
      reveal_mObj.style.top = reveal_mRect.top;
    
    if (reveal_sObj) 
    { 
      if (revealDirection=='left' || revealDirection=='right')
        reveal_sObj.style.left = reveal_sRect.left;
      else
        reveal_sObj.style.top = reveal_sRect.top;
    }
  }
}

function ctrlPos(left, top, width, height, right, bottom)
{
  this.left = left;
  this.top = top;
  this.width = width;
  this.height = height;
  this.right = right;
  this.bottom = bottom;
}

//Determine relative position of elements in any browser
function getElementRec(obj)
{
  var pos = new ctrlPos();
  
  if (obj.getBoundingClientRect) 
  { //IE
    objRect = obj.getBoundingClientRect();
    pos.left = objRect.left;
    pos.top = objRect.top;
    pos.width = objRect.right - objRect.left;
    pos.height = objRect.bottom - objRect.top;
    pos.right = objRect.right;
    pos.bottom = objRect.bottom;
  } 
  else 
    if (document.getBoxObjectFor) 
    { 
      objRect = document.getBoxObjectFor(obj); //<-INVESTIGATE, not document, obj ref incorrect?
      pos.left = objRect.y;
      pos.top = objRect.x;
      pos.width = objRect.width;
      pos.height = objRect.height;
      pos.right = objRect.left + obj.pixelWidth;
      pos.bottom = objRect.top + obj.pixelHeight;
  	} 
  	else 
  	{ //Safari
      pos.left = obj.offsetLeft;
      pos.top = obj.offsetTop;
      pos.width = obj.offsetWidth;
      pos.height = obj.offsetHeight;
      
      //aggregate heierarchy of offsets
      parent = obj.offsetParent;
      if (parent != obj) 
      {
        while (parent) 
        {
          pos.left += parent.offsetLeft;
          pos.top += parent.offsetTop;
          parent = parent.offsetParent;
        }
      }

      //...and then add aggregated scroll positions
      parent = obj.offsetParent;
      while (parent && parent != 'BODY') 
      {
        pos.left -= parent.scrollLeft;
        if (parent.tagName != 'TR') 
          pos.top -= parent.scrollTop;
          
        parent = parent.offsetParent;
      }
      
      pos.right = pos.left + obj.width;
      pos.bottom = pos.top + obj.height;
    }
    
  return pos;  
}

function dropdown_rel(anchor_element, whatdiv, pos, revealDirection)
{
  if (document.getElementById(whatdiv).style.visibility == "visible")	
  {
    document.getElementById(whatdiv).style.visibility = "hidden";
    document.getElementById('gp_div_shadow').style.visibility = "hidden";
  }
  else
  {
    var aRect = getElementRec( document.getElementById(anchor_element) );
    var whatRect = getElementRec( document.getElementById(whatdiv) );
  
    gapWidth = whatRect.width - aRect.width+2;

    switch(pos)
    {
    case 'down_leftjustify':
      document.getElementById(whatdiv).style.pixelTop = aRect.bottom + document.body.scrollTop - 1;
      document.getElementById(whatdiv).style.pixelLeft = aRect.left + document.body.scrollLeft;
      break;
    
    case 'down_rightjustify':
      document.getElementById(whatdiv).style.pixelTop = aRect.bottom + document.body.scrollTop - 1;
      document.getElementById(whatdiv).style.pixelLeft = aRect.right - whatRect.width;
      break;
    
    case 'down_leftoverlap':
      document.getElementById(whatdiv).style.pixelTop = aRect.top + document.body.scrollTop - 1;
      document.getElementById(whatdiv).style.pixelLeft = aRect.left + document.body.scrollLeft;
      break;
    
    case 'down_rightoverlap':
      document.getElementById(whatdiv).style.pixelTop = aRect.top + document.body.scrollTop - 1;
      document.getElementById(whatdiv).style.pixelLeft = aRect.right - whatRect.width;
      break;
      
    case 'up_leftjustify':
      document.getElementById(whatdiv).style.pixelTop = aRect.top + document.body.scrollTop - whatRect.height - 1;
      document.getElementById(whatdiv).style.pixelLeft = aRect.left + document.body.scrollLeft;
      break;
      
    case 'up_rightjustify':
      document.getElementById(whatdiv).style.pixelTop = aRect.top + document.body.scrollTop - whatRect.height - 1;
      document.getElementById(whatdiv).style.pixelLeft = aRect.right - whatRect.width;
      break;
      
    case 'up_leftoverlap':
      document.getElementById(whatdiv).style.pixelTop = aRect.bottom + document.body.scrollTop - whatRect.height - 1;
      document.getElementById(whatdiv).style.pixelLeft = aRect.left + document.body.scrollLeft;
      break;
      
    case 'up_rightoverlap':
      document.getElementById(whatdiv).style.pixelTop = aRect.bottom + document.body.scrollTop - whatRect.height - 1;
      document.getElementById(whatdiv).style.pixelLeft = aRect.right - whatRect.width;
      break;
    }
  
    if (isIE) 
    {
      //document.getElementById(whatdiv).style.pixelTop = document.getElementById(whatdiv).style.pixelTop - 2;
      //document.getElementById(whatdiv).style.pixelLeft = document.getElementById(whatdiv).style.pixelLeft - 2;
    }
  
    //shadowme(document.getElementById(whatdiv), false);
    reveal_divs(document.getElementById(whatdiv), document.getElementById('gp_div_shadow'), revealDirection);
  }
}

function shadowme(obj, reveal)
{
  oRect = getElementRec( obj );

  document.getElementById('gp_div_shadow').style.pixelTop = oRect.top + 3 + ff_horiz_buffer;
  document.getElementById('gp_div_shadow').style.pixelLeft = oRect.left + 3 + ff_horiz_buffer;
  document.getElementById('gp_div_shadow').style.pixelHeight = oRect.height;
  document.getElementById('gp_div_shadow').style.pixelWidth = oRect.width;

  if (reveal)
    document.getElementById('gp_div_shadow').style.visibility = 'visible';
}

//functions supporting the draggable slider to resize navbar:
function nav_start_drag()
{

  var textRect = document.getElementById('slider').getBoundingClientRect();

  //**mouse_offset = (event.clientX - textRect.left) - 1;
  mouse_offset = (mouseX - textRect.left) - 1;
  nav_dragup();
}

function nav_end_resize()
{
  slider_position = document.getElementById('slider').style.pixelLeft;
  document.execCommand('Unselect');
  //i_dispatch('cookie_cutter.php?id=<? echo $modulename."_detheight" ?>&val='+document.getElementById("cell_three").height);
}

function nav_dragup(evt)
{
  getMouseXY();
  
  if (event.clientX > 20)
  {
     document.getElementById("navtree_outer").style.width = mouseX - mouse_offset - slider_offset;
     document.getElementById('navtree_inner').style.width = mouseX - mouse_offset - (slider_offset + 4) - ff_horiz_buffer;
     document.getElementById('slider').style.left = (mouseX - mouse_offset - slider_offset) + 1;
     
     document.getElementById('main_content').style.left = document.getElementById('slider').style.pixelLeft + 6;
     document.getElementById('main_content').style.width = document.body.clientWidth - document.getElementById('main_content').style.pixelLeft;
  }
}


function dropdown_hide(whatdiv)
{
  document.getElementById(whatdiv).style.visibility = "hidden";
}

function dropdown_recurse(node)
{
  if (node.className == 'popup')
  {
    node.style.visibility = 'hidden';
    func = node.name + 'close()';
    eval(func);
  }
    
  if ( node.hasChildNodes() )  
    for (var i=0; i<node.childNodes.length; i++)
      dropdown_recurse(node.childNodes[i])
}

function dropdown_hideall()
{
  document.getElementById('disable_all').style.height = '0%';
  document.getElementById('disable_all').style.width = '0%';

  for (var i=0; i<document.body.childNodes.length; i++)
    dropdown_recurse(document.body.childNodes[i])
}

function validate_email(form_id,email) {
   var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
   var address = document.forms[form_id].elements[email].value;
   if(reg.test(address) == false) {
      alert('Invalid Email Address');
      document.forms[form_id].elements[email].value = '';
      return false;
   }
}

function getFieldIndex(input)
{    
  var index = -1, i = 0, found = false;    
  
  while (i < input.form.length && index == -1)      
    if (input.form[i] == input)
      index = i;      
    else 
      i++;    
      
  return index;  
}

function tabto_next_control(currControl)
{
  var objForm = document.getElementById('layerform');

  objForm[(getFieldIndex(objForm[currControl])+1) % objForm.length].focus();
}

//functions serving the testpicklist
	  var filtering = false;

	  function textpicklist_popup(linkto, divid)
	  {
	    if (document.getElementById(divid).style.visibility == 'visible')
	      document.getElementById(divid).style.visibility = 'hidden'
	    else
	    {
	    	if (!filtering)
	    	{
	    		var s;
  				var tx = '';
  		
  				eval('var localArray=' + linkto+'_list');
  				var t = document.getElementById(linkto).value.toUpperCase();

  				for (var i=1; i<localArray.length; i++)
 				  tx = tx + '<div class="textpicklist_item_off" onmouseover="this.className=' +"'" + 'textpicklist_item_on' + "'" + '" onmouseout="this.className=' +"'"+ 'textpicklist_item_off' +"'"+ '" onclick="textpicklist_popdown(' + "'" + linkto + "_div'" + ', ' + "'" + linkto + "'" + ', this.innerText, '+ "''" +')">' + localArray[i] + '</div>';
  
  				document.getElementById(divid).innerHTML = tx;
  		    }		
	    
	        dropdown_rel(linkto, divid, 'down_leftjustify', 'down');
	        
    		//var textRect = document.getElementById(linkto).getBoundingClientRect();
    		//document.getElementById(divid).style.pixelTop = textRect.top + document.body.scrollTop + 19;
   			//document.getElementById(divid).style.pixelLeft = textRect.left + document.body.scrollLeft;
   			
    		eval('document.getElementById(divid).style.pixelWidth = ('+linkto+'_width+17)');

	    	//document.getElementById(divid).style.visibility = 'visible';
	    }
	  }

	  function textpicklist_popdown(divid, textbox, selected_text, callback_func)
	  {
	    document.getElementById(textbox).value = selected_text;
	    document.getElementById(divid).style.visibility = 'hidden';
	    
	    //if (callback_func<>'')
	    //  eval(callback_func);
	  }
	  
	  function textpicklist_typeahead(listanme)
	  {
  		if (window.event.keyCode == 13)
  		{
	       document.getElementById(listanme+'_div').style.visibility = 'hidden';
  		   //window.event.keyCode = 9;
  		   tabto_next_control(listanme);
		}
		
		else
		
		{
	    	filtering = true;

	    	if (document.getElementById(listanme+'_div').style.visibility == 'hidden')
	    	  textpicklist_popup(listanme, listanme+'_div');
	    
	    	var s;
  			var tx = '';
  		
  			eval('var localArray=' + listanme+'_list');
  			var t = document.getElementById(listanme).value.toUpperCase();

  			for (var i=1; i<localArray.length; i++)
  			{
  			    s = localArray[i].toUpperCase();
		
  			 	if (s.indexOf(t) == -1)
  			 	  s = localArray[i].toUpperCase();
  			 	else
  			 	  tx = tx + '<div class="textpicklist_item_off" onmouseover="this.className=' +"'" + 'textpicklist_item_on' + "'" + '" onmouseout="this.className=' +"'"+ 'textpicklist_item_off' +"'"+ '" onclick="textpicklist_popdown(' + "'" + listanme + "_div'" + ', ' + "'" + listanme + "'" + ', this.innerText, '+ "''" +')">' + localArray[i] + '</div>';
  			}
  
  			document.getElementById(listanme+'_div').innerHTML = tx;
	    	filtering = false;
	    }
	  }
	  
//Form Validation Functions__________________________________
	function CalcKeyCode(aChar) 
	{
	  var character = aChar.substring(0,1);
	  var code = aChar.charCodeAt(0);
	  return code;
	}	  

 	function validate_num_only(val) 
	{
	  var strPass = val.value;
	  var strLength = strPass.length;
	  var lchar = val.value.charAt((strLength) - 1);
	  var cCode = CalcKeyCode(lchar);
	
	  if (cCode < 48 || cCode > 57 ) 
	  {
	    var myNumber = val.value.substring(0, (strLength) - 1);
	    val.value = myNumber;
	  }
	  return false;
    }
  
	function validate_width(val, lenLimit) 
	{
	  var strPass = val.value;
	  var strLength = strPass.length;
	
	  if (strLength > lenLimit) 
	  {
	    var myNumber = val.value.substring(0, lenLimit);
	    val.value = myNumber;
	  }
	  return false;
    }
	
	function zpad(obj, len)
	{
	   var lval = obj.value;
	   
	   if ( lval.length < (parseInt(len)) )
	   {
	   	for (var i=lval.length; i<parseInt(len); i++)
	     	lval = '0' + lval;
		 
	   	obj.value = lval;
	   }
	}
  
 	function trim(stringToTrim) 
 	{
   		return stringToTrim.replace(/^\s+|\s+$/g,"");
 	}
	
	function luhn_check(number) {
	  var number=number.replace(/\D/g, '');
	  var number_length=number.length;
	  var parity=number_length % 2;
	
	  var total=0;
	  for (i=0; i < number_length; i++) {
		var digit=number.charAt(i);
		if (i % 2 == parity) {
		  digit=digit * 2;
		  if (digit > 9) {
			digit=digit - 9;
		  }
		}
		total = total + parseInt(digit);
	  }
	
	  if (total % 10 == 0) {
		return true;
	  } else {
		return false;
	  }
	}
	
	function changeCase(txtCtrl) 
	{
		var tmpStr = txtCtrl.value.toLowerCase();
		
		tmpStr = tmpStr.replace (/(\d+)([a-z]{3,})/gi, "$1 $2"); // add space after numbers when 3+ alphachars follow
		tmpStr = tmpStr.replace (/\,/g, " "); // delete commas - replace by space (essential!)
		tmpStr = tmpStr.replace (/(\d+)([.{2,}$])/gi, " $1$2"); // add 4 spaces before numbers not at end of string
		tmpStr = tmpStr.replace (/(\S*)\"(\D+)\"(\S*)/g, '$1 "$2" $3'); // put spaces around "string" (force uppercase)
		tmpStr = tmpStr.replace (/o\'/gi, "O' "); // change o' to O'+space (O' Reilly) (force uppercase)
		tmpStr = tmpStr.replace (/(\b|\s|\.)(mc)([a-z])/g, "$1mc $3"); // add space after Mc (force uppercase)
		tmpStr = tmpStr.replace (/(\D)\./g, "$1. "); // add space after literal . (B. M. Smith > uppercase)
		tmpStr = tmpStr.replace (/\-([a-z])/g, " - $1"); // add spaces around hyphens (force uppercase)
		tmpStr = tmpStr.replace (/(^\s+)/, ""); // remove spaces at start of string
		tmpStr = tmpStr.replace (/\s{4,}/g, " "); // remove excessive spaces > 4
		
		if ((/fpo\b/.test(tmpStr)) || (/fpo\d/.test(tmpStr))) 
		{
			tmpStr = tmpStr.toUpperCase();
			tmpStr = tmpStr.replace (/([A-Z])(\s{2,})/g, "$1 "); // remove spaces >1 between A-Z and A-Z/0-9 (not converse)
		}
		
		var SplitStuff = tmpStr.split(" ");
		var ArrLen = SplitStuff.length;
		
		for (var k=0; k<ArrLen; k++) 
		{
			var word = SplitStuff[k];
			if (/\d/.test(word)) {word = word.toUpperCase()}
			var wordLen = word.length;
			var posn = word.search(/[a-zA-Z]/);
			var firstChars = word.substring(0, posn+1).toUpperCase();
			var postString = word.substring(posn+1,wordLen);
			word = firstChars + postString;
			word = word.replace ( /C\/O\b/g, "C\/o" );
			word = word.replace ( /Po\b/g, "PO" );
			word = word.replace (/\'a/, "'A"); // De'Ath and D'Arcy!
			
			SplitStuff[k] = word;
		}
		
		var newline = SplitStuff.join(" ");
		newline = newline.replace (/\.\s/g, "."); // re-format names B. M. Smith > B.M.Smith
		newline = newline.replace (/Mc\s/g,"Mc"); // reformat McXxxx
		txtCtrl.value = newline;
	}
	
	
 // End form validation functions 
    
	  
//
