/*********************************************************\

COMP External API

As the COMP object is refactoered, additions ge below this
point in the file until a time comes when the entire object
has been updated.

Guidelines for new object creation, are the use of
closures, private variable scoping, and get/set methods.

\*********************************************************/

(function(){ //user management
	
Ext.namespace('COMP');
Ext.namespace('COMP.user');

var userData = {};

Ext.apply(COMP.user, {
	set: function(property, value){
		var type = typeof key;
		switch (type) {
			case 'string':
				userData[key] = value;
			break;
			case 'object':
				var config = property;
				for (property in config) {
					if (config.hasOwnProperty(property)) {
						userData[property] = config[property];
					}
				}
			break;
			case 'undefined' :
				COMP.sys.log('Value passed for user data "' + key + '" is not defined.');
			break;
		}
	},
	get: function(key){
		return userData[key];
	},
	getSessionID: function(){
		//return userData.sessionID;
		return COMP.V.sessionid;
	}
});

})();


(function(){ //systems management
	
Ext.namespace('COMP.sys');

var status = {
	isLogging : false
};

function parseDebugData(args) {
	return args.length == 1 && typeof args[0] == 'string' ? args[0] : args;
};

Ext.apply(COMP.sys, {
	getStatus: function(){
		var copy = {};
		Ext.apply(copy, status);
		return copy;
	},
	activateLogging: function(){
		if (!status.isLogging) {
			status.isLogging = true;
			COMP.V.debug = true;
			this.log('Logging activated: ' + new Date());
		}
	},
	deactivateLogging: function(){
		status.isLogging = false;
		COMP.V.debug = false;
	},
	log: function(){
		if (status.isLogging) {
			var message = parseDebugData(arguments);
			if (window.console) window.console.log(message);
		}
	}
});

if (window.console) COMP.sys.activateLogging();

})();

/*********************************************************\

Tracking Field
COMP.form.TrackingField

This is a Field object that has the ability to track its
value and trigger an 'update' event. This is useful because
various browsers have differing event handeling with form
fields based on key-presses mouse-clicks, and with
cut-and-pastes.

\*********************************************************/

(function(){
	
Ext.namespace('COMP.form');

var TrackingField = COMP.form.TrackingField = Ext.extend(Ext.form.Field, {
	trackingDelay: 200,
	trackedValue: null,
	trackingID: null,
	autoTracking: true, 
	isfocused: false,
	cls: 'TrackingField',
	isFocused: function(){
		return this.isfocused;
	},
	isTracking: function(){
		return this.trackingID !== null;
	},
	trackValue: function(){
		var current = this.getValue();
		var tracked = this.trackedValue;
		if (tracked !== current) {
			this.fireEvent('update', {currentValue: current, trackedValue: tracked});
			this.trackedValue = current;
		}
	},
	startTracking: function(){
		if (this.trackingID === null){
			this.trackedValue = this.getValue();
			this.trackingID = setInterval(this.trackValue.createDelegate(this), this.trackingDelay);
		}
	},
	stopTracking: function(){
		if (this.trackingID !== null){
			clearInterval(this.trackingID);
			this.trackingID = null;
			this.trackedValue = null;
		}
	},
	initComponent: function(){
		this.addEvents({
			'update' : true,
			'beforetracking' : true,
			'aftertracking': true
		});
		if (this.autoTracking) {
			this.addListener('focus', function(){ this.startTracking(); });
			this.addListener('blur', function(){ this.stopTracking(); });
		}
		this.addListener('focus', function(){ this.isfocused = true; });
		this.addListener('blur', function(){ this.isfocused = false; });
		TrackingField.superclass.initComponent.apply(this, arguments);
	}
});

/*********************************************************\

SuggestedSearchBar
COMP.form.SuggestedSearchBar

The Suggested Search Bar deliveres a number of results from
the server based on user input. The use can then tab
through and select any of the offered options. Works pretty
much in the same way Google's searchbar does.

\*********************************************************/

var SuggestionStore = Ext.extend(Ext.data.ArrayStore, {
	baseParams : { sessionid : COMP.user.getSessionID() },
	url: '/ajax/rws_search_autocomplete',
	initComponent: function(){
		SuggestionStore.superclass.initComponent.apply(this, arguments);
	}
});

var SuggestionList = Ext.extend(Ext.DataView, {
	autoHeight: true,
	singleSelect: true,
	cls: 'SuggestionList',
	itemSelector: 'div.SuggestionListItem',
	selectedClass: 'selected',
	overClass: 'hover',
	tpl: new Ext.XTemplate(
		'<tpl for=".">',
			'<div class="SuggestionListItem">{name}</div>',
		'</tpl>'
	),
	initComponent: function(){
		this.hide();
        SuggestionList.superclass.initComponent.apply(this, arguments);
	}
});

var SuggestedSearchField = Ext.extend(COMP.form.TrackingField, {
	cls: 'SuggestedSearchField',
	id: 'simpleSearchBar_textfield', //TODO: remove this default call
	trackingDelay : 333,
	initComponent: function(){
        SuggestedSearchField.superclass.initComponent.apply(this, arguments);
	},
	hide: function(){
		SuggestedSearchField.superclass.hide.apply(this, arguments);
		return this;
	},
	clear: function(){
		this.setValue('');
		return this;
	}
});

var SuggestedSearchBar = Ext.extend(Ext.Container, {
    cls: 'SuggestedSearchBar',
	id: 'simpleSearchBar', //TODO: remove this default call
	filtering: true,
	
	GetSearchText: function(){//TODO: Find where this is being called from, and fix name
		return Ext.getCmp('simpleSearchBar_textfield').getValue(); //TODO: hacky, but works with other function calls... remove it asap!
	},
	
	initComponent: function(){
		
		
		//private memebers
		var isMoused = false;
		
		var field = new SuggestedSearchField();
		var store = new SuggestionStore({fields: ['name']});
		var list = new SuggestionList({store:store});
		
		//privite methods
		function chooseFromList(index){
			if (index > -1) {
				field.blur();
				var choice = store.getAt(index).data.name;
				field.setValue(choice);
				field.focus();
				list.clearSelections();
				list.hide();
			}
		}
		
		field.on({
			update: function(event){
				var value = this.getValue();
				var filtered = value.replace(/(\\)/gi, '');
				this.setValue(filtered);
				
				if (filtered.length > 1) {
					store.load({
						params: { query : event.currentValue }
					});
				}
				else {
					list.hide();
				}
			},
			blur: function(){
				if (!isMoused) list.hide();
			},
			focus: function(){
				//if (this.getValue().length > 1) list.show();
			},
			specialkey: function(field, event){
				var key = event.getKey();
				var selecting = list.isVisible();
				var selections = list.getSelectedIndexes();
				var selection = selections.length ? selections[0] : -1;
				if (selecting) {
					switch (key) {
					
						case event.BACKSPACE :
							list.hide();
							COMP.sys.log(event)
							return true;
						break;
						
						case event.ESC :
							list.hide();
							return true;
						break;
					
						case event.LEFT : 
							list.hide();
							return true;
						break;
					
						case event.RIGHT :
							chooseFromList(selection);
						break;
					
						case event.DOWN :
							if (selection == store.getCount()) {
								list.select(0);
							}
							else {
								list.select(selection + 1);
							}
						break;
					
						case event.UP : 
							if (selection < 0) {
								list.hide();
							}
							else {
								list.select(selection - 1);
							}
						break;
					
						case event.ENTER : 
							chooseFromList(selection);
							InitSearch(null, event);
						break;
					}
					event.preventDefault();
				}
				else if (key == event.DOWN){
					if (store.getCount() > 0) list.show();
					event.preventDefault();
				}
				else if (key == event.ENTER){
					InitSearch(null, event);
				}
			}
		});
		
		list.on({
			mouseenter: function(){
				isMoused = true;
			},
			mouseleave: function(){
				isMoused = false;
				if (!field.isFocused()) {
					this.hide();
				}
			},
			beforeclick: function(self, index){
				isMoused = false;
				chooseFromList(index);
			}
		});
		
		store.on({
			load: function(str,evt){
				store.filterBy(function(record){
					return record.data.name.startsWith(field.getValue());
				});
				if (field.isFocused() && field.getValue().length > 2 && store.getCount() > 0) list.show();
			}
		});
		
        this.items = [
			field,
            {
				xtype:'button',
				cls:'SuggestedSearchButton',
				text:L(3638),
				width:72,
				handler: function(unknown,evt) {InitSearch(null, evt)}
			},
			list
        ];

        SuggestedSearchBar.superclass.initComponent.apply(this, arguments);
    }
});

Ext.namespace('COMP.form');
COMP.form.SuggestedSearchBar = SuggestedSearchBar;

})();if (window.COMP) COMP.Broadcast('scriptLoaded_COMP2');