//-----------------------------------------------------------------------------
// File:  SearchPane.js
//
// Purpose:  This file contains the javascript code that is specicific to
//           the advanced and basic search.
//
// Depenedencies:  CollectionTreeManager.js, common.js
//----------------------------------------------------------------------------

/*global document, tab_state, window */

function SearchPane()
{
    this.errors = [];

    this.errorString = "";

    SearchPane.instance = this;
}

//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------

/**
 * Error messages
 */
SearchPane.beginDateAfterEndDate = "SearchPane.beginDateAfterEndDate";
SearchPane.noCategoriesSelected  = "SearchPane.noCategoriesSelected";
SearchPane.searchEmptyMessage    = "SearchPane.searchEmptyMessage";
SearchPane.searchFieldEmpty      = "SearchPane.searchFieldEmpty";

SearchPane.minYear = 1900;
SearchPane.currentYear = new Date().getFullYear();

/**
 * The single instance of the searchPane object
 */
SearchPane.instance = null;

/**
 * regexp for empty field expression test.
 */
SearchPane.emptyString = /^\s*$/;

/**
 * Set focus on the first search field.
 */
SearchPane.prototype.focusOnSearch = function()
{
    if (tab_state == "simple")
    {
        document.getElementById("search_terms").focus();
    }
    else
    {
        // Find the first input element in the form and set focus to it
        var formElements = document.search.elements;
        for (var i = 0; i < formElements.length; ++i)
        {
            if (formElements[i].type == "text")
            {
                formElements[i].focus();
                break;
            }
        }
    }
};

/**
 * add an error the the array of errors to display.
 * @param errorMessage the error message to add
 */
SearchPane.prototype.addError = function(errorMessage)
{
    this.errors.push(errorMessage);
};

/**
 * An associative array that contains the name of test elements to ignore when
 * determininng if at least one field is filled out
 */
SearchPane.textElementsToIgnore = {"toYear":"toYear",
                            "fromYear":"fromYear",
                            "alertName":"alertName",
                            "description":"description",
                            "frequency.multiplier": "frequency.multiplier"};

/**
 * Ensure that at least one of the required fields is filled out.
 * @param errors object to add errors to if any have occurred
 * @param form the form to validate against
 */
SearchPane.prototype.atLeastOne = function(form)
{
    var isNoSearchTerms = true;
    var formElements = form.elements;
    for (var i = 0; i < formElements.length; ++i)
    {
        if (formElements[i].type == "text")
        {
            if (typeof SearchPane.textElementsToIgnore[formElements[i].name] != "undefined")
            {
                continue;
            }

            isNoSearchTerms &= SearchPane.emptyString.test(formElements[i].value);
            if (!isNoSearchTerms)
            {
                break;
            }
        }
    }

    if (isNoSearchTerms)
    {
        this.addError(SearchPane.searchEmptyMessage);
    }
};

/**
 * Determines if any of the checkboxes in the search form are checked
 */
SearchPane.prototype.areAnyCollectionsChecked = function()
{
    var root = document.getElementById("categoryBlock");
    var nodes = root.getElementsByTagName("input");
    var areAnyCollectionsChecked = false;

    for (var i = 0; i < nodes.length && !areAnyCollectionsChecked; i++)
    {
        if (nodes[i].type == "checkbox" && nodes[i].checked)
        {
            areAnyCollectionsChecked = true;
        }
    }

    if (!areAnyCollectionsChecked)
    {
        this.addError(SearchPane.noCategoriesSelected);
    }
};

/**
 * Validates the single field in a simple search form
 * @param requiredElementId the id of the single field that would contain the term to search for.
 * @return true if the data in the form is valid, false otherwise
 */
SearchPane.prototype.validateSimpleSearch = function(requiredElementId)
{
    var isValid = true;
    var simpleSearchInput = document.getElementById(requiredElementId);

    if (isBlank(simpleSearchInput.value))
    {
        MessageBox.error("Invalid Search Parameters", "The search field must contain text");
        isValid = false;
    }

    return isValid;
};

/**
 * Validates the elements in the advanced search form
 * @param form the form to validate
 * @param displayAlert true if an alert should be displayed to the user on error. [optional, default = true]
 * @return true if the data in the form is valid, false otherwise
 */
SearchPane.prototype.validateAdvancedSearch = function(form, displayAlert)
{
    var i;
    var isValid = true;

    if (typeof(displayAlert) == "undefined")
    {
        displayAlert = true;
    }

    // Reset the errors array
    this.errors = [];

    this.atLeastOne(form);

    this.validateDates();

    this.areAnyCollectionsChecked();

    if (this.errors.length > 0)
    {
        this.errorString = "";
        for (i = 0; i < this.errors.length; ++i)
        {
            this.errorString += this.errors[i];
            this.errorString += '<br/>';
        }

        if (displayAlert)
        {
            MessageBox.error("Invalid Search Parameters", this.errorString);
        }

        isValid = false;
    }

    return isValid;
};

/**
 * Determines if the date field element is valid.  The criteria is that it exists
 * and it is a text input field
 * @param ele the element to check
 * @return true if valid, false otherwise
 */
SearchPane.prototype.isValidDateElement = function(ele)
{
    return (ele !== null) && (ele.tagName == "input") && (ele.type == "text");
};

/**
 * Performs validation on the date field elements, if they exist.
 * Adds an error to the errors array if the date fields do not contain valid dates
 */
SearchPane.prototype.validateDates = function()
{
    var a = document.getElementById('fromYear');
    var b = document.getElementById('toYear');

    if (!a || !b)
    {
        return true;
    }

    // Validate each field
    this.dateFieldIsValid(a);
    this.dateFieldIsValid(b);

    if (a.value !== "" && b.value !== "" && a.value > b.value)
    {
        this.addError(SearchPane.beginDateAfterEndDate);
    }
};

/**
 * Performs validation on each date field
 * Adds an error to the errors array if the date field does not contain valid dates
 * @param field the field to validate
 */
SearchPane.prototype.dateFieldIsValid = function(field)
{
    var value = field.value;

    if (value.length === 0)
    {
        // empty fields are fine
    }
    else if (! value.match(/^[0-9]{4}$/))
    {
        if (field.id == 'fromYear')
        {
            this.addError('The start date must have four digits.');
        }
        else
        {
            this.addError('The end date must have four digits.');
        }
    }
    else if (value < SearchPane.minYear)
    {
        if (field.id == 'fromYear')
        {
            this.addError('The earliest searchable start year is '+SearchPane.minYear);
        }
        else
        {
            this.addError('The earliest searchable end year is ' +SearchPane.minYear);
        }
    }
    else if (value > SearchPane.currentYear)
    {
        if (field.id == 'fromYear')
        {
            this.addError('The latest searchable start year is ' + SearchPane.currentYear + '.');
        }
        else
        {
            this.addError('The latest searchable end year is ' + SearchPane.currentYear + '.');
        }
    }
};

/**
 * Switches between the advanced and simple search.
 * @param caller the tab being clicked
 */
function switchTabs(caller)
{
    var simple_tab_container = document.getElementById('simple-tab-content');
    var advanced_tab_container = document.getElementById('advanced-tab-content');
    //do nothing if the user clicks on the currently highlighted tab
    if(caller == tab_state){
        return;
    }
    if (tab_state == 'simple' ) {
        // switch to advanced
        simple_tab_container.className = 'Removed';
        advanced_tab_container.className = '';
        tab_state = 'advanced';
    } else {
        // switch to simple
        simple_tab_container.className = '';
        advanced_tab_container.className = 'Removed';
        tab_state = 'simple';
    }

    SearchPane.instance.focusOnSearch();
}
