var search_panel = function(window, controller, settings, cache) {
    /* Private properties */
    var _root_selector     = '#search_panel_wrapper';
    var $root              = null;
    
    var _templates         = {};
    var _parser            = TrimPath.parseDOMTemplate;
    
    var _messenger         = window;
    var _settings          = settings;
    var _controller        = controller;
    var _cache             = cache;

    var _sid               = '';
    var _ftypes            = {};
    var _species           = {};
    
    var _profile_display_name = '';

    var _saved_state       = '';
    var _use_page_from_arg = false;

    var _explore_request   = null;


    /* Private Methods */
    function _make_pager(t, p, l) {
        t = parseInt(t);
        p = parseInt(p);
        l = parseInt(l);
        
        var pager_middle = Math.ceil(6 / 2);
        var pager_first  = p - pager_middle + 1;
        var pager_last   = p + 6 - pager_middle;
        var pager_max    = Math.ceil(t / l);
        var i            = pager_first;

        if (pager_max < 2) {
            return [];
        }

        if (pager_last > pager_max) {
            i = i + (pager_max - pager_last);
            pager_last = pager_max;
        }
        if (i <= 0) {
            pager_last = pager_last + (1 - i);
            i = 1;
        }

        var pager = [];

        if (p > 1) {
            pager.push({page: (p - 1), label: '&laquo; Prev', prev: true});
        }
        for (; i <= pager_last && i <= pager_max; i++) {
            var active = (i == p) ? true : false;
            pager.push({page: i, label: i});
        }
        if (p < pager_max) {
            pager.push({page: (p + 1), label: 'Next &raquo;', next: true});
        }
        
        return pager;
    }

    function _highlight_result(e, id) {
        $('#search_result_list li').removeClass('active');
        $('#search_result_list li[@rel=' + id + ']').addClass('active');
    }

    function _update_explore_state() {
        var sf  = _controller.getArgsByNamespace(_saved_state, 'sf');
        var se  = _controller.getArgsByNamespace(_saved_state, 'se');
        var ep  = _controller.explodeQueryString($('#explore_filters_form').serialize());
        
        _saved_state = _controller.implodeSearchArgs(sf, se, ep);

        var url = $('#explore_filters_form').attr('action');
        $(_messenger).trigger('sp::explore::parameters::updated', [url, ep]);
    }

    function _update_search_filters_state() {
        var sf  = _controller.getArgsByNamespace(_saved_state, 'sf');
        var se  = _controller.getArgsByNamespace(_saved_state, 'se');
        var fil = _controller.explodeQueryString($('#search_filters_form').serialize());
        
        sf.sf_page = 1;
        
        delete sf.sf_f_l;
        delete sf.sf_f_p;
        delete sf.sf_f_d;
        delete sf.sf_f_f;
        delete sf.sf_f_b;
        delete sf.sf_f_pa;
        
        _saved_state = _controller.implodeSearchArgs($.extend(sf, fil));
        
        $(_messenger).trigger('sp::search::start::' + sf.sf_type, [_saved_state]);
    }

	function _add_with_decoration(addr, prefix, token, suffix) {
        var addition = token ? token + suffix : '';
	   
	    return addr ?
                    addition ?
                        addr + prefix + addition:
                        addr :
                    addition;
	}

	function _make_pretty_address(item) {
        var addr = '';
        
        addr = _add_with_decoration(addr, ' ', item.address, '');
        addr = _add_with_decoration(addr, ' ', item.address2, '');
        addr = _add_with_decoration(addr, ', ', item.county, ' County');
        addr = _add_with_decoration(addr, ', ', item.city, '');
        addr = _add_with_decoration(addr, ', ', item.state, '');
        addr = _add_with_decoration(addr, ' ', item.zip, '');

        return addr;
    }
    

    /* Search form processing */
    function _start_search(e, form, type, page) {
        var q = $(form).serialize();

        $(_messenger).trigger('sp::search::start::' + type, [q]);

        return false;
    };

    function _bof_search(e, q) {
        var args = _controller.explodeQueryString(q);
        
        if (!args['sf_page']) args['sf_page'] = 1;

        if (!args.sf_state) {
            return;
        }

        if (args.sf_addr == 'Address') {
            args.sf_addr = '';
        }

        if (args.sf_city == 'City') {
            args.sf_city = '';
        }

        if (args.sf_zip == 'Zip') {
            args.sf_zip = '';
        }

        if (args.sf_name == 'Name') {
            args.sf_name = '';
        }

        if (!args.sf_addr && !args.sf_city &&
            !args.sf_zip  && !args.sf_name) {

            return;
        }

        args.view = 'results';
        q = _controller.implodeSearchArgs(args);

        _controller.dispatch(q);
    }

    function _loc_search(e, q) {
        var args = _controller.explodeQueryString(q);
        
        if (!args['sf_page']) args['sf_page'] = 1;

        if (!args.sf_state) {
            return;
        }

        if (!args.sf_addr || !args.sf_city || !args.sf_zip) {
            return;
        }

        if (args.sf_addr == 'Address') {
            args.sf_addr = '';
        }

        if (args.sf_city == 'City') {
            args.sf_city = '';
        }

        if (args.sf_zip == 'Zip') {
            args.sf_zip = '';
        }

        if (args.sf_addr == '' && args.sf_city == '' && args.sf_zip == '') {
            return;
        }

        args.view = 'results';
        q = _controller.implodeSearchArgs(args);

        _controller.dispatch(q);
    }

    function _fac_search(e, q) {
        var args = _controller.explodeQueryString(q);
        
        if (!args['sf_page']) args['sf_page'] = 1;

        if (!args.sf_state) {
            return;
        }

        if (args.sf_addr == 'Address') {
            args.sf_addr = '';
        }

        if (args.sf_city == 'City') {
            args.sf_city = '';
        }

        if (args.sf_zip == 'Zip') {
            args.sf_zip = '';
        }

        if (args.sf_name == 'Name') {
            args.sf_name = '';
        }

        if (!args.sf_addr && !args.sf_city &&
            !args.sf_zip  && !args.sf_name &&
            !args.sf_facility_type) {

            return;
        }

        args.view = 'results';
        q = _controller.implodeSearchArgs(args);

        _controller.dispatch(q);
    }

    function _fish_search(e, q) {
        var args = _controller.explodeQueryString(q);
        
        if (!args['sf_page']) args['sf_page'] = 1;

        if (!args.sf_state) {
            return;
        }

        if (args.sf_addr == 'Address') {
            args.sf_addr = '';
        }

        if (args.sf_city == 'City') {
            args.sf_city = '';
        }

        if (args.sf_zip == 'Zip') {
            args.sf_zip = '';
        }

        args.view = 'results';
        q = _controller.implodeSearchArgs(args);

        _controller.dispatch(q);
    }

    function _perform_search(e, args) {
        var url  = _settings['base_url'];
        
        switch (args.sf_type) {
            case 'bof':
                url += _settings['bof_path'];
                break;
            case 'fac':
                url += _settings['fac_path'];
                break;
            case 'loc':
                url += _settings['loc_path'];
                break;
            case 'fish':
                url += _settings['fish_path'];
                break;
            default:
                return;
        }

        $.get(url, args, function(res) {
            var o  = null;
            try {
                o = eval( '(' + res + ')' );

                if (!o['success'])
                    o['success'] = false;

            } catch(e) {o = {sucess: false}}

            if (o['success'] === false) {
                $(_messenger).trigger('sp::search::canceled', ['Server error']);
                return false;
            }

            var idx = 65;
            for (i in o.data) {   
                if(typeof o.data[i] != 'object'){
                    continue;
                }
                o.data[i].label = String.fromCharCode(idx++);
                o.data[i].mtype = 'result';
                o.data[i].pretty_address = _make_pretty_address(o.data[i]);
            }

            var pager = _make_pager(o.total, o.page, _settings['page_length']);
            o['pager'] = pager;

            var q = _controller.implodeSearchArgs(args);

            $(_messenger).trigger('sp::search::received', [o, q]);
        });
    }


    /* View Methods */
    function _show_home(e, d) {
        _saved_state = '';

        var html = _templates['common_searches_box'].process({
            facility_types: _ftypes,
            species: _species,
            state_selector_url : _settings['state_selector_link']
        });
        var html = _templates['search_forms_box'].process({
            state_id           : _sid,
            content            : html,
            explore_title_url  : '?view=explore',
            ttooltip           : 'Select an option below to begin. Click for more help.'
        });
        $root.html(html);
        
        
        return false;
    }

    function _show_bof_search(e, d) {
        var q  = _controller.implodeSearchArgs(d);
        var sf = _controller.getArgsByNamespace(q, 'sf');
        
        _saved_state = _controller.implodeSearchArgs(sf);
        
        d.state = _sid;
        
        var html = _templates['form_footer_box'].process({
            state_selector_url : _settings['state_selector_link']
        });
        
        var html = _templates['bof_search_box'].process({
            footer   : html,
            form     : d,
            base_url : _settings['base_url'],
            path     : _settings['bof_path'],
            state    : d.state
        });
        var html = _templates['search_forms_box'].process({
            state_id          : _sid,
            content           : html,
            explore_title_url : '?view=explore',
            ttooltip          : 'Search for a body of water by entering its name and/or location.'
        });
        $root.html(html);
    
        return false;
    }

    function _show_loc_search(e, d) {
        _saved_state = '';
        
        d.state = _sid;

        var html = _templates['form_footer_box'].process({
            state_selector_url : _settings['state_selector_link']
        });

        var html = _templates['loc_search_box'].process({
            footer   : html,
            form     : d,
            base_url : _settings['base_url'],
            path     : _settings['loc_path']
        });
        var html = _templates['search_forms_box'].process({
            state_id: _sid,
            content: html,
            explore_title_url: '?view=explore',
            ttooltip: 'Explore the map by entering a location\'s street address, city or zip code.'
        });
        $root.html(html);
    
        return false;
    }

    function _show_fac_search(e, d) {
        var q  = _controller.implodeSearchArgs(d);
        var sf = _controller.getArgsByNamespace(q, 'sf');
        
        _saved_state = _controller.implodeSearchArgs(sf);
        
        d.state = _sid;

        var selected_type = '';
        if (sf.sf_facility_type) {
            selected_type = sf.sf_facility_type;
        }

        var html = _templates['form_footer_box'].process({
            state_selector_url : _settings['state_selector_link']
        });

        var html = _templates['fac_search_box'].process({
            footer         : html,
            form           : d,
            facility_types : _ftypes,
            selected_type  : selected_type,
            base_url       : _settings['base_url'],
            path           : _settings['fac_path']
        });
        var html = _templates['search_forms_box'].process({
            state_id          : _sid,
            content           : html,
            explore_title_url : '?view=explore',
            ttooltip          : 'To locate a facility or service, select a business type and enter the name and/or location to narrow your search.'
        });
        $root.html(html);
    
        return false;
    }

    function _show_fish_search(e, d) {
        var q  = _controller.implodeSearchArgs(d);
        var sf = _controller.getArgsByNamespace(q, 'sf');
        
        _saved_state = _controller.implodeSearchArgs(sf);
        
        d.state = _sid;

        var selected_type = '';
        if (sf.sf_fish_id) {
            selected_type = sf.sf_fish_id;
        }

        var html = _templates['form_footer_box'].process({
            state_selector_url : _settings['state_selector_link']
        });

        var html = _templates['fish_search_box'].process({
            footer        : html,
            form          : d,
            species       : _species,
            selected_type : selected_type,
            base_url      : _settings['base_url'],
            path          : _settings['fish_path']
        });
        var html = _templates['search_forms_box'].process({
            state_id          : _sid,
            content           : html,
            explore_title_url : '?view=explore',
            ttooltip          : 'To locate a place to fish, select a fish species and enter an address to narrow your search.'
        });
        $root.html(html);
    
        return false;
    }

    function _show_results(e, d, q) {
        var sf = _controller.getArgsByNamespace(q, 'sf');
        
        _saved_state = _controller.implodeSearchArgs(sf);
		
        /* Generate explore URLs */
        for (var i = 0; i < d.data.length; i++) {
            if(typeof d.data[i] != 'object'){
                continue;
            }
            var args = {};
            args.view       = 'explore';
            args.se_name    = d.data[i].name;
            args.se_lat     = d.data[i].lat;
            args.se_lng     = d.data[i].lng;
            args.se_zoom    = d.data[i].zoom;
            args.se_label   = d.data[i].label;
            args.se_id      = d.data[i].id;
            args.se_rtype   = d.data[i].rtype;
            args.se_rank    = d.data[i].rank;
            args.se_pretty_address = _make_pretty_address(d.data[i]);
            args.se_return  = '1';

            for (m in sf) {
                args[m] = sf[m];
            }
            
            d.data[i].url = _controller.implodeSearchArgs(args);
        }
        
        if (d.total == 1) {
            var q = d.data[0].url + '&se_return=0';
            _controller.dispatch(q);
            
            return false;
        }
        
        /* Generate pager URLs */
        for (i in d.pager) {
            if(typeof d.pager[i] == 'function'){
                continue;
            }
            sf.sf_page = d.pager[i].page;
            d.pager[i].url = 'view=results&' + _controller.implodeSearchArgs(sf);
        }

        /* Create and render HTML */
        var footer = _templates['form_footer_box'].process({
            state_selector_url : _settings['state_selector_link']
        });
        var pager  = _templates['search_results_pager_box'].process({
            pager : d.pager,
            page  : d.page
        });
        var filters = (sf.sf_type != 'loc') ?
            _templates['search_results_filter_box'].process({
                form    : sf,
                classes : (readCookie('rbff_hide_search_filters') == 'true') ? 'collapsed' : ''
            }) :
            '';
            
        var html   = _templates['search_results_box'].process({
            data       : d.data,
            filters    : filters,
            footer     : footer,
            pager      : pager,
            hasCSearch : controller.hasCampingSearch()
        });
        var html = _templates['search_forms_box'].process({
            state_id          : _sid,
            content           : html,
            explore_title_url : '?view=explore',
            ttooltip          : "Below is a list of what we found in our database based on your search criteria. If you did not find what you were looking for click the 'Search Again' button below. Click for more help."
        });

        $root.html(html);
    
        return false;
    }

    function _show_explore(e, d) {
        var q  = _controller.implodeSearchArgs(d);
        var sf = _controller.getArgsByNamespace(q, 'sf');
        var se = _controller.getArgsByNamespace(q, 'se');
        var ep = _controller.getArgsByNamespace(q, 'ep');
        
        _saved_state = _controller.implodeSearchArgs(sf, se, ep);

        var page = 0;
        if (ep['ep_page']) {
            if (parseInt(ep['ep_page'])) {
                page = parseInt(ep['ep_page']);
                _use_page_from_arg = true;
            }
        }

        var water = '';
        if (ep['ep_water']) {
            if (ep['ep_water'] == 'a') {
                water = 'all';
            }
            if (ep['ep_water'] == 'f') {
                water = 'fish';
            }
        }

        var fish = 0;
        if (ep['ep_fish']) {
            if (parseInt(ep['ep_fish'])) {
                fish = parseInt(ep['ep_fish']);
            }
        }
        
        var boating = false;
        if (ep['ep_b'] && ep['ep_b'] == 'on') {
            boating = true;
        }
        var marinas = false;
        if (ep['ep_m'] && ep['ep_m'] == 'on') {
            marinas = true;
        }
        var outfitters = false;
        if (ep['ep_o'] && ep['ep_o'] == 'on') {
            outfitters = true;
        }
        var family = false;
        if (ep['ep_f'] && ep['ep_f'] == 'on') {
            family = true;
        }
        var urban = false;
        if (ep['ep_u'] && ep['ep_u'] == 'on') {
            urban = true;
        }
        var camping = false;
        if (ep['ep_c'] && ep['ep_c'] == 'on') {
            camping = true;
        }
        var restaurant = false;
        if (ep['ep_r'] && ep['ep_r'] == 'on') {
            restaurant = true;
        }
        var charter = false;
        if (ep['ep_ch'] && ep['ep_ch'] == 'on') {
            charter = true;
        }
        var state_park = false;
        if (ep['ep_sp'] && ep['ep_sp'] == 'on') {
            state_park = true;
        }
        var fishing = false;
        if (ep['ep_fi'] && ep['ep_fi'] == 'on') {
            fishing = true;
        }
        var lodging = false;
        if (ep['ep_h'] && ep['ep_h'] == 'on') {
            lodging = true;
        }

        var community = '';
        if (ep['ep_community']) {
            if (ep['ep_community'] == 'a') {
                community = 'all';
            }
            if (ep['ep_community'] == 'o') {
                community = 'only';
            }
        }
        
        var hotspot = '';
        if (ep['ep_hotspot']) {
            if (ep['ep_hotspot'] == 'm') {
                hotspot = 'my';
            }
            if (ep['ep_hotspot'] == 'b') {
                hotspot = 'bud';
            }
        }

        var id       = se.se_id;
        var name     = '';
        var rtype    = '';
        var label    = '';
        var sret     = false;
        var url_back = '';
        var selected = false;
        var pretty_address = '';
        var lat = '';
        var lng = '';
        var ttooltip = 'Use the Explore options below to narrow down your search results. Click for more help.';
        var rank = false;
        
        if (id) {
            name           = se.se_name;
            rtype          = se.se_rtype;
            sret           = se.se_return == '1' ? true : false;
            pretty_address = se.se_pretty_address;
            ttooltip       = 'You are currently viewing ' + name + '. ' + ttooltip;
            url_back       = _controller.implodeSearchArgs(sf);
            lat            = se.se_lat;
            lng            = se.se_lng;
            rank           = se.se_rank;
            selected       = true;
        }

        var html = _templates['search_filters_box'].process({
            state_id         : _sid,
            selected         : selected,
            sreturn          : sret,
            item             : {name: name, label: '', pretty_address: pretty_address, lat: lat, lng: lng, rank: rank },
            url_back         : url_back + '&view=results',
            species          : _species,
            search_title_url : '?view=home',
            aPage            : page,
            aState           : _sid,
            aWater           : water,
            aFish            : fish,
            aBoating         : boating,
            aMarinas         : marinas,
            aOutfitters      : outfitters,
            aFamily          : family,
            aUrban           : urban,
            aCamping         : camping,
            aRestaurant      : restaurant,
            aCharter         : charter,
            aStatePark       : state_park,
            aFishing         : fishing,
            aLodging         : lodging,
            aCommunity       : community,
            aHotspot         : hotspot,
            ttooltip         : ttooltip,
            sel_id           : id,
            sel_rtype        : rtype,
            profile_name     : _profile_display_name,
            base_url         : _settings['base_url'],
            path             : _settings['explore_path']
        });
        $root.html(html);
        
        return false;
    }


    /* Public Functions and Variables */
    return {
        /**
        * Init function
        *
        * @method init
        * @public
        */
        init: function() {
            _controller.setSearchPanel(this);
            
            /* Parse _templates */
            _templates['search_filters_box']        = _parser('search_filters_box_tpl');
            _templates['search_forms_box']          = _parser('search_forms_box_tpl');
            
            _templates['common_searches_box']       = _parser('common_searches_box_tpl');
            _templates['bof_search_box']            = _parser('bof_search_box_tpl');
            _templates['fac_search_box']            = _parser('fac_search_box_tpl');
            _templates['fish_search_box']           = _parser('fish_search_box_tpl');
            _templates['loc_search_box']            = _parser('loc_search_box_tpl');
            _templates['form_footer_box']           = _parser('form_footer_box_tpl');

            _templates['search_results_filter_box'] = _parser('search_results_filter_box_tpl');
            _templates['search_results_box']        = _parser('search_results_box_tpl');
            _templates['search_results_pager_box']  = _parser('search_results_pager_box_tpl');
            
            
            /* Initialize local vars */
            _sid                  = _settings.curr_state;
            _ftypes               = _settings.ftypes;
            _species              = _settings.fish;
            $root                 = $(_root_selector);
            _profile_display_name = _settings['profile_display_name'];


            /* Register message responders */
            $(_messenger).bind('view::home',    _show_home);
            $(_messenger).bind('view::bof',     _show_bof_search);
            $(_messenger).bind('view::loc',     _show_loc_search);
            $(_messenger).bind('view::fac',     _show_fac_search);
            $(_messenger).bind('view::fish',    _show_fish_search);
            $(_messenger).bind('view::results', _perform_search);
            $(_messenger).bind('view::explore', _show_explore);

            $(_messenger).bind('sp::search::start',       _start_search);
            $(_messenger).bind('sp::search::start::bof',  _bof_search);
            $(_messenger).bind('sp::search::start::loc',  _loc_search);
            $(_messenger).bind('sp::search::start::fac',  _fac_search);
            $(_messenger).bind('sp::search::start::fish', _fish_search);
            $(_messenger).bind('sp::search::received',    _show_results);
            $(_messenger).bind('sp::explore::parameters::updated', function(e, url, ep) {
                if (!url || ep.ep_page < 1) {
                    return false;
                }

                if (_explore_request) {
                    try { _explore_request.abort();}
                    catch(e) {}
                }

                _explore_request = $.get(url, ep, function(res) {
                    var o  = null;
                    try {
                        o = eval( '(' + res + ')' );

                        if (!o['success'])
                            o['success'] = false;

                    } catch(e) {o = {sucess: false}}

                    if (o['success'] === false) {
                        $(_messenger).trigger('sp::search::canceled', ['Server error']);
                        return false;
                    }

                    /* Create labels and convert species IDs to names */
                    var idx = 65;
                    for (i in o.page.data) {   
                        if(typeof o.page.data[i] != 'object'){
                            continue;
                        }
                        o.page.data[i].label = String.fromCharCode(idx++);
                        o.page.data[i].pretty_address = _make_pretty_address(o.page.data[i]);
                        o.page.data[i].mtype = 'item';
                        
                        var species = [];
                        for (var j = 0; j < o.page.data[i].inhabitants.length; j++) {  
                            var id   = o.page.data[i].inhabitants[j];
                            var fish = {
                                name     : _settings['fish_names']['id' + id],
                                url_token: _settings['fish_urls']['id' + id]
                            };

                            species.push(fish);
                        }
                        species.sort();
                        o.page.data[i].inhabitants = species;
                    }
                    for (i in o.bof) {  
                        if(typeof o.bof[i] != 'object'){
                            continue;
                        }
                        if (o.bof[i]['count'] && o.bof[i]['count'] > 1) {
                            o.bof[i].mtype = 'cluster';
                        }
                        else {
                            o.bof[i].mtype = 'item';
                        }
                    }
                    for (i in o.fac) { 
                        if(typeof o.fac[i] != 'object'){
                            continue;
                        } 
                        if (o.fac[i]['count'] && o.fac[i]['count'] > 1) {
                            o.fac[i].mtype = 'cluster';
                        }
                        else {
                            o.fac[i].mtype = 'item';
                        }
                    }
                    for (i in o.hot) {
                        if(typeof o.hot[i] != 'object'){
                            continue;
                        }    
                        if (o.hot[i]['count'] && o.hot[i]['count'] > 1) {
                            o.hot[i].mtype = 'cluster';
                        }
                        else {
                            o.hot[i].mtype = 'item';
                        }
                    }

                    /* Create pager */
                    var pager = _make_pager(o.total, o.page.num, 10);
                    o['pager'] = pager;

                    $(_messenger).trigger('sp::explore::received', [o]);
                });

                return false;
            });
            $(_messenger).bind('sp::search::filters::changed', function(e) {
                var curr_view = _controller.getCurrentView();
                
                if (curr_view != 'results') {
                    return false;
                }
                
                _update_search_filters_state();
                
                return false;
            });
            $(_messenger).bind('sp::explore::parameters::changed', function(e) {
                var curr_view = _controller.getCurrentView();
                
                if (curr_view != 'explore') {
                    return false;
                }

                $('#explore_filters_form input[@name=ep_page]').val(1);
                _update_explore_state();
                
                return false;
            });
            $(_messenger).bind('mp::explore::parameters::changed', function(e, vp) {
                var curr_view = _controller.getCurrentView();

                if (curr_view != 'explore') {
                    return false;
                }

                $('#explore_filters_form input[@name=ep_swlat]').val(vp.ep_swlat);
                $('#explore_filters_form input[@name=ep_swlng]').val(vp.ep_swlng);
                $('#explore_filters_form input[@name=ep_nelat]').val(vp.ep_nelat);
                $('#explore_filters_form input[@name=ep_nelng]').val(vp.ep_nelng);
                $('#explore_filters_form input[@name=ep_htiles]').val(vp.ep_htiles);
                $('#explore_filters_form input[@name=ep_vtiles]').val(vp.ep_vtiles);

                var page = $('#explore_filters_form input[@name=ep_page]').val();
                if (page > 0) {
                    if (_use_page_from_arg == true) {
                        _use_page_from_arg = false;
                    }
                    else {
                        $('#explore_filters_form input[@name=ep_page]').val(1);
                    }
                }
                _update_explore_state();
                
                return false;
            });
            $(_messenger).bind('ep::explore::parameters::changed', function(e, page) {
                var curr_view = _controller.getCurrentView();

                if (curr_view != 'explore') {
                    return false;
                }

                if (!parseInt(page) || page < 1) {
                    return false;
                }

                $('#explore_filters_form input[@name=ep_page]').val(page);
                _update_explore_state();
                
                return false;
            });

            //$(_messenger).bind('app::result::clicked', _highlight_result);
            

            /* Local DOM responders */
            $('span.help a', $root[0]).
            livequery('click', function() {
                if (_settings['embedded'] == true) {
                    return false;
                }
                
                $(_messenger).trigger('all::open::clicked', ['help']);

                return false;
            });

            $('span.help a', $root[0]).
            livequery('mouseover', function(e) {
    	        var text = this.title;
	            this.originalTitle = text;
	        
	            if(text.indexOf(settings.split) != -1) {
	                text = '<h3>'+ text.split(settings.split)[0] + '</h3><p>' + text.split(settings.split)[1] + '</p>';
	            } 
	            else {
	                text = '<p>' + text + '</p>';
	            }   										  

    		    this.title = ""; 							  

    		    $("body").prepend("<div id='tooltip'>"+ text +"</div>");

    		    $("#tooltip")
                    .css("top",(e.pageY - _settings['tt_xOffset']) + "px")
                    .css("left",(e.pageX + _settings['tt_yOffset']) + "px")
                    .css("max-width", _settings['tt_maxWidth'])
                    .css("max-height", _settings['tt_maxHeight'])
                    .css("z-index", "3000")
                    //.fadeIn("fast");
                    .show();

                return false;
            }).
            livequery('mouseout', function() {
    		    this.title = this.originalTitle;
    		    $("#tooltip").remove();

                return false;
            }).
            livequery('mousemove', function(e) {
    		    $("#tooltip")
                    .css("top",(e.pageY - _settings['tt_xOffset']) + "px")
                    .css("left",(e.pageX + _settings['tt_yOffset']) + "px");

                return false;
            });

            $('input.toggle_text', $root[0]).
            livequery('focus', function() {
                var original_text = $(this).attr('rel');

                if (!original_text) {
                    return false;
                }

                if ($(this).val() == original_text) {
                    $(this).val('');
                }
            }).
            livequery('blur', function(){
                var original_text = $(this).attr('rel');
        
                if (!original_text) {
                    return false;
                }

                if ($(this).val() == '') {
                    $(this).val(original_text);
                }
            });

            $('a[@rel=show_help]', $root[0]).
            livequery('click', function() {
                $(_messenger).trigger('hc::open::clicked', []);
            
                return false;
            });

            $('a.action', $root[0]).
            livequery('click', function() {
                var q = $(this).attr('href').replace(/^\?/, '');

                _controller.dispatch(q);

                return false;
            });

            $('form.preselect', $root[0]).
            livequery('submit', function() {
                var view = $(this).attr('action');
                if (!view) { return false; }
                
                var q = 'view=' + view + '&' + $(this).serialize();
                
                _controller.dispatch(q);

                return false;
            });

            $('form.search_details_form', $root[0]).
            livequery('submit', function() {
                var type = $(this).attr('rel');
                if (!type) { return false; }
                
                $(_messenger).trigger('sp::search::start', [this, type, 0]);

                return false;
            });
            
            $('#search_results_box h3.toggle', $root[0]).
            livequery('click', function() {
                var $this = $(this);
                var $form = $this.next();
                
                if ($form.hasClass('collapsed')) {
                    createCookie('rbff_hide_search_filters', false, 3);
                    $form.removeClass('collapsed');
                }
                else {
                    createCookie('rbff_hide_search_filters', true, 3);
                    $form.addClass('collapsed');
                }
                
                return false;
            });
            

            $('#search_result_list li', $root[0]).
            livequery('click', function() {
                var id = $(this).attr('rel');
                
                if (!id) {
                    return;
                }
                
                //$(_messenger).trigger('app::result::clicked', [id]);
            });

            $('#search_filters_form input').
            livequery('click', function(e, g) {
                $(_messenger).trigger('sp::search::filters::changed', []);
            });

            $('#explore_filters_form input').
            livequery('click', function(e, g) {
                $('input', $root[0]).parents('li').removeClass('active');
                $('input:checked', $root[0]).parents('li').addClass('active');
                
                $(_messenger).trigger('sp::explore::parameters::changed', []);
            });

            $('#explore_filters_form select').
            livequery('click', function(e, g) {
                var sel  = e.target;
                var form = $(sel).parents('form');

                /* Switch selected radio */
                $(this).parents('ul').find('input[@type=radio]').attr('checked', false);
                $(this).siblings('input').attr('checked', true);

                /* Highlight selected rows */
                $('input', $root[0]).parents('li').removeClass('active');
                $('input:checked', $root[0]).parents('li').addClass('active');

                $(_messenger).trigger('sp::explore::parameters::changed', []);
                
                return false;
            });
        },
        /**
        * 
        *
        * @method getState
        * @public
        */
        getState: function() {
            return _saved_state;
        }
    };
}(window, controller, settings, cache);

$(function() {
    search_panel.init();
});

