(function($) {
	
	var methods = {
		init: function(position, duration, callback) {
			// default values
			if (typeof duration == 'undefined') {
				duration = 0;
			}
			
			
			var body = document.body || document.documentElement;
			var style = body.style;
			var endEvent = (style.WebkitTransition !== undefined) ? "webkitTransitionEnd" : (style.OTransition !== undefined) ? "oTransitionEnd" : "transitionend";
			var hasCSSTransitionsSupport = style.WebkitTransition !== undefined || style.MozTransition !== undefined || style.OTransition !== undefined || style.transition !== undefined;
			var has3DSupport = ('WebKitCSSMatrix' in window && 'm11' in new WebKitCSSMatrix());
			var prefixes = ["", "-webkit-", "-moz-", "-o-"];
			var x = typeof position.x != 'undefined'? position.x: 0;
			var y = typeof position.y != 'undefined'? position.y: 0;
			
			return this.each(function() {
				var target = $(this);
				if (hasCSSTransitionsSupport) {
					if (typeof callback == 'function') {
						target.one(endEvent, callback);
					}
					for (var i in prefixes) {
						target.css(prefixes[i] + 'transition-duration', (duration / 1000).toFixed(1) + 's');
						if (has3DSupport) {
							target.css(prefixes[i] + 'transform', 'translate3d(' + x + 'px, ' + y + 'px, 0)');
						} else {
							target.css(prefixes[i] + 'transform', 'translate(' + x + 'px, ' + y + 'px)');
						}
					}
					if (duration == 0 && typeof callback == 'function') {
						callback();
					}
				} else {
					if (typeof callback != 'undefined') {
						target.animate({'margin-left': x + 'px', 'margin-top': y + 'px'}, duration, 'swing', callback);
					} else {
						target.animate({'margin-left': x + 'px', 'margin-top': y + 'px'}, duration);
					}
				}
			});
		}
	}
	
	$.fn.translate = 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.translate');
		}
		return false;
	}
})(jQuery);
