/*
 * Copyright 2009 Greg Monroe
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */

/**
 * @fileOverview Contains the word Filter plug-in code.
 * @version 0.9
 * @author Greg Monroe <monroe@dukece.com> 
 */

/**
 * See (http://jquery.com/).
 * @name jQuery
 * @class 
 * See the jQuery Library  (http://jquery.com/) for full details.  This just
 * documents the function and classes that are added to jQuery by this plug-in.
 */

/**
 * See (http://jquery.com/)
 * @name jQuery.fn
 * @class 
 * See the jQuery Library  (http://jquery.com/) for full details.  This just
 * documents the function and classes that are added to jQuery by this plug-in.
 * @memberOf jQuery
 */

/**
 * <p>Remove all elements from the set of matched elements using a a set of 
 * words and options settings. The default is to show return only elements that
 * contain all the specified words.  However, the options can be used to
 * change this to be be any word or the inverse match.</p>
 *
 * The example below will only show paragraphs that contain both the words
 * foo and bar.
 *
 * @example $('p').hide().wordFilter(['foo','bar']).show(); 
 *
 * @param words An array of words to filter the selected items by.
 * @param options An optional options object.
 * @param options.useOr If true, show selections that contain ANY single word in
 *                      the list. If false, (default) only show selections that
 *                      contain ALL the works in the list. 
 * @param options.invert If true, invert the selection display. I.e., don't 
 *                       show selection if it contains words.
 * @param options.matchType Can be three values, "whole", "prefix", or 
 *                      "contains".  "whole" (default) means the whole word must                      
 *                      be matched.  "prefix" means that any word that starts
 *                      with the word is matched.  "contains" means that
 *                      any word that contains the word is matched.  Note
 *                      that contained may match HTML tags as well.
 * @param options.ignoreCase If false, the case of the word must match. If true,
 *                      (default) the case is ignored.
 * @param options.skipHidden If true, any element that is already hidden is 
 *                      skipped.  Makes for faster drill down searches in 
 *                      autoSearch.  Default is false.                       
 *
 */
jQuery.fn.wordFilter = function ( words, options ) {
    
    var i, regEx, regExps, eStart, eEnd, exp, found, flags;
    //this.children().show();
    options = jQuery.extend({
        useOr: false,
        invert: false,
        matchType: 'prefix',
        ignoreCase: true,
        skipHidden: false
    }, options);
    if ( ! words ) {
        return this;
    }
    if ( options.matchType == 'prefix' ) {
        eStart = '.*\\W';
        eEnd = '.*';
    } else if ( options.matchType == 'contains' ) {
        eStart = '.*';
        eEnd = '.*';
    } else {
        eStart = '.*\\W';
        eEnd = '\\W.*';
    }
    regExps = [];
    for( i=0; i < words.length; i++ ) {
        exp = eStart + words[i] + eEnd;
        regEx = new RegExp();
        flag = 'm';
        if  ( options.ignoreCase ) {
            flags = 'im';
        }
        regEx.compile(exp,flags);
        regExps.push(regEx);
    }

		//return this.children("span.date");
    return this.filter( function ( index ) {
        if ( options.skipHidden && $(this).is(':hidden') ) {
            return;
        }
        var txt = ' ' + $(this).children("span.date").text() + ' ';
        found = false;
        for( var i=0; i < regExps.length; i++ ) {
            if ( regExps[i].test(txt) ) {
                found = true;
                if ( options.useOr ) {  // Or requires only 1 word found
                    break;
                }
            } else {
                found = false;
                if ( ! options.useOr ) { // And finished if any word not found.
                    break;
                }
            }
        }
        return options.invert ? ! found : found;
    });
		
};
