/*jquery.cascade.js */
/*
* jQuery UI cascade
* version: 1.1.1 (6/16/2008)
* @requires: jQuery v1.2 or later
* adapted from Yehuda Katz, Rein Henrichs autocomplete plugin
* Dual licensed under the MIT and GPL licenses:
*   http://www.opensource.org/licenses/mit-license.php
*   http://www.gnu.org/licenses/gpl.html
*
* Copyright 2008 Mike Nichols
   	
*/

; (function($) {

	$.ui = $.ui || {}; $.ui.cascade = $.ui.cascade || {};

	$.fn.cascade = function(parent, opt) {
		if (opt.event) {
			//namespace our event 
			opt.event = opt.event.replace('.cascade', '') + '.cascade';
		}

		opt = $.extend({}, {
			list: [], //static list to use as datasource 
			timeout: 10, //delay before firing getList operation
			getList: function(select) { $(this).trigger("updateList", [opt.list]); }, //function to fetch datasource
			template: function(str) { return "<option value='" + str + "'>" + str + "</option>"; }, //applied to each item in datasource      
			match: function(selectedValue, status) { return true; }, //'this' is the js object, or the current list item from 'getList',
			event: "change.cascade", //event to listen on parent which fires the cascade
			getParentValue: function(parent) { return $(parent).val(); } //delegate for retrieving the parent element's value
		}, opt);

		if ($.ui.cascade.ext) {
			for (var ext in $.ui.cascade.ext) {
				if (opt[ext]) {
					opt = $.extend(opt, $.ui.cascade.ext[ext](opt));
					delete opt[ext];
				}
			}
		}

		return this.each(function() {
			var source = $(parent);
			var self = $(this);

			//bind any events in extensions to each instance
			if ($.ui.cascade.event) {
				for (var e in $.ui.cascade.event) {
					self.bind(e + ".cascade", [source], $.ui.cascade.event[e]);
				}
			}

			$(source).bind(opt.event, function() {
				self.trigger("loading.cascade", [source[0]]);

				var selectTimeout = $.data(self, "selectTimeout");
				if (selectTimeout) { window.clearInterval(selectTimeout); }
				$.data(self, "selectTimeout", window.setTimeout(function() {
					self.trigger("cascade");
				}, opt.timeout));

			});

			self.bind("cascade", function() {
				var status = self.parent().parent().find("input[type='checkbox']").attr("checked");
				self.one("updateList", function(e, list) {
					list = $(list)
              .filter(function() {
              	return opt.match.call(this, opt.getParentValue(parent), status);
              })
              .map(function() {
              	var node = $(opt.template(this))[0];
              	return node;
              });
					self.empty(); //clear the source/select

					if (list.length) {
						self.html(list);
					}
					var string = self.attr("id").toString();
					var id = string.substring(string.length - 1, string.length);
					if (!status) {

						if (id - 1 != 0)
							$("#selectedLocation").val($("#chained" + (id - 1)).val());
						return;
					}

					self.trigger("loaded.cascade", [source[0]]); //be sure to fire even if there is no data
					if (list && list.length == 0) {
						$("#c" + id).attr("checked", false);
						$("#chained" + id).attr("disabled", true);
					}
					if (self.is(":input")) { //opinionated , but  enables cascading from this element as  well
						self.trigger("change.cascade");
					}
				});

				opt.getList.call(self[0], source); //call with child element as this

			});
		});
	};

})(jQuery);

(function($) {
	$.makeTemplate = function(template, begin, end) {
		var rebegin = begin.replace(/([\]{}[\\])/g, '\\$1');
		var reend = end.replace(/([\]{}[\\])/g, '\\$1');

		var code = "try { with (_context) {" +
      "var _result = '';" +
        template
          .replace(/[\t\r\n]/g, ' ')
          .replace(/^(.*)$/, end + '$1' + begin)
          .replace(new RegExp(reend + "(.*?)" + rebegin, "g"), function(text) {
          	return text
              .replace(new RegExp("^" + reend + "(.*)" + rebegin + "$"), "$1")
              .replace(/\\/g, "\\\\")
              .replace(/'/g, "\\'")
              .replace(/^(.*)$/, end + "_result += '$1';" + begin);
          })
          .replace(new RegExp(rebegin + "=(.*?)" + reend, "g"), "_result += ($1);")
          .replace(new RegExp(rebegin + "(.*?)" + reend, "g"), ' $1 ')
          .replace(new RegExp("^" + reend + "(.*)" + rebegin + "$"), '$1') +
      "return _result;" +
    "} } catch(e) { return '' } ";

		return new Function("_context", code);
	};
})(jQuery);