var defaultEmptyOK = false;
var reInteger = /^\d+$/
var reSignedInteger = /^('+'|'-')?\d+$/
var reEmail = /^.+\@.+\..+$/
var reFloat = /^((\d+(\.\d*)?)|((\d*\.)?\d+))$/

// Check whether string s is empty.

function isEmpty(s)
{   return ((s == null) || (s.length == 0))
}

function isEmail (s){
   if (isEmpty(s)) 
       if (isEmail.arguments.length == 1) return defaultEmptyOK;
       else return (isEmail.arguments[1] == true);
    
    else {
       return reEmail.test(s)
    }
}


// isFloat (STRING s [, BOOLEAN emptyOK])
// 
// True if string s is an unsigned floating point (real) number. 
//
// Also returns true for unsigned integers. If you wish
// to distinguish between integers and floating point numbers,
// first call isInteger, then call isFloat.
//
// Does not accept exponential notation.
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.

function isFloat (s)

{   if (isEmpty(s)) 
       if (isFloat.arguments.length == 1) return defaultEmptyOK;
       else return (isFloat.arguments[1] == true);

    return reFloat.test(s)
}


// isSignedInteger (STRING s [, BOOLEAN emptyOK])
// 
// Returns true if all characters are numbers; 
// first character is allowed to be + or - as well.
//
// Does not accept floating point, exponential notation, etc.
//
// We don't use parseInt because that would accept a string
// with trailing non-numeric characters.
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.
//
// EXAMPLE FUNCTION CALL:          RESULT:
// isSignedInteger ("5")           true 
// isSignedInteger ("")            defaultEmptyOK
// isSignedInteger ("-5")          true
// isSignedInteger ("+5")          true
// isSignedInteger ("", false)     false
// isSignedInteger ("", true)      true

function isSignedInteger (s)

{   if (isEmpty(s)) 
       if (isSignedInteger.arguments.length == 1) return defaultEmptyOK;
       else return (isSignedInteger.arguments[1] == true);

    else {
       return reSignedInteger.test(s)
    }
}


// isNonnegativeInteger (STRING s [, BOOLEAN emptyOK])
// 
// Returns true if string s is an integer >= 0.
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.

function isNonnegativeInteger (s)
{   var secondArg = defaultEmptyOK;

    if (isNonnegativeInteger.arguments.length > 1)
        secondArg = isNonnegativeInteger.arguments[1];

    // The next line is a bit byzantine.  What it means is:
    // a) s must be a signed integer, AND
    // b) one of the following must be true:
    //    i)  s is empty and we are supposed to return true for
    //        empty strings
    //    ii) this is a number >= 0

    return (isSignedInteger(s, secondArg)
         && ( (isEmpty(s) && secondArg)  || (parseInt (s) >= 0) ) );
}

function makeArray(n) {
//*** BUG: If I put this line in, I get two error messages:
//(1) Window.length can't be set by assignment
//(2) daysInMonth has no property indexed by 4
//If I leave it out, the code works fine.
//   this.length = n;
   for (var i = 1; i <= n; i++) {
      this[i] = 0
   } 
   return this
}

var daysInMonth = makeArray(12);
daysInMonth[1] = 31;
daysInMonth[2] = 29;   // must programmatically check this
daysInMonth[3] = 31;
daysInMonth[4] = 30;
daysInMonth[5] = 31;
daysInMonth[6] = 30;
daysInMonth[7] = 31;
daysInMonth[8] = 31;
daysInMonth[9] = 30;
daysInMonth[10] = 31;
daysInMonth[11] = 30;
daysInMonth[12] = 31;

// Array Extensions  v1.0
// http://www.dithered.com/javascript/array/index.html
// code by Chris Nott (chris@dithered.com)


// Join two arrays
function _Array_concat(secondArray) {
	var firstArray = this.copy();
	for (var i = 0; i < secondArray.length; i++) {
		firstArray[firstArray.length] = secondArray[i];
	}
	return firstArray;
}


// Copy an array
function _Array_copy() {
	var copy = new Array();
	for (var i = 0; i < this.length; i++) {
		copy[i] = this[i];
	}
	return copy;
}


// Remove the last element of an array and return it
function _Array_pop() {
	var lastItem = this[this.length - 1];
	this.length--;
	return lastItem;
}


// Add an element to the end of an array
function _Array_push() {
	var currentLength = this.length;
	for (var i = 0; i < arguments.length; i++) {
		this[currentLength + i] = arguments[i];
	}
	return arguments[arguments.length - 1];
}


// Remove the first element of an array and return it
function _Array_shift() {
	var firstItem = this[0];
	for (var i = 0; i < this.length - 1; i++) {
		this[i] = this[i + 1];
	}
	this.length--;
	return firstItem;
}


// Copy several elements of an array and return them
function _Array_slice(start, end) {
	var temp;
	
	if (end == null || end == '') end = this.length;
	
	// negative arguments measure from the end of the array
	else if (end < 0) end = this.length + end;
	if (start < 0) start = this.length + start;
	
	// swap limits if they are backwards
	if (end < start) {
		temp  = end;
		end   = start;
		start = temp;
	}
	
	// copy elements from array to a new array and return the new array
	var newArray = new Array();
	for (var i = 0; i < end - start; i++) {
		newArray[i] = this[start + i];
	}
	return newArray;
}


// Splice out and / or replace several elements of an array and return any deleted elements
function _Array_splice(start, deleteCount) {
	if (deleteCount == null || deleteCount == '') deleteCount = this.length - start;
	
	// create a temporary copy of the array
	var tempArray = this.copy();
	
	// Copy new elements into array (over-writing old entries)
	for (var i = start; i < start + arguments.length - 2; i++) {
		this[i] = arguments[i - start + 2];
	}
	
	// Copy old entries after the end of the splice back into array and return
	for (var i = start + arguments.length - 2; i < this.length - deleteCount + arguments.length - 2; i++) {
		this[i] = tempArray[i + deleteCount - arguments.length + 2];
	}
	this.length = this.length - deleteCount + (arguments.length - 2);
	return tempArray.slice(start, start + deleteCount);
}


// Add an element to the beginning of an array
function _Array_unshift(the_item) {
	for (loop = this.length-1 ; loop >= 0; loop--) {
		this[loop+1] = this[loop];
	}
	this[0] = the_item;
	return this.length;
}


// For those browsers that don't define these Array methods, make functions Array instance methods
var agent = navigator.userAgent.toLowerCase(); 

   if (Array && !((agent.indexOf('mozilla')!=-1) && (agent.indexOf('spoofer')==-1) && (agent.indexOf('compatible') == -1) && (agent.indexOf('opera')==-1) && (agent.indexOf('webtv')==-1) && parseInt(navigator.appVersion) > 4)) {
      if((agent.indexOf("msie") != -1) || (agent.indexOf('spoofer')!=-1) || (agent.indexOf('compatible') != -1) || (agent.indexOf('opera')!=-1) || (agent.indexOf('webtv')!=-1)){
	Array.prototype.pop     = _Array_pop;
	Array.prototype.push    = _Array_push;
	Array.prototype.shift   = _Array_shift;
	Array.prototype.splice  = _Array_splice;
	Array.prototype.unshift = _Array_unshift;
   }
	
   if (agent.indexOf("msie") != -1 && parseInt(navigator.appVersion) < 4) {
	Array.prototype.concat = _Array_concat;
	Array.prototype.slice  = _Array_slice;
   }
}
Array.prototype.copy = _Array_copy;


// _____________________________________________________________

function trim(field){
   if(field.value == "") return
   var fieldIndex=field.value.length;
   while(fieldIndex>0){
      if(field.value.charAt(fieldIndex - 1) == " "){
         field.value = field.value.substr(0,fieldIndex-1);
      }else{
         fieldIndex --;
         break;
      }
      fieldIndex --;
   }
   while(field.value.length>0){
      if(field.value.charAt(0) == " "){
         field.value = field.value.substr(1,field.value.length -1);
      }else{
         break;
      }
   }
   ini = 0;
   tmp_field = field.value;
   prefix = "";
   while( (last = tmp_field.indexOf('"',ini)) >= 0){
      prefix += tmp_field.substr(ini,last) + "\u201D";
      tmp_field = tmp_field.substr(last+1);
   }
   prefix += tmp_field;
   field.value = prefix;
}


function fields_not_null(form){
/*
This function requires the array "no_empty_fields" declared as follows:
var no_empty_fields = {
                     "0": {name:"field1",label: "Field One"},
                     "1": {name:"field2",label: "Field Two"},
                     "2": {name:"field3",label: "Field Three"},
                     "3": {name:"field4",label: "Field Four"}
                  };
This function returns a true value if all fields in the above array are filled.
If there are some fileds not filled then a message is inssued and the
funtion returns a false value.
*/
   var ECS_NOEMPTY_LST = new Array();

   var cont = 0;
   var cad_err = "";

   while(no_empty_fields[cont]){
      if(form[no_empty_fields[cont].name].value==""){
         pushed = ECS_NOEMPTY_LST.push(cont);
      }
      cont++;
   }
   if (ECS_NOEMPTY_LST.length !=0){
      if(ECS_NOEMPTY_LST.length == 1){
         num_field = ECS_NOEMPTY_LST.pop();
         alert("El campo \""+no_empty_fields[num_field].label+"\" debe ser llenado.");
         form[no_empty_fields[num_field].name].focus();
         return false;
      }else{
         while(ECS_NOEMPTY_LST.length>0){
            num_field = ECS_NOEMPTY_LST.pop();
            cad_err = "              "+no_empty_fields[num_field].label+"\n"+cad_err;
            first_field = num_field;
         }
         alert("Los siguientes campos deben ser llenados:\n"+cad_err);
         form[no_empty_fields[first_field].name].focus();
         return false;
      }
   }

   return true;
}

// Verifica que una cadena tenga solo numeros
function isNumeric(string, ignoreWhiteSpace) {
	if (string.search) {
		if ((ignoreWhiteSpace && string.search(/[^\d\s]/) != -1) || (!ignoreWhiteSpace && string.search(/\D/) != -1)) return false;
	}
	return true;
}


// isYear (STRING s [, BOOLEAN emptyOK])
// 
// isYear returns true if string s is a valid 
// Year number.  Must be 2 or 4 digits only.
// 
// For Year 2000 compliance, you are advised
// to use 4-digit year numbers everywhere.
//
// And yes, this function is not Year 10000 compliant, but 
// because I am giving you 8003 years of advance notice,
// I don't feel very guilty about this ...
//
// For B.C. compliance, write your own function. ;->
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.

function isYear (s)
{   if (isEmpty(s)) 
       if (isYear.arguments.length == 1) return defaultEmptyOK;
       else return (isYear.arguments[1] == true);
    if (!isNonnegativeInteger(s)) return false;
    return ((s.length == 2) || (s.length == 4));
}

function isInteger (s)

{   var i;

    if (isEmpty(s)) 
       if (isInteger.arguments.length == 1) return defaultEmptyOK;
       else return (isInteger.arguments[1] == true);

    return reInteger.test(s)
}

// isIntegerInRange (STRING s, INTEGER a, INTEGER b [, BOOLEAN emptyOK])
// 
// isIntegerInRange returns true if string s is an integer 
// within the range of integer arguments a and b, inclusive.
// 
// For explanation of optional argument emptyOK,
// see comments of function isInteger.


function isIntegerInRange (s, a, b)
{   if (isEmpty(s)) 
       if (isIntegerInRange.arguments.length == 1) return defaultEmptyOK;
       else return (isIntegerInRange.arguments[1] == true);

    // Catch non-integer strings to avoid creating a NaN below,
    // which isn't available on JavaScript 1.0 for Windows.
    if (!isInteger(s, false)) return false;

    // Now, explicitly change the type to integer via parseInt
    // so that the comparison code below will work both on 
    // JavaScript 1.2 (which typechecks in equality comparisons)
    // and JavaScript 1.1 and before (which doesn't).
    var num = parseInt (s);
    return ((num >= a) && (num <= b));
}


// isMonth (STRING s [, BOOLEAN emptyOK])
// 
// isMonth returns true if string s is a valid 
// month number between 1 and 12.
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.

function isMonth (s)
{   if (isEmpty(s)) 
       if (isMonth.arguments.length == 1) return defaultEmptyOK;
       else return (isMonth.arguments[1] == true);
    return isIntegerInRange (s, 1, 12);
}



// isDay (STRING s [, BOOLEAN emptyOK])
// 
// isDay returns true if string s is a valid 
// day number between 1 and 31.
// 
// For explanation of optional argument emptyOK,
// see comments of function isInteger.

function isDay (s)
{   if (isEmpty(s)) 
       if (isDay.arguments.length == 1) return defaultEmptyOK;
       else return (isDay.arguments[1] == true);   
    return isIntegerInRange (s, 1, 31);
}

// daysInFebruary (INTEGER year)
// 
// Given integer argument year,
// returns number of days in February of that year.

function daysInFebruary (year)
{   // February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (  ((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0) ) ) ? 29 : 28 );
}

// isDate (STRING year, STRING month, STRING day)
//
// isDate returns true if string arguments year, month, and day 
// form a valid date.
// 

function isDate (year, month, day)
{   // catch invalid years (not 2- or 4-digit) and invalid months and days.
    if (! (isYear(year, false) && isMonth(month, false) && isDay(day, false))) return false;

    // Explicitly change type to integer to make code work in both
    // JavaScript 1.1 and JavaScript 1.2.
    var intYear = parseInt(year);
    var intMonth = parseInt(month);
    var intDay = parseInt(day);

    // catch invalid days, except for February
    if (intDay > daysInMonth[intMonth]) return false; 

    if ((intMonth == 2) && (intDay > daysInFebruary(intYear))) return false;

    return true;
}


function ValIntField(campo,zero){
   trim(campo);
   var tmpEval= campo.value;
   var result = true;
   if (tmpEval.search) {
      if (tmpEval.search(/\D/) != -1){
         alert('Favor de ingresar sólo números en este campo.');
         result = false;
      }else{
         tmpEval = eval(tmpEval);
         if (tmpEval==0 & !zero) {
            alert('La cantidad no puede ser igual a cero.');
            result = false;
         }
      }
   }

   if(!result){
      campo.value="";
      campo.focus();
   }
   return result;
}

