var _DEBUG = false;

/**
 * tSearch.
 * TODO: search innerHTML except html! (now it breaks html)
 * 
 */

/**
 * Init debug, grabs console object if accessible, or makes dummy debugger
 */
var fb = _DEBUG && 'undefined' != typeof(console) ? console : {
    log         : function(){},
    debug       : function(){},
    info        : function(){},
    warn        : function(){},
    error       : function(){},
    assert      : function(){},
    dir         : function(){},
    dirxml      : function(){},
    trace       : function(){},
    group       : function(){},
    groupEnd    : function(){},
    time        : function(){},
    timeEnd     : function(){},
    profile     : function(){},
    profileEnd  : function(){},
    count       : function(){},
    msg         : function(){}
};

// Boosting native trim function
String.prototype.trim = function()
{
    var str = this;
    str = str.replace(/^\s+/, '');
	for (var i = str.length - 1; i >= 0; i--) {
		if (/\S/.test(str.charAt(i))) {
			str = str.substring(0, i + 1);
			break;
		}
	}
	return str;
}


var tSearch = Class.create(
{
    /**
     * Default configs
     */
    settings :
    {
        'tInput':               'search',
        'tTrigger':             'go-search',
        'tTargetId':            '#search-container',
        'tDefaultText':         'search',
        'tContentStatic':       true,
        'tHighlightClassName':  'highlighted',
        'tBeforeSearch':        function(){},
        'tAfterSearch':         function(){},
        'tNothingFound':        function(readable_key){ fb.log('Nothing Found for ' + readable_key); }
    },

    /**
     * Constructor
     */
    initialize : function(config)
    {
        this.userStarted = false;
        this.prevSearchKey = new String();
        this.searchKey = new String();
        this.key = new String();
        this.cache = $('branches-chisinau').down('tbody').clone(true);

        Object.extend( this.settings, config );

        $(this.settings.tInput).value = this.settings.tDefaultText;

        // todo: non-static content handle
        this.cachedBox = $$( this.settings.tTargetId );//$( this.settings.tTargetId ).select( '*' );

        //this.tTarget = $$( this.settings.tTargetId )

        var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\' ];

        this.sRE = new RegExp(
            '(\\' + specials.join( '|\\' ) + ')', 'g'
        );

        // Bind listener
        this.__listen__();
    },

    /**
     * User input sanitizing. Prepares to use input as regexp key
     */
    sanitize : function( key )
    {
        return key.replace(this.sRE, '\\$1');
    },

    /**
     *
     */
    search : function()
    {
        this.userStarted = true;
        this.searchKey  = $(this.settings.tInput).value;
        // check if input is not empty or contains only spaces
        
        if (((this.searchKey == this.settings.tDefaultText) && !this.userStarted) || this.searchKey.trim() == '')      {
            // if empty or only spaces, check if there were previously highlighted results
            if (this.prevSearchKey.length != 0) {
                this.prevSearchKey = '';
                //this.tClearStage();
                $('branches-chisinau').down('tbody').replace(this.numerize(this.cache.clone(true)));                
                return -1;
            }
            else {                
                $('branches-chisinau').down('tbody').replace(this.numerize(this.cache.clone(true)));
                return -1;
            }
        }            
        
        var rgxp_key = new RegExp('(' + this.sanitize(this.searchKey) + ')', 'gi');
        var highlight_class = this.settings.tHighlightClassName;
        var copyCatTable = this.cache.clone(true);
        
        copyCatTable.select('tr').each(function(tr)
        {
            var matched = [];
            tr.select('td').each(function(td)
            {
                if (rgxp_key.test(td.innerHTML)) {
                    matched.push(td);                    
                }
            });
            if (matched.length > 0) {
                tr.removeClassName('hidden');
                $(matched).each(function(td)
                {
                    var content = td.innerHTML;
                    content = (content.replace(rgxp_key, "<strong class=\""+highlight_class+"\">\$1</strong>"));
                    td.update(content);     
                });
            }
            else {
                tr.addClassName('hidden');
            }
        });
        
        $('branches-chisinau').down('tbody').replace(this.numerize(copyCatTable));        
    },
    
    numerize: function(tbody)
    {
        var index = 1;
        tbody.select('tr').each(function(tr)
        {
            if (!tr.hasClassName('hidden')) {
                tr.down('td').update(index);
                index++;
            }
        });
        
        return tbody;
    },

    /**
      * Hides 
      */
    tHide : function()
    {
        this.settings.tBeforeSearch();
        var globalFound = false;
        this.cachedBox.each(function(o, i)
        {
            var found = false;

            var children = o.select('*');
            if (children.length > 0)
            {
                children.each(function(o2, i2)
                {
                    if( this.key.test(o2.innerHTML) )
                    {
                        this.makeDolly(o2);
                        found = true;
                        globalFound = true;
                    }
                }.bind(this));
            }
            else {
                if( this.key.test(o.innerHTML) )
                {
                    this.makeDolly(o);
                    found = true;
                    globalFound = true;
                }
            }

            found ? -1 : o.addClassName('hidden');
        }.bind(this));

        this.settings.tAfterSearch();
        globalFound ? -1 : this.settings.tNothingFound(this.searchKey);
    },


    makeDolly : function( elm )
    {
        elm.addClassName('tDollied');
        var holder = new Element('div', {
            className:'tDolly'
        }).addClassName('hidden').update(elm.innerHTML);
        elm.insert({
            'bottom': holder
        });
    },

    /**
      * Elements highlighter
      */
    tHighlight : function(elm, rgxp_key)
    {
        if (elm.length > 0) {
            $(elm).each(function(td)
            {
                var content = td.cloneNode(true);
                td.update( content.innerHTML.replace(rgxp_key, "<strong class=\""+this.settings.tHighlightClassName+"\">\$1</strong>") );
                td.insert({ 'bottom' : content }); 
            });
        }
        /*this.cachedBox.each(function(o, i)
        {
            o.select('.tDollied').each(function(src)
            {
                var content = src.down('.tDolly').cloneNode(true);
                src.update( content.innerHTML.replace(this.key, "<strong class=\""+this.settings.tHighlightClassName+"\">\$1</strong>") );
                src.insert({ 'bottom' : content });
            }.bind(this));
        }.bind(this));*/
    },

    /**
      * Clear changes
      */
    tClearStage : function( callback )
    {
        $('branches-chisinau').down('tbody').select('tr').each(function(o)
        {
            o.select('.tDollied').each(function(src)
            {
                src.removeClassName('tDollied');
                var content = src.down( '.tDolly' );
                src.update( content.innerHTML );
                //content.remove();
            });

            o.removeClassName('hidden');
        });
    },

    __listen__ : function()
    {
        $(this.settings.tInput).observe('keypress', function()
        {            
            setTimeout( function(){ this.search(); }.bind(this), 50);
        }.bind(this));

        $(this.settings.tInput).observe('focus', function()
        {
            $(this.settings.tInput).value == this.settings.tDefaultText && !this.userStared ? $(this.settings.tInput).value = '' : -1;
        }.bind(this));

        $(this.settings.tInput).observe('blur', function()
        {
            $(this.settings.tInput).value.trim() == 0 && !this.userStared ? $(this.settings.tInput).value = this.settings.tDefaultText : -1 ;
        }.bind(this));
    }
});


//t.sanitize('');
//t.search();

