var modal = function(options, callback){
	var settings = {
		url: '',
		methodType: 'GET',
		encode: 'UTF-8',
		param: '',
		loaderImage: '/img/ico/load.gif',
		transition: 'fast',
		backgroundOpacity: 0.5,
		backgroundColor: '#000',
		position: 'center',
		referencePosition: '',
		top: 0,
		left: 0,
		executionTimeout: 2500,
		numbersOfAttempt: 5,
		inSuccess: function(){},
		inError: function(){},
		callbackClose: function(){},
		closeEsc: true,
		closeClickOut: true
	};

	options = jQuery.extend(settings, options);

	var attempt=0, altura='', leftModal, topModal;

	var close_modal = function(callback){
		$('.view_modal').fadeTo(options.transition, 0, function(){
			$(this).remove();
			$('.bg_modal').fadeTo(options.transition, 0, function(){
				$(this).remove();
				if(callback) callback();
			});
		});
		$(window, '.bg_modal').unbind();
		$('select').css('visibility', 'visible');
	};

	var build_elements = function(){
		var bgElement   = options.backgroundOpacity!=0 ? '<div class="bg_modal"><!-- --></div>' : '',
			loadElement = '<img src="'+options.loaderImage+'" alt="" class="load" />',
			viewElement = '<div class="view_modal"><!-- --></div>';

		$('body').append(bgElement+loadElement+viewElement);

		altura = $('html')[0].scrollHeight < $(window).height() ? $(window).height() : $('html')[0].scrollHeight;

		$('.bg_modal').width($('html')[0].scrollWidth).height(altura);

		options.backgroundOpacity!=0 ? $('.bg_modal').css('background-color',options.backgroundColor) : '';
		$('.view_modal, .bg_modal, .load').css('opacity', 0);

		$('select').css('visibility', 'hidden');

		$('.bg_modal').fadeTo(options.transition, options.backgroundOpacity, function(){
			$('.load')
				.css({
					'margin-top': parseInt(getTop('.load') - ($('.load').height()/2)),
					'margin-left': -parseInt($('.load').width()/2)
				})
				.fadeTo(options.transition, 1);
		});
	};

	var getTop = function(elem){
		var yScrolltop;
		if ($(elem).pageYOffset){
			yScrolltop = $(elem).pageYOffset;
		}else if(document.documentElement && document.documentElement.scrollTop || document.documentElement.scrollLeft){
			yScrolltop = document.documentElement.scrollTop;
		}else if(document.body){
			yScrolltop = document.body.scrollTop;
		};
		return yScrolltop;
	};

	var positioning_elements = function(){
		if(options.position!='center'){
			var offset=$(options.referencePosition).offset();
				leftModal=offset.left;
				topModal=offset.top;

			$('.view_modal').css({
					'margin-top': options.top,
					'margin-left': options.left,
					'left': leftModal,
					'top': topModal
				}
			);
		} else {
			$('.view_modal').css({
				'margin-top': parseInt(getTop('.view_modal') - ($('.view_modal').height()/2)),
				'margin-left': -parseInt($('.view_modal').width()/2)
			});
		};
	};

	var request_modal = function(){
		$.ajax({
			url: options.url,
			contentType: 'application/x-www-form-urlencoded; charset='+options.encode,
			type: options.methodType,
			data: !options.param ? {_:Math.random()} : '',
			error: function(msg){
				alert('erro', msg);
			},
			beforeSend: function(){
				build_elements();
				if(options.closeClickOut==true) {
					$('.bg_modal').click(function(){
						close_modal();
						return false;
					});
				}
			},
			success: function(data){
				$('.view_modal').append(data);
				if(options.inSuccess) options.inSuccess();
				$("a[rel='close-modal']").click(function(){
					close_modal();
					return false;
				});
				if(callback) callback();
			},
			complete: function(msg){
				window.setTimeout(function(){
					positioning_elements();
					$('.load').fadeTo(options.transition, 0, function(){
						$(this).remove();
						options.backgroundOpacity!=0 ? $('.view_modal').fadeTo(options.transition, 1) : '';
					});
				}, 1000);
			}
		});
		return false;
	};

	if(options.closeEsc==true){
		function trigger(e){
			if(!e){var e=window.event;};
			e.keyCode ? e.keyCode==27 ? close_modal() : '' : '';
			e.which   ? e.which==27   ? close_modal() : '' : '';
		};
		$(window).bind("keydown keypress keyup",trigger);
	};

	if($(".view_modal").size() > 0) {
		close_modal(request_modal);
	} else {
		request_modal();
	}
};
