<?xml version="1.0"?>
<!--
    ***** BEGIN LICENSE BLOCK *****
    
    Copyright © 2009 Center for History and New Media
                     George Mason University, Fairfax, Virginia, USA
                     http://zotero.org
    
    This file is part of Zotero.
    
    Zotero is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    Zotero is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.
    
    You should have received a copy of the GNU Affero General Public License
    along with Zotero.  If not, see <http://www.gnu.org/licenses/>.
    
    ***** END LICENSE BLOCK *****
-->

<!DOCTYPE bindings SYSTEM "chrome://zotero/locale/searchbox.dtd">

<bindings xmlns="http://www.mozilla.org/xbl"
		  xmlns:xbl="http://www.mozilla.org/xbl"
		  xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
	
	<binding id="search-box">
		<resources>
			<stylesheet src="chrome://zotero/skin/bindings/search.css"/>
		</resources>
		
		<implementation>
			<property name="groups"/>
			
			<field name="searchRef"/>
			<property name="search" onget="return this.searchRef;">
				<setter>
					<![CDATA[
						this.searchRef = val;
						
						this.buildLibraryMenu();
						
						var conditionsBox = this.id('conditions');
						while(conditionsBox.hasChildNodes())
							conditionsBox.removeChild(conditionsBox.firstChild);
						
						var conditions = this.search.getConditions();
						for (let id in conditions) {
							let condition = conditions[id];
							// Checkboxes
							switch (condition.condition) {
								case 'recursive':
								case 'noChildren':
								case 'includeParentsAndChildren':
									let checkbox = condition.condition + 'Checkbox';
									this.id(checkbox).setAttribute('condition', id);
									this.id(checkbox).checked = condition.operator == 'true';
									continue;
							}
							
							if(condition.condition == 'joinMode') {
								this.id('joinModeMenu').setAttribute('condition', id);
								this.id('joinModeMenu').value = condition.operator;
							}
							else {
								this.addCondition(condition);
							}
						}
					]]>
				</setter>
			</property>
			
			<method name="buildLibraryMenu">
				<body><![CDATA[
					var menulist = this.id('libraryMenu');
					var menupopup = menulist.firstChild;
					
					while (menupopup.hasChildNodes()) {
						menupopup.removeChild(menupopup.firstChild);
					}
					
					var libraryID = this.searchRef.libraryID;
					var libraryIndex = 0;
					
					// Add My Library
					var menuitem = document.createElement('menuitem');
					menuitem.setAttribute('label', Zotero.getString('pane.collections.library'));
					menuitem.setAttribute('libraryID', Zotero.Libraries.userLibraryID);
					menupopup.appendChild(menuitem);
					
					// Add groups
					for (let i = 0; i < this.groups.length; i++) {
						let group = this.groups[i];
						let menuitem = document.createElement('menuitem');
						menuitem.setAttribute('label', group.name);
						menuitem.setAttribute('libraryID', group.libraryID);
						if (group.libraryID == libraryID) {
							libraryIndex = i + 1;
						}
						menupopup.appendChild(menuitem);
					}
					
					menulist.appendChild(menupopup);
					menulist.selectedIndex = libraryIndex;
					
					if (this.searchRef.id) {
						this.id('libraryMenu').disabled = true;
					}
					
					this.updateLibrary();
				]]></body>
			</method>
			
			<method name="addCondition">
				<parameter name="ref"/>
				<body>
					<![CDATA[
						var conditionsBox = this.id('conditions');
						var condition = document.createElement('zoterosearchcondition');
						condition.setAttribute('flex','1');
						
						conditionsBox.appendChild(condition);
						
						// Default to an empty 'title' condition
						if (!ref) {
							ref = this.search.getCondition(this.search.addCondition("title","contains",""))
						}
						
						condition.initWithParentAndCondition(this, ref);
						
						if (conditionsBox.childNodes.length == 2){
							conditionsBox.childNodes[0].enableRemoveButton();
						}
						else if (conditionsBox.childNodes.length == 1){
							conditionsBox.childNodes[0].disableRemoveButton();
						}
					]]>
				</body>
			</method>
			
			<method name="removeCondition">
				<parameter name="id"/>
				<body>
					<![CDATA[
						var conditionsBox = this.id('conditions');
						
						this.search.removeCondition(id);
						
						for (var i = 0, len=conditionsBox.childNodes.length; i < len; i++){
							if (conditionsBox.childNodes[i].conditionID == id){
								conditionsBox.removeChild(conditionsBox.childNodes[i]);
								break;
							}
						}
						
						if (conditionsBox.childNodes.length == 1){
							conditionsBox.childNodes[0].disableRemoveButton();
						}
					]]>
				</body>
			</method>
			
			<method name="updateLibrary">
				<body><![CDATA[
					var menu = this.id('libraryMenu');
					var libraryID = parseInt(menu.selectedItem.getAttribute('libraryID'));
					
				 	if (this.onLibraryChange) {
				 		this.onLibraryChange(libraryID);
					}
					if (!this.searchRef.id) {
						this.searchRef.libraryID = libraryID;
					}
				]]></body>
			</method>
			
			<method name="updateJoinMode">
				<body>
					<![CDATA[
						var menu = this.id('joinModeMenu');
						if(menu.hasAttribute('condition'))
							this.search.updateCondition(menu.getAttribute('condition'),'joinMode',menu.value,null);
						else
							menu.setAttribute('condition', this.search.addCondition('joinMode',menu.value,null));
					]]>
				</body>
			</method>
			
			<method name="updateCheckbox">
				<parameter name="condition"/>
				<body>
					<![CDATA[
						var checkbox = this.id(condition + 'Checkbox');
						var value = checkbox.checked ? 'true' : 'false';
						if(checkbox.hasAttribute('condition'))
						{
							this.search.updateCondition(checkbox.getAttribute('condition'),
								condition, value, null);
						}
						else
						{
							checkbox.setAttribute('condition',
								this.search.addCondition(condition, value, null));
						}
					]]>
				</body>
			</method>
			
			<!-- Calls updateSearch() on all search conditions -->
			<method name="updateSearch">
				<body>
					<![CDATA[
						var conditionsBox = this.id('conditions');
						if (conditionsBox.hasChildNodes()) {
							for(var i = 0, len=conditionsBox.childNodes.length; i < len; i++) {
								conditionsBox.childNodes[i].updateSearch();
							}
						}
					]]>
				</body>
			</method>
			
			<method name="save">
				<body>
					<![CDATA[
						this.updateSearch();
						return this.search.save();
					]]>
				</body>
			</method>
			
			<method name="handleKeyPress">
				<parameter name="event"/>
				<body>
				<![CDATA[
					switch (event.keyCode) {
						case event.DOM_VK_RETURN:
							this.active = true;
							
							if (event.shiftKey) {
								this.addCondition();
							}
							else {
								this.doCommand();
							}
							break;
					}
				]]>
				</body>
			</method>
			
			<method name="id">
				<parameter name="id"/>
				<body>
					<![CDATA[
						return document.getAnonymousNodes(this)[0].getElementsByAttribute('id',id)[0];
					]]>
				</body>
			</method>
		</implementation>
		
		<content>
			<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
					id="search-box" flex="1" onkeypress="document.getBindingParent(this).handleKeyPress(event)">
				<hbox align="center">
					<label value="&zotero.search.searchInLibrary;" control="libraryMenu"/>
					<menulist id="libraryMenu" oncommand="document.getBindingParent(this).updateLibrary();">
						<menupopup/>
					</menulist>
				</hbox>
				<groupbox xbl:inherits="flex">
					<caption align="center">
						<label value="&zotero.search.joinMode.prefix;"/>
						<menulist id="joinModeMenu" oncommand="document.getBindingParent(this).updateJoinMode();">
							<menupopup>
								<menuitem label="&zotero.search.joinMode.any;" value="any"/>
								<menuitem label="&zotero.search.joinMode.all;" value="all" selected="true"/>
							</menupopup>
						</menulist>
						<label value="&zotero.search.joinMode.suffix;"/>
					</caption>
					<vbox id="conditions"/>
				</groupbox>
				<hbox>
					<checkbox id="recursiveCheckbox" label="&zotero.search.recursive.label;" oncommand="document.getBindingParent(this).updateCheckbox('recursive');"/>
					<checkbox id="noChildrenCheckbox" label="&zotero.search.noChildren;" oncommand="document.getBindingParent(this).updateCheckbox('noChildren');"/>
				</hbox>
				<hbox>
					<checkbox id="includeParentsAndChildrenCheckbox" label="&zotero.search.includeParentsAndChildren;" oncommand="document.getBindingParent(this).updateCheckbox('includeParentsAndChildren');"/>
				</hbox>
			</vbox>
		</content>
	</binding>
	
	
	
	<binding id="search-condition">
		<resources>
			<stylesheet src="chrome://zotero/skin/bindings/search.css"/>
		</resources>
		
		<implementation>
			<field name="conditionID"/>
			<field name="selectedCondition"/>
			<field name="mode"/>
			<field name="selectedOperator"/>
			<field name="value"/>
			<field name="parent"/>
			<field name="dontupdate"/>
			<constructor>
				<![CDATA[
					var operators = new Array('is', 'isNot', 'beginsWith', 'contains', 'doesNotContain', 'isLessThan', 'isGreaterThan', 'isBefore', 'isAfter', 'isInTheLast');
					var operatorsList = this.id('operatorsmenu');
					
					// Build operator menu
					for(var i in operators)
					{
						operatorsList.appendItem(Zotero.getString('searchOperator.'+operators[i]),operators[i]);
					}
					
					// Build conditions menu
					var conditionsList = this.id('conditionsmenu');
					var conditions = Zotero.SearchConditions.getStandardConditions();
					
					for (var i=0, len=conditions.length; i<len; i++) {
						var menuitem = conditionsList.appendItem(conditions[i]['localized'], conditions[i]['name']);
						
						var baseFields = null;
						try {
							baseFields = Zotero.ItemFields.getTypeFieldsFromBase(conditions[i]['name']);
						}
						catch (e) {}
						
						// Add tooltip, building it if it doesn't exist
						if (baseFields) {
							if (!this.id(conditions[i]['name'] + '-tooltip')) {
								var fieldName = null;
								try {
									fieldName = Zotero.ItemFields.getLocalizedString(null, conditions[i].name);
								}
								catch (e) {}
								
								if (fieldName) {
									var localized = [fieldName];
								}
								else {
									var localized = [];
								}
								
								for (var j in baseFields) {
									var str = Zotero.SearchConditions.getLocalizedName(Zotero.ItemFields.getName(baseFields[j]));
									
									if (localized.indexOf(str) == -1) {
										localized.push(str);
									}
								}
								localized.sort();
								
								var tt = document.createElement('tooltip');
								tt.setAttribute('id', conditions[i]['name'] + '-tooltip');
								tt.setAttribute('orient', 'vertical');
								tt.setAttribute('noautohide', true);
								
								var grid = document.createElement('grid');
								
								var columns = document.createElement('columns');
								var col1 = document.createElement('column');
								var col2 = document.createElement('column');
								columns.appendChild(col1);
								columns.appendChild(col2);
								
								var rows = document.createElement('rows');
								
								var fieldRow = document.createElement('row');
								var label = document.createElement('label');
								label.setAttribute('value', Zotero.getString('searchConditions.tooltip.fields'));
								fieldRow.appendChild(label);
								var vbox = document.createElement('vbox');
								for each(var str in localized) {
									var label = document.createElement('label')
									label.setAttribute('value', str);
									vbox.appendChild(label);
								}
								fieldRow.appendChild(vbox);
								
								rows.appendChild(fieldRow);
								
								grid.appendChild(rows);
								tt.appendChild(grid);
								
								this.id('condition-tooltips').appendChild(tt);
							}
							
							menuitem.setAttribute('tooltip', conditions[i]['name'] + '-tooltip');
						}
					}
					conditionsList.selectedIndex = 0;
				]]>
			</constructor>
			<method name="onConditionSelected">
				<body>
					<![CDATA[
					// Skip if correct condition already selected
					if (this.id('conditionsmenu').value==this.selectedCondition){
						return;
					}
					var conditionsMenu = this.id('conditionsmenu');
					var operatorsList = this.id('operatorsmenu');
					
					this.selectedCondition = conditionsMenu.value;
					this.selectedOperator = operatorsList.value;
					
					var condition = Zotero.SearchConditions.get(conditionsMenu.value);
					var operators = condition['operators'];
					
					// Display appropriate operators for condition
					var selectThis;
					for(var i = 0, len = operatorsList.firstChild.childNodes.length; i < len; i++)
					{
						var val = operatorsList.firstChild.childNodes[i].getAttribute('value');
						var hidden = !operators[val];
						operatorsList.firstChild.childNodes[i].setAttribute('hidden', hidden);
						if (!hidden && (selectThis == null || this.selectedOperator == val))
						{
							selectThis = i;
						}
					}
					operatorsList.selectedIndex = selectThis;
					
					// Generate drop-down menu instead of textbox for certain conditions
					switch (conditionsMenu.value){
						case 'collection':
							var rows = [];
							
							var libraryID = this.parent.search.libraryID;
							var cols = Zotero.getCollections(false, true, libraryID);
							for (var i in cols) {
								// Indent subcollections
								var indent = '';
								if (cols[i].level) {
									for (var j=1; j<cols[i].level; j++) {
										indent += '    ';
									}
									indent += '- ';
								}
								rows.push([indent + cols[i].name, 'C' + cols[i].key]);
							}
							this.createValueMenu(rows);
							break;
						
						case 'savedSearch':
							var rows = [];
							var libraryID = this.parent.search.libraryID;
							var searches = Zotero.Searches.getAll(libraryID);
							for (var i in searches) {
								if (searches[i].id != this.parent.search.id) {
									rows.push([searches[i].name, 'S' + searches[i].key]);
								}
							}
							this.createValueMenu(rows);
							break;
						
						case 'itemType':
							var t = Zotero.ItemTypes.getTypes();
							
							// Sort by localized name
							var types = [];
							for (var i=0; i<t.length; i++) {
								types.push({
									id: t[i].id,
									name: t[i].name,
									localized: Zotero.ItemTypes.getLocalizedString(t[i].id)
								});
							}
							var collation = Zotero.getLocaleCollation();
							types.sort(function(a, b) {
								return collation.compareString(1, a.localized, b.localized);
							});
							
							for (var i in types) {
								types[i][0] = types[i].localized;
								types[i][1] = types[i].name;
								delete types[i]['name'];
								delete types[i]['id'];
							}
							this.createValueMenu(types);
							break;
						
						case 'fileTypeID':
							var types = Zotero.FileTypes.getTypes();
							for (var i in types) {
								types[i][0] = Zotero.getString('fileTypes.' + types[i]['name']);
								types[i][1] = types[i]['id'];
								delete types[i]['name'];
								delete types[i]['id'];
							}
							this.createValueMenu(types);
							break;
						
						default:
							if (operatorsList.value=='isInTheLast')
							{
								this.id('value-date-age').value = this.value;
							}
							
							// Textbox
							else {
								// If switching from menu to textbox, clear value
								if (this.id('valuefield').hidden){
									this.id('valuefield').value = '';
								}
								// If switching between textbox conditions, get loaded value for new one
								else {
									this.id('valuefield').value = this.value;
								}
								
								// Update field drop-down if applicable
								this.id('valuefield').update(conditionsMenu.value, this.mode);
							}
					}
					
					this.onOperatorSelected();
					]]>
				</body>
			</method>
			<method name="onOperatorSelected">
				<body>
					<![CDATA[
					var conditionsMenu = this.id('conditionsmenu');
					var operatorsList = this.id('operatorsmenu');
					
					// Drop-down menu
					if (conditionsMenu.value == 'collection'
							|| conditionsMenu.value == 'savedSearch'
							|| conditionsMenu.value == 'itemType'
							|| conditionsMenu.value == 'fileTypeID') {
						this.id('valuefield').hidden = true;
						this.id('valuemenu').hidden = false;
						this.id('value-date-age').hidden = true;
					}
					
					// Textbox + units dropdown for isInTheLast operator
					else if (operatorsList.value=='isInTheLast')
					{
						// If switching from text field, clear value
						if (this.id('value-date-age').hidden){
							this.value = '';
						}
						this.id('valuefield').hidden = true;
						this.id('valuemenu').hidden = true;
						this.id('value-date-age').hidden = false;
					}
					
					// Textbox
					else
					{
						// If switching from date age, clear value
						if (this.id('valuefield').hidden){
							this.value = '';
						}
						this.id('valuefield').hidden = false;
						this.id('valuemenu').hidden = true;
						this.id('value-date-age').hidden = true;
					}
					]]>
				</body>
			</method>
			<method name="createValueMenu">
				<parameter name="values"/>
				<body>
					<![CDATA[
						while (this.id('valuemenu').hasChildNodes()){
							this.id('valuemenu').removeChild(this.id('valuemenu').firstChild);
						}
						
						if (values.length){
							for (var i in values){
								this.id('valuemenu').appendItem(values[i][0], values[i][1]);
							}
							this.id('valuemenu').selectedIndex = 0;
						}
						
						if (this.value)
						{
							this.id('valuemenu').value = this.value;
						}
					]]>
				</body>
			</method>
			<method name="initWithParentAndCondition">
				<parameter name="parent"/>
				<parameter name="condition"/>
				<body>
					<![CDATA[
						this.parent = parent;
						this.conditionID = condition['id'];
						
						if(this.parent.search)
						{
							this.dontupdate = true;	//so that the search doesn't get updated while we are creating controls.
							var prefix = '';
							
							// Handle special conditions
							switch (condition.condition) {
								case 'savedSearch':
									prefix = 'S';
									break;
								
								case 'collection':
									prefix = 'C';
									break;
							}
							
							this.id('conditionsmenu').value = condition.condition;
							
							// Convert datetimes from UTC to localtime
							if ((condition['condition']=='accessDate' ||
									condition['condition']=='dateAdded' ||
									condition['condition']=='dateModified') &&
									Zotero.Date.isSQLDateTime(condition['value'])){
								
								condition['value'] =
									Zotero.Date.dateToSQL(Zotero.Date.sqlToDate(condition['value'], true));
							}
							
							this.mode = condition['mode'];
							this.id('operatorsmenu').value = condition['operator'];
							this.value = prefix +
								(condition.value ? condition.value : '');

							this.dontupdate = false;
						}
						
						this.onConditionSelected();
						
						this.id('conditionsmenu').focus();
					]]>
				</body>
			</method>
			<!-- Gets the value from the field and updates the associated search condition -->
			<method name="updateSearch">
				<body>
					<![CDATA[
						if(this.parent && this.parent.search && !this.dontupdate)
						{
							var condition = this.id('conditionsmenu').value;
							var operator = this.id('operatorsmenu').value;
							
							// Regular text field
							if (!this.id('valuefield').hidden)
							{
								var value = this.id('valuefield').value;
								
								// Convert datetimes to UTC before saving
								switch (this.id('conditionsmenu').value) {
									case 'accessDate':
									case 'dateAdded':
									case 'dateModified':
										if (Zotero.Date.isSQLDateTime(value)) {
											var value = Zotero.Date.dateToSQL(Zotero.Date.sqlToDate(value), true);
										}
								}
								
								// Append mode to condition
								if (this.id('valuefield').mode){
									condition += '/' + this.id('valuefield').mode;
								}
							}
							
							// isInTheLast operator
							else if (!this.id('value-date-age').hidden)
							{
								var value = this.id('value-date-age').value;
							}
							
							// Handle special C1234 and S5678 form for
							// collections and searches
							else if (this.id('conditionsmenu').value == 'collection' || this.id('conditionsmenu').value == 'savedSearch')
							{
								var letter = this.id('valuemenu').value.substr(0,1);
								if (letter=='C')
								{
									condition = 'collection';
								}
								else if (letter=='S')
								{
									condition = 'savedSearch';
								}
								var value = this.id('valuemenu').value.substr(1);
							}
							
							// Regular drop-down menu
							else
							{
								var value = this.id('valuemenu').value;
							}
							this.parent.search.updateCondition(this.conditionID, condition, operator, value);
						}
					]]>
				</body>
			</method>
			<method name="onRemoveClicked">
				<body>
					<![CDATA[
						if (this.parent){
							this.parent.removeCondition(this.conditionID);
							window.sizeToContent()
						}
					]]>
				</body>
			</method>
			<method name="onAddClicked">
				<body>
					<![CDATA[
						if (this.parent){
							this.parent.addCondition();
							window.sizeToContent();
						}
					]]>
				</body>
			</method>
			<method name="disableRemoveButton">
				<body>
					<![CDATA[
						var button = this.id("remove");
						button.setAttribute('disabled', true);
						button.removeAttribute('onclick');
					]]>
				</body>
			</method>
			<method name="enableRemoveButton">
				<body>
					<![CDATA[
						var button = this.id("remove");
						button.setAttribute('disabled', false);
						button.setAttribute('onclick', "document.getBindingParent(this).onRemoveClicked(event)");
					]]>
				</body>
			</method>
			<method name="id">
				<parameter name="id"/>
				<body>
					<![CDATA[
						var elems = document.getAnonymousNodes(this)[0].getElementsByAttribute('id',id);
						return elems[0] ? elems[0] : false;
					]]>
				</body>
			</method>
		</implementation>
		
		<content>
			<xul:hbox id="search-condition" xbl:inherits="flex">
				<xul:popupset id="condition-tooltips"/>
				
				<xul:menulist id="conditionsmenu" oncommand="document.getBindingParent(this).onConditionSelected(); event.stopPropagation()">
					<xul:menupopup/>
				</xul:menulist>
				<xul:menulist id="operatorsmenu" oncommand="document.getBindingParent(this).onOperatorSelected(); event.stopPropagation()">
					<xul:menupopup/>
				</xul:menulist>
				<xul:zoterosearchtextbox id="valuefield" flex="1"/>
				<xul:menulist id="valuemenu" flex="1" hidden="true">
					<xul:menupopup/>
				</xul:menulist>
				<xul:zoterosearchagefield id="value-date-age" hidden="true" flex="1"/>
				<xul:label id="remove" class="zotero-clicky zotero-clicky-minus" value="-" onclick="document.getBindingParent(this).onRemoveClicked(event)"/>
				<xul:label id="add" class="zotero-clicky zotero-clicky-plus" value="+" onclick="document.getBindingParent(this).onAddClicked(event)"/>
			</xul:hbox>
		</content>
	</binding>
	
	
	
	<binding id="search-textbox">
		<resources>
			<stylesheet src="chrome://zotero/skin/bindings/search.css"/>
		</resources>
		
		<implementation>
			<property name="value"
				onget="return document.getAnonymousNodes(this)[0].value"
				onset="document.getAnonymousNodes(this)[0].setAttribute('value', val); return val"/>
			<property name="mode">
				<getter>
					<![CDATA[
						if (this.getAttribute('hasOptions')!='true'){
							return false;
						}
						
						var button = this.id('textbox-button');
						var menu = this.id(button.popup);
						
						var selectedIndex = -1;
						for (var i=0; i<menu.childNodes.length; i++){
							if (menu.childNodes[i].getAttribute('checked')=='true'){
								selectedIndex = i;
								break;
							}
						}
						switch (button.popup){
							case 'textbox-fulltext-menu':
								switch (selectedIndex){
									case 0:
										return false;
									
									case 1:
										return 'phraseBinary';
									
									case 2:
										return 'regexp';
									
									case 3:
										return 'regexpCS';
								}
								break;
						}
						
						throw('Invalid search textbox popup');
					]]>
				</getter>
			</property>
			<method name="update">
				<parameter name="condition"/>
				<parameter name="mode"/>
				<body>
					<![CDATA[
						var button = this.id('textbox-button');
						
						switch (condition){
							case 'fulltextContent':
								button.popup = 'textbox-fulltext-menu';
								button.setAttribute('popup', 'textbox-fulltext-menu');
								var menu = this.id(button.popup);
								this.setAttribute('hasOptions', true);
								
								var selectedIndex = 0;
								if (mode){
									switch (mode){
										case 'phrase':
											selectedIndex = 0;
											break;
										
										case 'phraseBinary':
											selectedIndex = 1;
											break;
										
										case 'regexp':
											selectedIndex = 2;
											break;
										
										case 'regexpCS':
											selectedIndex = 3;
											break;
									}
								}
								menu.childNodes[selectedIndex].setAttribute('checked', true);
								break;
								
							default:
								this.setAttribute('hasOptions', false);
								
								// Set textbox to autocomplete mode
								switch (condition)
								{
									// Skip autocomplete for these fields
									case 'date':
									case 'note':
									case 'extra':
										break;
									
									default:
									
										var textbox = document.getAnonymousNodes(this)[0];
										textbox.setAttribute('type', 'autocomplete');
										textbox.setAttribute('autocompletesearch', 'zotero');
										textbox.setAttribute('timeout', '250');
										
										var autocompleteParams = {
											fieldName: condition
										};
										if (condition == 'creator') {
											autocompleteParams.fieldMode = 2;
										}
										textbox.setAttribute(
											'autocompletesearchparam',
											JSON.stringify(autocompleteParams)
										);
								}
						}
						
						if (!autocompleteParams) {
							var textbox = document.getAnonymousNodes(this)[0];
							textbox.removeAttribute('type');
						}
					]]>
				</body>
			</method>
			<method name="id">
				<parameter name="id"/>
				<body>
					<![CDATA[
						return document.getAnonymousNodes(this)[0].getElementsByAttribute('id',id)[0];
					]]>
				</body>
			</method>
		</implementation>
		
		<content>
			<xul:textbox id="search-textbox" xbl:inherits="hasOptions,flex">
				<xul:popupset>
					<xul:menupopup id="textbox-fulltext-menu">
						<xul:menuitem type="radio" label="&zotero.search.textModes.phrase;"/>
						<xul:menuitem type="radio" label="&zotero.search.textModes.phraseBinary;"/>
						<xul:menuitem type="radio" label="&zotero.search.textModes.regexp;"/>
						<xul:menuitem type="radio" label="&zotero.search.textModes.regexpCS;"/>
					</xul:menupopup>
				</xul:popupset>
				
				<xul:toolbarbutton id="textbox-button" type="menu"/>
			</xul:textbox>
		</content>
	</binding>
	
	
	
	<binding id="search-in-the-last">
		<resources>
			<stylesheet src="chrome://zotero/skin/bindings/search.css"/>
		</resources>
		
		<implementation>
			<property name="value">
				<getter>
					<![CDATA[
						var menulist = document.getAnonymousNodes(this)[0].firstChild.nextSibling;
						
						return document.getAnonymousNodes(this)[0].firstChild.value + ' ' +
							menulist.firstChild.childNodes[menulist.selectedIndex].getAttribute('value')
					]]>
				</getter>
				<setter>
					<![CDATA[
						var [num, units] = val.split(' ');
						document.getAnonymousNodes(this)[0].firstChild.setAttribute('value', num);
						
						var menulist = document.getAnonymousNodes(this)[0].firstChild.nextSibling;
						var menupopup = menulist.firstChild;
						
						var selectThis = 0;
						for (var i=0; i<menupopup.childNodes.length; i++){
							if (menupopup.childNodes[i].value == units)
							{
								selectThis = i;
								break;
							}
						}
						menulist.selectedIndex = selectThis;
						
						return val;
					]]>
				</setter>
			</property>
			<method name="id">
				<parameter name="id"/>
				<body>
					<![CDATA[
						return document.getAnonymousNodes(this)[0].getElementsByAttribute('id',id)[0];
					]]>
				</body>
			</method>
		</implementation>
		
		<content>
			<xul:hbox id="search-in-the-last" flex="1">
				<xul:textbox flex="1"/>
				<xul:menulist>
					<xul:menupopup flex="1">
						<xul:menuitem label="&zotero.search.date.units.days;" value="days" selected="true"/>
						<xul:menuitem label="&zotero.search.date.units.months;" value="months"/>
						<xul:menuitem label="&zotero.search.date.units.years;" value="years"/>
					</xul:menupopup>
				</xul:menulist>
			</xul:hbox>
		</content>
	</binding>
</bindings>