/**
 * scripts.js
 * javascript functions used in healthylunch.org.uk
 * @author Peter Edwards <tech@e-2.org>
 * @version 1.0
 * @package healthylunch
 * @requires jQuery 1.3
 */
/**
 * checkUserPassword
 */
function checkUserPassword(val)
{
    var errors = '';
    if (val.length < 6) {
        errors += '- Your new password must contain 6 or more characters\n';
    }
    if (!val.match(/[A-Z]+/) || !val.match(/[a-z]+/) || !val.match(/[0-9]+/)) {
        errors += '- Your new password must contain a mixture of lowercase and uppercase letters and numbers\n';
    }
    if (errors !== '') {
        return errors;
    } else {
        return true;
    }
}
/**
 * checkEmail
 */
function checkEmail(email)
{
    var filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
    if (filter.test(email)) {
        return true;
    } else {
        return false;
    }  
}

/**
 * login
 */
function trylogin()
{
    var f = document.forms['login-app'];
    var errorMsg = false;
    if (f.username.value === '' && f.password.value === '') {
        errorMsg = 'Please enter your username and password';
        if (f.username.focus) {
        	f.username.focus();
        }
    } else if (f.username.value === '') {
        errorMsg = 'Please enter your username';
        if (f.username.focus) {
        	f.username.focus();
        }
    } else if (f.password.value === '') {
        errorMsg = 'Please enter your password';
        if (f.password.focus) {
        	f.password.focus();
        }
    }
    if (errorMsg) {
        alert(errorMsg);
        return false;
    } else {
        return true;
    }
}
/**
 * getLostPassword
 */
function getLostPassword()
{
    var f = document.forms['login-pass'];
    if (!checkEmail(f.lostpassword.value)) {
        alert('The email address you entered appears to be invalid\nPlease try again');
        return false;
    } else {
        return true;
    }
}
/**
 * checkChangePassword
 */
function checkChangePassword()
{
    var f = document.forms['password-update'];
    var errorMsg = '';
    if (f.old_passwd.value === '') {
        errorMsg += '- Please type in your current password\n';
        if (f.old_passwd.focus) {
        	f.old_passwd.focus();
        }
    }
    if (checkUserPassword(f.new_passwd1.value) !== true) {
        errorMsg += checkUserPassword(f.new_passwd1.value);
        f.new_passwd1.value = "";
        f.new_passwd2.value = "";
    }
    if (f.new_passwd1.value !== f.new_passwd2.value) {
        errorMsg += '- Your two new passwords do not match\n';
        f.new_passwd1.value = "";
        f.new_passwd2.value = "";
    }
    if (errorMsg === '') {
        return true;
    } else {
        alert("Your password could not be changed for the following reason(s)\n\n"+errorMsg+"\nPlease try again");
        f.old_passwd.value = "";
        f.new_passwd1.value = "";
        f.new_passwd2.value = "";
        return false;
    }
}
/**
 * checkAddSchoolForm
 */
function checkAddSchoolForm()
{
    var f = document.forms['school-user-add'];
    var errorMsg = '';
    if (f.org_name.value === '') {
        errorMsg += '- Please type in the name of the School\n';
    }
    if (f.username.value === '') {
        errorMsg += '- Please type in a username for the School user\n';
    }
    if (f.email.value === '') {
        errorMsg += '- Please type in an email address for the school user\n';
    } else {
        if (!checkEmail(f.email.value)) {
            errorMsg += '- Please check the email address, it appears to be invalid\n';
        }
    }
    if (errorMsg) {
        alert("The new School could not be added for the following reason(s):\n\n"+errorMsg+"\nPlease try again");
        return false;
    } else {
        return true;
    }
}
/**
 * checkOrgName
 */
function checkOrgName()
{
    var f = document.forms["org-update"];
    if (f.org_name.value === '') {
        alert("You must enter a name here");
        f.reset();
        return false;
    } else {
        return true;
    }
}
/**
 * checkUserUpdateForm
 */
function checkUserUpdateForm(idx)
{
    var f = document.forms['user-update'+idx];
    
}
/**
 * confirmSchoolDeletion
 */
function confirmSchoolDeletion()
{
    var f = document.forms["org-update"];
    if (confirm("Are you sure?\nAll the Schools details will be permanently lost!")) {
        f.form_action.value = "delete_school";
        f.submit();
    }
}
/**
 * confirmAdminResetPassword
 */
function confirmAdminResetPassword(form_name)
{
    var f = document.forms[form_name];
    if (confirm("This user will have their password reset and the\nnew password will be sent to their registered email address.\n\nContinue?")) {
        f.form_action.value = "reset_org_user_password";
        f.submit();
    }
}
/**
 * confirmAdminDeleteUser
 */
function confirmAdminDeleteUser(form_name)
{
    var f = document.forms[form_name];
    if (confirm("Are you sure?\nAll details for this user will be permanently lost!")) {
        f.form_action.value = "delete_org_user";
        f.submit();
    }
}
/**
 * invoice confirmation dialogs
 * @param string task
 * @param integer org_id
 */
function confirmInvoice(task, org_id) 
{
	var msg = "Are you sure?";
	var newdate = false;
	switch (task) {
	case 'cancel':
		msg += "\nThis will cancel the invoice ONLY\nYou still have to delete the school\nto prevent them from logging in...";
		break;
	case 'paid':
		var now = new Date();
		var months = ["January","February","March","April","May","June","July","August","Sepember","October","November","December"];
		var dateStr = now.getDate() + '/' + (now.getMonth() + 1) + '/' + now.getFullYear();
		var date = prompt("Please confirm the date this invoice was paid", dateStr);
		if (date !== dateStr) {
    		newdate = new Date();
		    var parts = date.split('/');
		    newdate.setMonth((parseInt(parts[1]) - 1));
		    newdate.setFullYear(parseInt(parts[2]));
		    newdate.setDate(parseInt(parts[0]));
		    msg = "Invoice paid on "+newdate.getDate()+" "+months[newdate.getMonth()]+" "+newdate.getFullYear()+"?";
		} else {
			msg = "Invoice paid on "+now.getDate()+" "+months[now.getMonth()]+" "+now.getFullYear()+"?";
		}
        break;
	case 'resend':
		break;
	case 'remind':
		break;
	case 'delete':
		msg += "\nAll the details for this school,\nuser and invoice will be deleted...";
	}
	if (msg && confirm(msg)) {
		var f = document.forms.schoolsubs;
		f.task.value = task;
		f.org_id.value = org_id;
		if (newdate) {
			f.newdate.value = newdate.getTime();
		}
		f.submit();
	}
}
function copyToClipboard()
{
    var cntnt = document.getElementById('textTable');
    cntnt.contentEditable = 'true';
    var controlRange;
    if (document.body.createControlRange) {
        controlRange = document.body.createControlRange();
        controlRange.addElement(cntnt);
        controlRange.execCommand('Copy');
    }
    cntnt.contentEditable = 'false';
}
function requestLogin()
{
    var f = document.forms.contactus;
    var errorMsg = '';
    if (f.fullname.value === "") {
        errorMsg += " - Please fill in your name\n";
    }
    if (f.email.value === "") {
        errorMsg += " - Please fill in your email address\n";
    } else if (!checkEmail(f.email.value)) {
        errorMsg += " - Your email address appears to be invalid\n";
    }
    if (f.org_name.value === "") {
        errorMsg += " - Please fill in the name of your Local Authority/PCT\n";
    }
    if (f.school_name.value === "") {
        errorMsg += " - Please fill in the name of your Organisation/School\n";
    }
    if (f.message.value === "") {
        errorMsg += " - Please tell us about your role in your Organisation.\n";
    }
    if (errorMsg) {
        alert("Sorry, some parts of this form are incomplete:\n"+errorMsg+"Please correct the error(s) and try again.");
        return false;
    } else {
        return true;
    } 
}
function checkSubscriptionForm()
{
	var f = document.forms.subscription;
    var errorMsg = '';
    if ($.trim(f.school_name.value) === "") {
        errorMsg += " - Please fill in the name of your school\n";
    }
    if ($.trim(f.first_name.value) === "") {
        errorMsg += " - Please fill in your first name\n";
    }
    if ($.trim(f.surname.value) === "") {
        errorMsg += " - Please fill in your surname\n";
    }
    if ($.trim(f.email.value) === "") {
        errorMsg += " - Please fill in your email address\n";
    } else if (!checkEmail(f.email.value)) {
        errorMsg += " - Your email address appears to be invalid\n";
    }
    if (!f.tc.checked) {
        errorMsg += " - You must agree to the terms and conditions by checking the box\n";
    }
    if (errorMsg) {
        alert("Sorry, some parts of this form are incomplete:\n"+errorMsg+"Please correct the error(s) and try again.");
        return false;
    } else {
        return true;
    } 
}
var winIndex = 1;
var openNoteEditor = function()
{
	var actions = [];
	for (i = 0; i < arguments.length; i++) {
		actions[i] = escape(arguments[i]);
	}
	var url = "/users/notes/" + actions.join('/');
	var winHeight = 700;
	var notesWin = window.open(url, "notesWindow"+winIndex, "width=500,height="+winHeight+",resizeable,menubar,scrollbars,left=0,top=0");
	if (notesWin.focus) { notesWin.focus(); }
	winIndex++;
}
var confirmDeleteNote = function(f)
{
	if (confirm("are you sure?")) {
		f.form_action.value = "delete";
    	return true;
	} else {
		return false;
	}
}
var hideNoteForm = function(form)
{
	var form_id = $(form).attr("id");
	$('#noteLink'+form_id).show();
	$('#noteForm'+form_id).slideUp('slow');
	return false;
}
/**
* object containing multiselect options
*/
var maxSelected = {
	"option-1-0": 1,       // Drinks policy options
	"option-1-0-1-0": 3,   // Bad drinks - all available options
	"option-1-0-2-0": 3,   // Good drinks - all available options
	"option-1-1": 3,       // Snacks policy options
	"option-1-1-0-0": 7,   // bad snacks - 1 less than maximum (chocolate / items containing chocolate exclusivity)
	"option-1-1-0-1": 4,   // Weekdays: max no. 4 (otherwise it would be every day so they shouldn't be using that option)
	"option-1-1-1-0": 7,   // bad snacks - 1 less than maximum (chocolate / items containing chocolate exclusivity)
	"option-1-1-2-0": 3,   // Bad ingredients - all available options
	"option-1-1-3-0": 7,   // bad snacks - 1 less than maximum (chocolate / items containing chocolate exclusivity)
	"option-1-1-4-0": 3,   // bad sandwich fillings  - all available options
	"option-1-2": 1,       // Allergens policy options
	"option-1-2-0-0": 3,   // Allergens - all available options
	"option-1-2-1-0": 3,   // Allergens - all available options
	"option-1-3": 1,       // Healthy policy options
	"option-1-4": 2,       // Foods bought within the school
	"option-2-3": 1,       // Content options - front cover
	"option-2-4": 1,       // Policy Options - policy compliance
	"option-3-3-0": 6,     // Breads
	"option-3-4-0": 4,     // Starchy foods
	"option-4-4-0": 3,     // Lean meats
	"option-4-5": 1,       // Which Fish
	"option-4-5-0-0": 3,   // Fish options
	"option-4-5-1-0": 3,   // Fish options
	"option-4-5-0": 3,     // Fish
	"option-4-6-0": 3,     // Cheeses
	"option-4-7-0": 3,     // Egg
	"option-4-9-0": 3,     // Meat alternatives
	"option-4-10-0": 3,    // Dishes
	"option-5-2-0": 4,     // Dairy foods/drinks
	"option-6-3-0": 4,     // Salads
	"option-6-4-0": 3,     // Vegetable dishes
	"option-6-5-0": 4,     // Fresh fruit
	"option-6-6-0": 3,     // Dried fruit
	"option-6-8-0": 3,     // Finger food
	"option-6-9-0": 2,     // Dips
	"option-7-2-0": 3,     // Other drinks
	"option-8-2-0": 4,     // Replace sweets
	"option-8-3-0": 4,     // Replace cakes
	"option-8-4-0": 4,     // Replace crisps
	"option-8-5-0": 3      // Replace Drinks
}
var selectOptions = {
 'showAllLink':false,
 'showNoneLink':false,
 'maxSelected': maxSelected,
 'showConsoleLog': false,
 'endSeparatorSpecial': {'option-1-1-0-1':"and"}
}    
document.write('<style type="text/css">div#form-content {display:none;} .insert-text {display:none;}</style>');
$(function(){
	$('#form-content').show();
    $('#org_name_suggest').suggest({dataurl:'http://'+window.location.host+'/access/1'});
    $('a.helpButton').click(function(){
    	$.fn.colorbox({href:$(this).attr('href').replace('help', 'help/iframe'),iframe:true,opacity:0.35,innerWidth:640,innerHeight:420,open:true});
    	return false;
    });
    $('#preview-stickers').click(function(){
    	$.fn.colorbox({href:'/stickers/preview/'+$('#sticker-format').val()+'/'+$('#sticker-design').val(),iframe:true,opacity:0.35,innerWidth:640,innerHeight:420,open:true});
    	return false;
    });
    $('#preview-labels').click(function(){
    	$.fn.colorbox({href:'/stickers/preview/'+$('#label-format').val()+'/'+$('#label-design').val(),iframe:true,opacity:0.35,innerWidth:640,innerHeight:420,open:true});
    	return false;
    });
    if ($('a.sticker-tooltip').length) {
    	$.getScript('/js/min/jquery.tooltip.min.js',function(){
            $('a.sticker-tooltip').tooltip({
    	        showURL:false,
    	        bodyHandler:function(){
    	            return $('<img/>').attr('src',$(this).attr('href'));
    	        }
            }).click(function(){return false;});
    	});
    }
    $('a.userStatsDetail').click(function(){
    	$.fn.colorbox({href:$(this).attr('href'),opacity:0.35,innerWidth:640,innerHeight:420,open:true});
    	return false;
    });
    $('#compareselected').click(function(){
    	var numSelected = $('.comparecheckbox:checked').length;
    	if (numSelected < 2) {
    		alert("Please select two or more audits from the list");
    		return false;
    	} else if (numSelected > 6) {
    		alert("The maximum number of audits which can be compared is six.\nPlease deselect "+(numSelected - 6)+" and try again.");
    		return false;
    	}
    });
    if (document.forms.downloadForm) {
        var f = document.forms.downloadForm;
        for (i = 0; i < f.elements.length; i++) {
            if (f.elements[i] && f.elements[i].name) {
                if (f.elements[i].name == "fill" || f.elements[i].name == "lang" || f.elements[i].name == "content") {
                    f.elements[i].checked = false;
                    if (f.elements[i].value == "col" || f.elements[i].value == "en" || f.elements[i].value == "full") {
                        f.elements[i].checked = true;
                    }                        
                }
            }
        }
    }
    $('#pageHeading.inserts').after('<p>Click on the titles to view the newsletter inserts, or <a href="#" onclick="$(\'.insert-text\').show();return false;">click here to expand them all</a>.</p>');
    $(".insert-title").css({color:"#393",fontWeight:"bold",cursor:"pointer"}).hover(
        function(){$(this).css({'background-color':'#efe','color':'#090'});},
        function(){$(this).css({'background-color':'#fff','color':'#393'});});
    $(".insert-title").click(function() {
        $(".insert-text:visible").slideToggle('normal');
        $(this).next('.insert-text:hidden').slideToggle('normal');
    });
    if ($('body').hasClass('notes')) {
    	$.getJSON('http://'+window.location.host+'/users/notes/tags', '', function(data, textStatus) {
        	$('.newtag').suggest({datasource:data,showonfocus:true});
        });
    	$('a.addtagLink').click(function(){
    		var tagName = $(this).siblings(':text').val();
    		if ($.trim(tagName) !== "") {
    			var existingTags = [];
        		$(this).parents('form').find(':hidden[name^=noteTags]').each(function(){
        			existingTags.push(this.value.toLowerCase());
    	    	});
    		    for (i = 0; i < existingTags.length; i++) {
    			    if (existingTags[i] == tagName.toLowerCase()) {
    				    alert("this note is already tagged with this tag!");
    				    return false;
    			    }
    		    }
       			var newtag = '<span class=\"tag\">'+tagName+' <a href=\"#\" onclick=\"removeTag(this);return false;\" title=\"remove this tag\"><img src=\"/images/bg/cross.gif\" width=\"12\" height=\"12\" title=\"remove this tag\" /></a><input type="hidden" name="noteTags[]" value="'+tagName+'" /></span>';
   	    		$(this).parents('form').find('p.taglist').append(newtag);
    		} else {
    			alert("Please type in a name for the tag");
    		}
			return false;
    	});
    	$('#addNote').click(function() {
    		$('#msg').hide();
    		// $('.noteform:visible').hide();
    		$('#noteFormnewNote').slideDown('slow');
    		return false;
    	});
    	// $('.noteform').hide();
    	$('a.showNoteForm').click(function(){
    		$(this).hide().next().slideDown('slow');
    		return false;
    	});
    	$('#tagsfilter').inlinemultiselect({'showAllLink':false,'showNoneLink':false,'separator':'; ','endSeparator':'; ','triggerPopup':{'empty':"[Add a filter...]",'nonempty':"[Change...]",'disabled':"[Filtering disabled]"},'changeCallback':function(tags){
    	    var classStr = '';
    		for (i = 0; i < tags.length; i++) {
    	    	if (tags[i].checked) {
    	    		classStr += '.tag'+tags[i].value+' ';
    	    	}
    	    }
    		if (classStr !== '') {
    			$($.trim(classStr)).show();
    			$('.note').not($.trim(classStr)).hide();
    		} else {
    			$('.note').show();
    		}
    	}});
    	$('form.ajaxificated').ajaxForm({
    		success: function(data, status, form){
    		    var form_id = $(form).attr("id");
    		    $('#noteForm'+form_id).slideUp('slow');
    		    if (data !== "noteDeleted") {
        		    $('#noteLink'+form_id).text(urlDecode(data)).show();
    		    } else {
    		    	$('noteContainer'+form_id).remove();
    		    }
    	    }
    	});
    }
    $('#showsd, #showpl').bind("click change", function(){
    	var showsd = $('#showsd')[0].checked;
    	var showpl = $('#showpl')[0].checked;
    	var set = "tl";
    	if (bardata && bardata.pl) {
     	    for (i = 0; i < bardata.pl.length; i++) {
     	    	if (showsd && showpl) {
     	    		$('#plbar'+i).css({width:bardata.tlpl[i]+'px'});
     	    		$('#sdbar'+i).css({width:bardata.tlsd[i]+'px'});
     	    		$('#pc'+i).text(bardata.tlpc[i]);
                } else {
     	    		$('#plbar'+i).css({width:bardata.pl[i]+'px'});
     	    		$('#sdbar'+i).css({width:bardata.sd[i]+'px'});
     	    		if (showpl) {
         	    		$('#pc'+i).text(bardata.plpc[i]);
     	    		} else if (showsd) {
     	    			$('#pc'+i).text(bardata.sdpc[i]);
     	    		} else {
     	    			$('#pc'+i).text('');
     	    		}
                }
     	    }
        	$('.sdbar').toggle(showsd);
        	$('.plbar').toggle(showpl);
    	}
    });
    $('input[name=subscription_status]').each(function(){
    	theID = $(this).attr("id");
    	if (this.checked) {
    		switch($(this).attr("id")){
    		case 'status0':
    			/* unsubscribed */
        		$('.trialfield .subfield').hide();
        		break;
    		case 'status1':
    			/* trial */
    			$('.subfield').hide();
    			$('.trialfield').show();
    			break;
    		}
    	}
    }).click(function(){
    	if (this.checked) {
    		switch($(this).attr("id")){
    		case 'status0':
    			/* unsubscribed */
        		$('.trialfield, .subfield').hide();
        		break;
    		case 'status1':
    			/* trial */
    			$('.subfield').hide();
    			$('.trialfield').show();
    			break;
    		case 'status2':
    			/* subscribed */
    			$('.subfield').show();
    			if ($('#subscription_start').val() == "" && $('#subscription_end').val() == "") {
        			$('#subscription_start').val(new Date().asString()).trigger('change');
    			    $('#subscription_end').val(new Date().addDays(365).asString()).trigger('change');
    			}
    		}
	    }
    });
    if ($('#subscription_start').length){
    	$.getScript('/js/min/jquery.datePicker.min-2.1.2.js',function(){
    		var opts = {startDate:'01/01/2006',clickInput:true,createButton:false};
    		$('#subscription_start').datePicker(opts);
    		$('#subscription_end').datePicker(opts);
    	});
    }
    $('#getNextInvoiceNumber').click(function(){
    	$.post('/users/', {'ob':'invoiceNumber'}, function(data, textstatus){
    		$('#nextInvoiceNumber').append('<br />The invoice number <strong>'+data+'</strong> has been reserved.');
    	});
    });
	if ($('.scaleRadios').length) {
		var slidercss = document.createElement("link");
		slidercss.setAttribute("rel", "stylesheet");
		slidercss.setAttribute("type", "text/css");
		slidercss.setAttribute("href", "/css/slider.css");
        document.getElementsByTagName("head")[0].appendChild(slidercss)
     	$.getScript('/js/min/jquery.slider.min.js',function(){
	        var imgCache = []
   	        for (i = 1; i < 6; i++) {
  	            imgCache[i] = new Image(40,40);
   	            imgCache[i].src = "/images/smilies/"+i+".png";
            }
		    $('.scaleRadios').each(function(idx){
			    var s_input = {'name':'','value':2};
			    $('input:radio', this).each(function(){
				    s_input['name'] = $(this).attr("name");
				    if ($(this).attr("checked")=="checked") {
					    s_input['value'] = $(this).attr("value");
				    }
			    });
			    $('.scale', this).remove();
			    $('<input type="hidden" name="'+s_input['name']+'" value="'+s_input['value']+'" id="s_input'+idx+'" />').appendTo(this);
    		    $('<div class="smiley" id="smiley'+idx+'"/>').appendTo(this);
    		    $('<div class="slider" id="slider'+idx+'"/>').slider({
	    		    value: 50,
		    	    slide: function(e, ui){
    		    	    var v = (Math.floor(ui.value/20))==5? 5: (Math.floor(ui.value/20) + 1);
    		    	    if ($('#s_input'+$(this).attr("id").replace("slider", "")).val() != v) {
        		    	    setSmiley(v, $(this).attr("id").replace("slider", ""));
    		            }
			        }
		        }).appendTo(this);
    	        setSmiley(3, idx);
		    });
    	});
    	function setSmiley(v, id)
	    {  
	        var smileyBg = "#fff url(/images/smilies/"+v+".png) no-repeat 0 0";
	        $("#s_input"+id).val(v);
	        $("#smiley"+id).css("background", smileyBg);
	    }
	}
});
var urlDecode = function(str)
{
    // http://kevin.vanzonneveld.net
    // + original by: Philip Peterson
    // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // + input by: AJ
    // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // + improved by: Brett Zamir
    // % note: info on what encoding functions to use from:
	// http://xkr.us/articles/javascript/encode-compare/
    // * example 1: urldecode('Kevin+van+Zonneveld%21');
    // * returns 1: 'Kevin van Zonneveld!'
    // * example 2: urldecode('http%3A%2F%2Fkevin.vanzonneveld.net%2F');
    // * returns 2: 'http://kevin.vanzonneveld.net/'
    // * example 3:
	// urldecode('http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a');
    // * returns 3:
	// 'http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'
    
    var histogram = {};
    var ret = str.toString();
    
    var replacer = function(search, replace, str) {
        var tmp_arr = [];
        tmp_arr = str.split(search);
        return tmp_arr.join(replace);
    };
    
    // The histogram is identical to the one in urlencode.
    histogram["'"]   = '%27';
    histogram['(']   = '%28';
    histogram[')']   = '%29';
    histogram['*']   = '%2A';
    histogram['~']   = '%7E';
    histogram['!']   = '%21';
    histogram['%20'] = '+';
 
    for (replace in histogram) {
        search = histogram[replace]; // Switch order when decoding
        ret = replacer(search, replace, ret) // Custom replace. No regexing
    }
    
    // End with decodeURIComponent, which most resembles PHP's encoding functions
    ret = decodeURIComponent(ret);
 
    return ret;
}
var removeTag = function(linkEl)
{
	$(linkEl).parents('span.tag').remove();
}
/* jQuery autosuggest extension */
jQuery.fn.suggest = function(settings) 
{
  return this.each(function()
  {
    /* HTML text input element */
    var textInput = $(this);
    textInput.attr("autocomplete", "off");
    /* create a new hidden input that will store the id */
    textInput.after('<input type="hidden" name="' + textInput.attr("name") + '_id" />');
    var valueInput = textInput.next();
    /* create the unordered list that will hold the suggestions */
    $("body").append('<ul class="suggestion_list"></ul>');
    var suggestionList = $("body ul:last");
    suggestionList.css({top:textInput.offset().top + textInput.outerHeight(), left:textInput.offset().left});
    var selected = 0;
    var size = null;

    settings = jQuery.extend(
    {
      datasource : null,
      dataurl: null,
      onupdate : null,
      showonfocus: false
    } , settings);

    function makeList(data)
    {
        var items = '';
        size = data.length;
        if (data) {
            for (i = 0; i < data.length; i++) {
                items += '<li value="' + data[i].id + '">' + data[i].name + '</li>';
            }
            suggestionList.html(items);
            suggestionList.children().
            hover(
                function() { $(this).addClass("selected").siblings().removeClass("selected"); },
                function() { $(this).removeClass("selected"); }).
            click(
                function() { 
                    valueInput.val($(this).attr('value'));
                    textInput.val($(this).text());
                    if (typeof settings.onupdate == "function") {
                        settings.onupdate(valueInput.val(), textInput.val());
                    }
                    clear();
            });
        } else {
            suggestionList.empty();
        }
    }
    
    function clear()
    {
        suggestionList.hide();
    }
    
    function checkMatch()
    {
        var matchFound = false;
        if (textInput.val() !== "") {
            suggestionList.children().removeClass("selected");
            suggestionList.children().each(function(){
                if ($(this).text().toLowerCase().indexOf(textInput.val().toLowerCase()) === 0) {
                    matchFound = true;
                    suggestionList.css({top:textInput.offset().top + textInput.outerHeight(), left:textInput.offset().left});
                    suggestionList.show();
                    $(this).addClass("selected");
                    suggestionList.scrollTop(suggestionList.scrollTop() + ($(this).offset().top - suggestionList.offset().top));
                    return false;
                }
            });
        }
        if (!matchFound) {
            clear();
        }
    }      
    
    /* load JSON data if a url is given */
    if (settings.dataurl) {
        $.getJSON(settings.dataurl, '', function(data, textStatus) {
        	makeList(data);
        });
    } else if (settings.datasource && settings.datasource.length) {
        makeList(settings.datasource);
    }

    textInput.keyup(function(e) 
    {
        if (e.which == 27) {
            /* escape */
            clear();
        } else if (e.which == 46 || e.which == 8 || e.which > 47) {
            checkMatch();
        }
    });
    
    if (settings.showonfocus) {
    	textInput.focus(function(e) {
    	    suggestionList.css({top:textInput.offset().top + textInput.outerHeight(), left:textInput.offset().left});
    		suggestionList.show();
    	});
    }
  });
};
