Ext.onReady(function(){
	var width = GetWindowSize("width");
	if (width < 1100) {
		$$("body")[0].setStyle({padding: "0px 1%"});	
	} else if (width < 1200) {
		$$("body")[0].setStyle({padding: "0px 7%"});	
	}
	init();		// Load google maps etc. 
});

function initialize_page() {
	// main frame
	var border = new Ext.Panel({
	    id: "panel_main_frame",
		title:"OBIS-SEAMAP",
		header: false,
	    layout:'fit',
	    monitorResize: true,
        region: "center",
		defaults: {
	        split: true,
			animFloat: false,
			autoHide: false,
			useSplitTips: true,
			stateful: false,
			monitorResize: true	
		},
	    items: [
			{
	    	region: "center",
	        title: 'Map and Tabs',
	        layout:'border',
	        header: false,
	        height: 400,
	        autoHeight: false,
	        border: false,
			defaults: {
		        split: false,
				animFloat: false,
				autoHide: false,
				useSplitTips: true,
				monitorResize: false
			},
	        items: [{
	        	title: 'Google Maps and tools',
	        	id: 'map_panel',
	        	region:'center',
	        	contentEl: "div_map",
   		        header: false,
		        height: 400,
		        autoHeight: false,
		        listeners: {
					resize: resize_map
		        } 	  
	        },{
		        region: 'south',
		        title: 'bottom_bar',
		        id: "map_bottom_bar",
		        header: false,
		        border: false,
		        height: 0
	        }
	    ]}]
	});

	var client = new Ext.Panel({
	    id: "panel_client",
		title: 'Species',
   		header: false,
	    renderTo: "body_frame",
	    height: Ext.get("body_frame").parent().getHeight(),
	    layout:'fit',
	    border: false,
	    bodyBorder: false,
	    items: [border]  
	});	
	build_quick_search();	
}

function resize_map(panel, adjWidth, adjHeight) {
	var width = panel.getInnerWidth();
	var height = panel.getInnerHeight();
	Ext.get("map").setSize(width, height);
	if(map) {
		map.checkResize();
	}
}
function window_resized() {
	Ext.getCmp("panel_client").doLayout(true);
}

function build_quick_search() {
	var box_quick_link = new Ext.form.TextField({
			    	xtype: 'textfield',
			    	name: 'tbox_quick_search',
			    	id: 'tbox_quick_search',
			    	renderTo: "div_quick_search",
			    	emptyText: rs_front_page.quick_search_empty_text,
		            listeners: {
		                specialkey: function(field, e){
		                    if (e.getKey() == e.ENTER) {
		                        var text = field.getValue();
		                    }
		                }
		            }
			    });
		
		var quick_search_fields = [ 
		    {name: 'category', type: 'string'},
		    {name: 'category_label', type: 'string'},
			{name: 'id', type: 'int'},
			{name: 'name', type: 'string'},
			{name: 'content', type: 'string'}
		];	
			
		var store_quick_search = new Ext.ux.OBISGroupingStore({
			id: 'store_quick_search',
			proxy: new Ext.ux.OBISProxy(),
			baseParams: {mode: "quick_search"},
			reader: new Ext.ux.OBISJsonReader({   
			    id: 'id',
			    fields: quick_search_fields
			    }),
			listeners: {
				beforeload: function(store, options) {
					// This is the key to solve the shaky combobox problem that it loses a focus
					// after selecting an item from the list and fails to show up when continuing to type in.
					Ext.getCmp("combo_quick_search").onFocus({});
					//options.params = Ext.apply(options.params, {name_search: gQuery.options.name_search, search_for: gQuery.options.search_for});
					
					if ($("full_search").checked) {
						options.params.mode = "full_search";
					}
				}
			}
		});
				
	    var resultTpl = new Ext.XTemplate(
        	'<tpl exec="this.category = &quot;&quot;"></tpl>',
	        '<tpl for=".">',
	        	'<tpl if="this.category != values.category">',
		        	'<tpl exec="this.category = values.category"></tpl>',
		        	'<div class="x-grid-group-hd"><div class="x-grid-group-title">{category_label}</div></div>',
	        	'</tpl>',
	        	'<div class="search-item">',
	            	'{name}',
	            	'<tpl if="content != &quot;&quot;">',
	            	'<div style="padding-left:15px; font-style:italic;">{content}</div>',
	            	'</tpl>',
	        	'</div>',
	        '</tpl>'
	    );   	 
	    
	    var species_search = new Ext.form.ComboBox({
	        store: store_quick_search,
	        id: "combo_quick_search",
	        typeAhead: false,
	        loadingText: rs_win_species.species_live_search.loadingText,
	        width: 430,
	        height: 600,
	        pageSize:10,
	        hideTrigger:true,
	        tpl: resultTpl,
	        applyTo: 'tbox_quick_search',
	        itemSelector: 'div.search-item',
	        minChars: 1,
	        onSelect: function(record){ // override default onSelect to do redirect
	            var category = record.data.category;
	            var id = record.data.id;
	            var url = String.format("/{0}/{1}", category.split("_")[0], id);
	            window.location.href = url;
	        },
	        listeners: {
	        	beforequery: function(event) {
	        		if (isNaN(parseInt(event.query)) && event.query.length < 3) {
	        			event.cancel = true;
	        			return false;
	        		}
	        	},
				expand: function(combo) {
					if (combo.assetHeight == 0 && combo.pageSize > 0 && Ext.isIE7) {
					   combo.assetHeight = 28;
					}
				}
	        }
	    });
}

function full_search_changed(checkbox) {
	var combo = Ext.getCmp('combo_quick_search');
	var textbox = Ext.getCmp("tbox_quick_search");
	var isDirty = textbox.getValue();
	checkbox.checked ? textbox.emptyText = rs_front_page.full_search_empty_text : textbox.emptyText = rs_front_page.quick_search_empty_text;
	combo.lastQuery = '';
	if (isDirty) {
		combo.doQuery(combo.getValue(), true);
	} else {
		textbox.reset();
	}
}

function build_dataset_search() {
	if (!Ext.getCmp("win_datasets")) {
		var width = $("map_tool_divs").getWidth();
		/* Providers Grid */
		var store_providers = new Ext.data.Store({
			id: 'store_providers',
			remoteSort: true,
			proxy: new Ext.ux.OBISProxy(),
			baseParams: {mode: 'provider'},		
			reader: new Ext.ux.OBISJsonReader({   
			    id: 'provider_id',
			    fields: [ 
			        {name: 'provider_id', type: 'string'},
			        {name: 'provider_name', type: 'string'},
			        {name: 'num_datasets', type: 'int'},
			        {name: 'num_records', type: 'int'}
			  	]}),
			sortInfo:{field: 'provider_name', direction: "ASC"},
			listeners: {
				beforeload: function(store, options){
                    var grid_datasets = Ext.getCmp("grid_datasets");
                    if (grid_datasets && grid_datasets.store.getCount() > 0) {
                    	grid_datasets.store.removeAll();
                    }
					this.remoteSort = true;
					var keyword = Ext.getCmp("tbox_keyword").getValue();
					var params = {keyword: keyword, publish: gQuery.publish};
					options.params = Ext.apply(options.params, params);
				},				
				load: function(store){
					this.remoteSort = false;
					if (store.getCount() == 1) {
						var grid = Ext.getCmp("grid_providers");
						grid.getSelectionModel().selectRow(0);
						provider_clicked(grid, 0);
					}
				}
			}
		});
		
		
		var cm_providers = new Ext.grid.ColumnModel({
			defaults: {readOnly: true, sortable: true}, 
			columns: [{
			    header: rs_grid_providers.cm.provider_name,
			    dataIndex: 'provider_name',
			    renderer: function(value, metadata, record, rowIndex, colIndex, store) {
			   		var text = value ? value : "Others";
			    	return text;
			    },
			    width: 170
			  },{
			    //header: rs_grid_providers.cm.num_resources,
			    header: "#",
			    dataIndex: 'num_datasets',
			    align: 'right',
			    width: 40
			  },{
			    header: rs_grid_providers.cm.num_records,
			    dataIndex: 'num_records',
			    align: 'right',
			    hidden: true,
			    renderer: function(value, metadata, record, rowIndex, colIndex, store) {
			   		var text = int_format(value);
			    	return text;
			    },
			    width: 80
			  },{
			    header: rs_grid_providers.cm.provider_id,
			    dataIndex: 'provider_id',
			    hidden: true,
			    width: 30
			  }]
		  });
		cm_providers.defaultSortable= true;	  
	
		var gv_providers = new Ext.grid.GridView({forceFit: true});
		
		var grid_providers = new Ext.grid.GridPanel({
			id: "grid_providers",
		    title: rs_grid_providers.title,
	        region: 'west',
		    width:280,
		    header: false,
		    store: store_providers,
		    trackMouseOver:true,
		    loadMask: true,
			autoHeight: false,
			autoExpandColumn: 'provider_name',
			cm: cm_providers,
			sm: new Ext.ux.RowSelectionModelMSBSC(),
			stripeRows: true,
			stateful: false,
			view: gv_providers,
			listeners: {
				rowclick: provider_clicked
			}
			
		});  		
		
		var grid_datasets = build_datasets_grid();
		grid_datasets.region = "center";
    	var rs_panel = rs_panel_datasets;
		var win_datasets = new Ext.Panel({
			id: "win_datasets",
			title: rs_win_datasets.title,
			header: false,
	        layout:'border',
   		    renderTo: "toolbar_datasets",
	        maximized: false,
	        width: width,
	        height: 300,
		    tbar: {hideBorders: true,	// no effects?
		    	items: [
		    	{xtype: 'tbtext', text: rs_win_datasets.keyword_box},
		    	{xtype: 'textfield', name: 'tbox_keyword', id: 'tbox_keyword', width: 350,
			    	emptyText: rs_win_datasets.tbar.emptyText,
		            listeners: {
		                specialkey: function(field, e){
		                    if (e.getKey() == e.ENTER) {
		                        var text = field.getValue();
		                        var grid_provider = Ext.getCmp("grid_providers");
		                        grid_provider.store.load();
		                    }
		                }
		            }}, new Ext.Toolbar.Fill(),
					new Ext.PagingToolbar({	// paging bar on the bottom
			            pageSize: 50,
			            store: grid_datasets.store,
			            displayInfo: true,
			            hideBorders: true,	// no effects?
			            displayMsg: rs_panel.bbar.displayMsg,
			            emptyMsg: rs_panel.bbar.emptyMsg/*,
			            listeners: {
			            	beforechange: function() {Ext.getCmp(grid_id).store.dirty = true;}
			            }*/
			        })		            
		    	]},
	        items: [grid_providers, grid_datasets]
		});
		
		grid_providers.store.load();
		grid_datasets.store.load();
	}
}

function provider_clicked(theGrid, rowIndex, e) {
	var row = theGrid.store.getAt(rowIndex);
	var provider_id = row.data.provider_id;
	var provider_name = row.data.provider_name;
	
	var grid_datasets = Ext.getCmp("grid_datasets");
	if (theGrid.getSelectionModel().isSelected(rowIndex)) {
		grid_datasets.store.remoteSort = true;
		grid_datasets.store.dirty = true;
		var keyword = Ext.getCmp("tbox_keyword").getValue();
		var params = {provider_id: provider_id, keyword: keyword, publish: gQuery.publish};
		grid_datasets.store.load({params: params});
	} else {
		grid_datasets.store.removeAll();
	}
}

function data_loaded(theStore, records, options) {
	theStore.remoteSort = false;
	theStore.remoteGroup = false;
	theStore.dirty = false;
}

function row_clicked(theGrid, rowIndex, e) {
	var row = theGrid.store.getAt(rowIndex);
	var dataset = row.data;
	var dataset_id = dataset.dataset_id;
	gQuery.datasets = [dataset];
	update_layers({}, update_map);
    if (dataset.data_extent != "") {
		zoomToBOX3D(dataset.data_extent);
    }
}

function build_datasets_grid() {
	type = "datasets";
	var store_id = "store_" + type;
	var grid_id = "grid_" + type;
	var group_field = "group_field";
	var param_list = null;
	var register = false;
	var columns = get_columns(type);
	// not a smart way but for the time being, hide platform/tracks
	//columns[5].hidden = true;	// Tracks
	var auto_expand_column = "entity_name";
	var mode = type;
	var fields = dataset_json_fields;
	var id_column = "dataset_id";
	group_field = "";
	param_list = ["provider_id", "keyword", "publish"];
	var rs_panel = rs_panel_datasets;
	
	var params = {mode: mode, start:0, limit:50};
	var store = new Ext.data.GroupingStore({
		groupField: group_field,
		storeId: store_id,
		//dirty: true,
		remoteGroup: true,
		remoteSort: true,
		autoLoad: false,
		proxy: new Ext.ux.OBISProxy(),
		baseParams: params,
		listeners: {
			beforeload: function(store, options){
				store.remoteSort = true;
				store.remoteGroup = true;
				var params = gQuery.toQueryObject();
				options.params = Ext.copyTo(options.params, params, param_list);
				var sortInfo = this.getSortState();
				options.params.sort = sortInfo.field;
				options.params.dir = sortInfo.direction;
				this.lastQuery = options.params;
			},
			load: data_loaded
		},
		reader: new Ext.ux.OBISJsonReader({   
		    id: id_column,
		    fields: fields
		}),
		sortInfo:{field: 'added', direction: "DESC"}
	});	
	
	cm = new Ext.grid.ColumnModel({defaults:{readOnly: true}, columns: columns});
	cm.defaultSortable= true;
	
	gv = new Ext.grid.GroupingView({
		groupTextTpl: '{group} ({[values.rs.length]})'
	});
	
		
    var grid = new Ext.grid.GridPanel({
    	id: grid_id,
        title:'List of datasets', header: false,
        store: store,
        trackMouseOver:true,
        loadMask: true,
		autoHeight: false,
		cm: cm,
		sm: new Ext.ux.RowSelectionModelMSBSC(),
	    view: gv,
		stripeRows: true,
		autoExpandColumn: auto_expand_column,
		stateful: false,
	    listeners: {
	    	rowclick: row_clicked
	    }
        
    });

    return grid;
}

function build_species_search() {
	if (!Ext.getCmp("win_species")) {
		var width = $("map_tool_divs").getWidth();
		var name_search_drop_downs = build_name_search_drop_downs();
		
		var panel_species = new Ext.Panel({
			title: rs_win_species.title,
			id: "win_species",
	        layout:'fit',
	        autoShow: true,
	        header: false,
		    //tools: [{id: 'help', handler: function(event, toolEl, panel, tc){panel.show_help_tip()}}],
		    renderTo: "toolbar_species",
		    html: "",
		    width: width, height: 300,
		    tbar: [
		    	{xtype: 'tbtext', text: name_search_drop_downs},
		    	{
			    	xtype: 'textfield',
			    	name: 'tbox_species',
			    	id: 'tbox_species',
			    	emptyText: rs_win_species.tbar.emptyText,
		            listeners: {
		                specialkey: function(field, e){
		                    if (e.getKey() == e.ENTER) {
		                        var text = field.getValue();
		                    }
		                }
		            }
			    }
		    ],
		    items: [build_taxon_tree()]
		});
	
		
		/***** Species live search *****/
		var store_species_search = new Ext.ux.OBISGroupingStore({
			id: 'store_species_search',
			proxy: new Ext.ux.OBISProxy(),
			baseParams: {mode: "species_search"},
			reader: new Ext.ux.OBISJsonReader({   
			    id: 'valid_id',
			    fields: species_json_fields
			    }),
			listeners: {
				beforeload: function(store, options) {
					// This is the key to solve the shaky combobox problem that it loses a focus
					// after selecting an item from the list and fails to show up when continuing to type in.
					Ext.getCmp("combo_species_search").onFocus({});
					options.params = Ext.apply(options.params, {name_search: gQuery.options.name_search, search_for: gQuery.options.search_for});
				}
			}
		});
				
	    var resultTpl = new Ext.XTemplate(
	        '<tpl for="."><div class="search-item">',
	            '{display_name} (',
	            '<tpl if="sp_common != &quot;&quot;">',
	            '{sp_common}, ',
	            '</tpl>',
	            '{sp_rank}, {num_records:number("0,000")})',
	        '</div></tpl>'
	    );   	 
	    
	    var species_search = new Ext.form.ComboBox({
	        store: store_species_search,
	        id: "combo_species_search",
	        typeAhead: false,
	        loadingText: rs_win_species.species_live_search.loadingText,
	        width: 400,
	        pageSize:20,
	        hideTrigger:true,
	        tpl: resultTpl,
	        applyTo: 'tbox_species',
	        itemSelector: 'div.search-item',
	        minChars: 4,
	        onSelect: function(record){ // override default onSelect to do redirect
	            var tree = Ext.getCmp("grid_taxa_tree");
	            if (tree && record.data.storedpath != "") {
		            // somehow tree.rendered returns false. So do not evaluate it.
	            	// For classified species with storedpath populated
	            	var parents = record.data.storedpath + record.data.sp_tsn;
		            tree.getSelectionModel().clearSelections(true);
		            tree.climb_down_to2(parents, record.data.sp_tsn, "|", 0);
	            } 
	            this.setValue(record.data.display_name);
	            this.collapse();
	            if (record.data.sp_rank != "Species") {
	            	record.data.include_children = true;
	            }
	            var species = record.data;
	            gQuery["species"] =[species];
	            update_layers({}, update_map);
                if (species.data_extent != "" && species.sp_rank != "Class") {
	            	zoomToBOX3D(record.data.data_extent);
                }
	        },
	        listeners: {
	        	afterrender: function() {
	        		if (gQuery.species.length > 0) {
	        			this.onSelect({data: gQuery.species[0]});
	        		}
	        	},
				expand: function(combo) {
					// hack for an issue that the paging toolbar does not show up in IE7.
					if (combo.assetHeight == 0 && combo.pageSize > 0 && Ext.isIE7) {
					   combo.assetHeight = 28;
					}
				}	        	
	        }
	    });
	}
}

function build_name_search_drop_downs() {
	var rs = rs_win_species.tbar;
	var html = "<table><tr>";
	html += "<td>";
	html += "<select onchange='gQuery.options.search_for = this.value;'>";
	html += "<option selected value='scientific'>{0}</option>";
	html += "<option value='common'>{1}</option>";
	html += "</select>";
	html += "</td>";
	html += "<td>";
	html += "<select onchange='gQuery.options.name_search = this.value;'>";
	html += "<option selected value='begin_with'>{2}</option>";
	html += "<option value='any_part_of'>{3}</option>";
	html += "</select>";
	html += "</td>";
	html += "</tr></table>";
	
	html = String.format(html, rs.scientific, rs.common, rs.begins_with, rs.contains);
	return html;
}

function build_taxon_tree() {
	var columns = get_taxon_tree_columns();
	var grid_taxa_tree = new Ext.ux.TaxonTreeGrid({
		id: "grid_taxa_tree",
		title: rs_grid_taxa_tree.title,
	    height: 300,
	    cls: 'x-tree-noicon',
	    rootVisible: false,
	    stateful: false,
	    columnResize: false,
	    autoExpandColumn: 'scientific_name',
	    enableSort: false,
	    enableHdMenu: false,
        columns: columns,
	    
		taxon_node_clicked: function(selModel, node) {
            var combo = Ext.getCmp("combo_species_search");
			combo.setValue(node.attributes.scientific_name);
            combo.collapse();
            var species = node.attributes;
            species.loader = null;	// somehow node.attributes has loader and uiProvider which cause too many iteration error.
            species.uiProvider = null;
            if (species.sp_rank != "Species") {
            	species.include_children = true;
            }            
			gQuery.species = [species];
            update_layers({}, update_map);
            if (species.data_extent != "" && species.sp_rank != "Class") {
           		zoomToBOX3D(species.data_extent);
            }
		}
	});	
	
	return grid_taxa_tree;
}


function toggle_button(button, tool) {
	var toolbars = ["species", "datasets"];
	var id_prefix = "frame_toolbar_";
	if ($(button).down('h3').hasClassName("selected")) {
		var invoke = "hide";
		close_panel(tool);
	} else {
		var invoke = "show";
	}
	$$("div.button h3").invoke("removeClassName", "selected");
	toolbars.each(function(item){
		if (item != tool) {
			$(id_prefix + item).hide();
			close_panel(item);
		}
	});
	$$("#" + id_prefix + tool, "#instructions_to_toolbar").invoke(invoke);
	if (invoke == "show") {
		$(button).down('h3').addClassName('selected');		
	}
}

function close_panel(type) {
	//var div_inst = "#instructions_to_toolbar";
	switch (type) {
		case "species":
			if (Ext.getCmp("grid_taxa_tree")) {
				Ext.getCmp("grid_taxa_tree").getSelectionModel().clearSelections(true);
			}
			break;
		case "datasets":
			if (Ext.getCmp("grid_datasets")) {
				Ext.getCmp("grid_datasets").getSelectionModel().clearSelections();
			}
			break;
	}
	gQuery[type] = [];
	
	update_layers({}, update_map);
}

function open_map_legend() {
	get_legend();
	var div_map = Ext.get("div_map");
	var div = Ext.get("div_legend");
	// it seems div.getHeight() returns inaccurate height because the div is not rendered yet??
	//div.setLocation(div_map.getRight() + 5, div_map.getBottom() - 175);
	//div.toggle(true);
}

/***** TaxonTreeGrid *****/
function get_taxon_tree_columns() {
	var width = Ext.getCmp("panel_main_frame").getWidth();
	var template_str = "<a href='" + SPECIES_PAGE.replace("0", "sp_tsn") + "' title='Go to Species Profile Page' target='species_profile' onmousedown='cancel_bubble(event);' onclick='cancel_bubble(event);'>{scientific_name}</a>";
	var columns = [{
            id: "scientific_name",
        	header: rs_panel_species.cm.scientific_name,
            dataIndex: 'scientific_name',
            width: 330,
            tpl: new Ext.XTemplate(template_str)
        },{
            header: rs_win_species.tbar.common,
            width: 180,
            dataIndex: 'sp_common'
        },{
            header: rs_panel_species.cm.rank,
            width: 90,
            dataIndex: 'sp_rank'
        },{
            header: rs_panel_species.cm.num_records,
            width: 100,
            dataIndex: 'num_records_incl',
            align: 'right',
            tpl: new Ext.XTemplate('{num_records_incl:this.format_num}', {
                format_num: function(value) {
                	return int_format(value);
                }
            })
        },{
            header: rs_panel_species.cm.num_datasets,
            width: 90,
            dataIndex: 'num_datasets_incl',
            align: 'right',
            tpl: new Ext.XTemplate('{num_datasets_incl:this.format_num}', {
                format_num: function(value) {
                	return int_format(value);
                }
            })
        }];
	return columns;
}

Ext.ux.TaxonTreeGridLoader = Ext.extend(Ext.ux.tree.TreeGridLoader, {
	dataUrl: ROOT_URL + BASE_URL + PORTAL_MAIN,
	baseParams2: {parent_id: 331030, mode: "species_in_tree"},
	nodeParamsDef: {sp_tsn: "parent_id"},
	
	attachNodeParams: function(node) {
		var params = [];
		if (node.isRoot) {
			params = this.baseParams2;
		} else {
			$H(this.nodeParamsDef).each(function (pair) {
				params[pair.value] = node.attributes[pair.key];
			});
		}
		return params;
	},
	
	build_parameters: function(treeLoader, node) {
		var nodeParams = this.attachNodeParams(node);
		this.baseParams = $H(this.baseParams2).merge(nodeParams).toObject();
	},
	
	listeners: {
		beforeload: function(treeLoader, node) {this.build_parameters(treeLoader, node);}
	}
	
});

/*****
<<< Taxonomic Tree Panel >>>
Combined with Taxonomic Tree Loader defined above.
*****/
Ext.ux.TaxonTreeGrid = Ext.extend(Ext.ux.tree.TreeGrid, {
	nodeTextField: "scientific_name	",
	nodeIdField: "sp_tsn",
	treeDelimiter: "|",
	leafKey: {sp_rank: "Species"},
	loader: new Ext.ux.TaxonTreeGridLoader(),
	
    initComponent:function() {
        // call parent init component
        Ext.ux.TaxonTreeGrid.superclass.initComponent.apply(this, arguments);
		this.getSelectionModel().on("selectionchange", this.taxon_node_clicked);        
    },
	
	prepareNode: function(theTree, parentNode, thisNode) {
		if (this.nodeIdField != "") {
			thisNode.id = thisNode.attributes[this.nodeIdField];
		}
		thisNode.text = this.setNodeText(theTree, parentNode, thisNode);
		thisNode.leaf = thisNode.attributes.sp_rank == "Species" ? true: false;
	},
	
	setNodeText: function(theTree, parentNode, thisNode) {
		if (thisNode.attributes.text == undefined || thisNode.attributes.text == "") {
	    	var s = thisNode.attributes[this.nodeTextField];
		} else {
			var s = thisNode.attributes.text;
		}
		return s;
	},
	taxon_node_clicked: function(selModel, node) {
		//this.fireEvent("taxonselect", this, selModel, node);
	},
	
	climb_down_to: function(tree, delimiter, index) {
		var branches = tree.split(delimiter);
		var taxon_tree = this;
		var node = this.getNodeById(branches[index]);		
		if (index < branches.length - 1) {
			var callback = function() {taxon_tree.climb_down_to(tree, delimiter,  index + 1)};
			node.expand(false, false, callback);
		} else {
			if (node.isLeaf()) {
				node.parentNode.select();	
			} else {
				node.select();
			}
		}
			
	},
	
	climb_down_to2: function(tree, target_tsn, delimiter, index) {
		var params = {mode: "species_in_tree2", storedpath: tree, target_tsn: target_tsn, tree_id: this.id};
		Ext.Ajax.request({
		   url: ROOT_URL + BASE_URL + PORTAL_MAIN,
		   success: this.climb_down_to_success,
		   failure: this.climb_down_to_failure,
		   params: params
		});		
	},

	climb_down_to_success: function(oj, opts) {
		var tree_data = oj.responseText.evalJSON();
		var tree = tree_data.records;
		//var grid_tree = this;
		var grid_tree = Ext.getCmp(opts.params.tree_id);
		var target_child = null;
		var delimiter = grid_tree.treeDelimiter;
		var id_field = grid_tree.nodeIdField;
		tree.each(function(item){
			var parents = item.storedpath.split(delimiter);
			var parent_id = parents[parents.length - 2];
			var node = grid_tree.getNodeById(parent_id);
			// For the time being, ignore the very top rank as it's not in the tree.
			if (parent_id != "331030") {
				if (!grid_tree.getNodeById(item[id_field])) {
					var child = node.appendChild(item);
					if (!node.isLeaf() && !node.isExpanded()) {
						node.loaded = true;
						node.expand(false, false);
					}
				} else {
					var child = grid_tree.getNodeById(item[id_field]);
				}
				if (parseInt(child.attributes[id_field]) == opts.params.target_tsn) {
					target_child = child;
				}
			}
		});
		grid_tree.getSelectionModel().suspendEvents(false);
		target_child.select();
		target_child.ensureVisible();
		grid_tree.getSelectionModel().resumeEvents();
	},
	
	listeners: {
		beforeappend: function(theTree, parentNode, thisNode) {this.prepareNode(theTree, parentNode, thisNode);}
	}
});
