/**
* webdosform.js 
* This file contain javascript event handlers and functions that
* make web form input behave as DOS form input.
* In a DOS form input, a user use keyboard as his primary input device instead of mouse. 
* It is much faster for a heavy data-entry user to use keyboard as their primary input device.
* This JavaScript library simulates DOS form input behavior, you can do all key-in use just one hand 
* and use keyboard only.
*
* Simulates DOS form input behavior, do all key-in using just one hand and  keyboard only:
  o Page Load :  Focus on first input element automatically.
  o Press <b> ENTER </b>key: Focus on next input element. If current input element is the last one,  focus goes to the first input element.
  o Press <b> DOWN </b>key: Focus on previous input element.  If current input element is the first one,   focus goes to the last input element.
  o Press <b> UP </b>key: Focus on previous input element.  If current input element is the first one,   focus goes to the last input element.
  o Press <b> LEFT </b>key: If current focus on DropdownList, select previous option.  If current selection is the first one, selection goes to the last option.
  o Press <b> RIGHT </b>key:  If current focus on DropdownList, select next option.  If current selection is the last one, selection goes to the first option.
  o Press <b> SPACE </b>key: If current focus on button, submit it .
  o Press <b> PAGE UP </b>key: Calls doPageUp function if the function has been defined. 
  o Press <b> PAGE DOWN </b>key: Calls doPageDown function if the function has been defined. 
  o Advancing Field Focus when the value length equal MaxLength attribute.
  o Focus on the first failed validation field automatically.
  o Setting <b>Input Mask</b> : Formated Input Mask<br>
         o <b>c or C</b> : Only a-z A-Z are allowed in this position.
         o <b>9</b> : Only 0-9 are allowed in this position.
         o <b>@, $, %, (, ), -, {, }, [, ], ;, :, ', ", , (comma), ., /, _, =, + and  space </b>: Only the specified special character is allowed in this position.
  o Setting <b>Input Mask</b> : Custom Input Mask<br>
          o <b>INTEGER</b> : Only 0-9 are allowed.
          o <b>REAL</b> :  Only 0-9 and . are allowed.
          o <b>CURRENCY</b> : Only 0-9 and . are allowed. 
                                               When Form Load and onFocus, format to currency . 
                                               When Form submit and onBlur, unformat automatcally.
*
* @author miles sun,  miles@uuu.com.tw
* @version Revision: 1.0 Created: 2004-3-5  Modified: 2004-3-16	 	
*/

   // mForm is a array that contains managed elements in a HTML form.
   // The types this library managed including text,textare,select-one,submit element
   var mForm= new Array();
   // This library intercept submit event, it save the original submit event handler in mOriginalSubmit variable
   var mOriginalSubmit=null;
   var mDOSForm=false;
   var mStyleBackgroundColor='paleturquoise';
   var mENTERtoSubmit=false;

    /************    Event Handlers  *******/

    /**
     * In order to use webdosform JavaScript library, this function HAS TO be called after document is loaded.
     * You can achive this by calling this function in body tag eg:
     *                <body onload="webdosform_init(true);" >
     * or in a script eg:
     *                <script>
     *                         if(typeof mDOSForm !="undefined"){
     *                              mDOSForm=true;
     *                         }
     *                         window.onload=webdosform_onload;
     *                </script> 
     *
     * If you want to use both input mask and DOS Form key,  pass true as the parameter.
     * Otherwise, you can only use input mask without DOS Form key
     */
   function webdosform_init(bDOSForm){
	var f=document.forms[0];
	reFillMForm();

	
	// the processKeyPress event handler control ENETR,SPACE,UP,DOWN,LEFT,RIGHT,PAGE UP,PAGE DWON
	if(bDOSForm==true) {
	   var elem=null;
	   for(var i=0; i < mForm.length;i++){
	      elem=mForm[i];
	      elem.onkeydown=processKeyDown;
	   }   
	  //document.onkeydown=processKeyDown;
	  // webwinform_submit event handler unformat all currency elements and set the focus to the first validation-failed element
	  mOriginalSubmit =f.onsubmit;
	  f.onsubmit=webwinform_submit;
	  formatAllCurrencyElement();
	  focusFirstInputElement();
	}
	// processKeyDown  event handler control input mask	
	document.onkeypress=processKeyPress;
	return true;
   }

   function webdosform_onload(evt) {
	webdosform_init(mDOSForm);
   }

   function webwinform_submit(){
	var retValue =true;
	if(typeof Page_BlockSubmit !="undefined"  ){
	   retValue=!Page_BlockSubmit ;
	}
	if(retValue){
	   unformatAllCurrencyElement();
	} else{
	   if (typeof(Page_ValidationVer) != "undefined") { // ASP.NET Validation
	      for (var i = 0; i < Page_Validators.length; i++) {
	         if (!Page_Validators[i].isvalid) {
	            var elem=document.getElementById(Page_Validators[i].controltovalidate);
	            var index=getElementIndex(elem);
                          setTimeout("setFocusByIndex("+index+")",0);
	            break;
	         }
	      }
	   }
	} 
	if(mENTERtoSubmit){
	   retValue=false;
	}
	return retValue;
   } 


   function processKeyDown(evt) {

	evt =(evt) ? evt : ((window.event) ? event : null);
	var elem = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement: null);
	var charCode=(evt.charCode) ? evt.charCode:((evt.which) ? evt.which : evt.keyCode);
	if(isManagedType(elem.type)==false)
	   return true;
	mENTERtoSubmit=false;
	switch (charCode){
	   case 13: // ENTER
	      mENTERtoSubmit=true;
	      return doFocusNext(elem);

	      break;
	   case 32: // SPACE BAR
	      if(isButtonType(elem.type)){
	         emptySelection();
	      }
	      return true;
	      break;
	   case 37: // LEFT
 	      if(isButtonType(elem.type)){
	            return doFocusPrevious(elem);
	      }
	      if(elem.type=="select-one"){
	         if(elem.selectedIndex!=null){
	            if(elem.selectedIndex==0)
	               elem.selectedIndex=elem.options.length-1;
	            else
	               elem.selectedIndex-=1;
	         } else {
	            elem.selectedIndex=0;
	         }
	      }
	      break;
	   case 38: // UP
	      return doFocusPrevious(elem);
	      break;
	   case 39: // RIGHT
	       if(isButtonType(elem.type)){
	            return doFocusNext(elem);
	      }
	      if(elem.type=="select-one"){
	         if(elem.selectedIndex!=null){
	            if(elem.selectedIndex==(elem.options.length-1)){
	               elem.selectedIndex=0;
	            }else{
	               elem.selectedIndex+=1;
	            } 
	         } else {
	            elem.selectedIndex=0;
	         }
	      }
	      break;
	   case 40: // DOWN
	           return doFocusNext(elem);
	      break;
	   case 33: // PAGE UP
	           if(typeof doPageUp !="undefined" && typeof doPageUp=="function"){
	               return doPageUp();
	           }
	           return true; 
	      break;
	   case 34: // PAGE DOWN
	           if(typeof doPageDown !="undefined"  && typeof doPageDown=="function"){
	               return doPageDown();
	           }
	           return true; 
	      break;
	   case 118: // F7 SUBMIT
	      var submitButton= getFirstSubmitButton();
	      doPostBack(submitButton.name,"");
	      break; 
	   default:

	      break; 
	}
	return true;
   }

   function processKeyPress(evt) {
	evt =(evt) ? evt : ((window.event) ? event : null);
	var elem = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement: null);
	var charCode=(evt.charCode) ? evt.charCode:((evt.which) ? evt.which : evt.keyCode);

	if(isManagedType(elem.type)==false)
	   return true;
	if(document.selection != null) {
	   if(document.selection.createRange().text != '')
	      document.selection.clear();
	}
	var retValue=true;
	if(elem.mask){
	   retValue=doMask(elem,charCode);	
	}
               if(elem.type=="text" && elem.value.length==elem.maxLength-1){
	   var index=getElementIndex(elem);
	   var nextIndex=index+1;
	   if(index==mForm.length-1){
	      nextIndex=0;
	   }	
	   setTimeout("setFocusByIndex("+nextIndex+")",0);	
	}
	return retValue;
   }

   function processFocus(evt) {
	evt =(evt) ? evt : ((window.event) ? event : null);
	var elem = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement: null);
	var charCode=(evt.charCode) ? evt.charCode:((evt.which) ? evt.which : evt.keyCode);
	if(isManagedType(elem.type)==false)
	   return true;
	if(elem.mask.toUpperCase()=="CURRENCY"){
	   unformatCurrencyElement(elem);
	}
	return doFocusMask(elem) ;
   }

   function processBlur(evt) {
	evt =(evt) ? evt : ((window.event) ? event : null);
	var elem = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement: null);
	var charCode=(evt.charCode) ? evt.charCode:((evt.which) ? evt.which : evt.keyCode);
	if(isManagedType(elem.type)==false)
	   return true;
	if(elem.mask.toUpperCase()=="CURRENCY"){
	   formatCurrencyElement(elem);
	}
	return true;
   }

/**
* do Functions. Those functions are called directly in event handler, the function HAS TO
* return true or false to indicate the default behavior should proceed or not.
*
*/
   
   function doFocusNext(elem) { 
	emptySelection();
	if(canBlur(elem)==false){
	   return true; 
	}
	var index=getElementIndex(elem);
	var nextIndex=index+1;
	if(index==mForm.length-1){
	   nextIndex=0;
	}
	elem.style.backgroundColor='';
	setTimeout("setFocusByIndex("+nextIndex+")",0);

	return false;
    }

   function doFocusPrevious(elem) { 
	emptySelection();
	if(canBlur(elem)==false){
	   return true; 
	}
	var index=getElementIndex(elem);
	var nextIndex=index-1;
	if(index==0){
	   nextIndex=mForm.length-1;
	}	
	elem.style.backgroundColor='';
	setTimeout("setFocusByIndex("+nextIndex+")",0);	
	return false;
    }

   function doMask(elem,keyCode) {

	var mask = elem.mask;
	if(mask == null || mask.length == 0  )
	   return true;
	if(mask.toUpperCase()=="INTEGER" ||mask.toUpperCase()=="REAL" || mask.toUpperCase()=="CURRENCY" ) {
	   return doNumericMask(elem,keyCode);
	}
	var val = elem.value;
	var retValue = false;
	
	var maskChar = mask.substr(val.length, 1);
	var nextMaskChar = '';
	if((val.length + 1) <= mask.length) {
	   nextMaskChar = mask.substr(val.length + 1, 1);
	}
	//charCode 57='9' 99='c'
	if ((maskChar.charCodeAt(0) == 57) && (keyCode >= 48) && (keyCode <= 57)) // digit
	   retValue = true;
	else if((maskChar.toLowerCase().charCodeAt(0) == 99) && (((keyCode >= 65) && (keyCode <=90)) || ((keyCode >= 97) && (keyCode <= 122)))) //&& (((keyCode >= 65) && (keyCode <= 90)) || ((keyCode >= 99) && (keyCode <= 122))))
 	   retValue = true;
	else if(maskChar == String.fromCharCode(keyCode)) // special
	   retValue = true;
	else
	   retValue = false;
	if(retValue) {
	   var i=1;
	   var addedKey = false;
	   while(nextMaskChar != '') {
	      if((val.length + i) <= mask.length)
	         nextMaskChar = mask.substr(val.length + i, 1);
	      if(nextMaskChar.toLowerCase() == '9' || nextMaskChar.toLowerCase() == 'c')
	         nextMaskChar = '';
	      var charCode = nextMaskChar.toLowerCase().charCodeAt(0);
	      if((charCode != 57) && ((charCode < 48) || (charCode > 57)) && (charCode != 99)) {
	         if(!addedKey) {
	            elem.value = elem.value + String.fromCharCode(keyCode) + nextMaskChar;
	            addedKey = true;
	         } else
	            elem.value = elem.value + nextMaskChar;
	         retValue = false;
	      }
	      i++;
	   }
	}
	return retValue;
   }


   function doNumericMask(elem,keyCode) {
	if(document.selection != null) {
	   if(document.selection.createRange().text != '')
	      document.selection.clear();
	}
	var mask = elem.mask;
	if(mask == null)
	   return true;
	var decSign = ".";
	var decPlaces =-1;
	var placesBeforeDec = -1;
	var isReal = false;
	if(mask.toUpperCase()=="REAL" || mask.toUpperCase()=="CURRENCY") {
	   isReal=true;
	   decPlaces=2;
	}
	var isPos = true;
	
	if((keyCode >= 48 && keyCode <= 57) ) {
	   if(decPlaces == -1 || isReal == false ) { //INTEGER
	      var tempVal = elem.value;
	      if(tempVal.indexOf('.', 0) == -1) {
	         if(tempVal.length < placesBeforeDec || placesBeforeDec == -1)
	            return true;
	         else
	            return false;
	      } else {
	         return true;
	      }
	   } else {  // REAL
	      var tempVal = elem.value;
	      if(tempVal.indexOf('.', 0) == -1) { // the current input value has no decimal part
	         if(tempVal.length < placesBeforeDec || placesBeforeDec == -1)
	            return true;
	         else
	            return false;
	      } else {
	         if((tempVal.length - tempVal.indexOf(decSign, 0)) <= decPlaces)
	            return true;
	         else
	            return false;
	      }
	   }
	} else if (keyCode == 45 || keyCode == 46 ) {
	   if(keyCode == 45) {  // -
	      var tempVal = elem.value + "-";
	      if(tempVal.indexOf("-") == 0 && tempVal.indexOf("-", 1) == -1) {
	         if(isPos == true)
	            return false;
	         else
	            return true;
	      } else
	         return false;
	   } else if(keyCode == 46 && decSign == "."){ // .
	      var tempVal = elem.value;
	      if(tempVal.indexOf(".", 0) == -1) {
	         if(isReal == true)
	            return true;
	         else
	            return false;
	      } else
	            return false;
	   } else
	      return false;
	} else
	   return false;
   }


   function doFocusMask(elem) {
	if(elem.value !='')
	   return true;
	var i=1;
	var mask = elem.mask;
	if(mask == null)
	   return true;
	var maskChar = mask.substr(0, 1);
	var charCode = maskChar.toLowerCase().charCodeAt(0);
	while((charCode != 57) && ((charCode < 48) || (charCode > 57)) && (charCode != 99)) {
	   elem.value = elem.value + maskChar;
	   maskChar = mask.substr(i, 1);
	   charCode = maskChar.toLowerCase().charCodeAt(0);
	   i++;
	}
	if(elem.createTextRange) {
	   var range = elem.createTextRange();
	   range.moveStart('character', event.srcElement.value.length);
	   range.collapse();
	   range.select();
	}
   }


 /************    help functions  *******/
 
   function reFillMForm(){
	var f =document.forms[0];
	mForm= new Array();
	for(var i=0; i < f.elements.length;i++){
	   var elem=f.elements[i];
	   if(isManagedType(elem.type)){
	      mForm[mForm.length]=elem;
	      if(elem.mask != null && elem.mask.toUpperCase()=="CURRENCY"){
	         elem.onfocus=processFocus;
	         elem.onblur=processBlur;
	      }	      	     
	   }
	} 
   }

  function debug_showform(){
   	var f=mForm;
	var s="";
	for(var i=0; i < f.length;i++){
	   var elem=f[i];
	   s+=elem.name +" type=[" +elem.type +"] value=["+elem.value+"]\n";
	}
	alert (s);  
   }

   function focusFirstInputElement() { 
	var f=mForm;
	var elem=null;
	for(var i=0; i < f.length;i++){
	   elem=f[i];
	   if(elem.type=="text" || elem.type=="textarea" || elem.type=="select-one" ){      
	      break;	
	   }       
	}   
	if(elem !=null) {
	   elem.focus();
	   elem.style.backgroundColor=mStyleBackgroundColor;
	   if(elem.type!="select-one"){
	      elem.select();
	   }
	}	
   }

   function isManagedType(type){
	if(type && (type=="text" || type=="textarea" || type=="select-one" || type=="submit" || type=="button" || type=="reset" || type=="password"    )) {         
	   return true;	
	} else {
	   return false;
	}       
   }

   function isTextBoxType(type){
	if(type && ( type=="text" || type=="textarea"  || type=="password"   )) {         
	   return true;	
	} else {
	   return false;
	}       
   }

   function isButtonType(type){
	if(type && ( type=="submit" || type=="button" || type=="reset"   )) {         
	   return true;	
	} else {
	   return false;
	}       
   }

   function getElementIndex(element){
	var f=mForm;
	var index=0;	
	for(var i=0; i < f.length;i++){
	   var elem=f[i];
	   if(elem.name==element.name && isManagedType(elem.type)) {         
	      index= i;
	      break;	
	   }       
	}   
	return index;
   }

   function getElementIndexByName(element_name){
	var f=mForm;
	var index=0;	
	for(var i=0; i < f.length;i++){
	   var elem=f[i];
	   if(elem.name==element_name && isManagedType(elem.type)) {         
	      index= i;
	      break;	
	   }       
	}   
	return index;
   }

   function canBlur(elem){
	var retValue=true;
	if(elem.type=="textarea"){
	   var re=new RegExp("\n","g");
	   var result = elem.value.match(re);
	   if(result==null) {
	       retValue= false;
	   } else {
	      var rows=(elem.rows) ? elem.rows :  5 ;
	      if(result.length < elem.rows){
	        retValue=false;
	      }
	   }
	}
	return retValue;
   } 

   function emptySelection(){
	if(document.selection != null) {
	   if(document.selection.createRange().text != '')
	      document.selection.empty();
	}
   }

   function setFocusByIndex(index){
	var elem=mForm[index];
	elem.focus();
	elem.style.backgroundColor=mStyleBackgroundColor;
	if(elem.type !="select-one"){ // select does not has select() method
	   elem.select();
	}
   }

   function setFocusByName(elem_name){
	var index=getElementIndexByName(elem_name);
	var elem=mForm[index];
	elem.focus();
	elem.style.backgroundColor=mStyleBackgroundColor;
	if(elem.type !="select-one"){  // select does not has select() method
	   elem.select();
	}
   }

   function unformatCurrency(value) {
	var dollarSign="NT$"; 
	var commaSign=",";
	var currentValue = value;
	var newValue = currentValue;
	while(newValue.indexOf(dollarSign) > -1)
	   newValue = newValue.replace(dollarSign, '');
	while(newValue.indexOf(commaSign) > -1)
	   newValue = newValue.replace(commaSign, '');
	return newValue;
   }

 function formatCurrency(currentValue) {
	var dollarSign="NT$"; 
	var commaSign=",";
	var decimalSign=".";
	var parseValue = '';
	var newValue = '';
	var getDecimal = false;
	var addNegative = false;
	if(currentValue.indexOf(dollarSign) > -1)
	   return;
	if(currentValue.indexOf('-') >= 0) {
	   addNegative = true;
	   currentValue = currentValue.replace('-', '');
	}
	if(currentValue != '' && currentValue.indexOf(decimalSign) > 0) {
	   parseValue = currentValue.substr(0, currentValue.indexOf(decimalSign));
	   getDecimal = true;
	} else {
	   parseValue = currentValue;
	   getDecimal = false;
	}
	var rotations = parseInt(parseValue.length / 3);
	if(parseValue.length % 3 == 0)
	   rotations--;
	for(var i=0; i<rotations; i++)
	   newValue = commaSign + parseValue.substr(parseValue.length - ((i + 1) * 3), 3) + newValue;
	newValue = parseValue.substr(0, parseValue.length - ((rotations) * 3)) + newValue;		
	if(getDecimal)
	   newValue = newValue + currentValue.substr(currentValue.indexOf(decimalSign));
	if(newValue.length > 0) {
	   if(addNegative)
	      newValue = dollarSign + '-' + newValue;
	   else
	      newValue = dollarSign + newValue;
	}
	return newValue;
   }

   function formatCurrencyElement(elem) {
	
	elem.value = formatCurrency(elem.value);
   }

   function unformatCurrencyElement(elem) {
	elem.value = unformatCurrency(elem.value);
	elem.select();
   }

   function formatAllCurrencyElement(){
	var f =mForm;
	for(var i=0; i < f.length;i++){
	   var elem=f[i];
	   if(elem.type=="text" || elem.type=="textarea"){
	       if(elem.mask != null && elem.mask.toUpperCase()=="CURRENCY"){
	          formatCurrencyElement(elem);
	      }
	   }
	} 
   }

    function unformatAllCurrencyElement(){
	   var f=mForm;
	   for(var i=0; i < f.length;i++){
	      var elem=f[i];
	      if(elem.mask && elem.mask.toUpperCase()=="CURRENCY") {         
	         unformatCurrencyElement(elem);	
	      }       
	   } 
   }

   function getFirstSubmitButton() { 
	var f=document.forms[0];	
	for(var i=0; i < f.elements.length;i++){
	   var elem=f.elements[i];
	   if(elem.type=="submit")
	     return elem;    
	}   
   }

   function preparePostBack(eventTarget, eventArgument){
	var theform = document.forms[0];
	if(!theform.__EVENTTARGET){
 	   theform.insertAdjacentHTML("afterBegin","<input name='__EVENTTARGET' type='hidden'>");
	   theform.__EVENTTARGET.value = eventTarget;
	}
	if(!theform.__EVENTARGUMENT){
	   theform.insertAdjacentHTML("afterBegin","<input name='__EVENTARGUMENT' type='hidden'>");
	   theform.__EVENTARGUMENT.value = eventArgument;
	} 
	var f=mForm;
	for(var i=0; i < f.length;i++){
	   var elem=f[i];
	   if(elem.mask && elem.mask.toUpperCase()=="CURRENCY") {         
	      unformatCurrencyElement(elem);	
	   }       
	}  
   }
   function doPostBackCauseValidation(eventTarget, eventArgument) {
	preparePostBack(eventTarget, eventArgument);
	var theform = document.forms[0];
	if(typeof ValidatorOnSubmit !="undefined"){
	   if(ValidatorOnSubmit()){
	      theform.submit();
	   }
	} else {
	   theform.submit();
	}
   }
   function doPostBack(eventTarget, eventArgument) {
	preparePostBack(eventTarget, eventArgument);
	var theform = document.forms[0];
	theform.submit();
   }

