/*global jQuery*/
String.prototype.rightOverwrite = function(value) {
	if(value.length >= this.length) { return value; }
	return this.slice(0, this.length - value.length) + value;
};

(function($) {
	$.fn.adBlockEditor = function(options) {
		var params = $.extend($.fn.adBlockEditor.defaults, options);
		
		// iterate over the result set and apply
		// the functionality
		return this.each(function() {
		
			// fetch swatches
			var sw = $(this).find(".controls>.swatch");
			
			// construct an associative array of swatches for
			// referencing later in the event handler
			var swatches = {};
			for(var i = 0; i < sw.length; i++) {
				swatches[sw.eq(i).attr("class").replace(/^swatch /, "")] = $(sw.get(i));
			}
			
			// fetch the necessary elements
			var container = $(this).find("div.container");
			var title = container.find("div.title");
			var description = container.find("div.description");
			var link = container.find("div.link");
			var tagline = container.find("div.tagline");
			
			// create hidden inputs
			var title_input = $('<input type="hidden" class="hidden" name="title_color" id="title_color" value="' + params.titleColor + '"/>').appendTo(this);
			var description_input = $('<input type="hidden" class="hidden" name="description_color" id="description_color" value="' + params.descriptionColor + '"/>').appendTo(this);
			var link_input = $('<input type="hidden" class="hidden" name="link_color" id="link_color" value="' + params.linkColor + '"/>').appendTo(this);
			var background_input = $('<input type="hidden" class="hidden" name="background_color" id="background_color" value="' + params.backgroundColor + '"/>').appendTo(this);
			var border_input = $('<input type="hidden" class="hidden" name="border_color" id="border_color" value="' + params.borderColor + '"/>').appendTo(this);
			
			// helper function to convert "rgb(R,G,B)" formatted strings
			// to a unified hex format
			var convertColor = function(s) {
				var res = s.match(/^rgb\(([0-9]{1,3}), *([0-9]{1,3}), *([0-9]{1,3})\)$/);
				if(!res) { return s; }
				return "#" +
				       "00".rightOverwrite(Number(res[1]).toString(16)) +
				       "00".rightOverwrite(Number(res[2]).toString(16)) +
				       "00".rightOverwrite(Number(res[3]).toString(16));
			};
			
			// computes the grayscale value of an RGB value
			var toGrayscale = function(color) {
				color = convertColor(color);
				var res = color.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/);
				if(!res) { return 0; }
				return Math.floor(parseInt(res[1], 16) * 0.3 + parseInt(res[2], 16) * 0.59 + parseInt(res[3], 16) * 0.11);
			};

			// updates the colours in the swatches and ad block elements
			var updateColors = function() {
				// set ad block colours
				title.css("color", params.titleColor);
				description.css("color", params.descriptionColor);
				link.css("color", params.linkColor);
				container.css({
					backgroundColor: params.backgroundColor,
					borderColor: params.borderColor
				});
				tagline.css("backgroundColor", params.borderColor);
				if(toGrayscale(params.borderColor) < 127) { tagline.css("color", "#fff"); }
				else { tagline.css("color", "#000"); }
				
				// change the swatch colours
				swatches.title.css("backgroundColor", params.titleColor);
				swatches.description.css("backgroundColor", params.descriptionColor);
				swatches.link.css("backgroundColor", params.linkColor);
				swatches.background.css("backgroundColor", params.backgroundColor);
				swatches.border.css("backgroundColor", params.borderColor);
				
				// assign colours to the hidden inputs
				title_input.val(params.titleColor);
				description_input.val(params.descriptionColor);
				link_input.val(params.linkColor);
				background_input.val(params.backgroundColor);
				border_input.val(params.borderColor);
			};
			
			// clear the picker control
			var clearPickers = function() {
				$("div.httpool-color-picker").remove();
			};
			
			// invoke the picker control
			var drawPicker = function(swatch) {
				var s = $(swatch);
				var c = s.attr("class").replace(/^swatch /, "");
				
				// create the picker and show it at the appropriate location
				var picker = $('<div class="httpool-color-picker"></div>').appendTo("body").hide().css({
					position: "absolute",
					top: s.offset().top - 10 + "px",
					left: s.offset().left + 21 + "px"
				}).show();
				
				// apply farbtastic to the container
				var popup = $.farbtastic(picker, function(color) {
					params[c + "Color"] = color;
					updateColors();
				});
				
				// set the initial colour for the picker
				popup.setColor(convertColor(s.css("backgroundColor")));
				$("body").one("click", clearPickers);
			};
			
			var getColors = function() {
				return {
					title: params.titleColor,
					description: params.descriptionColor,
					link: params.linkColor,
					background: params.backgroundColor,
					border: params.borderColor
				};
			};
			
			
			// assign the click handler on the swatch collection
			sw.css("cursor", "pointer").click(function() {
				clearPickers();
				drawPicker(this);
				return false;
			});
			
			// update the colours assigned from the parameter passed
			updateColors();
		});
	};
	
	// default values, extended via the parameter
	$.fn.adBlockEditor.defaults = {
		titleColor: "#00b",
		descriptionColor: "#333",
		linkColor: "#0b0",
		backgroundColor: "#fff",
		borderColor: "#666"
	};
})(jQuery);