(function() {
	/*
		Generic
	*/
	var checkeds = Array();

	var default_settings = {
		checked:"not-set",
		unchecked:"not-set",
		checked_hover:false,
		unchecked_hover:false,
		checked_down:false,
		unchecked_down:false,
		show_input:false
	 };

	var replace = function(input, settings) {
		img = jQuery('<img src="'+image(input.attr("checked"), settings, true)+'" />');

		if(!settings.show_input)
			input.hide(1);

		input.before(img);
		return img;
	};

	var image = function (bool, settings, init) {
		return bool ? 	(settings.checked_hover && !init ? settings.checked_hover : settings.checked) :
						(settings.unchecked_hover && !init ? settings.unchecked_hover : settings.unchecked);
	};

	var attach_hovers = function(img, settings) {
		img.mouseover(function(){
			if(img.attr("src") == settings.checked && settings.checked_hover) {
				img.attr("src", settings.checked_hover);
			} else if(settings.unchecked_hover) {
				img.attr("src", settings.unchecked_hover);
			}
		});

		img.mouseout(function(){
			if(img.attr("src") == settings.checked_hover) {
				img.attr("src", settings.checked);
			} else if(img.attr("src") == settings.unchecked_hover) {
				img.attr("src", settings.unchecked);
			}
		});

		img.mousedown(function(){
			src = img.attr("src")
			if((src == settings.checked || src == settings.checked_hover) && settings.checked_down) {
				img.attr("src", settings.checked_down);

			} else if((src == settings.unhecked || src == settings.unchecked_hover) && settings.unchecked_down) {
				img.attr("src", settings.unchecked_down);
			}
		})
	};

	/*
		Checkboxes
	*/
	var checkize = function(img, input, settings) {
		invert = false;

		input.click(function(){
			checked = input.attr("checked")
			if(invert)
				checked = !checked
			img.attr("src", image(checked, settings, !invert));
		});

		checkeds[1] = input.attr("checked");

		img.click(function(){
			invert = true;
			input.click();
			invert = false;
		});

		attach_hovers(img, settings);
	};

	/*
		Radiobuttons
	*/
	var radize = function(img, input, img_siblings, settings) {
		invert = false;

		input.click(function(){
			for (n in img_siblings) {
				n = img_siblings[n]
				if(n !== img) {
					n.attr("src", image(false, settings, true));
				} else {
					n.attr("src", image(true, settings, !invert));
				}
			}
		});

		img.click(function() {
			invert = true;
			input.click();
			invert = false;
		});

		attach_hovers(img, settings);
	};
 
	jQuery.fn.checkize = function(settings) {
		var settings = jQuery.extend(default_settings, settings);
		var map = new Array();
		var imgs = new Array();

		// Preload images
		for (i in settings) {
			img = settings[i];
			if(img) {
				jQuery("<img />").attr("src", img);
			}
		}

		this.each(function(i, input){
			input = $(input);

			// Checkbox
			if(input.attr("type") == "checkbox") {
				checkize(replace(input, settings), input, settings);

			// Radiobutton
			} else if (input.attr("type") == "radio") {
				name = input.attr("name");
				if(!map[name]) {
					map[name] = new Array();
					imgs[name] = new Array();
				}
				map[name].push(input);
				imgs[name].push(replace(input, settings));
			}

		});

		// Handle radiobutton collections
		for(i in map) {
			for(j in map[i]) {
				radize(imgs[i][j], map[i][j], imgs[i], settings);
			}
		}

	};

})();
