/* Filename:		main.js
 * Author:		Adam Isom
 * Last Modification:	June 12, 2005
 *
 * The JavaScript supporting the index pages.  It validates the
 *   user's email and ensures that the chain fields have an
 *   appropriate value.
 */


rcsbID = 'rcsb';
rcsbErrID = 'rcsbErr';
localsID = 'local';
localsErr = 'localsErr';


function fileBasename(path)
{
  // for windows file path look for '\'; if not found, 
  // assume unix path, look for '/'
  var slash = path.lastIndexOf('\\');
  if (slash == -1) {
    slash = path.lastIndexOf('/');
  }			   
  if (slash != -1) {
    var name = path.substring(slash+1);
    return name;
  }
  return path;
}

function guessPdb(index)
{
    var fileId = fileManager.getFileID(index);
    var filename = fileBasename(document.getElementById(fileId).value);

    var re1 = /.*[a-zA-Z0-9]{4}\.pdb$/;          // ends in XXXX.pdb
    var re2 = /.*pdb[a-zA-Z0-9]{4}\.ent$/;       // ends in pdbXXXX.ent

    var pdb = "";
    if (re1.test(filename)) {
        pdb = filename.slice(filename.length - "XXXX.pdb".length,
                             filename.length - ".pdb".length);
    }
    else if (re2.test(filename)) {
        pdb = filename.slice(filename.length - "XXXX.ent".length,
                             filename.length - ".ent".length);
    }
    
    var pdbId = fileManager.getPdbID(index);
    document.getElementById(pdbId).value = pdb;
    return showPdbChangeError(index);
}    


function validEmail(email) 
{
    /* regular expression to validate email format */
    var emailFilter=/^.+@.+\..{2,4}$/;
    
    /* list of illegal characters */
    var illegalChars= /[\(\)\<\>\,\;\:\\\/\"\[\]\*]/

    if (!(emailFilter.test (email))) {
	return false;
    }
    else if (email.match (illegalChars)) {
        return false;
    }

    return true;
}

function showEmailError(email) 
{
    var emailErr = document.getElementById('emailErr');
    if (!validEmail(email) != "") {
        emailErr.innerHTML = "!!!";
	return true;
    }
    else {
        emailErr.innerHTML = "";
	return false;
    }
}


function showEntriesError(entriesId, errId) 
{
    var entries = getEntries(entriesId);
    var err = document.getElementById(errId);
    if (!checkEntries(entries)) {
        err.innerHTML = "!!!";
	return true;
    }
    else {
        err.innerHTML = "";
	return false;
    }
}

function checkEntries(entries) 
{
    for(var i = 0; i < entries.length; ++i) {
        if( !checkSingleEntry(entries[i]) ) {
	    return false;
	}
    }
    return true;
}

function checkSingleEntry(entry) 
{
    entry = entry.toUpperCase();

//     var re1 = /^[A-Z0-9]{4}:[_A-Z0-9]$/;
//     var re2 = /^[A-Z0-9]{4}:[_A-Z0-9]:\d+$/;
//     var re3 = /^[A-Z0-9]{4}:[_A-Z0-9]:\d+:[_A-Z0-9]:\d+$/;

    var re1 = /^[A-Z0-9]{4}$/;
    var re2 = /^[A-Z0-9]{4}:[_A-Z0-9]$/;
    var re3 = /^[A-Z0-9]{4}:[_A-Z0-9]:-?\d{1,4}$/;
    var re4 = /^[A-Z0-9]{4}:[_A-Z0-9]:-?\d{1,4}:[_A-Z0-9]:-?\d{1,4}$/;
    
    if ( re1.test(entry) || 
	 re2.test(entry) || 
	 re3.test(entry) || 
	 re4.test(entry) ) {
        return true;
    }
    else {
        return false;
    }
}

function showPdbChangeError(index) 
{
    var pdbId = fileManager.getPdbID(index);
    var errId = fileManager.getErrID(index);

    var pdb = document.getElementById(pdbId).value.toUpperCase();
    var err = document.getElementById(errId);	

    if ( !isEmpty(pdb) && !checkPdbID(pdb) ) {
       err.innerHTML = "invalid!!!";
       return true;
    }
    else if (isEmpty(pdb)) {
       err.innerHTML = "";
       return false;
    }
    else if (showDuplicatePDBError()) {
      return true;
    }
    else {
      err.innerHTML = "";
      return false;
    }
}

function checkPdbID(pdb) 
{
    pdb = pdb.toUpperCase();

    var re = /^[A-Z0-9]{4}$/;
    return re.test(pdb);
}

function isEmpty(field) 
{
    var re = /^\s*$/;         // is all white space
    return re.test(field);
}

function showFileUploadError()
{
  var error = false;
  for(var i = 0; i < fileManager.getCount(); ++i) {
      if (!checkFileUpload(i)) {
	  error = true;
      }
  }
  return error;
}

function checkFileUpload(count)
{
    var fileId = fileManager.getFileID(count);
    var pdbId = fileManager.getPdbID(count);
    var errId = fileManager.getErrID(count);
    
    var file = document.getElementById(fileId).value.toUpperCase();
    var pdb = document.getElementById(pdbId).value.toUpperCase();
    var err = document.getElementById(errId);	
    
    if ( isEmpty(file) && 
	 isEmpty(pdb) ) {
      err.innerHTML = "";
      return true;
    }
    else if ( !checkPdbID(pdb) ) {
      err.innerHTML = "invalid!!!";
      return false;
    }
    else if ( isEmpty(file) ) {
      err.innerHTML = "no file!!!";
      return false;
    }
    else {
      err.innerHTML = "";
      return true;
    }
}
                            
function getEntries(entriesId)
{
  var pdbs = document.getElementById(entriesId).value;
  if (isEmpty(pdbs)) {
     return new Array();
  }
  pdbs = pdbs.match(/\S+/g);
  for (var i = 0; i < pdbs.length; ++i) {
    pdbs[i] = pdbs[i].toUpperCase();
  }

  return pdbs;
}


function getLocalFilesPDBs()
{
  var emptyRe = /^\s*$/;

  var pdbsList = new Array();
  for(var i = 0; i < fileManager.getCount(); ++i) {
    var fileId = fileManager.getFileID(i); 
    var pdbId = fileManager.getPdbID(i); 
    
    var filename = document.getElementById(fileId).value;
    var pdb = document.getElementById(pdbId).value;

    if ( !isEmpty(filename) &&
         !isEmpty(pdb) )
    {
       pdbsList.push(pdb.toUpperCase());
    }
  }
  
  return pdbsList;
}


function showMismatchError()
{
    var err = document.getElementById(localsErr);
    if (hasMismatch()) {
        err.innerHTML = "";
	return false;
    }
    else {
        err.innerHTML = "!!!";
	return true;
    }
}

function hasMismatch()
{
    pdbs = getLocalFilesPDBs();
    entries = getEntries(localsID);

    for (var i = 0; i < entries.length; ++i) {
       var match = false;
       for (var j = 0; j < pdbs.length && !match; ++j) {
           if (entries[i].indexOf(pdbs[j]) == 0) {
	       match = true;
	   }
       }
       if (!match) {
	   return false;
       }
    }
    return true;
}


function showDuplicateEntriesError()
{
  var rcsbList = getEntries(rcsbID);
  if (hasDuplicates(rcsbList)) {
    alert("Duplicates found in 'RCSB PDB Entries' field!");
    return true;
  }

  var localsList = getEntries(localsID);
  if (hasDuplicates(localsList)) {
    alert("Duplicates found in 'Locals Entries' field!");
    return true;
  }
  
  return false;
}

function hasDuplicates(list)
{
  // make a copy of the list; sort; check for same neighbors
  list = list.slice(0);
  list.sort();
  for (var i = 0; i < list.length-1; ++i) {
    if (list[i] == list[i+1]) {
      return true;
    }
  }
  return false;
}

function checkDuplicatePDB(index) 
{
    var dup = false;
    var pdb1 = document.getElementById(fileManager.getPdbID(index));
    var err1 = document.getElementById(fileManager.getErrID(index));
    if (isEmpty(pdb1.value)) {
       return false;
    }
    for (var i = 0; i < fileManager.getCount(); ++i) {
        var pdb2 = document.getElementById(fileManager.getPdbID(i));
        var err2 = document.getElementById(fileManager.getErrID(i));
        if (index != i && pdb1.value.toUpperCase() == pdb2.value.toUpperCase()) {
            err1.innerHTML = "duplicate!!!";
            err2.innerHTML = "duplicate!!!";
            dup = true;
        }
    }
    if (!dup) {
        err1.innerHTML = "";
    }
    return dup;
}

function showDuplicatePDBError() 
{
    var dup = false;
    for (var i = 0; i < fileManager.getCount(); ++i) {
        if (checkDuplicatePDB(i)) {
            dup = true;
        }
    }
    return dup;
}


function countSubmitted()
{
  var len1 = getEntries(rcsbID).length;
  var len2 = getEntries(localsID).length;

  return len1 + len2;
}


function checkForm()
{
//   var email = document.getElementById('email');
//   if (showEmailError(email.value)) {
//     alert("Please provide a valid email address!");
//     return false;	
//   }

  if (showEntriesError(rcsbID, rcsbErrID)) {
    alert("Found incorrectly formatted entries in the 'RCSB PDB Entries' field!");
    return false;
  }

  if (showEntriesError(localsID, localsErr)) {
    alert("Found incorrectly formatted entries in the 'Local Files Entries' field!");
    return false;
  }

  if (showDuplicateEntriesError()) {
    return false;
  }

  if (document.getElementById('multifileRadio').checked) {
      if (showFileUploadError()) {
          alert("There are errors in the 'Local Files' section!");
          return false;
      }


      if (showDuplicatePDBError()) {
          alert("Found duplicate PDB IDs in 'PDB ID' fields!");
	  return false;
      }

      if (showMismatchError()) {
	alert("Some entries in the 'Local Files Entries' field \n do not correspond to uploaded proteins!");
	return false;
      }
  }

  if (document.getElementById('archiveRadio').checked) {
     if ( !isEmpty(document.getElementById('archive').value) &&
          isEmpty(document.getElementById(localsID).value) ) {
       alert("Please provide at least one entry in the 'Local Files Field'!");
       return false;
     }
     else if ( isEmpty(document.getElementById('archive').value) &&
               !isEmpty(document.getElementById(localsID).value) ) {
       alert("Please upload a zip archive in the 'Local Archive' field!");
       return false;
     }

  }

  if (countSubmitted() < 2) {
    alert(" \
     Please provide a total of at least two entries \n \
in the 'RCSB PDB Entires' and 'Local Files Entries' fields!");
    return false;
  }

  return true;
}

