// FILE: validate.js
// AUTHOR: Phan Lu
// MODIFIED BY: Ilan Wapinski, 04-06-2001, Paul Pavlidis 12/02
// CREATE DATE: 04-10-2000
// PROJECT: SVM Server
// DESCRIPTION: Validate the SVM-Server inputs at the client site to filter
//		any bad input before it is passed to the server. If the client
//		uses a browser that does not support JavaScript, or the
//		JavaScript is disabled on the client's browser, runsvm.cgi
//		will verify that the input is consistent.


//if empty parameters are enters, return false
var defaultEmptyOK = false 
var decimalPointDelimiter = "."

function validateForm()
{

  if (!document.form1.usetest.checked && document.form1.trainfile.value == "")
  {
    alert('A training file name is required.');
    document.form1.trainfile.focus();
    document.form1.trainfile.select();
    return false;
  }
  else if (!document.form1.usetest.checked && document.form1.classfile.value == "")
  {
    alert('A classification file name is required.');
    document.form1.classfile.focus();
    document.form1.classfile.select();
    return false;
  }
  else if (!document.form1.usetest.checked && document.form1.testfile.value == "")
  {
    alert('A test file name is required.');
    document.form1.testfile.focus();
    document.form1.testfile.select();
    return false;
  }
  else if (document.form1.adddiag.value != "" )
  {
	if( !isSignedFloat( document.form1.adddiag.value ) )
	{
		alert( "Invalid Input: Non-Numeric entry for adddiag." );
		document.form1.adddiag.focus();
		return false;
	}
  }
  else if (document.form1.constant.value != "" )
  {
	if( !isSignedFloat( document.form1.constant.value ) )
	{
		alert( "Invalid Input: Non-Numeric entry for constant." );
		document.form1.constant.focus();
		return false;
	}
  }
  else if (document.form1.coefficient.value != "" )
  {
	if( !isFloat( document.form1.coefficient.value ) )
	{
		alert( "Invalid Input: Non-Positive Numeric entry for coefficient." );
		document.form1.coefficient.focus();
		return false;
	}
  }
  else if (document.form1.power.value != "" )
  {
	if( !isSignedFloat( document.form1.power.value ))
	{
		alert( "Invalid Input: Non-Numeric entry for power." );
		document.form1.power.focus();
		return false;
	}
  }
  else if (document.form1.radial.checked )
  {
if( document.form1.widthfactor.value == "" )
	{
		reply = prompt( 'Enter a width factor:', '1');
		if( reply == null ){ return false; }
		document.form1.widthfactor.value = reply;
		return isFloat( reply );
	}
  }
  else if (!document.form1.noconstraint.checked )
  {
	if( document.form1.posconstraint.value == "" )
	{
		reply = prompt( 'Enter upper bound:', '1');
		if( reply == null ){ return false; }
		document.form1.posconstraint.value = reply;
		return validateInput( document.form1.posconstraint );
	}
	if( document.form1.negconstraint.value == "" )
	{
		reply = prompt( 'Enter upper bound:', '1');
		if( reply == null ){ return false; }
		document.form1.negconstraint.value = reply;
		return validateInput( document.form1.negconstraint );
	}
  }
  else if ( document.form1.diagfactor.value == "" )
  {
	reply = prompt( 'Enter diagonalization factor:', '0');
	if( reply == null ){ return false; }
	document.form1.diag.value = reply;
	return validateInput( document.form1.diagfactor );
  }
  else if (document.form1.threshold.value < 0.00000000000000015 )
  {
	alert('Threshold too small. Value must be larger than 1.5e-16');
	document.form1.threshold.focus();
	return false;
  }


  return validateFilePath(document.form1.trainfile,
                          document.form1.classfile,
                          document.form1.testfile);

  return false;
}


function validateFilePath(trainset, classset, testset)
{
  var trainpath = false;
  var classpath = false;
  var testpath  = false;
  var trainname = trainset.value;
   var classname = classset.value;
  var testname  = testset.value;

  if ((trainname != "") && (classname != "") && (testname != ""))
  {
    for (i = 0; i < trainname.length; i++)
    {
      if ((trainname.charAt(i) == '\\') || (trainname.charAt(i) == '/'))
      {
        trainpath = true;
        break;
      }
    }

    for (i = 0; i < classname.length; i++)
    {
      if ((classname.charAt(i) == '\\') || (classname.charAt(i) == '/'))
      {
        classpath = true;
        break;
      }
    }

    for (i = 0; i < testname.length; i++)
    {
      if ((testname.charAt(i) == '\\') || (testname.charAt(i) == '/'))
      {
        testpath = true;
        break;
      }
    }

  }

  return true;
}



// 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

function isSignedInteger (s)
{

   if (isEmpty(s)) 
   {

	return false;

   } else {

        var startPos = 0;

        // skip leading + or -
        if ( (s.charAt(0) == "-") || (s.charAt(0) == "+") )
           startPos = 1;    
        return (isInteger(s.substring(startPos, s.length)));
    }
}

// Returns true if character c is a digit 
// (0 .. 9).

function isDigit (c)
{   return ((c >= "0") && (c <= "9"))
}


// Check whether string s is empty.

function isEmpty(s)
{  return ((s == null) || (s.length == 0))
}

// isInteger (STRING s [, BOOLEAN emptyOK])
// 
// Returns true if all characters in string s are numbers.
//
// Accepts non-signed integers only. Does not accept floating 
// point, exponential notation, etc.
//
// We don't use parseInt because that would accept a string
// with trailing non-numeric characters.
//
// By default, returns defaultEmptyOK if s is empty.
// There is an optional second argument called emptyOK.
// emptyOK is used to override for a single function call
//      the default behavior which is specified globally by
//      defaultEmptyOK.
// If emptyOK is false (or any value other than true), 
//      the function will return false if s is empty.
// If emptyOK is true, the function will return true if s is empty.
//
// EXAMPLE FUNCTION CALL:     RESULT:
// isInteger ("5")            true 
// isInteger ("")             defaultEmptyOK
// isInteger ("-5")           false

function isInteger (s)
{   var i;

    if (isEmpty(s)) 

	return false;

    // Search through string's characters one by one
    // until we find a non-numeric character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is number.
        var c = s.charAt(i);

        if (!isDigit(c)) return false;
    }

    // All characters are numbers.
    return true;
}


// isSignedFloat (STRING s [, BOOLEAN emptyOK])
// 
// True if string s is a signed or unsigned floating point 
// (real) number. First character is allowed to be + or -.
//
// Also returns true for unsigned integers. If you wish
// to distinguish between integers and floating point numbers,
// first call isSignedInteger, then call isSignedFloat.
//
// Does not accept exponential notation.
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.

function isSignedFloat (s)

{   if (isEmpty(s)) { return false; }
//       if (isSignedFloat.arguments.length == 1) return defaultEmptyOK;
//       else return (isSignedFloat.arguments[1] == true);

    else {
        var startPos = 0;
        var secondArg = defaultEmptyOK;

        if (isSignedFloat.arguments.length > 1)
            secondArg = isSignedFloat.arguments[1];

        // skip leading + or -
        if ( (s.charAt(0) == "-") || (s.charAt(0) == "+") )
           startPos = 1;    
        return (isFloat(s.substring(startPos, s.length), secondArg))
    }
}



// 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)

{   var i;
    var seenDecimalPoint = false;

    if (isEmpty(s)) { return false; }
//       if (isFloat.arguments.length == 1) return defaultEmptyOK;
//       else return (isFloat.arguments[1] == true);

    if (s == decimalPointDelimiter) return false;

    // Search through string's characters one by one
    // until we find a non-numeric character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is number.
        var c = s.charAt(i);

        if ((c == decimalPointDelimiter) && !seenDecimalPoint) seenDecimalPoint = true;
        else if (!isDigit(c)) return false;
    }

    // All characters are numbers.
    return true;
}


function disableFields()
{
	//document.form1.posconstraint.disabled = 1;
	//document.form1.negconstraint.disabled = 1;
	document.form1.widthfactor.disabled = 1;
}

function enableConstraintFields()
{
	if( document.form1.posconstraint.disabled )
	{
		document.form1.posconstraint.disabled = 0;
		document.form1.negconstraint.disabled = 0;
		validateInput( document.form1.posconstraint );
		validateInput( document.form1.negconstraint );
	} else {
		document.form1.posconstraint.disabled = 1;
		document.form1.negconstraint.disabled = 1;
	}
}

function enableWidth( radial )
{
	if( document.form1.widthfactor.disabled )
	{
		document.form1.widthfactor.disabled = 0;
		if( document.form1.widthfactor.value == "" )
		{
			alert( "Please specify a width factor (default = 1)" );
			radial.blur();
			document.form1.widthfactor.focus();
		}
		validateInput( document.form1.widthfactor );
	} else {
		document.form1.widthfactor.disabled = 1;
	}
}

function validateInput( inputfield )
{
	if( inputfield.name == "widthfactor" && !document.form1.radial.checked )
	{
		inputfield.blur();
		return;
	}
	if( inputfield.name == "posconstraint" 
		&& document.form1.noconstraint.checked )
	{
		inputfield.blur();
		return;
	}
	if( inputfield.name == "negconstraint" 
		&& document.form1.noconstraint.checked )
	{
		inputfield.blur();
		return;
	}
	if( !isSignedFloat( inputfield.value ) )
	{
	    alert( "Numeric input required" );
	    //inputfield.blur();
	    inputfield.focus();
	}

}
