/**
 * JQuery plugin to populate HTML and image content from the Datalex adserver.
 * It can optionally hook into fields on the page to automatically change field values, or can be called programmatically to change the values
 */
jQuery.widget("ui.adserver", 
{
	/**
	 * Coding characters used for parsing a Base64 encoded value
	 */
    BASE64CHARS: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

	/**
	 * The default values to use
	 * Required additional parameters:
	 * server --> this should be the URL of the adserver itself
	 * advert --> the advert name to read
	 */
	options:
	{
		mode: "html",
		initialUpdate: true,
		args:
		{
		},
		hooks:
		{
		}
	},

	/**
	 * Initial create method - called by the framework to set up this values
	 */
	_create: function()
	{
		for (var i in this.options.hooks)
		{
			this.addHook(this.options.hooks[i], i);
		}
		if (this.options.initialUpdate)
		{
			this.update();
		}
	},
	/**
	 * Internal method to figure out the suffix to use when contacting the server
	 * This will either be derived based on the content type, or can be overridden using the
	 * 'suffix' option.
	 */
	_getSuffix: function()
	{
		if (this.options.suffix)
		{
			return this.options.suffix;
		}
		else
		{
			switch (this.options.mode)
			{
				case "image":
					return "js";
				default:
					return this.options.mode;
			}
		}
	},

	/**
	 * Update the contents of the widget.  This should be called after any manipulation
	 */
	update: function()
	{
		var widget = this;
		var url = this.options.server + "/" + this.options.advert + "." + this._getSuffix() + "?";
		var first = true;
		for (var i in this.options.args)
		{
			if (this.options.args[i] && this.options.args[i].length > 0)
			{
				if (first)
				{
					first = false;
				}
				else
				{
					url += '&';
				}
				url += (i + "=" + this.options.args[i]);
			}
		}
		if (!first)
		{
			url += '&';
		}
		url += 'callback=?';
		jQuery.getJSON(url, function(data)
		{
			switch (widget.options.mode)
			{
				case "image":
					widget.element.empty();
					for (var i in data.entry)
					{
						if (data.entry[i].image)
						{
							jQuery("<a href='" + data.entry[i].link + "'><img src='" + data.entry[i].image + "'></a>").appendTo(widget.element);
						}
					}
					break;
				default:
					widget.element.empty().append(widget.decodeBase64(data.data));
					break;
			}
			widget.element.trigger("advertUpdated", this.element);
		});
	},
	/**
	 * Set a particular parameter
	 */
	setArg: function(name, value)
	{
		this.options.args[name] = value;
	},

	/**
	 * Add a new hook to the advert
	 */
	addHook: function(field, argumentName)
	{
		var widget = this;
		this.options.args[argumentName] = jQuery(field).val();
		jQuery(field).change(function()
		{
			widget.setArg(argumentName, jQuery(this).val());
			widget.update();
		});
	},
	/**
	 * Utility method to convert Base64 encoded data into a document.
	 */
	decodeBase64: function(input)
	{
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        for (var i = 0 ; i < input.length ; )
        {
            enc1 = this.BASE64CHARS.indexOf(input.charAt(i++));
            enc2 = this.BASE64CHARS.indexOf(input.charAt(i++));
            enc3 = this.BASE64CHARS.indexOf(input.charAt(i++));
            enc4 = this.BASE64CHARS.indexOf(input.charAt(i++));
            chr1 = (enc1 << 2) | (enc2 >> 4);
            output = output + String.fromCharCode(chr1);
            if (enc3 != 64)
            {
                chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64)
            {
                chr3 = ((enc3 & 3) << 6) | enc4;
                output = output + String.fromCharCode(chr3);
            }
        }
        return output;
	}
});
