// Plugin checkbox modifier.
// Author : Nordès Ménard-Lamarre
// Last modif: August 12 2008
// Version: 0.2
//
// Copyright (c) 2008 Nordès Ménard-Lamarre
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

(function($) {
	$.fn.CheckboxMod = function(options) {
		// build main options before element iteration
		var opts = $.extend({}, $.fn.CheckboxMod.defaults, options);

		// We preload the images.
		jQuery("<img>").attr("src", opts.ImageUrlUnchecked);
		jQuery("<img>").attr("src", opts.ImageUrlChecked);

		return this.each(function() {
			var $this = $(this);
			// build element specific options
			var o = opts;
			var cb = this;
			var heartBeatOptions;
			try {
				heartBeatOptions = $.extend({}, $.fn.heartBeat.defaults, {
					opacityMax: $(this).css("opacity"),	// This is required to get back to initial opacity.
					alwaysBeat: false, 
					delayBetweenAnimation:300
					});
			} catch(err) {}

			// We don't want to create multiple CheckboxMod for one checkbox.
			if ($this.attr("cbModified") == "1"){
				return $this;
			}

			$this.attr("cbModified", "1");
			var img = $("<img>")
				.attr({
						src: (this.checked ? o.ImageUrlChecked : o.ImageUrlUnchecked),
						alt: o.Alt
					})
				.css({
						height: o.Height,
						width: o.Width,
						border: o.Border
					})
				.bind("click", function(){ 
						cb.checked = !cb.checked;
						if (!o.KeepSynchronized){
						$(this)
							.attr({ src: cb.checked ? opts.ImageUrlChecked : opts.ImageUrlUnchecked });
						}
					 })
				.bind("mouseover", function(){
					// Start the heart beat.
					if (o.EnableHeatBeatAnimation && ($(this).attr("intervalId") == null || $(this).attr("intervalId") == "" || $(this).attr("intervalId") == 0)){
						var myThis = $(this);
						var myBeatOptions = heartBeatOptions;
						// start faster the animation

						// run the heartbeat
						try{
							$.fn.heartBeat.start($(this), heartBeatOptions);
							var intervalFct = function(){ $.fn.heartBeat.start(myThis, myBeatOptions); }; // Workaround for the setInterval bug
							var intervalId = setInterval(intervalFct, heartBeatOptions.delayBetweenAnimation + (heartBeatOptions.delay * 2));
							$(this).attr("intervalId", intervalId); 
						}catch(err)
						{
							$(this).attr("intervalId", 0); 
						}
					}
					})
				.bind("mouseout", function(){
					// Stop the heart beat.
					if (o.EnableHeatBeatAnimation){
						var intervalId = $(this).attr("intervalId");
						clearInterval(intervalId);
						$(this).attr("intervalId", 0);
					}
					})
				.insertBefore(this);

			// Keep synchronised, it's usefull when we have javascript modifying the checked value.
			if (o.KeepSynchronized){
				setInterval(function() {
					var correctValue = cb.checked ? o.ImageUrlChecked : o.ImageUrlUnchecked;
					if (img.attr("src") != correctValue ){
						img.attr({ src: correctValue });
					}
					}, 50);
			}
			else {
				// Keep a click event, in case somebody want to simulate a click.
				$this.bind("click", function(){
					var correctValue = cb.checked ? o.ImageUrlChecked : o.ImageUrlUnchecked;
					if (img.attr("src") != correctValue ){
						img.attr({ src: correctValue });
					}
				});
			}

			if (!o.showRealCheckBox)
				$this.hide(0);
			});
		};
		
		//
		// plugin defaults
		//
		$.fn.CheckboxMod.defaults = {
			ImageUrlChecked: 'images/checked.jpg',
			ImageUrlUnchecked: 'images/unchecked.jpg',
			Alt: '', // Should become a tooltips. Not implemented yet
			Height: "16px",
			Width: "",
			KeepSynchronized: true,
			//backgroundColor: '',
			//foregroundColor: '',
			Border: '0px',
			EnableHeatBeatAnimation: false,
			showRealCheckBox: false 
		};	
})(jQuery);
