songcentral.search=Class.create
(
	{
		form:				false,
		addCriteria:		false,
		submitCriteria:		false,
		rowCount:			0,
		activeRows:			0,
//		insertedRows:		0,
		usedCriteria:		[],
		songWriterWindow:	false,
		criterionOptions:	null,
		config:
		{
			form:			false,
			type:			'quick',
			submitType:		'ajax'
		},
		criterionOptionsForAdvanced:
		[
			{key:'Select a criteria&#8230;',	value:''},
			{key:'Song Title',				value:'song_title'},
			{key:'Song Subject',			value:'song_subject'},
			{key:'Song Description',		value:'song_description'},
			{key:'Song Writer',				value:'song_writer'},
			{key:'Song Contributor',		value:'v_contributors'},
			{key:'Song Genre',				value:'genre_id'},
			{key:'Song Signature',			value:'version_signature'},
			{key:'Song Harmonies',			value:'version_isharmony'},
			{key:'Song Vocals',				value:'version_vocals'}
		],
		criterionOptionsForWatch:
		[
			{key:'Select a criteria&#8230;',	value:''},
			{key:'Song Writer',				value:'song_writer'},
			{key:'Song Genre',				value:'genre_id'},
			{key:'Song Vocals',				value:'version_vocals'}
		],
		genreOptions:
		[
			{key:' Select a genre',					value:''},
			{key:'Classical',						value:1},
			{key:'Country',							value:2},
			{key:'Pop',								value:3},
			{key:'Folk',							value:4},
			{key:'Gospel',							value:5},
			{key:'Metal',							value:6},
			{key:'Rock',							value:7},
			{key:'Jazz',							value:8},
			{key:'Jingle',							value:9},
			{key:'World',							value:10},
			{key:'Urban',							value:11},
			{key:'Alternative',						value:12},
			{key:'Children',						value:13},
			{key:'Blues',							value:14},
			{key:'Big Band',						value:15},
			{key:'Library Music',					value:16},
			{key:'Vocal',							value:17},
			{key:'Cabaret',							value:18},
			{key:'Dance',							value:19},
			{key:'*Unclassified',					value:150}
		],
		subGenreOptions:
		[
			[
				1,
				[
					{key:'Symphony',				value:21},
					{key:'Modern',					value:22},
					{key:'Symphonic Rock',			value:23},
					{key:'Chamber Music',			value:24},
					{key:'Opera',					value:25},
					{key:'Alternate',				value:26},
					{key:'Folk',					value:27},
					{key:'Traditional',				value:28},
					{key:'Choral',					value:29},
					{key:'Mediaeval',				value:30}
				]
			],
			[
				2,
				[
					{key:'Traditional',				value:31},
					{key:'Modern',					value:32},
					{key:'Rock',					value:33},
					{key:'Pop',						value:145},
					{key:'Blues',					value:34},
					{key:'Bluegrass',				value:35},
					{key:'Bush',					value:36},
					{key:'Ballad',					value:37},
					{key:'Acapella',				value:38},
					{key:'Comedy',					value:39},
					{key:'Cross Over',				value:40},
					{key:'Rockabilly',				value:41},
					{key:'Cajun',					value:42},
					{key:'Spiritual',				value:151},
					{key:'Instrumental',			value:160}
				]
			],
			[
				3,
				[
					{key:'Rock',					value:43},
					{key:'Ballad',					value:44},
					{key:'Acapella',				value:45},
					{key:'Power Ballad',			value:46},
					{key:'Comedy',					value:47},
					{key:'Disco',					value:48},
					{key:'Opera',					value:49},
					{key:'Mediaeval',				value:50},
					{key:'Spiritual',				value:152},
					{key:'Instrumental',			value:161}
				]
			],
			[
				4,
				[
					{key:'Traditional',				value:51},
					{key:'Mediaeval',				value:52},
					{key:'Modern',					value:53},
					{key:'Acapella',				value:54},
					{key:'Comedy',					value:55},
					{key:'Operatic',				value:56},
					{key:'Alt-folk',				value:146},
					{key:'Spiritual',				value:153},
					{key:'Instrumental',			value:162}
				]
			],
			[
				5,
				[
					{key:'Pop',						value:57},
					{key:'Christmas',				value:58},
					{key:'Hymn Style',				value:59},
					{key:'Rock',					value:60},
					{key:'Acapella',				value:61},
					{key:'Blues',					value:62},
					{key:'Spiritual',				value:154}
				]
			],
			[
				6,
				[
					{key:'Heavy Metal',				value:63},
					{key:'Thrash',					value:64},
					{key:'Hard Rock',				value:65},
					{key:'Goth Rock',				value:66},
					{key:'Progressive Metal',		value:67},
					{key:'Instrumental',			value:163}
				]
			],
			[
				7,
				[
					{key:'Alternate Rock',			value:68},
					{key:'Rock n Roll',				value:69},
					{key:'Rhythm & Blues',			value:70},
					{key:'Soft Rock',				value:71},
					{key:'Pop',						value:72},
					{key:'Acapella',				value:73},
					{key:'Rock Ballad',				value:74},
					{key:'Power Ballad',			value:75},
					{key:'Spiritual',				value:155},
					{key:'Instrumental',			value:164}
				]
			],
			[
				8,
				[
					{key:'Funk',					value:76},
					{key:'Fusion',					value:77},
					{key:'Traditional',				value:78},
					{key:'Acapella',				value:79},
					{key:'Blues',					value:144},
					{key:'Instrumental',			value:165}
				]
			],
			[
				9,
				[
					{key:'Ringtone',				value:80},
					{key:'Catchy',					value:81},
					{key:'Evocative',				value:82},
					{key:'Cute',					value:83},
					{key:'Busy',					value:84},
					{key:'Emotive',					value:85},
					{key:'Zany',					value:86},
					{key:'Funky',					value:87}
				]
			],
			[
				10,
				[
					{key:'Indigenous Aust.',		value:88},
					{key:'Pacific Island',			value:89},
					{key:'Latino',					value:90},
					{key:'Salsa',					value:91},
					{key:'Reggae',					value:92},
					{key:'Cajun',					value:93},
					{key:'Carribean',				value:94},
					{key:'Mex style',				value:95},
					{key:'Sth American',			value:96},
					{key:'Indian',					value:97},
					{key:'Spiritual',				value:156},
					{key:'Instrumental',			value:166}
				]
			],
			[
				11,
				[
					{key:'Hip Hop',					value:98},
					{key:'Funk',					value:99},
					{key:'Dance',					value:100},
					{key:'Electronica',				value:101},
					{key:'RAP',						value:102},
					{key:'Soul',					value:103},
					{key:'Mo Town',					value:104},
					{key:'Crunk',					value:105},
					{key:'Acapella',				value:106},
					{key:'Instrumental',			value:167}
				]
			],
			[
				12,
				[
					{key:'Pop',						value:107},
					{key:'Acoustic',				value:108},
					{key:'Punk',					value:109},
					{key:'Indie',					value:110},
					{key:'Grunge',					value:111},
					{key:'Emo',						value:112},
					{key:'SKA',						value:113},
					{key:'Hardcore',				value:114},
					{key:'Instrumental',			value:168}
				]
			],
			[
				13,
				[
					{key:'Comedy',					value:115},
					{key:'Teen Age',				value:116},
					{key:'Very Young',				value:117},
					{key:'Christmas',				value:118},
					{key:'Novelty',					value:119},
					{key:'Educational',				value:120},
					{key:'Spiritual',				value:157},
					{key:'Instrumental',			value:169}
				]
			],
			[
				14,
				[
					{key:'Delta Blues',				value:121},
					{key:'Chicago Blues',			value:122},
					{key:'Rock',					value:123},
					{key:'Spiritual',				value:158},
					{key:'Instrumental',			value:170}
				]
			],
			[
				15,
				[
					{key:'Swing',					value:124},
					{key:'Dance Hall',				value:125},
					{key:'Crooner',					value:126},
					{key:'Instrumental',			value:171}
				]
			],
			[
				16,
				[
					{key:'Sound Clip',				value:127},
					{key:'Sound Bed',				value:128},
					{key:'Background',				value:129}
				]
			],
			[
				17,
				[
					{key:'Crooner',					value:130},
					{key:'Inspirational',			value:131},
					{key:'Acapella',				value:132},
					{key:'Spiritual',				value:159}
				]
			],
			[
				18,
				[
					{key:'Jazz',					value:133},
					{key:'Crooner',					value:134},
					{key:'Swing',					value:135},
					{key:'Dance',					value:136},
					{key:'Opera',					value:137},
					{key:'Instrumental',			value:172}
				]
			],
			[
				19,
				[
					{key:'RAP',						value:138},
					{key:'Hip Hop',					value:139},
					{key:'Funk',					value:140},
					{key:'Techno',					value:141},
					{key:'Electronica',				value:142},
					{key:'Garage',					value:143},
					{key:'Instrumental',			value:173}
				]
			]
		],
		template:
		{
			row: s3core.template
			(
				'<tr class="row">',
					'<th class="col_1" scope="row"><div align="right">&#8230;and where<input type="hidden" id="#{id}" name="search_query[]" /></div></th>',
					'<td class="col_2"><div class="field">#{col2}&nbsp;</div><div class="value" style="display:none;"></div></td>',
					'<td class="col_3"><div class="field">#{col3}&nbsp;</div><div class="value" style="display:none;"></div></td>',
					'<td class="col_4"><div class="field">#{col4}&nbsp;</div><div class="value" style="display:none;"></div></td>',
					'<td class="col_5"><div class="field">#{col5}&nbsp;</div><div class="value" style="display:none;"></div></td>',
				'</tr>'
			),
			option:		new Template('<option value="#{value}"#{selected}>#{key}</option>'),
			select:		new Template('<select id="#{id}" name="#{name}">#{options}</select>'),
			check:		new Template('<br /><label><input type="checkbox" id="#{id}" name="#{name}" value="#{value}" />#{key}</label>')
		},
		initialize: function(config)
		{
			Object.extend(this.config,config);
			if (Object.isString(this.config.form))this.config.form=$(this.config.form);
			this.form=					this.config.form;
			this.addCriteria=			$('addCriteria');
			this.submitCriteria=		$('submitCriteria');
			this.searchToggle=			$('searchToggle');
			this.searchToggleCheckbox=	$('searchToggleCheckbox');
			this.resultsToggle=			$('resultsToggle');
			this.resultsToggleCheckbox=	$('resultsToggleCheckbox');
			this.conditionsWrapper=		$('conditionsWrapper');
			this.resultsWrapper=		$('resultsWrapper');
			if (this.config.type=='advanced' || this.config.type=='watchCriteria')
			{
				if (this.config.type=='advanced')
				{
					this.criterionOptions=this.criterionOptionsForAdvanced;
				}
				else
				{
					this.criterionOptions=this.criterionOptionsForWatch;
				}
				// Sort items within the genreOptions and subGenreOptions objects by their key
				this.genreOptions.ksort();
				for(var i=0,j=this.subGenreOptions.length;i<j;i++)
				{
					var element=this.subGenreOptions[i][1];
					if(element && Object.isFunction(element.ksort))
					{
						element.ksort();
					}
				}
				this.createCriteriaRow();
				this.addCriteria.observe		('click',	this.createCriteriaRow.bind(this));
				this.submitCriteria.observe		('click',	this.submit.bind(this));
			}
			else
			{
				if ($('qsearchSubmitBtn')!=null && this.config.type=='simple')
				{
					$('qsearchSubmitBtn').observe('click',this.submit.bind(this));
				}
				if ($('qsearchSubmitBtnPanel')!=null && this.config.type=='quick')
				{
					$('qsearchSubmitBtnPanel').observe('click',this.submit.bind(this));
				}
				if ($('search_criterion')!=null && this.config.type=='simple')
				{
					$('search_criterion').observe
					(
						'keyup',
						function(event)
						{
							var row=event.element().up('.row');
							if (!$F(event.element()).blank())
							{
								$('qsearchSubmitBtn').enable();
							}
							else
							{
								$('qsearchSubmitBtn').disable();
							}
							return true;
						}.bindAsEventListener(this)
					);
				}
				if ($('search_criterionPanel')!=null && this.config.type=='quick')
				{
					$('search_criterionPanel').observe
					(
						'keyup',
						function(event)
						{
							var row=event.element().up('.row');
							if (!$F(event.element()).blank())
							{
								$('qsearchSubmitBtnPanel').enable();
							}
							else
							{
								$('qsearchSubmitBtnPanel').disable();
							}
							return true;
						}.bindAsEventListener(this)
					);
				}
			}
			if (this.config.submitType=='ajax')
			{
				this.searchToggleCheckbox.observe	('click',	this.toggleSearch.bind(this.conditionsWrapper));
				this.resultsToggleCheckbox.observe	('click',	this.toggleResults.bind(this.resultsWrapper));
				if(this.config.type=='watchCriteria') this.loadSongAlertsListGrid();
			}
			return;
		},
		createCriteriaRow: function()
		{
			//Increment the row count.
			this.rowCount++;
			//Hide the Add Criteria button.
			this.addCriteria.hide();
			//Select the last row, and insert a new row after it.
			this.form.select('tbody.conditionsWrapper .row').last().insert
			(
				{
					//Use the row template to create a new row.
					after: this.template.row.evaluate
					(
						{
							id:		this.rowCount,
							//COL 2: Use the select field template to create the field selector.
							col2:	this.template.select.evaluate
							(
								{
									id:			'searchFieldSelector',
									options:	this.criterionOptions.collect
									(
										function(option)
										{
											if (!this.usedCriteria.in_array(option.key+'::'+option.value))
											{
												return this.template.option.evaluate(option);
											}
										}.bind(this)
									).join('')
								}
							),
							//COL 5: Action button.
							col5:
							[
								'<input type="button" value="OK" disabled="disabled" />',
								(this.rowCount!==1)?'<input type="button" id="action_remove_'+this.rowCount+'" value="REMOVE" />':''
							].join('')
						}
					)
				}
			);
			//Bind Event.
			this.form.select('tbody.conditionsWrapper .row').last().down('.col_2 .field select').observe
			(
				'change',
				this.handleCriterionSelection.bindAsEventListener(this)
			);
			this.form.select('tbody.conditionsWrapper .row').last().select('.col_5 input')[0].observe
			(
				'click',
				this.handleActionButtonClick.bindAsEventListener(this)
			);
			if (this.rowCount!==1)
			{
				this.form.select('tbody.conditionsWrapper .row').last().select('.col_5 input')[1].observe
				(
					'click',
					this.handleActionRemoveButtonClick.bindAsEventListener(this)
				);
			}
			//Change active row number.
			this.activeRows++;
			return this;
		},
		createCriterionOperand: function(bitwiseNum,selected)
		{
			var options=[];
			if (bitwiseNum &  1)	options.push({key:'is equal to',		value:'equals'});
			if (bitwiseNum &  2)	options.push({key:'does not equal',		value:'not equals'});
			if (bitwiseNum &  4)	options.push({key:'contains',			value:'contains'});
			if (bitwiseNum &  8)	options.push({key:'excludes',			value:'excludes'});
			if (bitwiseNum & 16)	options.push({key:'is like',			value:'like'});
			if (bitwiseNum & 32)	options.push({key:'is greater than',	value:'is greater than'});
			if (bitwiseNum & 64)	options.push({key:'is less than',		value:'is less than'});
			if (bitwiseNum & 128)	options.push({key:'is not like',		value:'not like'});
			return this.template.select.evaluate
			(
				{
					options:options.collect
					(
						function(option)
						{
							if (!Object.isUndefined(selected) && (selected==option.value))
							{
								Object.extend(option,{selected:' selected="selected"'})
							}
							return this.template.option.evaluate(option);
						}.bind(this)
					).join('')
				}
			);
		},
		handleCriterionSelection: function(event)
		{
			this.makeInputFromCriterionSelection(event.element());
			return;
		},
		makeInputFromCriterionSelection: function(element)
		{
			var row=element.up('tr');
			var field=row.down('.col_2 .field select');
			//Flag the previous value as unused.
			if (!Object.isUndefined(field.previousValue))this.removeUsedCriteria(field,field.previousValue);
			//Save the new value as the previous value.
			field.previousValue=field.options[field.selectedIndex].text+'::'+field.value;
			//Flag this criteria as used.
			this.addUsedCriteria(field,field.options[field.selectedIndex].text+'::'+field.value);
			//Check that the row below isn't a sub-genre row - If it is, destroy it.
			if (!Object.isUndefined(row.next('.row')) && !Object.isUndefined(row.next('.row').down('.col_1 input#subGenre')))
			{
				row.next('.row').remove();
			}
			switch ($F(element))
			{
				case 'version_isharmony':
				{
					row.down('.col_3 .field').update(this.createCriterionOperand(3,'equals'));
					row.down('.col_4 .field').update
					(
						[
							'<label><input type="radio" value="yes" name="version_isharmony" />yes</label>',
							'<label><input type="radio" value="no" name="version_isharmony" />no</label>'
						].join('')
					);
					row.select('.col_4 .field input').invoke
					(
						'observe',
						'change',
						function(event)
						{
							var row=element.up('.row');
							if (row.select('.col_4 .field input').getNumSelected())
							{
								row.down('.col_5 input').enable();
							}
							else
							{
								row.down('.col_5 input').disable();
							}
						}.bindAsEventListener(this)
					);
					break;
				}
				case 'version_vocals':
				{
					if(this.config.type=='watchCriteria')
					{
						row.down('.col_3 .field').update(this.createCriterionOperand(1,'equals'));
					}
					else
					{
						row.down('.col_3 .field').update(this.createCriterionOperand(15,'contains'));
					}
					row.down('.col_4 .field').update
					(
						[
							'<label><input type="checkbox" value="male" name="version_vocals[]" />male</label>',
							'<label><input type="checkbox" value="female" name="version_vocals[]" />female</label>'
						].join('')
					);
					row.select('.col_4 .field input').invoke
					(
						'observe',
						'change',
						function(event)
						{
							var row=element.up('.row');
							if (row.select('.col_4 .field input').getNumSelected())
							{
								row.down('.col_5 input').enable();
							}
							else
							{
								row.down('.col_5 input').disable();
							}
						}.bindAsEventListener(this)
					);
					break;
				}
				case 'version_signature':
				{
					row.down('.col_3 .field').update(this.createCriterionOperand(3,'equals'));
					row.down('.col_4 .field').update
					(
						[
							'<label><input type="checkbox" name="version_signature[]" value="2:4" />2:4</label>',
							'<label><input type="checkbox" name="version_signature[]" value="4:4" />4:4</label>',
							'<label><input type="checkbox" name="version_signature[]" value="5:4" />5:4</label><br />',
							'<label><input type="checkbox" name="version_signature[]" value="8:4" />8:4</label>',
							'<label><input type="checkbox" name="version_signature[]" value="6:8" />6:8</label>'
						].join('')
					);
					row.select('.col_4 .field input').invoke
					(
						'observe',
						'change',
						function(event)
						{
							var row=element.up('.row');
							if (row.select('.col_4 .field input').getNumSelected())
							{
								row.down('.col_5 input').enable();
							}
							else
							{
								row.down('.col_5 input').disable();
							}
						}.bindAsEventListener(this)
					);
					break;
				}
				case 'genre_id':
				{
					row.down('.col_3 .field').update(this.createCriterionOperand(1));
					row.down('.col_4 .field').update
					(
						this.template.select.evaluate
						(
							{
								id:		'genre_id',
								name:	'genre_id',
								options:this.genreOptions.collect
								(
									function(option)
									{
										return this.template.option.evaluate(option);
									}.bind(this)
								).join('')
							}
						)
					);
					row.down('.col_4 .field select').observe('change', this.handleCreateSubGenreRow.bindAsEventListener(this,row));
					break;
				}
				default:
				{
					if (!$F(element).empty())
					{
						if($F(element)=='song_writer' && this.config.type=='watchCriteria')
						{
							row.down('.col_3 .field').update(this.createCriterionOperand(4,'contains'));
						}
						else
						{
							row.down('.col_3 .field').update(this.createCriterionOperand(15,'contains'));
						}
						row.down('.col_4 .field').update('<input type="text" name="'+$F(element)+'" value="" size="20" />');
						row.down('.col_4 .field input').observe
						(
							'keyup',
							function(event)
							{
								var row=element.up('.row');
								if (!$F(element).blank())
								{
									row.down('.col_5 input').enable();
								}
								else
								{
									row.down('.col_5 input').disable();
								}
								return true;
							}.bindAsEventListener(this)
						);
					}
					else
					{
						row.down('.col_3 .field').update('&nbsp;');
						row.down('.col_4 .field').update('&nbsp;');
					}
				}
			}
			return;
		},
		handleCreateSubGenreRow: function(event,row)
		{
			this.createSubGenreRow(event.element(),row);
			return true;
		},
		createSubGenreRow: function(element,row)
		{
			var genre=this.findSubGenreGroupByGenreId($F(row.down('.col_4 .field select')));
			if (!$F(row.down('.col_4 .field select')).blank())
			{
				row.down('.col_5 input').enable();
			}
			else
			{
				row.down('.col_5 input').disable();
			}
			if (!genre)
			{
				if (!Object.isUndefined(row.next('.row')) && !Object.isUndefined(row.next('.row').down('.col_1 input#subGenre')))
				{
					row.next('.row').remove();
				}
			}
			else
			{
				//If there isn't a next row.
				if (Object.isUndefined(row.next('.row')))
				{
					this.form.select('tbody.conditionsWrapper .row').last().insert
					(
						{
							//Use the row template to create a new row.
							after: this.template.row.evaluate
							(
								{
									id:		'subGenre',
									//COL 2: Static set to 'Sub Genre'.
									col2:	this.template.select.evaluate
									(
										{
											name:		'subGenre[]',
											options:	this.template.option.evaluate({key:'Sub Genre',value:'subGenre'})
										}
									),
									//COL 3: Set to 'equals'.
									col3:	this.createCriterionOperand(4),
									//COL 4:
									col4:	genre.collect
									(
										function(checkboxes)
										{
											Object.extend(checkboxes,{id:'subGenre',name:'subGenre[]'});
											return this.template.check.evaluate(checkboxes);
										}.bind(this)
									).join(''),
									//COL 5: Action button.
									col5:	'<input type="hidden" id="action_'+this.rowCount+'" value="OK" />'
								}
							)
						}
					);
				}
				//If there is a next row.
				else
				{
					//Check if it is the sub-genre row and destroy it if there is.
					if (!Object.isUndefined(row.next('.row')) && !Object.isUndefined(row.next('.row').down('.col_1 input#subGenre')))
					{
						row.next('.row').remove()
					}
					this.form.select('tbody.conditionsWrapper .row').last().insert
					(
						{
							//Use the row template to create a new row.
							after: this.template.row.evaluate
							(
								{
									id:		'subGenre',
									//COL 2: Static set to 'Sub Genre'.
									col2:	this.template.select.evaluate
									(
										{
											name:		'subGenre[]',
											options:	this.template.option.evaluate({key:'Sub Genre',value:'subGenre'})
										}
									),
									//COL 3: Set to 'equals'.
									col3:	this.createCriterionOperand(4),
									//COL 4:
									col4:	genre.collect
									(
										function(checkboxes)
										{
											Object.extend(checkboxes,{id:'subGenre',name:'subGenre[]'});
											return this.template.check.evaluate(checkboxes);
										}.bind(this)
									).join(''),
									//COL 5: Action button.
									col5:	'<input type="hidden" id="action_'+this.rowCount+'" value="OK" />'
//													col5:
//													[
//														'<input type="button" value="OK" disabled="disabled" />',
////														(this.rowCount!==1)?'<input type="button" id="action_remove_'+this.rowCount+'" value="REMOVE" />':''
//													].join('')
								}
							)
						}
					);
				}
				row.next('.row').select('.col_4 .field input').invoke
				(
					'observe',
					'change',
					function(event)
					{
//										var row=element.up('.row');
//										if (row.select('.col_4 .field input').getNumSelected())
//										{
//											row.down('.col_5 input').enable();
//										}
//										else
//										{
//											row.down('.col_5 input').disable();
//										}
					}.bindAsEventListener(this)
				);
				if (!Object.isFunction(this.SG_handleActionButtonClick))
				{
					this.SG_handleActionButtonClick=function()
					{
						if(!Object.isUndefined(row.next('.row')))
						{
							var element=row.next('.row').down('.col_5 input');
							if (element!=null)
							{
								this.handleActionButtonClick(element);
							}
						}
					}.bind(this);
				}
				try
				{
					Event.stopObserving(row.down('.col_5 input'),'click',this.SG_handleActionButtonClick);
				}
				catch(e){}
				row.down('.col_5 input').observe
				(
					'click',
					this.SG_handleActionButtonClick
				);
				row.down('.col_2 select').observe
				(
					'change',
					function()
					{
						if (Object.isFunction(this.SG_handleActionButtonClick))
						{
							try
							{
								Event.stopObserving(row.down('.col_5 input'),'click',this.SG_handleActionButtonClick);
							}
							catch(e){}
						}
						this.SG_handleActionButtonClick=false;
						return;
					}.bind(this)
				)
			}
			return true;
		},
		SG_handleActionButtonClick:	false,
		handleActionButtonClick: function(element)
		{
			if (Object.isFunction(element.element)) element=element.element();
			//Get the row.
			var row=element.up('tr');
			//Check if the row has been frozen or not.
			if (element.value=='OK')
			{
				//Add id to row
				row.id='criterionRow_'+$F(row.down('.col_2 select'));
				row.down('.col_2 .value').update(row.down('.col_2 select').select('option').getSelected().first().text);
				if(!Object.isUndefined(row.down('.col_3 select').select('option')) && 
					Object.isFunction(row.down('.col_3 select').select('option').getSelected) &&
						row.down('.col_3 select').select('option').getSelected().length>0
				)
				{
					row.down('.col_3 .value').update(row.down('.col_3 select').select('option').getSelected().first().text);
				}
				var query='.col_4 .field';
				if (!Object.isUndefined(row.down('.col_4 .field label')))
				{
					query+=' label';
				}
				if (row.down(query).down().tagName.toLowerCase()=='input')
				{
					if (row.select('.col_4 .field input').length>1)
					{
						if ($F(row.down('.col_2 select'))=='subGenre')
						{
							var values=[];
							row.select('.col_4 .field input').getSelected().each
							(
								function(input)
								{
									var o=input.up('label');
									if(o && !Object.isUndefined(o.innerText))
									{
										values.push(o.innerText);
									}
									else if(o && !Object.isUndefined(o.textContent))
									{
										values.push(o.textContent);
									}
									return;
								}.bind(this)
							)
							row.down('.col_4 .value').update(values.join(' or '));
							//Capture the value of each column.
							row.down('.col_1 input').value=row.down('.col_2 select').value+'::'+row.down('.col_3 select')
																					.value+'::'+row.select('.col_4 .field input').getSelectedValues().join(',');
						}
						else
						{
							row.down('.col_4 .value').update(row.select('.col_4 .field input').getSelectedValues().join(' or '));
							//Capture the value of each column.
							row.down('.col_1 input').value=row.down('.col_2 select').value+'::'+row.down('.col_3 select')
																					.value+'::'+row.select('.col_4 .field input').getSelectedValues().join(',');
						}
					}
					else
					{
						row.down('.col_4 .value').update(row.down('.col_4 .field input').value);
						//Capture the value of each column.
						row.down('.col_1 input').value=row.down('.col_2 select').value+'::'+row.down('.col_3 select').value+'::'+row.down('.col_4 input').value;
					}
				}
				else
				{
					var field=row.down('.col_4 .field select');
					row.down('.col_4 .value').update(field.options[field.selectedIndex].text);
					//Capture the value of each column.
					row.down('.col_1 input').value=row.down('.col_2 select').value+'::'+row.down('.col_3 select').value+'::'+row.down('.col_4 .field select').value;
				}
				row.down('.col_2 .value').update(row.down('.col_2 select').select('option').getSelected().first().text);
				row.down('.col_3 .value').update(row.down('.col_3 select').select('option').getSelected().first().text);
				
				//Freeze each column.
				row.down('.col_2 .field').hide();
				row.down('.col_2 .value').show();
				row.down('.col_3 .field').hide();
				row.down('.col_3 .value').show();
				row.down('.col_4 .field').hide();
				row.down('.col_4 .value').show();
				//Change the button value.
				element.value='CHANGE';
				if (row.down('.col_2 .field select').value!='subGenre')
				{
					//Change active row number.
					this.activeRows--;
				}
				//Show the add criteria button
				if (this.activeRows===0)
				{
					this.addCriteria.show();
					// Disable button if there isn't any criterion options available
					if(this.usedCriteria.length >= (this.criterionOptions.length - 1)) this.addCriteria.disabled=true;
				}
				//Enable the Perform Search button.
				this.submitCriteria.enable();
			}
			//Row has not been frozen.
			else
			{
				if (row.down('.col_2 .field select').value!='subGenre')
				{
					//Change active row number.
					this.activeRows++;
				}
				//Hide the Add Criteria button.
				this.addCriteria.hide();
				//Change the button value.
				element.value='OK';
				//Disable the add criteria button.
				if (this.rowCount==1)this.submitCriteria.disable();
				//Reset the hidden form value to empty until the row gets the OK again.
				row.down('.col_1 input').value='';
				//Switch the divs.
				row.down('.col_2 .value').hide();
				row.down('.col_2 .field').show();
				row.down('.col_3 .value').hide();
				row.down('.col_3 .field').show();
				row.down('.col_4 .value').hide();
				row.down('.col_4 .field').show();
			}
			return;
		},
		handleActionRemoveButtonClick: function(event)
		{
			var row=event.element().up('.row');
			this.handleRemoveRow(row);
			return true;
		},
		handleRemoveRow: function(row)
		{
			//Remove this criteria from the used criteria list.
			var field=row.down('.col_2 .field select');
			this.removeUsedCriteria(field,field.options[field.selectedIndex].text+'::'+field.value);
			//Check if the row is currently active so that we can deduct it from the total.
			if (row.down('.col_2 .field').visible())
			{
				//Change active row number.
				this.activeRows--;
			}
			//Check if the row being removed is genre and remove the sub-genre as well.
			if (row.down('.col_2 .field select').value=='genre_id')
			{
				if (!Object.isUndefined(row.next('.row')) && !Object.isUndefined(row.next('.row').down('.col_1 input#subGenre'))) row.next('tr').remove();
			}
			row.remove();
			//Show the Add Criteria button.
			if (this.activeRows===0)
			{
				this.addCriteria.show();
				// Enable button if disabled and there are criterion options available.
				if(this.addCriteria.disabled==true && this.usedCriteria.length < (this.criterionOptions.length - 1)) this.addCriteria.disabled=false;
			}
			return true;
		},
		bound_genreSelectHandler: false,
		genreSelectHandler: function()
		{
			if (this.subGenres.innerHTML.length)
			{
				this.subGenres.update();
			}
			var genre=this.findSubGenreGroupByGenreId($F('criterionValue'));
			if (genre)
			{
				this.subGenres.update
				(
					genre.collect
					(
						function(checkboxes)
						{
							Object.extend(checkboxes,{id:'criterionValue_sub',name:'criterionValue_sub'});
							return this.template.check.evaluate(checkboxes);
						}.bind(this)
					).join('')
				);
			}
			return;
		},
		findSubGenreGroupByGenreId: function(genreID)
		{
			$return=false;
			if (!Object.isNumber(genreID))genreID=Number(genreID);
			this.subGenreOptions.find
			(
				function(genre)
				{
					if (genre[0]===genreID)
					{
						$return=genre[1];
						return true;
					}
					return false;
				}.bind(this)
			);
			return $return;
		},
		addUsedCriteria: function(field,value)
		{
			//Add the value to the used container.
			this.usedCriteria.push(value);
			//Get all select fields and remove the value from them.
			$$('tbody.conditionsWrapper .row .col_2 select:not([name=subGenre\[\]])').each
			(
				function(selectField)
				{
					//Don't remove the value if it is the active field.
					if (selectField!=field)
					{
						var fragments=value.split('::',2);
						selectField.select('option').each
						(
							function(option)
							{
								if (option.value==fragments[1])
								{
									option.remove();
									return true;
								}
								return false;
							}.bind(this)
						)
					}
					return;
				}.bind(this)
			);
			return;
		},
		removeUsedCriteria: function(field,value)
		{
			//Remove the value from the used container.
			this.usedCriteria=this.usedCriteria.without(value);
			//Get all select fields and add the value to them.
			$$('tbody.conditionsWrapper .row .col_2 select:not([name=subGenre\[\]])').each
			(
				function(selectField)
				{
					//Don't add the value if it is the active field.
					if (selectField!=field)
					{
						//Catch the selected index so that we can restore it after we re-insert the option.
						var selectedIndex=selectField.selectedIndex;
						//Re-insert the option.
						var fragments=value.split('::',2);
						selectField.insert('<option value='+fragments[1]+'>'+fragments[0]+'</option>');
						//Restore the selected index.
						selectField.selectedIndex=selectedIndex;
					}
					return;
				}.bind(this)
			);
			return;
		},
		in_usedCriteria: function(value)
		{
			for(var i in this.criterionOptions)
			{
				if(this.criterionOptions[i].value==value && this.usedCriteria.in_array(this.criterionOptions[i].key+'::'+this.criterionOptions[i].value)) 
				{
					return true;
				}
			}
			return false;
		},
		resetFormToBlank_ifEdit: function()
		{
			if ($('songalert_id') && $('songalert_id').value.length)
			{
				//Set (special) fixed criteria rows to empty.
				$('songalert_id').value='';
				if($('songalert_title').value.length) $('songalert_title').value='';
				//Delete variable criteria rows
				this.criterionOptions.collect
				(
					function(option)
					{
						if (option.value.length)
						{
							var row=$('criterionRow_'+option.value);
							if(row!=null) this.handleRemoveRow(row);
						}
					}.bind(this)
				);
				//Recreate a single variable-criteria row.
				if(!$('searchFieldSelector')) this.createCriteriaRow();
			}
		},
		submit: function()
		{
			if (this.config.submitType=='ajax')
			{
				var error=false;
				if (this.config.type=='advanced' || this.config.type=='watchCriteria')
				{
					if (Object.isUndefined(this.form['search_query[]'].length))
					{
						if (!this.form['search_query[]'].present())
						{
							alert('Please Add Criteria Before Submitting');
							error=true;
						}
					}
					else
					{
						$A(this.form['search_query[]']).each
						(
							function(field)
							{
								if (field.id!='subGenre' && !field.present())
								{
									alert('Please Add Criteria Before Submitting');
									error=true;
									throw $break;
								}
								return;
							}.bind(this)
						);
					}
				}
				if (!error)
				{
					//Check whether we need to remove an existing message within the message box.
					var messagebox=null;
					if((messagebox=$$('.messageBox').first())!=null && !Object.isUndefined($$('.messageBox .message')))
					{
						messagebox.update('&nbsp;');
					}
					if(this.config.type=='watchCriteria')
					{
						this.prepSongAlertsLoader();
						new Ajax.Request
						(
							$COREROOT+'data/song_alerts/submit/',
							{
								method:			this.form.method,
								parameters:		this.form.serialize(),
								evalJS:			false,
								onSuccess:		function(response)
								{
									// Remove criteria within form if user has just submitted an edit of an existing record
									this.resetFormToBlank_ifEdit();
									if (response.responseJSON.success)
									{
										this.loadSongAlertsListGrid();
									}
									else
									{
										this.loader.updateMessage('Song-Alert criteria submit was successful.'); //'But no results were found. Please try again.'
										(function()
										{
											this.loader.fade();
											this.lightscreen.hide();
											return;
										}.bind(this)).delay(2);
										return;
									}
									return;
								}.bind(this),
								onFail:			function(response)
								{
									this.loader.updateMessage('Submit Failed. Please try again later.');
									(function()
									{
										this.loader.fade();
										this.lightscreen.hide();
										return;
									}.bind(this)).delay(2);
									return;
								}.bind(this)
							}
						);
					}
					else
					{
						this.prepSearchLoader();
						new Ajax.Request
						(
							$COREROOT+'data/search/',
							{
								method:			this.form.method,
								parameters:		this.form.serialize(),
								evalJS:			false,
								onSuccess:		function(response)
								{
									if (response.responseJSON.success)
									{
										this.onSearchSubmitSuccess(response.responseJSON);
									}
									else
									{
										this.loader.updateMessage('Search Successful. But no results were found. Please try again.');
										(function()
										{
											this.destroyGrid();
											this.loader.fade();
											this.lightscreen.hide();
											return;
										}.bind(this)).delay(2);
										return;
									}
									return;
								}.bind(this),
								onFail:			function(response)
								{
									this.loader.updateMessage('Search Failed. Please try again later.');
									(function()
									{
										this.destroyGrid();
										this.loader.fade();
										this.lightscreen.hide();
										return;
									}.bind(this)).delay(2);
									return;
								}.bind(this)
							}
						);
					}
				}
			}
			else
			{
				this.form.submit();
			}
			return false;
		},
		prepSongAlertsLoader: function()
		{
			if (Object.isUndefined(this.loader))
			{
				this.loader=new s3core.loader
				(
					{
						header:		'Processing Request&#8230;',
						info:		'Please wait. We are processing your song-alerts criteria.',
						message:	'Building your song-alerts list&#8230;'
					}
				);
			}
			else
			{
				this.loader.show();
				this.loader.updateMessage('Building your song-alerts list&#8230;');
			}
			if (Object.isUndefined(this.lightscreen))
			{
				this.lightscreen=new s3core.lightscreen({color:'#FFF'});
				this.lightscreen.add(this.loader.toString());
			}
			else
			{
				this.lightscreen.show();
			}
			return;
		},
		prepSearchLoader: function()
		{
			if (Object.isUndefined(this.loader))
			{
				this.loader=new s3core.loader
				(
					{
						header:		'Processing Request&#8230;',
						info:		'Please wait. We are processing your search criteria.',
						message:	'Sending search criteria&#8230;'
					}
				);
			}
			else
			{
				this.loader.show();
				this.loader.updateMessage('Sending search criteria&#8230;');
			}
			if (Object.isUndefined(this.lightscreen))
			{
				this.lightscreen=new s3core.lightscreen({color:'#FFF'});
				this.lightscreen.add(this.loader.toString());
			}
			else
			{
				this.lightscreen.show();
			}
			return;
		},
		stopSearchLoader: function(message)
		{
			if(!Object.isUndefined(this.loader))
			{
				if(!Object.isUndefined(this.lightscreen) && Object.isFunction(this.lightscreen.hide))
				{
					this.lightscreen.screen.fade();
					this.lightscreen.hide();
				}
				if(message && Object.isFunction(this.loader.updateMessage))
				{
					this.loader.updateMessage(message);
					(function(){this.loader.hide();}.bind(this)).delay(5);
				}
				else if(Object.isFunction(this.loader.hide))
				{
					(function(){this.loader.hide();}.bind(this)).delay(1);
				}
			}
			return;
		},
		loadSongAlertsListGrid: function()
		{
			//Remove any existing messages within the resultsWrapper div.
			if($('resultsWrapper')!=null && !Object.isUndefined($('resultsWrapper').down('p'))) $('resultsWrapper').update('');
			//Prepare message-feedback mechanisms
			if (Object.isUndefined(this.loader)) this.prepSongAlertsLoader();
			this.loader.updateMessage('Gathering your Song-Alerts list data.');
			new Ajax.Request
			(
				$COREROOT+'data/song_alerts/list/',
				{
					method:			this.form.method,
					parameters:		this.form.serialize(),
					evalJS:			false,
					onSuccess:		function(response)
					{
						if (response.responseJSON.success)
						{
							this.onSongAlertsGridResultReceived(response.responseJSON).doLayout();
						}
						else
						{
							if($('resultsWrapper')!=null)
							{
								if (!this.resultsWrapper.visible())		this.toggleResults();
								$('resultsWrapper').update('<p class="message note standout"><img src="'+$PUBLICROOT+'images/spacer.gif" width="40" height="10" />You have Nil saved Song-Alert criteria records.</p>');
							}
							this.loader.updateMessage('Nil Song-Alert criteria received.');
							(function()
							{
								this.loader.fade();
								this.lightscreen.hide();
								return;
							}.bind(this)).delay(2);
							return;
						}
					}.bind(this),
					onFail:			function(response)
					{
						this.loader.updateMessage('Failed to load the table/grid of your song-alerts. Please try again later.');
						(function()
						{
							this.loader.fade();
							this.lightscreen.hide();
							return;
						}.bind(this)).delay(2);
						return;
					}.bind(this)
				}
			)
		},
		onSongAlertsGridResultReceived: function(result)
		{
			if (result!=null)
			{
				var msg_prefix = 'Song-Alerts list data received. '; //Building Song-Alerts grid.';
				this.loader.updateMessage(msg_prefix + ' Processing results&#8230;');
				if (!this.searchToggle.visible())		this.searchToggle.show();
				if (!this.resultsToggle.visible())		this.resultsToggle.show();
				if (this.conditionsWrapper.visible())	this.toggleSearch();
				if (!this.resultsWrapper.visible())		this.toggleResults();
				if (!this.libsLoaded)
				{
					this.loader.updateMessage(msg_prefix + ' Loading Ext Core&#8230;');
					s3core.include_once
					(
						[$EXT+'adapter/ext/ext-base.js',	function(){this.loader.updateMessage(msg_prefix + ' Loading UI Components&#8230;');}	.bind(this)],
						[$EXT+'ext-all.js',					function(){this.loader.updateMessage(msg_prefix + ' Loading Plugins&#8230;');}			.bind(this)],
//						[$EXT+'plugins/rowExpander.js',		function(){this.loader.updateMessage(msg_prefix + ' Loading Grid&#8230;');}			.bind(this)],
						[
							$SCRIPTS+'grid.js',
							function()
							{
								this.libsLoaded=true;
								this.loader.updateMessage(msg_prefix + ' Initializing Grid and showing results&#8230;');

								document.observe
								(
									'grid:rendered',
									function()
									{
										this.grid.getGrid().getSelectionModel().on
										(
											{
												rowselect: function()
												{
													this.resetFormToBlank_ifEdit();
													var selectionCount=this.grid.getGrid().getSelectionModel().getCount();
													if (selectionCount)
													{
														if (selectionCount>1)
														{
															Ext.getCmp('button_editCriteria').disable();
														}
														else
														{
															Ext.getCmp('button_editCriteria').enable();
														}
														Ext.getCmp('button_deleteCriteria').enable();
													}
													else
													{
														Ext.getCmp('button_editCriteria').disable();
														Ext.getCmp('button_deleteCriteria').disable();
													}
													return;
												}.bind(this),
												rowdeselect: function()
												{
													this.resetFormToBlank_ifEdit();
													var selectionCount=this.grid.getGrid().getSelectionModel().getCount();
													if (selectionCount)
													{
														if (selectionCount>1)
														{
															Ext.getCmp('button_editCriteria').disable();
														}
														else
														{
															Ext.getCmp('button_editCriteria').enable();
														}
														Ext.getCmp('button_deleteCriteria').enable();
													}
													else
													{
														Ext.getCmp('button_editCriteria').disable();
														Ext.getCmp('button_deleteCriteria').disable();
													}
													return;
												}.bind(this)
											}
										);
										Ext.getCmp('button_editCriteria').on
										(
											'click',
											function()
											{
												// Then transfer the selected grid record's values into the criteria-form inputs.
												var record=this.grid.getGrid().getSelectionModel().getSelected();
												if(!Object.isUndefined(record.id) && record.id!=null && record.id.length)
												{
													// Display search-criteria if not already so
													if (!this.searchToggle.visible())				this.searchToggle.show();
													if (!this.conditionsWrapper.visible())			this.toggleSearch();
													// Deal with fixed input element values
													if ($('songalert_id')) 
													{
														$('songalert_id').value=record.id;
													}
													if (!Object.isUndefined(record.json.songalert_title) && record.json.songalert_title!=null && $('songalert_title'))
													{
														$('songalert_title').value=record.json.songalert_title;
													}
													if($(this.form['showcase_num']) && !Object.isUndefined(record.json.showcase_num))
													{
														$A(this.form['showcase_num']).each
														(
															function(element)
															{
																if(element.value==record.json.showcase_num)
																{
																	element.checked=true;
																}
																else
																{
																	element.checked=false;
																}
															}
														);
													}
													if($(this.form['content_type']) && !Object.isUndefined(record.json.content_type_bits) && record.json.content_type_bits!=null)
													{
														$A(this.form['content_type']).each
														(
															function(element)
															{
																if(element.value==record.json.content_type_bits)
																{
																	element.checked=true;
																}
																else
																{
																	element.checked=false;
																}
															}
														);
													}
													// Deal with variable input element values
													// ** SONG-WRITER
													if(!Object.isUndefined(record.json.song_writer) && record.json.song_writer!=null && record.json.song_writer.length)
													{
														var row=this.buildCriterionRow('song_writer');
														if (row!=null)
														{
															var field=row.down('.col_4 .field input');
															// Put the value to the criterion-input field.
															if(field) field.value=record.json.song_writer;
															this.finishBuildRow(row);
														}
													}
													else if (this.in_usedCriteria('song_writer'))
													{
														var row=$('criterionRow_song_writer');
														if(row!=null) this.handleRemoveRow(row);
													}
													// ** GENRE-ID
													// First remove the sub-genre row if exists.
													var row=$('criterionRow_subGenre');
													if(row!=null) this.handleRemoveRow(row);
													if(!Object.isUndefined(record.json.genre_id) && record.json.genre_id!=null && record.json.genre_id > 0)
													{
														var row=this.buildCriterionRow('genre_id');
														if (row!=null)
														{
															var values=[];
															if(!Object.isUndefined(record.json.genre_ids) && record.json.genre_ids!=null && record.json.genre_ids.length)
															{
																values=record.json.genre_ids.split(',');
															}
															var field=row.down('.col_4 .field select');
															// Put the value to the criterion-input field.
															if(field) 
															{
																$A(field.options).each
																(
																	function(element)
																	{
																		if(element.value==record.json.genre_id) //values.in_array(element.value)
																		{
																			element.selected=true;
																			this.createSubGenreRow(element,row);
																			if (values.length && !Object.isUndefined(row.next('.row')) && 
																				!Object.isUndefined(row.next('.row').down('.col_1 input#subGenre')))
																			{
																				$(row.next('.row').select('.col_4 .field input')).each
																				(
																					function(element)
																					{
																						if (values.in_array(element.value)) 
																						{
																							element.checked=true;
																						}
																						else if(element.checked)
																						{
																							element.checked=false;
																						}
																					}
																				);
																			}
																			throw $break;
																		}
																	}.bind(this)
																);
															}
															this.finishBuildRow(row);
//															row.hide().show();//...so that forces refresh.
														}
													}
													else if (this.in_usedCriteria('genre_id'))
													{
														var row=$('criterionRow_genre_id');
														if(row!=null) this.handleRemoveRow(row);
													}
													// ** VERSION-VOCALS
													if(!Object.isUndefined(record.json.version_vocals) && record.json.version_vocals!=null && record.json.version_vocals.length)
													{
														var row=this.buildCriterionRow('version_vocals');
														if (row!=null)
														{
															var values=record.json.version_vocals.split(',');
															// Put the value to the criterion-input field.
															$(row.select('.col_4 .field input')).each
															(
																function(element)
																{
																	if(values.in_array(element.value)) 
																	{
																		element.checked=true;
																	}
																	else
																	{
																		element.checked=false;
																	}
																}
															);
															this.finishBuildRow(row);
														}
													}
													else if (this.in_usedCriteria('version_vocals'))
													{
														var row=$('criterionRow_version_vocals');
														if(row!=null) this.handleRemoveRow(row);
													}
												}
												return true;
											}.bind(this)
										);
										Ext.getCmp('button_deleteCriteria').on
										(
											'click',
											function()
											{
												var records=this.grid.getGrid().getSelectionModel().getSelections();
												if(records.length)
												{
													// Make sure that none of the selected records being deleted has its id set within criteria (for edit)
													if ($('songalert_id') && $('songalert_id').value.length)
													{
														for(var i in records)
														{
															if(records[i].id==$('songalert_id').value)
															{
																$('songalert_id').value='';
																if($('songalert_title').value.length) $('songalert_title').value='';
																break;
															}
														}
													}
													new Ajax.Request
													(
														$COREROOT+'data/song_alerts/delete/',
														{
															method:			this.form.method,
															parameters:		{idVars:records.pluck('id').join(',')},
															evalJS:			false,
															onSuccess:		function(response)
															{
																this.loader.updateMessage('Deletion of Song-Alert criteria was successful.');
																if (response.responseJSON.success)
																{
																	this.loadSongAlertsListGrid();
																}
																else
																{
																	(function()
																	{
																		this.loader.fade();
																		this.lightscreen.hide();
																		return;
																	}.bind(this)).delay(2);
																	return;
																}
																return;
															}.bind(this),
															onFail:			function(response)
															{
																this.loader.updateMessage('Deletion of Song-Alert criteria Failed. Please try again later.');
																(function()
																{
																	this.loader.fade();
																	this.lightscreen.hide();
																	return;
																}.bind(this)).delay(2);
																return;
															}.bind(this)
														}
													);
												}
												return;
											}.bind(this)
										);
										return;
									}.bind(this)
								);
								if (!this.searchToggle.visible())		this.searchToggle.show();
								if (!this.resultsToggle.visible())		this.resultsToggle.show();
								if (this.conditionsWrapper.visible())	this.toggleSearch();
								if (!this.resultsWrapper.visible())		this.toggleResults();
								(function(){this.grid=new songcentral.grid(result);}.bind(this)).delay(1);
								this.loader.fade();
								this.lightscreen.hide();
/*
								new songcentral.quicktip
								(
									[
										'To edit a song-alert criteria, click its row within the grid/table below.'
									].join('')
									//'To perform an action in the grid, simply select a row and watch for the buttons to highlight.'
								);
*/
								return;
							}.bind(this)
						]
					);
				}
				else
				{
					this.loader.updateMessage(msg_prefix + ' Updating results grid&#8230;');
					this.destroyGrid();
					this.grid=new songcentral.grid(result);
					if (!this.searchToggle.visible())		this.searchToggle.show();
					if (!this.resultsToggle.visible())		this.resultsToggle.show();
					if (this.conditionsWrapper.visible())	this.toggleSearch();
					if (!this.resultsWrapper.visible())		this.toggleResults();
					this.loader.fade();
					this.lightscreen.hide();
				}
			}
			else
			{
				this.loader.updateMessage(msg_prefix); // + ' But no results were found. Please try again.'
				(function()
				{
					this.destroyGrid();
					this.loader.fade();
					this.lightscreen.hide();
					return;
				}.bind(this)).delay(2);
			}
			return;
		},
		buildCriterionRow: function(criteriaString)
		{
			var row=null;
			//Check if there are any active rows.
			if (!this.usedCriteria.length)
			{
				row=this.form.select('tbody.conditionsWrapper .row').last();
			}
			else if (this.in_usedCriteria(criteriaString))
			{
				row=$('criterionRow_'+criteriaString);
				var changeBtn=(row && Object.isFunction(row.down))?row.down('.col_5 input:[value="CHANGE"]'):null;
				if(changeBtn)
				{
					this.handleActionButtonClick(changeBtn);
				}
			}
			else
			{
				this.createCriteriaRow();
				row=this.form.select('tbody.conditionsWrapper .row').last();
			}
			if (row!=null)
			{
				// Make sure that the criterion-choice value is set.
				var field=row.down('.col_2 .field select');
				if (field)
				{
					$A(field.options).each
					(
						function(element)
						{
							if(element.value==criteriaString) 
							{
								element.selected=true;
								throw $break;
							}
						}
					);
					// Do we have a criterion-input field?
					if (!row.down('.col_4 .field input')) this.makeInputFromCriterionSelection(field);
				}
				row.down('.col_5 input').enable();
			}
			return row;
		},
		finishBuildRow: function(row)
		{
			row.down('.col_5 input').enable();
			var okBtn=row.down('.col_5 input:[value="OK"]');
			if(okBtn)
			{
				this.handleActionButtonClick(okBtn);
			}
			//Check whether subGenre row has been created and therefore has an associated actionButton click event.
			if (Object.isFunction(this.SG_handleActionButtonClick))
			{
				if (!Object.isUndefined(row.next('.row')) && 
					!Object.isUndefined(row.next('.row').down('.col_1 input#subGenre')))
				{
					var element=row.next('.row').down('.col_5 input');
					if (element!=null)
					{
						this.handleActionButtonClick(element);
					}
				}
			}
		},
		onSearchSubmitSuccess: function(result)
		{console.debug('onSearchSubmitSuccess');
			if (result!=null)
			{
				this.loader.updateMessage('Search Successful. Processing results&#8230;');
				if (!this.searchToggle.visible())		this.searchToggle.show();
				if (!this.resultsToggle.visible())		this.resultsToggle.show();
				if (this.conditionsWrapper.visible())	this.toggleSearch();
				if (!this.resultsWrapper.visible())		this.toggleResults();
				
				
				return;
				if (!this.libsLoaded)
				{
					this.loader.updateMessage('Search Successful. Loading Ext Core&#8230;');
					s3core.include_once
					(
						[$EXT+'adapter/ext/ext-base.js',	function(){this.loader.updateMessage('Search Successful. Loading UI Components&#8230;');}	.bind(this)],
						[$EXT+'ext-all.js',					function(){this.loader.updateMessage('Search Successful. Loading Plugins&#8230;');}			.bind(this)],
						[$EXT+'plugins/rowExpander.js',		function(){this.loader.updateMessage('Search Successful. Loading Grid&#8230;');}			.bind(this)],
						[
							$SCRIPTS+'grid.js',
							function()
							{
								this.libsLoaded=true;
								this.loader.updateMessage('Search Successful. Initializing Grid and showing results&#8230;');
								document.observe
								(
									'grid:rendered',
									function()
									{
										this.bindListManager();
										this.bindPlayerHandler();
										this.bindSongWriterHandler();
										Ext.getCmp('button_playSong').on
										(
											'click',
											function()
											{
												if (!songcentral.audioCenterIsOpen())
												{
													if (!Object.isFunction(this.bound_playerInitiatedHandler))
													{
														this.bound_playerInitiatedHandler=this.playerInitiatedHandler.bind(this);
													}
													try
													{
														Event.stopObserving('player:initiated',this.bound_playerInitiatedHandler);
													}
													catch(e){}
													document.observe
													(
														'player:initiated',
														this.bound_playerInitiatedHandler
													);
													songcentral.launchAudioCenterWindow('?URI=');
												}
												else
												{
													this.playerInitiatedHandler();
												}
												return;
											}.bind(this)
										);
										return;
									}.bind(this)
								);
								if (!this.searchToggle.visible())		this.searchToggle.show();
								if (!this.resultsToggle.visible())		this.resultsToggle.show();
								if (this.conditionsWrapper.visible())	this.toggleSearch();
								if (!this.resultsWrapper.visible())		this.toggleResults();
								(function(){this.grid=new songcentral.grid(result);}.bind(this)).delay(1);
								this.loader.fade();
								this.lightscreen.hide();
								new songcentral.quicktip
								(
									[
										'Read the steps below, then close this TIP.<br />',
										'To select a song:<br />',
										'<ol class="ttip">',
											'<li>Click checkboxes ( <img src="'+$PUBLICROOT+'images/checkbox.gif" align="texttop" alt="checkbox" /> ) or highlight a row.<\/li>',
											'<li>Appropriate functions (buttons) will then highlight at the top &amp; bottom of the grid.<\/li>',
											'<li>Click on your chosen function.<\/li>',
										'<\/ol>'
									].join('')
									//'To perform an action in the grid, simply select a row and watch for the buttons to highlight.'
								);
								return;
							}.bind(this)
						]
					);
				}
				else
				{
					this.loader.updateMessage('Search Successful. Updating results grid&#8230;');
					this.destroyGrid();
					this.grid=new songcentral.grid(result);
					if (!this.searchToggle.visible())				this.toggle.show();
					if (!this.resultsToggle.visible())		this.resultsToggle.show();
					if (this.conditionsWrapper.visible())	this.toggleSearch();
					if (!this.resultsWrapper.visible())		this.toggleResults();
					this.loader.fade();
					this.lightscreen.hide();
				}
			}
			else
			{
				this.loader.updateMessage('Search Successful. But no results were found. Please try again.');
				(function()
				{
					this.destroyGrid();
					this.loader.fade();
					this.lightscreen.hide();
					return;
				}.bind(this)).delay(2);
			}
			return;
		},
		destroyGrid: function()
		{
			try
			{
				this.grid.grid.destroy();
			}
			catch(e)
			{
				try
				{
					delete this.grid;
				}
				catch(e)
				{
					this.grid=null
				}
			}
			this.resultsWrapper.update('');
			return;
		},
		toggleSearch: function()
		{
			var object=(Object.isUndefined(this.tagName))?this.conditionsWrapper:$(this);
			if (object.visible())
			{
				object.blindUp({duration:0.5});
				$('searchToggleCheckbox').checked=false;
			}
			else
			{
				object.blindDown({duration:0.5});
				$('searchToggleCheckbox').checked=true;
			}
			return;
		},
		toggleResults: function()
		{
			var object=(Object.isUndefined(this.tagName))?this.resultsWrapper:$(this);
			if (object.visible())
			{
				object.blindUp({duration:0.5});
				$('resultsToggleCheckbox').checked=false;
			}
			else
			{
				object.blindDown({duration:0.5});
				$('resultsToggleCheckbox').checked=true;
			}
			return;
		},
		bindListManager: function()
		{
			Ext.getCmp('button_saveSearch').on
			(
				'click',
				function()
				{
					songcentral.openListManager
					(
					    {
				    		showTitle:	false,
				    		save:		true,
				    		records:	[],
							callback:	function(listmanager)
							{
								window.listManagerWindow=new Ext.Window
								(
									{
										title:		'List Manager',
										width:		615,
										height:		404,
										modal:		true,
										resizable:	false,
										items:		listmanager.getShell()
									}
								);
								window.listManagerWindow.show();
								listmanager.getCancelButton().on
								(
									'click',
									function()
									{
										window.listManagerWindow.close();
										return;
									}
								);
								return;
							}
						}
					);
				}.bind(this)
			);
			this.grid.getGrid().getSelectionModel().on
			(
				{
					 rowselect: function()
					 {
					 	Ext.getCmp('button_addToList').enable();
					 	return
					 }.bind(this),
					 rowdeselect: function()
					 {
					 	Ext.getCmp('button_addToList').disable();
					 	return
					 }
				}
			);
			Ext.getCmp('button_addToList').on
			(
				'click',
				function()
				{
					versionIDs=[];
					this.grid.getGrid().getSelectionModel().getSelections().each
					(
						function(row)
						{
							versionIDs.push(row.json.version_id);
							return;
						}
					);
					songcentral.openListManager
					(
					    {
				    		showTitle:	false,
				    		save:		true,
				    		add:		true,
				    		records:	versionIDs,
							callback:	function(listmanager)
							{
								window.listManagerWindow=new Ext.Window
								(
									{
										title:		'List Manager',
										width:		615,
										height:		404,
										modal:		true,
										resizable:	false,
										items:		listmanager.getShell()
									}
								);
								window.listManagerWindow.show();
								listmanager.getCancelButton().on
								(
									'click',
									function()
									{
										window.listManagerWindow.close();
										return;
									}
								);
								return;
							}.bind(this)
						}
					);
				}.bind(this)
			);
			return;
		},
		bindPlayerHandler: function()
		{
			this.grid.getGrid().getSelectionModel().on
			(
				{
					rowselect: function()
					{
						var selectionCount=this.grid.getGrid().getSelectionModel().getCount();
						if (selectionCount)
						{
							Ext.getCmp('button_playSong').enable();
						}
						else
						{
							Ext.getCmp('button_playSong').disable();
						}
						return;
					}.bind(this),
					rowdeselect: function()
					{
						var selectionCount=this.grid.getGrid().getSelectionModel().getCount();
						if (selectionCount)
						{
							Ext.getCmp('button_playSong').enable();
						}
						else
						{
							Ext.getCmp('button_playSong').disable();
						}
						return;
					}.bind(this)
				}
			);
			return;
		},
		bindSongWriterHandler: function()
		{
			this.grid.getGrid().getSelectionModel().on
			(
				{
					rowselect: function()
					{
						var selectionCount=this.grid.getGrid().getSelectionModel().getCount();
						if (selectionCount)
						{
							Ext.getCmp('button_aboutSongWriter').enable();
						}
						else
						{
							Ext.getCmp('button_aboutSongWriter').disable();
						}
						return;
					}.bind(this),
					rowdeselect: function()
					{
						var selectionCount=this.grid.getGrid().getSelectionModel().getCount();
						if (selectionCount)
						{
							Ext.getCmp('button_aboutSongWriter').enable();
						}
						else
						{
							Ext.getCmp('button_aboutSongWriter').disable();
						}
						return;
					}.bind(this)
				}
			);
			Ext.getCmp('button_aboutSongWriter').addListener
			(
				'click',
				function()
				{
					this.songWriterWindow=new Ext.Window
					(
						{
							title:			'Song Writer Information',
							modal:			true,
							resizable:		false,
							maximizable:	false,
							width:			800,
							height:			600,
							//autoLoad:		$COREROOT+'data/audiocenter/writerinfo/',
							buttons:
							{
								text:		'Close',
								handler:	function()
								{
									this.songWriterWindow.close();
									return;
								}.bind(this)
							}
						}
					);
					this.songWriterWindow.show();
					this.songWriterWindow.getUpdater().update
					(
						{
							url:	$COREROOT+'data/audiocenter/writerinfo/',
							params:
							{
								cust_id: this.grid.getGrid().getSelectionModel().getSelected().json.cust_id
							},
							text:	'Loading writer information. Please wait&#8230;'
						}
					);
					return;
				}.bind(this)
			);
			return;
		},
		bound_playerInitiatedHandler: false,
		playerInitiatedHandler: function()
		{
			var id='sc_grid_'+Math.round(Math.random()*1000);
			var selections=this.grid.getGrid().getSelectionModel().getSelections();
			if (selections.length)
			{
				songcentral.audiocenter.player.panel_tabs.add
				(
					{
						id:			'tab_'+id,
						title:		'Search Results',
						closable:	true,
						html:		'<div id="'+id+'"></div>'
					}
				);
				songcentral.audiocenter.player.panel_tabs.setActiveTab('tab_'+id);
				var config=this.grid.originalConfig;
				config.renderTo=id;
				config.options.autoWidth=true;
				config.options.autoHeight=true;
				try
				{
					delete config.options.width;
					delete config.options.height;
					delete config.toolbar.top;
					delete config.toolbar.bottom;
				}
				catch(e)
				{
					config.options.width=false;
					config.options.height=false;
					config.toolbar.top=false;
					config.toolbar.bottom=false;
				}
				songcentral.audiocenter.createGrid(config);
				for(var i=0; i<selections.length; i++)
				{
					if(!i)
					{
						songcentral.audiocenter.player.playlist.addAndActivateRecord(selections[i].json.id3,{notShowInfo:false});
					}
					else
					{
						songcentral.audiocenter.player.playlist.addRecord(selections[i].json.id3);
					}
				}
				songcentral.focusAudioCenter();
			}
			return;
		}
	}
);