Callbacks = {
    map: null,
    icon: null,
    markers: [],
    records: [],
    markerFields: {},
    htmlFields: {},
    init: function( map, markerFields, htmlFields, htmlResults, icon, cluster_icon ) {
        this.icon = icon;
        if ( cluster_icon ) {
            map.declutterGroup( icon.groupName, { 'cluster_icon' : cluster_icon } );
        }
        this.markerFields = markerFields;
        this.htmlFields = htmlFields;
        this.htmlResults = htmlResults;
        this.map = map;
    },
    storeSearch: function( data, searchpoint ) {
        this.map.removeAllOverlays();
        this.markers = [], this.records = [];
        var record, marker, bounds, infobox, html = [];
        bounds = new MMBounds();
        if ( data.totalRecordCount > 0 && data.records && data.records.length > 0 ) {
            for ( var i = 0, j = data.records.length; i < j; i++ ) {
                record = data.records[i];
                infobox = this.getInfoBoxHtml( record, this.markerFields, 'infobox', 'div', i );
                html.push( this.getHtml( record, this.htmlFields, 'result', 'a', i ) );
                marker = this.map.createMarker( record.point, { 
                    'label' : ( i + 1 ) + ' ' + record['torex_branch_name'], 
                    'icon' : this.icon, 
                    'text' : i + 1  
                } );
                marker.setInfoBoxContent( infobox );
                marker.recordid = i;
                this.markers.push( marker );
                this.records.push( record );
                bounds.extend( record.point );
            }
            this.handleResults( html );
            bounds.extend( searchpoint );
            this.map.goToPosition( this.map.getAutoScaleLocation( bounds ) );
            document.body.removeCssClass( 'routesearch' );
            document.body.addCssClass( 'storesearch' );
            UpdateRouting( 0 );
        } else {
            this.map.goToPosition( searchpoint );
            document.body.removeCssClass( 'routesearch' );
            document.body.removeCssClass( 'storesearch' );
        }
        return true;
    },
    handleResults: function( results ) {
        this.htmlResults.innerHTML = '';
        this.htmlResults.innerHTML = results.join( '' );
    },
    getInfoBoxHtml: function( record, tabs, classname, rootel, id ) {
        var markertabs = [], tabhtml, validtab;
        for ( var tab in tabs ) {
            tabhtml = this.getHtml( record, tabs[tab], classname, rootel, id );
            if ( tabhtml.match( /class/ig ).length > 1 ) {
                validtab = tabhtml;
                markertabs.push( new MMInfoBoxTab( tab, tabhtml ) );
            }
        }
        if ( markertabs.length > 1 ) {
            return markertabs;
        } else {
            return validtab;
        }
    },
    getHtml: function( record, fields, classname, rootel, id ) {
        var html;
        if ( fields.addOnClick ) {
            if ( typeof fields.customOnclick == 'function' ) {
                window[classname + 'customonclick'] = fields.customOnclick;
                html = '<' + rootel + ' class="MM' + classname + 'Root" onclick="' + classname + 'customonclick( ' + id + ' ); return false;">';
            } else {
                html = '<' + rootel + ' class="MM' + classname + 'Root" onclick="Callbacks.markers[' + id + '].openInfoBox(); return false;">';
            }
        } else {
            html = '<' + rootel + ' class="MM' + classname + 'Root">';
        }
        if ( typeof fields.customInsert == 'function' ) {
            html += fields.customInsert( record, id + 1 );
        }
        for ( var field in fields ) {
            if ( record[fields[field].fieldname] ) {
                html += '<' + fields[field].element + ' class="MM' + classname + fields[field].fieldname + '">';
                html += record[fields[field].fieldname].toLowerCase();
                html += '</' + fields[field].element + '>';
            }
        }
        html += '</' + rootel + '>';
        return html.replace( /(\<a)+/ig, '<a href="#"' );
    }
}
