var Search = {
	search_input : null,
	search_button : null,
	search_value : '',
	matches_found : null,
	previous_button : null,
	next_button : null,
			
	last_key : null,
	matches : null,
	selected_match : null,
	
	searching : false,
	
	_keydown : null,
	_keyup : null,
	_shift_select : null,
	_blur : null,
	_focus : null,
	
	initialized : false,
	
	initialize : function(initial_search) {
		if (!this.initialized) {
			this.search_input = $('search').down('input');
			this.search_button = $('search').down('.go');
			this.previous_button = $('matches').down('.previous');
			this.next_button = $('matches').down('.next');
			this.matches_found = $('matches_quantity');	
			
			this._keydown = this.keydown.bindAsEventListener(this);
			this._keyup = this.keyup.bindAsEventListener(this);
			this._click = this.click.bindAsEventListener(this);
			this._shift_select = this.shift_select.bindAsEventListener(this);
			this._blur = this.blur.bindAsEventListener(this);
			this._focus = this.focus.bindAsEventListener(this);			

			Event.observe(document, 'keydown', this._keydown);
			Event.observe(this.search_input, 'focus', this._focus);
			Event.observe(this.search_input, 'blur', this._blur);

			Event.observe(this.search_input, 'keyup', this._keyup);
			Event.observe(this.search_button, 'click', this._click);
			Event.observe(this.previous_button, 'mousedown', function(event) {event.stop()});
			Event.observe(this.next_button, 'mousedown', function(event) {event.stop()});			
			Event.observe(this.previous_button, 'mouseup', this._shift_select);
			Event.observe(this.next_button, 'mouseup', this._shift_select);			
			
			this.selected_match = 0;
			if (initial_search) {
				this.search_input.value = initial_search;
				this.search_input.focus();
				this.update_search();
			}			

			this.initialized = true;
		}
	},
	
	blur : function(event) {
		this.set_focus(false);
	},
	
	focus : function(event) {
		this.set_focus(true);
	},
	
	set_focus : function(focused) {
		this.searching = focused || false;
	},
	
	keydown : function(event) {
		if (event.keyCode == Event.KEY_TAB || event.keyCode == Event.KEY_RETURN) {
			this.search_input.focus();
			if (event.shiftKey) {
				this.shift_selected_result(-1);
			} else {
				this.shift_selected_result(1);
			}
			Transcript.select_line(this.matches[this.selected_match].line_id);
			event.stop();
		}
	},
	
	keyup : function(event) {
		this.update_search();
	},
	
	click : function(event) {
		Transcript.select_line(this.matches[this.selected_match].line_id);
		event.stop();
	},
	
	update_search : function() {
		var new_value = this.search_input.value;
		if (new_value == this.search_value) {
			return false;
		}
		
		this.clear_matches();
		
		this.search_value = new_value;
		if (this.search_value.length >= 3) {
			this.do_search();
			this.set_focus(true);
		} else {
			this.selected_match = 0;
		}
		Transcript.output_transcript();
		this.highlight_selected_result(this.selected_match);
	},
	
	shift_select : function(event) {
		if (event.element().hasClassName('previous')) {
			this.shift_selected_result(-1);
		} else {
			this.shift_selected_result(1);
		}
		Transcript.select_line(this.matches[this.selected_match].line_id);
	},
	
	shift_selected_result : function(shift_value) {
		this.highlight_selected_result(this.selected_match, true);
		this.selected_match += shift_value;
		if ((this.selected_match) >= this.matches.length) {
			this.selected_match = 0;
		} else if (this.selected_match < 0) {
			this.selected_match = this.matches.length - 1;
		}
		
		this.highlight_selected_result(this.selected_match);
	},
	
	highlight_selected_result : function(id, clear) {
		var selected = $$('#transcript .match_' + id);
		for (var i=0, c=selected.length; i<c; i++) {
			var span = selected[i];
			var position = span.positionedOffset()[1];
			var scrollTop = Transcript.output.scrollTop;
			if (position > scrollTop + Transcript.output.getHeight() || position < scrollTop) {
				Transcript.output.scrollTop = position;
			};
			if (clear) {
				span.removeClassName('selected');
			} else {
				span.addClassName('selected');
			}
		}
	},
	
	clear_matches : function() {
		for (var i=0, c=Transcript.transcript_array.length; i<c; i++) {
			var line = Transcript.transcript_array[i];
			line.matches = null;
		}
		this.matched_strings = null;
	},

	do_search : function() {
		var matches;
		var matched;
		var regex = new RegExp(this.search_value, "gi");
		this.matched_strings = [];

		var text_to_search = Transcript.transcription_string;
		var offset = 0;
		var i = 0;
		matches = [];

		while ((matched = text_to_search.search(regex)) != -1) {
			text_to_search = text_to_search.substr(matched + this.search_value.length);
			matched = {index: offset + matched, length: this.search_value.length, id: i}
			offset = matched.index + matched.length;
			matches.push(matched);
			i++;
		}
		this.matches = matches;
		this.matches_found.innerHTML = this.matches.length;
		this.assign_matches_by_line(matches);
		this.output_matches_to_flash();
	},
	
	output_matches_to_flash : function() {
		var matched_times = [];
		for (var i=0, c=this.matches.length; i<c; i++) {
			var matched = this.matches[i];
			matched_times.push(Transcript.transcript_array[matched.line_id].time);
		}
		Transcript.transcription_player.markFromJavascript(matched_times);
	},
	
	assign_matches_by_line : function(matches) {
		for (var i=0, c=matches.length; i<c; i++) {
			var matched = matches[i];
			for (var j=0, d=Transcript.transcript_array.length; j<d; j++) {
				var line = Transcript.transcript_array[j];
				if (matched.index >= line.index && matched.index <= (line.index + line.length)) {
					line.matches = line.matches || [];
					if (matched.index + matched.length > line.index + line.length) {
						matched.index = matched.index - line.index;
						line.matches.push({index: matched.index, length: line.length - matched.index, id: matched.id})
						matched.length -= line.length - matched.index;
						matched.index = line.index + line.length;
					} else {
						matched.index = matched.index - line.index;
						line.matches.push(matched);
					}
					matched.line_id = line.id;
				}
			}
		}
	}	
}
