
// jquery.stopwatch.js
// v.2012-09-07
// modified by unixman:
//	* disabled optional use of jintervals.js

(function( $ ){

	function incrementer(ct, increment) {
		return function() { ct+=increment; return ct; };
	}

	function pad2(number) {
		 return (number < 10 ? '0' : '') + number;
	}

	function defaultFormatMilliseconds(millis) {
		var x, seconds, minutes, hours;
		x = millis / 1000;
		seconds = Math.floor(x % 60);
		x /= 60;
		minutes = Math.floor(x % 60);
		x /= 60;
		hours = Math.floor(x % 24);
		// x /= 24;
		// days = Math.floor(x);
		return [pad2(hours), pad2(minutes), pad2(seconds)].join(':');
	}

	//NOTE: This is a the 'lazy func def' pattern described at http://michaux.ca/articles/lazy-function-definition-pattern
	function formatMilliseconds(millis, data) {
		// Use jintervals if available, else default formatter
		var formatter;
	//	if (typeof jintervals == 'function') {
	//		formatter = function(millis, data){return jintervals(millis/1000, data.format);};
	//	} else {
			formatter = defaultFormatMilliseconds;
	//	}
		formatMilliseconds = function(millis, data) {
			return formatter(millis, data);
		};
		return formatMilliseconds(millis, data);
	}

	var methods = {

		init: function(options) {
			var defaults = {
				updateInterval: 1000,
				startTime: 0,
				format: '{HH}:{MM}:{SS}',
				formatter: formatMilliseconds
			};

			// if (options) { $.extend(settings, options); }

			return this.each(function() {
				var $this = $(this),
					data = $this.data('stopwatch');

				// If the plugin hasn't been initialized yet
				if (!data) {
					// Setup the stopwatch data
					var settings = $.extend({}, defaults, options);
					data = settings;
					data.active = false;
					data.target = $this;
					data.elapsed = settings.startTime;
					// create counter
					data.incrementer = incrementer(data.startTime, data.updateInterval);
					data.tick_function = function() {
						var millis = data.incrementer();
						data.elapsed = millis;
						data.target.trigger('tick.stopwatch', [millis]);
						data.target.stopwatch('render');
					};
					$this.data('stopwatch', data);
				}

			});
		},

		start: function() {
			return this.each(function() {
				var $this = $(this),
					data = $this.data('stopwatch');
				// Mark as active
				data.active = true;
				data.timerID = setInterval(data.tick_function, data.updateInterval);
				$this.data('stopwatch', data);
			});
		},

		stop: function() {
			return this.each(function() {
				var $this = $(this),
					data = $this.data('stopwatch');
				clearInterval(data.timerID);
				data.active = false;
				$this.data('stopwatch', data);
			});
		},

		destroy: function() {
			return this.each(function(){
				var $this = $(this),
					data = $this.data('stopwatch');
				$this.stopwatch('stop').unbind('.stopwatch').removeData('stopwatch');
			});
		},

		render: function() {
			var $this = $(this),
				data = $this.data('stopwatch');
			$this.html(data.formatter(data.elapsed, data));
		},

		getTime: function() {
			var $this = $(this),
				data = $this.data('stopwatch');
			return data.elapsed;
		},

		toggle: function() {
			return this.each(function() {
				var $this = $(this);
				var data = $this.data('stopwatch');
				if (data.active) {
					$this.stopwatch('stop');
				} else {
					$this.stopwatch('start');
				}
			});
		},

		reset: function() {
			return this.each(function() {
				var $this = $(this);
					data = $this.data('stopwatch');
				data.incrementer = incrementer(data.startTime, data.updateInterval);
				data.elapsed = data.startTime;
				$this.data('stopwatch', data);
			});
		}
	};


	// Define the function
	$.fn.stopwatch = function( method ) {
		if (methods[method]) {
			return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
		} else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		} else {
			$.error( 'Method ' +  method + ' does not exist on jQuery.stopwatch' );
		}
	};

})( jQuery );

// #END
