$j = jQuery.noConflict();

var Radio = {
	mOver: function(e)
	{
		e.data.addClass('hover');
	},

	mOut: function(e)
	{
		e.data.removeClass('hover');
	},

	mClick: function(e)
	{
		var $radio = e.data.children('input:radio'), radio = $radio.get(0);
		if (e.target !== radio) radio.checked = 'checked';
		if (Radio.onClick) Radio.onClick($radio);
	},

	onClick: null
};

var BooleanCheckbox = {
	mOver: function(e)
	{
		e.data.addClass('checkbox-hover');
	},

	mOut: function(e)
	{
		e.data.removeClass('checkbox-hover');
	},

	mClick: function(e)
	{
		var $box = e.data.find('input:checkbox'), box = $box.get(0);
		if (e.target !== box) box.checked = (box.checked ? '' : 'checked');
		if (BooleanCheckbox.onClick) BooleanCheckbox.onClick($box);
	},

	onClick: null
};


var Hidden = {
	show: function(el, rec)
	{
		var parent = $j(el).parents('.conditional');
		parent.add(parent.add($j('.hidden', parent))).removeClass('hidden');
		if ($j.browser.msie) {
			// Sometimes fields won't appear in IE until they're tabbed into.
			// This hack makes sure they all appear correctly.
			parent.find('input,textarea,select').each(function() { this.focus(); });
		}
		if (!el.value) el.focus();
	},

	hide: function(el)
	{
		$j(el).parents('.conditional').addClass('hidden');
	}
};

var unique_id = (function() {
		var stamp = "uid" + (new Date()).getTime(), id = 0;

		function next() {
			return stamp + '_' + (id++);
		}

		return function(el, id) {
			       if (el) {
				       el = el.jquery ? el.get(0) : el;
				       if (!el.uniqueId) {
					       el.uniqueId = (id || next());
				       }
			       }
			       return el ? el.uniqueId : (id || next());
	       }
})();

function map(a, proc)
{
	var result = [];
	for (var i = 0, len = a.length; i < len; i++) {
		result.push(proc(a[i]));
	}
	return result;
}

function trim(str, char)
{
	var re = char ? new RegExp('^' + char + '+|' + char + '$', 'g') : /^,+|,+$/g;
	return str.replace(re, '');
}

function popup(url) {
	var pop = window.open(url, 'window', 'height=400,width=600,resizable=1,scrollbars=1');
	if (!pop.opener) pop.opener = self;
}

var Drugs = {
	template: null,
	appendTo: null,

	addClone: function()
	{
		var uid = unique_id(), clone = $j(this.template.html().replace(/template/g, uid));
		unique_id(clone, uid);

		// fix for tab-index problem
		var index = clone.find('input[tabindex]:first').attr('tabindex');
		clone.find('input').attr('tabIndex', index);

		this.appendTo.append(clone.css('visibility', 'hidden'));
		this.init.apply(clone).css('visibility', 'visible');
		return clone;
	},

	addCloneIfNoneEmpty: function()
	{
		var names = $j('#all-drugs input.drug-name'), not_empty = names.filter('[value]');
		if (not_empty.length && (not_empty.length == names.length)) {
			Drugs.addClone();
			// always keep an even number of inputs
			if (names.length % 2 == 0) {
				Drugs.addClone();
			}
		}
	},

	build: function(template, append)
	{
		this.template = template;
		this.appendTo = append;
		$j('#all-drugs .drug-input').each(this.init);
		Drugs.addCloneIfNoneEmpty();
	},

	init: function()
	{
		var $this = $j(this), $prev = $this.prev();
		$this.addClass(($prev && $prev.is('.even')) ? 'odd' : 'even');
		LookupDrug.build($j('.drug-name', this));
		return this;
	}
};

var LookupDrug = {
	mNoResults: "This isn't a recognized drug.  Perhaps it's spelled differently?",
	mNotSelected: "You must choose a drug from the drop-down list.",

	build: function($q) {
		this.autoComplete($q.filter('.autocomplete-input').find('input'));
		this.notAutocomplete($q.filter('not(.autocomplete-input)').find('input'));
	},

	autoComplete: function($q)
	{
		$q.each(function() {
			this.$ndc = LookupDrug.getNDC(LookupDrug.findGroup($j(this)));
		});
		$q.autocomplete('ndc/name-to-ndc', {
			minChars: 2,
			cacheLength: 10,
			matchSubset: 1,
			selectOnly: 1,
			selectFirst: 1,
			popupOnFocus: true,
			onItemSelect: LookupDrug.onItemSelect,
			onChange: LookupDrug.onChange
		});
	},

	notAutocomplete: function($q)
	{
		$q.change(function() {
			LookupDrug.advance($j(this));
		});
	},

	findGroup: function($input) {
		return $input.parents('.drug-input');
	},

	onItemSelect: function(li, $input) {
		LookupDrug.setNDC(LookupDrug.advance($input), li.extra[0]);
	},

	advance: function($input)
	{
		var $group = LookupDrug.findGroup($input);
		Drugs.addCloneIfNoneEmpty();
		LookupDrug.focusDosage($group);
		return $group;
	},

	onBlur: function(e, $input) {
		var $group = LookupDrug.findGroup($input), val = $input.val(), $ndc = LookupDrug.getNDC($group);
		if (val && !$ndc.val()) {
			var inp = $input.get(0), message = ($input.attr('noResults') ? LookupDrug.mNoResults : LookupDrug.mNotSelected);

			if (confirm(message + "  Click 'OK' to try again.")) {
				setTimeout(function() {
					inp.forceFocus(true);
				}, 10);
			}
			else {
				$input.val('');
			}
		}
	},

	onNoResults: function($input) {
		alert(LookupDrug.mNoResults);
	},

	onChange: function($input, prev) {
		if ($input.val() != prev) {
			$input.get(0).$ndc.val(0);
		}
	},

	focusName: function ($group) {
		$j('.drug-name input', $group).get(0).focus();
	},

	focusDosage: function ($group) {
		$j('.dosage input', $group).get(0).focus();
	},

	getNDC: function($group)
	{
		return $j('.ndc', $group);
	},

	setNDC: function($group, s)
	{
		LookupDrug.getNDC($group).val(s);
	}
};

$j('span.radio').livequery(function() {
	var $this = $j(this);
	$this.bind('mouseover', $this, Radio.mOver)
		.bind('mouseout', $this, Radio.mOut)
		.bind('click', $this, Radio.mClick);
});

$j('div.boolean-checkbox').livequery(function() {
	var $this = $j(this);
	$this.bind('mouseover', $this, BooleanCheckbox.mOver)
		.bind('mouseout', $this, BooleanCheckbox.mOut)
		.bind('click', $this, BooleanCheckbox.mClick);
});