SubjectTermPicker = Class.create();
SubjectTermPicker.Translations;

SubjectTermPicker.prototype.initialize = function(root, name, textDirection) {

	// Configurable public fields
	this.ContextRoot = root;
	this.Name = name;
	this.TextDirection = textDirection;
	this.AjaxProcessorURL = '';
	this.ElementsPrefix = '';
	this.AddSubjectTermButtonID = 'addNewSubjectTerm';
	this.NewTermFieldID = 'newSubjectTerm';
	this.ValidTermsFieldID = 'searchSubjectTerms';
	this.ValidTermsDivID = 'acceptedTerms';
	this.NoValidTermsDivID = 'noAcceptedTerms';
	this.PendingTermsDivID = 'pendingTerms';
	this.InvalidTermsDivID = 'invalidTerms';
	
	// Protected control fields
	this.FindSubjectTermsManager = new SubjectTermFind(this.ContextRoot, this.Name + '.FindSubjectTermsManager', this.TextDirection);
	this.CurrentSubjectTermIndex = 0;
	this.AddedTerms = new Array();
	this.PendingTerms = new Array();
	this.ValidTerms = new Array();
	this.InvalidTerms = new Array();
}

SubjectTermPicker.prototype.Create = function() {
	Event.observe($(this.AddSubjectTermButtonID), 'click', this.addNewSubjectTermClicked.bindAsEventListener(this));
	
	this.FindSubjectTermsManager.ElementsPrefix = this.ElementsPrefix;
	this.FindSubjectTermsManager.NewTermFieldID = this.NewTermFieldID;
	this.FindSubjectTermsManager.hasSubjectTermFunction = this.hasSubjectTerm.bind(this);
	this.FindSubjectTermsManager.findSubjectTermsAddClickedListener = this.findSubjectTermsAddClicked.bindAsEventListener(this);
	this.FindSubjectTermsManager.findSubjectTermsRemoveClickedListener = this.findSubjectTermsRemoveClicked.bindAsEventListener(this);
	this.FindSubjectTermsManager.Create();
}

SubjectTermPicker.prototype.hasSubjectTerm = function(subjectTermID) {
	return this.ValidTerms.invoke('get', 'ID').include(subjectTermID);
}

SubjectTermPicker.prototype.addNewSubjectTermClicked = function(evt) {
	var clearField = true;
	var newSubjectTermField = $(this.NewTermFieldID);
	
	// Only attempt adding it if not already done
	var newSubjectTerm = Trim(newSubjectTermField.value);
	
	if (newSubjectTerm != '') {
		clearField = this.handleNewSubjectTerm(newSubjectTerm);
	}
	
	if (clearField) {
		newSubjectTermField.value = '';
	}
	
	// Only focus if field hasn't been disabled, to prevent an IE error
	if (!newSubjectTermField.disabled) {
		newSubjectTermField.focus();
	}
}

SubjectTermPicker.prototype.handleNewSubjectTerm = function(newSubjectTerm) {
	var pending = false;
	
	var terms = newSubjectTerm.split(";").select(function(term) {
		return (! term.blank()); 
	});
	
	if (!this.continueNewTermProcessing(terms)) {
		return false;
	}
	
	terms.each(function(term) {				
		term = Trim(term);
			
		this.CurrentSubjectTermIndex++;
		this.AddedTerms.push(term);
		this.PendingTerms.push(this.CurrentSubjectTermIndex);
		
		this.sendNewTermAjaxRequest(term);
		$(this.PendingTermsDivID).insert( { bottom: '<div class="lTerm" id="'+ this.ElementsPrefix + 'subTermDiv_' + this.CurrentSubjectTermIndex + '">' + term + '</div>' } );
		pending = true;		
	}.bind(this));
	
	if (pending && this.PendingTerms.length > 0) {
		Element.show($(this.PendingTermsDivID));
	}
	
	return true;
}

SubjectTermPicker.prototype.continueNewTermProcessing = function(terms) {
	return true;
}

SubjectTermPicker.prototype.sendNewTermAjaxRequest = function(newSubjectTerm) {
	var queryComponents = new Array();
	
	queryComponents.push('subjectTermText=' + encodeURIComponent(newSubjectTerm));
	queryComponents.push('subjectTermIndex=' + encodeURIComponent(this.CurrentSubjectTermIndex));
	
	var myAjax = new Ajax.Request(this.AjaxProcessorURL, 
		{method: 'post', parameters: queryComponents.join('&'),
			onSuccess: this.handleSubjectTermProcessed.bind(this) });
}

SubjectTermPicker.prototype.handleSubjectTermProcessed = function(request) {
	var response = eval('(' + request.responseText + ')');
	
	Element.remove(this.ElementsPrefix + 'subTermDiv_' + response.subjectTermIndex);	
	this.PendingTerms = this.PendingTerms.without(response.subjectTermIndex);
	
	if (this.PendingTerms.length <= 0) {
		Element.hide($(this.PendingTermsDivID));
	}
	
	if (response.success) {
		this.addResolvedSubjectTerm(response.subjectTermText, response.subjectTermID);
	} else {
		this.addInvalidSubjectTerm(response.subjectTermText, response.subjectTermIndex);
	}
}

SubjectTermPicker.prototype.addExistingSubjectTerm = function(subjectTerm, termID) {
	this.AddedTerms.push(subjectTerm);
	this.addResolvedSubjectTerm(subjectTerm, termID);
}

SubjectTermPicker.prototype.addResolvedSubjectTerm = function(subjectTerm, termID) {
	if (this.hasSubjectTerm(termID)) {
		return;
	}
		
	this.ValidTerms.push($H({ ID: termID, name: subjectTerm}));
	
	$(this.ValidTermsDivID).insert( { bottom: '<div class="lTerm clearDiv" id="' + this.ElementsPrefix + 'acceptedTermDiv_' + termID + '" term="' 
			+ subjectTerm + '"><div class="lTermLinks"><a href="javascript:void(0)" id="' + this.ElementsPrefix + 'acceptedTermRemove_' + termID 
			+ '" termID="' + termID + '">' + this.Translations.get('global.remove.action')+'</a></div>' + subjectTerm + '</div>' } );
	
	Event.observe($(this.ElementsPrefix + 'acceptedTermRemove_' + termID), 'click', this.removeResolvedSubjectTermClicked.bindAsEventListener(this));
	Element.hide(this.NoValidTermsDivID);
	this.FindSubjectTermsManager.findSubjectTermsReloaded();
	this.updateTermsFields(this.ValidTerms);
}

SubjectTermPicker.prototype.addInvalidSubjectTerm = function(subjectTerm, subjectTermIndex) {
	this.InvalidTerms.push(subjectTermIndex);
	
	$(this.InvalidTermsDivID).insert( { bottom: '<div class="lTerm clearDiv" id="' + this.ElementsPrefix + 'invalidTermDiv_' 
				+ subjectTermIndex + '" term="' + subjectTerm + '">' 
				+ '<div class="lTermLinks">'
				+ '<a href="javascript:void(0)" id="' + this.ElementsPrefix + 'invalidTermRemove_' + subjectTermIndex + '">' + this.Translations.get('global.remove.action')+ '</a> '
				+ '<a href="javascript:void(0)" id="' + this.ElementsPrefix + 'invalidTermReplace_' + subjectTermIndex + '">' + this.Translations.get('global.replace.action') + '</a>'
				+ '</div>' + subjectTerm + '</div>' } );
	Event.observe($(this.ElementsPrefix + 'invalidTermRemove_' + subjectTermIndex), 'click', this.removeInvalidSubjectTermClicked.bindAsEventListener(this));
	Event.observe($(this.ElementsPrefix + 'invalidTermReplace_' + subjectTermIndex), 'click', this.replaceInvalidSubjectTermClicked.bindAsEventListener(this));
	Element.show(this.InvalidTermsDivID);
}

SubjectTermPicker.prototype.removeResolvedSubjectTermClicked = function(evt) {
	this.removeResolvedSubjectTerm(Event.element(evt).getAttribute("termID"));
}

SubjectTermPicker.prototype.removeResolvedSubjectTerm = function(subjectTermID) {
	var subjectTermText = $(this.ElementsPrefix + 'acceptedTermDiv_' + subjectTermID).getAttribute('term');
	
	this.AddedTerms = this.AddedTerms.without(subjectTermText);
	this.ValidTerms = this.ValidTerms.reject(function(term) { return term.get('ID') == subjectTermID; });
	
	if (this.ValidTerms.length <= 0) {
		Element.show(this.NoValidTermsDivID);
	}
	
	Element.remove(this.ElementsPrefix + 'acceptedTermDiv_' + subjectTermID);
	
	this.FindSubjectTermsManager.findSubjectTermsReloaded();
	this.updateTermsFields(this.ValidTerms);
}

SubjectTermPicker.prototype.removeInvalidSubjectTermClicked = function(evt) {
	var removeLink = Event.element(evt);
	var subjectTermIndex = removeLink.id.split("_")[1];
	this.removeInvalidSubjectTerm(subjectTermIndex);
}

SubjectTermPicker.prototype.removeInvalidSubjectTerm = function(subjectTermIndex) {
	var subjectTermText = $(this.ElementsPrefix + 'invalidTermDiv_' + subjectTermIndex).getAttribute('term');
	
	this.AddedTerms = this.AddedTerms.without(subjectTermText);
	this.InvalidTerms = this.InvalidTerms.without(subjectTermIndex);
		
	Element.remove(this.ElementsPrefix + 'invalidTermDiv_' + subjectTermIndex);
	
	if (this.InvalidTerms.length == 0) {
		Element.hide(this.InvalidTermsDivID);
	}
}

SubjectTermPicker.prototype.replaceInvalidSubjectTermClicked = function(evt) {
	var replaceLink = Event.element(evt);
	var subjectTermIndex = replaceLink.id.split("_")[1];
	var subjectTermText = $(this.ElementsPrefix + 'invalidTermDiv_' + subjectTermIndex).getAttribute('term');
	
	this.replaceInvalidSubjectTerm(subjectTermText, subjectTermIndex);
}

SubjectTermPicker.prototype.replaceInvalidSubjectTerm = function(subjectTerm, subjectTermIndex) {
	var newSubjectTermField = $(this.NewTermFieldID);
	newSubjectTermField.value = subjectTerm;
	newSubjectTermField.focus();
	
	this.removeInvalidSubjectTerm(subjectTermIndex);
}

SubjectTermPicker.prototype.findSubjectTermsAddClicked = function(evt) {
	var addLink = Event.element(evt);
	
	this.AddedTerms.push(addLink.getAttribute("subjectTerm"));
	
	this.addResolvedSubjectTerm(addLink.getAttribute("subjectTerm"), addLink.getAttribute("termID"));
}

SubjectTermPicker.prototype.findSubjectTermsRemoveClicked = function(evt) {
	this.removeResolvedSubjectTerm(Event.element(evt).getAttribute("termID"));
}

SubjectTermPicker.prototype.updateTermsFields = function(validTerms) {
	$(this.ValidTermsFieldID).value = this.ValidTerms.invoke('get', 'name').join(';');
}
