var modifierSuffix = 'Modifier';
var noFieldPrefix = 'noField-';
var AND_MODIFIER = '+';
var NOT_MODIFIER = '-';
var OR_MODIFIER  = ' ';

var NO_MODIFIER = 0;
var DEFAULT_TERM_MODIFIER = AND_MODIFIER;
var DEFAULT_GROUP_MODIFIER = AND_MODIFIER;
var VALUE_DELIMITER = ' ';

function doMakeQuery( query, dbg )
{
    
  var frm = query.form;
  var formElements = frm.elements;
  query.value = '';
  
  // keep track of the fields we've examined
  var dict = new Array();
  
  for(var i=0; i<formElements.length; i++)
  {
    var element = formElements[i];
    var elementName = element.name;
    if(elementName != "" && !contains(dict, elementName))
    {
      dict[dict.length] = elementName;
      
      // ensure we get the whole group (of checkboxes, radio, etc), if applicable
      var elementValue = getFieldValue(frm[element.name]);
      if(elementValue.length > 0)
      {
        var subElement = frm[elementName + modifierSuffix];
        if(typeof(subElement) != "undefined") // found a field/fieldModifier pair
        {
          var termMod, groupMod;
          var modifier = getFieldValue(subElement);
          // modifier field is in the form <termModifier>|<groupModifier>
          if(modifier.indexOf('|') > -1)
          {
            var idx = modifier.indexOf('|');
            termMod = modifier.substring(0, idx);
            if(termMod == '') termMod = DEFAULT_TERM_MODIFIER;
            groupMod = modifier.substring(idx + 1);
            if(groupMod == '') groupMod = DEFAULT_GROUP_MODIFIER;
          }
          else
          {
            termMod = modifier;
            if(termMod == '') termMod = DEFAULT_TERM_MODIFIER;
            groupMod = DEFAULT_GROUP_MODIFIER;
          }
          appendTerms(query, termMod, elementValue, elementName, groupMod);
        }
      }
    }
  }
 
    return query;
}

// Constructs a Google-like query (all terms are ANDed)
// @param query Form field to represent the constructed query to be submitted
// @return Submits the form if submitOnConstruction=true, else returns the query param
function doANDTerms(query)
{
  var value = query.value;
  query.value = "";
  appendTerms(query, AND_MODIFIER,  value);
  if(submitForm)
  {
    frm.submit();
  }
  else
  {
    return query;
  }
}

function buildTerms(termModifier, fieldValue)
{
  fieldValue = trim(fieldValue);
  var splitStr = fieldValue.split(" ");
  fieldValue = '';
  var inQuotes = false;
  for(var i=0;i<splitStr.length;i++)
  {
    if(splitStr[i].length > 0)
    {
      if(!inQuotes)
      {
        if (termModifier == AND_MODIFIER) {
            fieldValue = fieldValue +  splitStr[i] + ' ';
	  } else {
	    fieldValue = fieldValue + termModifier + splitStr[i] + ' ';
	  }
      }
      else
      { 
        fieldValue = fieldValue + splitStr[i] + ' ';
      }      
      if(splitStr[i].indexOf('"') > -1) inQuotes = !inQuotes
    }
  }
  fieldValue = trim(fieldValue);  
  return fieldValue;
}

// Appends terms to a query. 
// @param query Form field of query
// @param termModifier Term modifier
// @param value Value to be appended. Tokenized by spaces, 
//    and termModifier will be applied to each token.
// @param fieldName Name of search field. Omit if not a field-specific query.
// @param groupModifier Modifier applied to each group of terms.
// @return query form field
function appendTerms(query, termModifier, value, fieldName, groupModifier)
{
  if(typeof(groupModifier) == "undefined")
    groupModifier = DEFAULT_GROUP_MODIFIER;

  value = buildTerms(termModifier, value);
  // not a field-specific search
  if(fieldName == null || fieldName.indexOf(noFieldPrefix) != -1 || fieldName.length == 0)
  {
    if(groupModifier == NO_MODIFIER)
    {
      if(query.value.length == 0)
      {
        query.value = value;
      }
      else
      {
        query.value = query.value + ' ' + value;
      }  
    }
    else
    { 
      if(query.value.length == 0)
      {
        //query.value = groupModifier + '(' + value + ')';
        query.value = value;

      }
      else
      {
//        query.value = query.value + ' ' + groupModifier + '(' + value + ')';
        query.value = query.value + ' ' + value;

      }  
    }
  }
  else
  {
   if(groupModifier == NO_MODIFIER) groupModifier = ''
    if(query.value.length == 0)
    {
      query.value = groupModifier + fieldName + ':(' + value + ')';
    }
    else
    {
      query.value = query.value + ' ' + groupModifier +fieldName + ':(' + value + ')';
    }  
  }
  query.value = trim(query.value)
  return query;
}

// Obtain the value of a form field.
// @param field Form field
// @return Array of values, or string value depending on field type, 
//    or empty string if field param is undefined or null
function getFieldValue(field)
{
  if(field == null || typeof(field) == "undefined")
    return "";
  if(typeof(field) != "undefined" && typeof(field[0]) != "undefined" && field[0].type=="checkbox")
    return getCheckedValues(field);
  if(typeof(field) != "undefined" && typeof(field[0]) != "undefined" && field[0].type=="radio")
    return getRadioValue(field);
  if(typeof(field) != "undefined" && field.type.match("select*")) 
    return getSelectedValues(field);
  if(typeof(field) != "undefined")
    return field.value;
}


function getSelectedValues (select) {
  var r = new Array();
  for (var i = 0; i < select.options.length; i++)
    if (select.options[i].selected)
    {
      r[r.length] = select.options[i].value;
    }
  return r.join(VALUE_DELIMITER);
}

function quote(value)
{
  return "\"" + trim(value) + "\"";
}

function contains(array, s)
{
  for(var i=0; i<array.length; i++)
  {
    if(s == array[i])
      return true;
  }
  return false;
}

function trim(inputString) {
   if (typeof inputString != "string") { return inputString; }
   
   var temp = inputString;
   
   // Replace whitespace with a single space
   var pattern = /\s+/ig;
   temp = temp.replace(pattern, " ");
  
   // Trim 
   pattern = /^(\s*)([\w\W]*)(\b\s*$)/;
   if (pattern.test(temp)) { temp = temp.replace(pattern, "$2"); }
   // run it another time through for words which don't end with a character or a digit
   pattern = /^(\s*)([\w\W]*)(\s*$)/;
   if (pattern.test(temp)) { temp = temp.replace(pattern, "$2"); }
   return temp; // Return the trimmed string back to the user
}

function parseQueryString(query) {

and = '';
not = '';
exact = '';
site = '';

currentModifer = DEFAULT_TERM_MODIFIER;
inQuote = false;
fieldName = '';
for (i = 0; i < query.length; i++) {

    if ((query[i].indexOf(AND_MODIFIER) > -1 || 
       query[i].indexOf(NOT_MODIFIER) > -1) && !inQuote && query[i - 1].indexOf(VALUE_DELIMITER) > -1) {
       currentModifer = query[i];
       fieldName = '';
       continue;
    }

    if (query[i].indexOf('"') > -1) {
        fieldName = '';
	if (checkCloseQuote(query, i+1) || inQuote) {
    	    inQuote = !inQuote;
    	    if (exact[exact.length-1] != ' ') {
    		exact = exact + ' ';
    	    }
    	    continue;
    	}
    }

    if (query[i].indexOf(' ') > -1 && !inQuote) {
	if (currentModifer == AND_MODIFIER && and[and.length-1] != ' ') {
	    and = and + ' ';
	}
	if (currentModifer == NOT_MODIFIER && not[not.length-1] != ' ') {
	    not = not + ' ';
	}
	currentModifer = DEFAULT_TERM_MODIFIER;	
	fieldName = '';
        continue;
    }
    if (inQuote) {
	exact = exact + query[i];
	continue;
    }


    if (currentModifer == AND_MODIFIER) {
	if (fieldName == 'site:') {
	    and = and.replace(/site:$/, '');
	    site = site + query[i];
	} else {	    
	    if (site.length == 0) {
		fieldName =  fieldName + query[i];
	    }
	    and = and + query[i];
	}
    }
    
    if (currentModifer == NOT_MODIFIER) {
        not = not + query[i];
    }
    

}
and = trim(and);
not = trim(not);
exact = trim(exact);
site = trim(site);

return [and, not, exact, site];
}

function checkCloseQuote(query, position) {
    for (ii = position; ii < query.length; ii++) {
	if (query[ii].indexOf('"') > -1) {
	    return true;
        }
    }
    return false;
}

