﻿///////////////////////////////////////////////////////
//   Requires /_js/framework/jquery.cookies.min.js   //
///////////////////////////////////////////////////////

(function($)
{
	$.fn.autoid = function(notInDOM)
	{
		var uidi = 0;
		var charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
		var len = 8;
		var uid = '', charsetlen = charset.length, charIndex;
		var uniqueids = {};

		for(uidi = 0; len > uidi; uidi++)
		{
			charIndex = Math.random() * charsetlen;
			uid += charset.charAt(charIndex);
		}

		if(uniqueids[uid] || (notInDOM && $("#" + uid).size()))
		{
			uniqueids[uid] = true;
			return $(this).autoid(notInDOM);
		}

		uniqueids[uid] = true;

		$(this).attr("id", "ddlbnd" + uid);
	};

	$.fn.ddlbind = function(parent, settings)
	{
		var confg =
		{
			event: "change",
			noUpdate: "empty",
			dataSrc: [],
			getSrcDelay: 10,
			getSrc: function(select) { $(this).trigger("updateSrc", [confg.dataSrc]); },
			match: function(selVal) { return this.When == selVal; },
			stateMngmnt: "cookie",
			template: function(obj)
			{
				var textNode = function(s)
				{
					var t = s;
					return document.createTextNode(t);
				}
				var opt = document.createElement("option");
				opt.value = obj.Value;
				if(obj.When == obj.Value)
					opt.setAttribute("selected", "selected", 0);
				opt.appendChild(textNode(obj.Text));
				return opt;
			},
			pValue: function(parent) { return $(parent).val(); }
		};

		if(settings)
		{
			$.extend(confg, settings);

			if(confg.ajax)
			{
				var acnfg = function(opt)
				{
					var ajax = opt.ajax;
					var res = $.extend(opt,
					{
						getSrc: function(parent)
						{
							var _ajax = {};
							var $this = $(this);
							var defaultAjaxOptions =
							{
								type: "GET",
								dataType: "json",
								success: function(json) { $this.trigger("updateSrc", [json]); },
								error: function(XMLHttpRequest, textStatus)
								{
									if(XMLHttpRequest && XMLHttpRequest.getstatusText)
										alert('failed: ' + XMLHttpRequest.getstatusText);
									else
										alert('failed: error unknown');
								},
								data: eval("$.extend(_ajax.data,ajax.data,{" + opt.ajaxKey + ": \"" + opt.pValue(parent) + "\"})")
							};

							$.extend(_ajax, ajax, defaultAjaxOptions);

							$.ajax(_ajax);
						}
					});
					delete res[ajax];
					return res;
				};
				$.extend(confg, acnfg(confg));
			}
		}

		if(confg.event)
			confg.event = confg.event.replace(".ddlbind", "") + ".ddlbind";

		return this.each(function()
		{
			var ddlp = $(parent);
			var ddl = $(this);
			var COOKIED_KEY = "cookie-filled";

			if(ddl.attr("id") == "")
				ddl.autoid();

			ddl.bind("loading.ddlbind", function(e, source)
			{
				$(this).empty();
				var position =
				{
					'z-index': '6000',
					'position': 'absolute',
					'width': '16px'
				};
				$.extend(position, $(this).offset());
				position.left = position.left + 6;
				$(this).css("display", "none");
				$("<div class='ddlbind-loading'>LOADING</div>").appendTo("body").css(position);
				$(this)[0].disabled = true;
			});

			ddl.bind("loaded.ddlbind", function(e, source)
			{
				$(this)[0].disabled = false;
				$(this).css("display", "inline");
				$(".ddlbind-loading").remove();
			});

			$(ddlp).bind(confg.event, function()
			{
				if(ddlp[0].value != confg.noUpdate)
				{
					ddl.trigger("loading.ddlbind", [ddlp[0]]);

					var selectTimeout = $.data(ddl, "selectTimeout");
					if(selectTimeout) { window.clearInterval(selectTimeout); }
					$.data(ddl, "selectTimeout", window.setTimeout(function() { ddl.trigger("ddlupdate"); }, confg.timeout));
				}
			});

			ddl.bind("ddlupdate", function()
			{
				ddl.one("updateSrc", function(e, dataSrc)
				{
					dataSrc = $(dataSrc).filter(function() { return confg.match.call(this, confg.pValue(ddlp)); })
					  .map(function()
					  {
					  	var node = $(confg.template(this))[0];
					  	return node;
					  });

					ddl.empty();

					if(dataSrc.length)
					{
						ddl.html(dataSrc);
						ddlp.cookify();
						ddl.cookify();
					}

					ddl.trigger("loaded.ddlbind", [ddlp[0]]);

					if(ddl.is(":input"))
					{
						ddl.trigger("change.ddlbind");
					}
				});

				confg.getSrc.call(ddl[0], ddlp);
			});

			if($.data(ddlp, COOKIED_KEY) != "true")
			{
				if($.cookies.get(ddlp.attr("id")) != null)
				{
					ddlp.cookieFill();
					$.data(ddlp, COOKIED_KEY, "true");
					if(ddlp[0].length > 0)
						ddlp.trigger("change.ddlbind");
				}
			}
			if($.data(ddl, COOKIED_KEY) != "true")
			{
				if($.cookies.get(ddl.attr("id")) != null)
				{
					ddl.cookieFill();
					$.data(ddl, COOKIED_KEY, "true");
					if(ddl[0].length > 0)
						ddl.trigger("change.ddlbind");
				}
			}
		});
	};
})(jQuery);

